mirror of
https://github.com/DarkStore-3DS/Project_CTR.git
synced 2026-07-04 08:49:03 +00:00
makerom v0.1
This commit is contained in:
+1352
File diff suppressed because it is too large
Load Diff
+202
@@ -0,0 +1,202 @@
|
||||
/**
|
||||
* \file aes.h
|
||||
*
|
||||
* \brief AES block cipher
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef POLARSSL_AES_H
|
||||
#define POLARSSL_AES_H
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <basetsd.h>
|
||||
typedef UINT32 uint32_t;
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#define AES_ENCRYPT 1
|
||||
#define AES_DECRYPT 0
|
||||
|
||||
#define POLARSSL_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
|
||||
#define POLARSSL_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
|
||||
|
||||
#if !defined(POLARSSL_AES_ALT)
|
||||
// Regular implementation
|
||||
//
|
||||
|
||||
/**
|
||||
* \brief AES context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int nr; /*!< number of rounds */
|
||||
uint32_t *rk; /*!< AES round keys */
|
||||
uint32_t 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, unsigned int keysize );
|
||||
|
||||
/**
|
||||
* \brief AES key schedule (decryption)
|
||||
*
|
||||
* \param ctx AES context to be initialized
|
||||
* \param key decryption key
|
||||
* \param keysize must be 128, 192 or 256
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
|
||||
*/
|
||||
int aes_setkey_dec( aes_context *ctx, const unsigned char *key, unsigned int keysize );
|
||||
|
||||
/**
|
||||
* \brief AES-ECB block encryption/decryption
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
* \param input 16-byte input block
|
||||
* \param output 16-byte output block
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int aes_crypt_ecb( aes_context *ctx,
|
||||
int mode,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] );
|
||||
|
||||
/**
|
||||
* \brief AES-CBC buffer encryption/decryption
|
||||
* Length should be a multiple of the block
|
||||
* size (16 bytes)
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_INPUT_LENGTH
|
||||
*/
|
||||
int aes_crypt_cbc( aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief AES-CFB128 buffer encryption/decryption.
|
||||
*
|
||||
* Note: Due to the nature of CFB you should use the same key schedule for
|
||||
* both encryption and decryption. So a context initialized with
|
||||
* aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
|
||||
*
|
||||
* both
|
||||
* \param ctx AES context
|
||||
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv_off offset in IV (updated after use)
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int aes_crypt_cfb128( aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief AES-CTR buffer encryption/decryption
|
||||
*
|
||||
* Warning: You have to keep the maximum use of your counter in mind!
|
||||
*
|
||||
* Note: Due to the nature of CTR you should use the same key schedule for
|
||||
* both encryption and decryption. So a context initialized with
|
||||
* aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
|
||||
*
|
||||
* \param length The length of the data
|
||||
* \param nc_off The offset in the current stream_block (for resuming
|
||||
* within current cipher stream). The offset pointer to
|
||||
* should be 0 at the start of a stream.
|
||||
* \param nonce_counter The 128-bit nonce and counter.
|
||||
* \param stream_block The saved stream-block for resuming. Is overwritten
|
||||
* by the function.
|
||||
* \param input The input data stream
|
||||
* \param output The output data stream
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int aes_crypt_ctr( aes_context *ctx,
|
||||
size_t length,
|
||||
size_t *nc_off,
|
||||
unsigned char nonce_counter[16],
|
||||
unsigned char stream_block[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* POLARSSL_AES_ALT */
|
||||
#include "polarssl/aes_alt.h"
|
||||
#endif /* POLARSSL_AES_ALT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int aes_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* aes.h */
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* An implementation of the ARCFOUR algorithm
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
* The ARCFOUR algorithm was publicly disclosed on 94/09.
|
||||
*
|
||||
* http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_ARC4_C)
|
||||
|
||||
#include "polarssl/arc4.h"
|
||||
|
||||
#if !defined(POLARSSL_ARC4_ALT)
|
||||
|
||||
/*
|
||||
* ARC4 key schedule
|
||||
*/
|
||||
void arc4_setup( arc4_context *ctx, const unsigned char *key, unsigned int keylen )
|
||||
{
|
||||
int i, j, a;
|
||||
unsigned int k;
|
||||
unsigned char *m;
|
||||
|
||||
ctx->x = 0;
|
||||
ctx->y = 0;
|
||||
m = ctx->m;
|
||||
|
||||
for( i = 0; i < 256; i++ )
|
||||
m[i] = (unsigned char) i;
|
||||
|
||||
j = k = 0;
|
||||
|
||||
for( i = 0; i < 256; i++, k++ )
|
||||
{
|
||||
if( k >= keylen ) k = 0;
|
||||
|
||||
a = m[i];
|
||||
j = ( j + a + key[k] ) & 0xFF;
|
||||
m[i] = m[j];
|
||||
m[j] = (unsigned char) a;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ARC4 cipher function
|
||||
*/
|
||||
int arc4_crypt( arc4_context *ctx, size_t length, const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
int x, y, a, b;
|
||||
size_t i;
|
||||
unsigned char *m;
|
||||
|
||||
x = ctx->x;
|
||||
y = ctx->y;
|
||||
m = ctx->m;
|
||||
|
||||
for( i = 0; i < length; i++ )
|
||||
{
|
||||
x = ( x + 1 ) & 0xFF; a = m[x];
|
||||
y = ( y + a ) & 0xFF; b = m[y];
|
||||
|
||||
m[x] = (unsigned char) b;
|
||||
m[y] = (unsigned char) a;
|
||||
|
||||
output[i] = (unsigned char)
|
||||
( input[i] ^ m[(unsigned char)( a + b )] );
|
||||
}
|
||||
|
||||
ctx->x = x;
|
||||
ctx->y = y;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif /* !POLARSSL_ARC4_ALT */
|
||||
|
||||
#if defined(POLARSSL_SELF_TEST)
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* ARC4 tests vectors as posted by Eric Rescorla in sep. 1994:
|
||||
*
|
||||
* http://groups.google.com/group/comp.security.misc/msg/10a300c9d21afca0
|
||||
*/
|
||||
static const unsigned char arc4_test_key[3][8] =
|
||||
{
|
||||
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
|
||||
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
||||
};
|
||||
|
||||
static const unsigned char arc4_test_pt[3][8] =
|
||||
{
|
||||
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
||||
};
|
||||
|
||||
static const unsigned char arc4_test_ct[3][8] =
|
||||
{
|
||||
{ 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 },
|
||||
{ 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 },
|
||||
{ 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A }
|
||||
};
|
||||
|
||||
/*
|
||||
* Checkup routine
|
||||
*/
|
||||
int arc4_self_test( int verbose )
|
||||
{
|
||||
int i;
|
||||
unsigned char ibuf[8];
|
||||
unsigned char obuf[8];
|
||||
arc4_context ctx;
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( " ARC4 test #%d: ", i + 1 );
|
||||
|
||||
memcpy( ibuf, arc4_test_pt[i], 8 );
|
||||
|
||||
arc4_setup( &ctx, arc4_test_key[i], 8 );
|
||||
arc4_crypt( &ctx, 8, ibuf, obuf );
|
||||
|
||||
if( memcmp( obuf, arc4_test_ct[i], 8 ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "passed\n" );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "\n" );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* \file arc4.h
|
||||
*
|
||||
* \brief The ARCFOUR stream cipher
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef POLARSSL_ARC4_H
|
||||
#define POLARSSL_ARC4_H
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if !defined(POLARSSL_ARC4_ALT)
|
||||
// Regular implementation
|
||||
//
|
||||
|
||||
/**
|
||||
* \brief ARC4 context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int x; /*!< permutation index */
|
||||
int y; /*!< permutation index */
|
||||
unsigned char m[256]; /*!< permutation table */
|
||||
}
|
||||
arc4_context;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief ARC4 key schedule
|
||||
*
|
||||
* \param ctx ARC4 context to be initialized
|
||||
* \param key the secret key
|
||||
* \param keylen length of the key
|
||||
*/
|
||||
void arc4_setup( arc4_context *ctx, const unsigned char *key, unsigned int keylen );
|
||||
|
||||
/**
|
||||
* \brief ARC4 cipher function
|
||||
*
|
||||
* \param ctx ARC4 context
|
||||
* \param length length of the input data
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer for the output data
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int arc4_crypt( arc4_context *ctx, size_t length, const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* POLARSSL_ARC4_ALT */
|
||||
#include "polarssl/arc4_alt.h"
|
||||
#endif /* POLARSSL_ARC4_ALT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int arc4_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* arc4.h */
|
||||
+246
@@ -0,0 +1,246 @@
|
||||
/**
|
||||
* \file asn1.h
|
||||
*
|
||||
* \brief Generic ASN.1 parsing
|
||||
*
|
||||
* Copyright (C) 2006-2011, 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_ASN1_H
|
||||
#define POLARSSL_ASN1_H
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_BIGNUM_C)
|
||||
#include "polarssl/bignum.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* \addtogroup asn1_module
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \name ASN1 Error codes
|
||||
* These error codes are OR'ed to X509 error codes for
|
||||
* higher error granularity.
|
||||
* ASN1 is a standard to specify data structures.
|
||||
* \{
|
||||
*/
|
||||
#define POLARSSL_ERR_ASN1_OUT_OF_DATA -0x0060 /**< Out of data when parsing an ASN1 data structure. */
|
||||
#define POLARSSL_ERR_ASN1_UNEXPECTED_TAG -0x0062 /**< ASN1 tag was of an unexpected value. */
|
||||
#define POLARSSL_ERR_ASN1_INVALID_LENGTH -0x0064 /**< Error when trying to determine the length or invalid length. */
|
||||
#define POLARSSL_ERR_ASN1_LENGTH_MISMATCH -0x0066 /**< Actual length differs from expected length. */
|
||||
#define POLARSSL_ERR_ASN1_INVALID_DATA -0x0068 /**< Data is invalid. (not used) */
|
||||
#define POLARSSL_ERR_ASN1_MALLOC_FAILED -0x006A /**< Memory allocation failed */
|
||||
#define POLARSSL_ERR_ASN1_BUF_TOO_SMALL -0x006C /**< Buffer too small when writing ASN.1 data structure. */
|
||||
|
||||
/* \} name */
|
||||
|
||||
/**
|
||||
* \name DER constants
|
||||
* These constants comply with DER encoded the ANS1 type tags.
|
||||
* DER encoding uses hexadecimal representation.
|
||||
* An example DER sequence is:\n
|
||||
* - 0x02 -- tag indicating INTEGER
|
||||
* - 0x01 -- length in octets
|
||||
* - 0x05 -- value
|
||||
* Such sequences are typically read into \c ::x509_buf.
|
||||
* \{
|
||||
*/
|
||||
#define ASN1_BOOLEAN 0x01
|
||||
#define ASN1_INTEGER 0x02
|
||||
#define ASN1_BIT_STRING 0x03
|
||||
#define ASN1_OCTET_STRING 0x04
|
||||
#define ASN1_NULL 0x05
|
||||
#define ASN1_OID 0x06
|
||||
#define ASN1_UTF8_STRING 0x0C
|
||||
#define ASN1_SEQUENCE 0x10
|
||||
#define ASN1_SET 0x11
|
||||
#define ASN1_PRINTABLE_STRING 0x13
|
||||
#define ASN1_T61_STRING 0x14
|
||||
#define ASN1_IA5_STRING 0x16
|
||||
#define ASN1_UTC_TIME 0x17
|
||||
#define ASN1_GENERALIZED_TIME 0x18
|
||||
#define ASN1_UNIVERSAL_STRING 0x1C
|
||||
#define ASN1_BMP_STRING 0x1E
|
||||
#define ASN1_PRIMITIVE 0x00
|
||||
#define ASN1_CONSTRUCTED 0x20
|
||||
#define ASN1_CONTEXT_SPECIFIC 0x80
|
||||
/* \} name */
|
||||
/* \} addtogroup asn1_module */
|
||||
|
||||
/** Returns the size of the binary string, without the trailing \\0 */
|
||||
#define OID_SIZE(x) (sizeof(x) - 1)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \name Functions to parse ASN.1 data structures
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Type-length-value structure that allows for ASN1 using DER.
|
||||
*/
|
||||
typedef struct _asn1_buf
|
||||
{
|
||||
int tag; /**< ASN1 type, e.g. ASN1_UTF8_STRING. */
|
||||
size_t len; /**< ASN1 length, e.g. in octets. */
|
||||
unsigned char *p; /**< ASN1 data, e.g. in ASCII. */
|
||||
}
|
||||
asn1_buf;
|
||||
|
||||
/**
|
||||
* Container for ASN1 bit strings.
|
||||
*/
|
||||
typedef struct _asn1_bitstring
|
||||
{
|
||||
size_t len; /**< ASN1 length, e.g. in octets. */
|
||||
unsigned char unused_bits; /**< Number of unused bits at the end of the string */
|
||||
unsigned char *p; /**< Raw ASN1 data for the bit string */
|
||||
}
|
||||
asn1_bitstring;
|
||||
|
||||
/**
|
||||
* Container for a sequence of ASN.1 items
|
||||
*/
|
||||
typedef struct _asn1_sequence
|
||||
{
|
||||
asn1_buf buf; /**< Buffer containing the given ASN.1 item. */
|
||||
struct _asn1_sequence *next; /**< The next entry in the sequence. */
|
||||
}
|
||||
asn1_sequence;
|
||||
|
||||
/**
|
||||
* Get the length of an ASN.1 element.
|
||||
* Updates the pointer to immediately behind the length.
|
||||
*
|
||||
* \param p The position in the ASN.1 data
|
||||
* \param end End of data
|
||||
* \param len The variable that will receive the value
|
||||
*
|
||||
* \return 0 if successful, POLARSSL_ERR_ASN1_OUT_OF_DATA on reaching
|
||||
* end of data, POLARSSL_ERR_ASN1_INVALID_LENGTH if length is
|
||||
* unparseable.
|
||||
*/
|
||||
int asn1_get_len( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
size_t *len );
|
||||
|
||||
/**
|
||||
* Get the tag and length of the tag. Check for the requested tag.
|
||||
* Updates the pointer to immediately behind the tag and length.
|
||||
*
|
||||
* \param p The position in the ASN.1 data
|
||||
* \param end End of data
|
||||
* \param len The variable that will receive the length
|
||||
* \param tag The expected tag
|
||||
*
|
||||
* \return 0 if successful, POLARSSL_ERR_ASN1_UNEXPECTED_TAG if tag did
|
||||
* not match requested tag, or another specific ASN.1 error code.
|
||||
*/
|
||||
int asn1_get_tag( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
size_t *len, int tag );
|
||||
|
||||
/**
|
||||
* Retrieve a boolean ASN.1 tag and its value.
|
||||
* Updates the pointer to immediately behind the full tag.
|
||||
*
|
||||
* \param p The position in the ASN.1 data
|
||||
* \param end End of data
|
||||
* \param val The variable that will receive the value
|
||||
*
|
||||
* \return 0 if successful or a specific ASN.1 error code.
|
||||
*/
|
||||
int asn1_get_bool( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
int *val );
|
||||
|
||||
/**
|
||||
* Retrieve an integer ASN.1 tag and its value.
|
||||
* Updates the pointer to immediately behind the full tag.
|
||||
*
|
||||
* \param p The position in the ASN.1 data
|
||||
* \param end End of data
|
||||
* \param val The variable that will receive the value
|
||||
*
|
||||
* \return 0 if successful or a specific ASN.1 error code.
|
||||
*/
|
||||
int asn1_get_int( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
int *val );
|
||||
|
||||
/**
|
||||
* Retrieve a bitstring ASN.1 tag and its value.
|
||||
* Updates the pointer to immediately behind the full tag.
|
||||
*
|
||||
* \param p The position in the ASN.1 data
|
||||
* \param end End of data
|
||||
* \param bs The variable that will receive the value
|
||||
*
|
||||
* \return 0 if successful or a specific ASN.1 error code.
|
||||
*/
|
||||
int asn1_get_bitstring( unsigned char **p, const unsigned char *end,
|
||||
asn1_bitstring *bs);
|
||||
|
||||
/**
|
||||
* Parses and splits an ASN.1 "SEQUENCE OF <tag>"
|
||||
* Updated the pointer to immediately behind the full sequence tag.
|
||||
*
|
||||
* \param p The position in the ASN.1 data
|
||||
* \param end End of data
|
||||
* \param cur First variable in the chain to fill
|
||||
* \param tag Type of sequence
|
||||
*
|
||||
* \return 0 if successful or a specific ASN.1 error code.
|
||||
*/
|
||||
int asn1_get_sequence_of( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
asn1_sequence *cur,
|
||||
int tag);
|
||||
|
||||
#if defined(POLARSSL_BIGNUM_C)
|
||||
/**
|
||||
* Retrieve a MPI value from an integer ASN.1 tag.
|
||||
* Updates the pointer to immediately behind the full tag.
|
||||
*
|
||||
* \param p The position in the ASN.1 data
|
||||
* \param end End of data
|
||||
* \param X The MPI that will receive the value
|
||||
*
|
||||
* \return 0 if successful or a specific ASN.1 or MPI error code.
|
||||
*/
|
||||
int asn1_get_mpi( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mpi *X );
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* asn1.h */
|
||||
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Generic ASN.1 parsing
|
||||
*
|
||||
* Copyright (C) 2006-2011, 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.
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_ASN1_PARSE_C)
|
||||
|
||||
#include "polarssl/asn1.h"
|
||||
|
||||
#if defined(POLARSSL_BIGNUM_C)
|
||||
#include "polarssl/bignum.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
/*
|
||||
* ASN.1 DER decoding routines
|
||||
*/
|
||||
int asn1_get_len( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
size_t *len )
|
||||
{
|
||||
if( ( end - *p ) < 1 )
|
||||
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
|
||||
|
||||
if( ( **p & 0x80 ) == 0 )
|
||||
*len = *(*p)++;
|
||||
else
|
||||
{
|
||||
switch( **p & 0x7F )
|
||||
{
|
||||
case 1:
|
||||
if( ( end - *p ) < 2 )
|
||||
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
|
||||
|
||||
*len = (*p)[1];
|
||||
(*p) += 2;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if( ( end - *p ) < 3 )
|
||||
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
|
||||
|
||||
*len = ( (*p)[1] << 8 ) | (*p)[2];
|
||||
(*p) += 3;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if( ( end - *p ) < 4 )
|
||||
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
|
||||
|
||||
*len = ( (*p)[1] << 16 ) | ( (*p)[2] << 8 ) | (*p)[3];
|
||||
(*p) += 4;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if( ( end - *p ) < 5 )
|
||||
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
|
||||
|
||||
*len = ( (*p)[1] << 24 ) | ( (*p)[2] << 16 ) | ( (*p)[3] << 8 ) | (*p)[4];
|
||||
(*p) += 5;
|
||||
break;
|
||||
|
||||
default:
|
||||
return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
|
||||
}
|
||||
}
|
||||
|
||||
if( *len > (size_t) ( end - *p ) )
|
||||
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int asn1_get_tag( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
size_t *len, int tag )
|
||||
{
|
||||
if( ( end - *p ) < 1 )
|
||||
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
|
||||
|
||||
if( **p != tag )
|
||||
return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
|
||||
|
||||
(*p)++;
|
||||
|
||||
return( asn1_get_len( p, end, len ) );
|
||||
}
|
||||
|
||||
int asn1_get_bool( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
int *val )
|
||||
{
|
||||
int ret;
|
||||
size_t len;
|
||||
|
||||
if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( len != 1 )
|
||||
return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
|
||||
|
||||
*val = ( **p != 0 ) ? 1 : 0;
|
||||
(*p)++;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int asn1_get_int( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
int *val )
|
||||
{
|
||||
int ret;
|
||||
size_t len;
|
||||
|
||||
if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( len > sizeof( int ) || ( **p & 0x80 ) != 0 )
|
||||
return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
|
||||
|
||||
*val = 0;
|
||||
|
||||
while( len-- > 0 )
|
||||
{
|
||||
*val = ( *val << 8 ) | **p;
|
||||
(*p)++;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_BIGNUM_C)
|
||||
int asn1_get_mpi( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mpi *X )
|
||||
{
|
||||
int ret;
|
||||
size_t len;
|
||||
|
||||
if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
ret = mpi_read_binary( X, *p, len );
|
||||
|
||||
*p += len;
|
||||
|
||||
return( ret );
|
||||
}
|
||||
#endif /* POLARSSL_BIGNUM_C */
|
||||
|
||||
int asn1_get_bitstring( unsigned char **p, const unsigned char *end,
|
||||
asn1_bitstring *bs)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Certificate type is a single byte bitstring */
|
||||
if( ( ret = asn1_get_tag( p, end, &bs->len, ASN1_BIT_STRING ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
/* Check length, subtract one for actual bit string length */
|
||||
if ( bs->len < 1 )
|
||||
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
|
||||
bs->len -= 1;
|
||||
|
||||
/* Get number of unused bits, ensure unused bits <= 7 */
|
||||
bs->unused_bits = **p;
|
||||
if( bs->unused_bits > 7 )
|
||||
return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
|
||||
(*p)++;
|
||||
|
||||
/* Get actual bitstring */
|
||||
bs->p = *p;
|
||||
*p += bs->len;
|
||||
|
||||
if( *p != end )
|
||||
return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Parses and splits an ASN.1 "SEQUENCE OF <tag>"
|
||||
*/
|
||||
int asn1_get_sequence_of( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
asn1_sequence *cur,
|
||||
int tag)
|
||||
{
|
||||
int ret;
|
||||
size_t len;
|
||||
asn1_buf *buf;
|
||||
|
||||
/* Get main sequence tag */
|
||||
if( ( ret = asn1_get_tag( p, end, &len,
|
||||
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( *p + len != end )
|
||||
return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||
|
||||
while( *p < end )
|
||||
{
|
||||
buf = &(cur->buf);
|
||||
buf->tag = **p;
|
||||
|
||||
if( ( ret = asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
buf->p = *p;
|
||||
*p += buf->len;
|
||||
|
||||
/* Allocate and assign next pointer */
|
||||
if (*p < end)
|
||||
{
|
||||
cur->next = (asn1_sequence *) malloc(
|
||||
sizeof( asn1_sequence ) );
|
||||
|
||||
if( cur->next == NULL )
|
||||
return( POLARSSL_ERR_ASN1_MALLOC_FAILED );
|
||||
|
||||
cur = cur->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set final sequence entry's next pointer to NULL */
|
||||
cur->next = NULL;
|
||||
|
||||
if( *p != end )
|
||||
return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* ASN.1 buffer writing functionality
|
||||
*
|
||||
* Copyright (C) 2006-2012, 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.
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_ASN1_WRITE_C)
|
||||
|
||||
#include "polarssl/asn1write.h"
|
||||
|
||||
int asn1_write_len( unsigned char **p, unsigned char *start, size_t len )
|
||||
{
|
||||
if( len < 0x80 )
|
||||
{
|
||||
if( *p - start < 1 )
|
||||
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
|
||||
|
||||
*--(*p) = len;
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( len <= 0xFF )
|
||||
{
|
||||
if( *p - start < 2 )
|
||||
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
|
||||
|
||||
*--(*p) = len;
|
||||
*--(*p) = 0x81;
|
||||
return( 2 );
|
||||
}
|
||||
|
||||
if( *p - start < 3 )
|
||||
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
|
||||
|
||||
// We assume we never have lengths larger than 65535 bytes
|
||||
//
|
||||
*--(*p) = len % 256;
|
||||
*--(*p) = ( len / 256 ) % 256;
|
||||
*--(*p) = 0x82;
|
||||
|
||||
return( 3 );
|
||||
}
|
||||
|
||||
int asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag )
|
||||
{
|
||||
if( *p - start < 1 )
|
||||
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
|
||||
|
||||
*--(*p) = tag;
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
int asn1_write_mpi( unsigned char **p, unsigned char *start, mpi *X )
|
||||
{
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
|
||||
// Write the MPI
|
||||
//
|
||||
len = mpi_size( X );
|
||||
|
||||
if( *p - start < (int) len )
|
||||
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
|
||||
|
||||
(*p) -= len;
|
||||
mpi_write_binary( X, *p, len );
|
||||
|
||||
// DER format assumes 2s complement for numbers, so the leftmost bit
|
||||
// should be 0 for positive numbers and 1 for negative numbers.
|
||||
//
|
||||
if ( X->s ==1 && **p & 0x80 )
|
||||
{
|
||||
if( *p - start < 1 )
|
||||
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
|
||||
|
||||
*--(*p) = 0x00;
|
||||
len += 1;
|
||||
}
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_INTEGER ) );
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
int asn1_write_null( unsigned char **p, unsigned char *start )
|
||||
{
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
|
||||
// Write NULL
|
||||
//
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, 0) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_NULL ) );
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
int asn1_write_oid( unsigned char **p, unsigned char *start, char *oid )
|
||||
{
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
|
||||
// Write OID
|
||||
//
|
||||
len = strlen( oid );
|
||||
|
||||
if( *p - start < (int) len )
|
||||
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
|
||||
|
||||
(*p) -= len;
|
||||
memcpy( *p, oid, len );
|
||||
|
||||
ASN1_CHK_ADD( len , asn1_write_len( p, start, len ) );
|
||||
ASN1_CHK_ADD( len , asn1_write_tag( p, start, ASN1_OID ) );
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
int asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start,
|
||||
char *algorithm_oid )
|
||||
{
|
||||
int ret;
|
||||
size_t null_len = 0;
|
||||
size_t oid_len = 0;
|
||||
size_t len = 0;
|
||||
|
||||
// Write NULL
|
||||
//
|
||||
ASN1_CHK_ADD( null_len, asn1_write_null( p, start ) );
|
||||
|
||||
// Write OID
|
||||
//
|
||||
ASN1_CHK_ADD( oid_len, asn1_write_oid( p, start, algorithm_oid ) );
|
||||
|
||||
len = oid_len + null_len;
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, oid_len + null_len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start,
|
||||
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
int asn1_write_int( unsigned char **p, unsigned char *start, int val )
|
||||
{
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
|
||||
// TODO negative values and values larger than 128
|
||||
// DER format assumes 2s complement for numbers, so the leftmost bit
|
||||
// should be 0 for positive numbers and 1 for negative numbers.
|
||||
//
|
||||
if( *p - start < 1 )
|
||||
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
|
||||
|
||||
len += 1;
|
||||
*--(*p) = val;
|
||||
|
||||
if ( val > 0 && **p & 0x80 )
|
||||
{
|
||||
if( *p - start < 1 )
|
||||
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
|
||||
|
||||
*--(*p) = 0x00;
|
||||
len += 1;
|
||||
}
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_INTEGER ) );
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
int asn1_write_printable_string( unsigned char **p, unsigned char *start,
|
||||
char *text )
|
||||
{
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
|
||||
// Write string
|
||||
//
|
||||
len = strlen( text );
|
||||
|
||||
if( *p - start < (int) len )
|
||||
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
|
||||
|
||||
(*p) -= len;
|
||||
memcpy( *p, text, len );
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_PRINTABLE_STRING ) );
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
int asn1_write_ia5_string( unsigned char **p, unsigned char *start,
|
||||
char *text )
|
||||
{
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
|
||||
// Write string
|
||||
//
|
||||
len = strlen( text );
|
||||
|
||||
if( *p - start < (int) len )
|
||||
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
|
||||
|
||||
(*p) -= len;
|
||||
memcpy( *p, text, len );
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_IA5_STRING ) );
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* \file asn1write.h
|
||||
*
|
||||
* \brief ASN.1 buffer writing functionality
|
||||
*
|
||||
* Copyright (C) 2006-2012, 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_ASN1_WRITE_H
|
||||
#define POLARSSL_ASN1_WRITE_H
|
||||
|
||||
#include "polarssl/asn1.h"
|
||||
|
||||
#define ASN1_CHK_ADD(g, f) if( ( ret = f ) < 0 ) return( ret ); else g += ret
|
||||
|
||||
int asn1_write_len( unsigned char **p, unsigned char *start, size_t len );
|
||||
int asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag );
|
||||
int asn1_write_mpi( unsigned char **p, unsigned char *start, mpi *X );
|
||||
int asn1_write_null( unsigned char **p, unsigned char *start );
|
||||
int asn1_write_oid( unsigned char **p, unsigned char *start, char *oid );
|
||||
int asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start, char *algorithm_oid );
|
||||
int asn1_write_int( unsigned char **p, unsigned char *start, int val );
|
||||
int asn1_write_printable_string( unsigned char **p, unsigned char *start,
|
||||
char *text );
|
||||
int asn1_write_ia5_string( unsigned char **p, unsigned char *start,
|
||||
char *text );
|
||||
|
||||
#endif /* POLARSSL_ASN1_WRITE_H */
|
||||
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* RFC 1521 base64 encoding/decoding
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_BASE64_C)
|
||||
|
||||
#include "polarssl/base64.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <basetsd.h>
|
||||
typedef UINT32 uint32_t;
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
static const unsigned char base64_enc_map[64] =
|
||||
{
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
|
||||
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
|
||||
'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
|
||||
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
|
||||
'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', '+', '/'
|
||||
};
|
||||
|
||||
static const unsigned char base64_dec_map[128] =
|
||||
{
|
||||
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
|
||||
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
|
||||
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
|
||||
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
|
||||
127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
|
||||
54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
|
||||
127, 64, 127, 127, 127, 0, 1, 2, 3, 4,
|
||||
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 127, 127, 127, 127, 127, 127, 26, 27, 28,
|
||||
29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
|
||||
39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
|
||||
49, 50, 51, 127, 127, 127, 127, 127
|
||||
};
|
||||
|
||||
/*
|
||||
* Encode a buffer into base64 format
|
||||
*/
|
||||
int base64_encode( unsigned char *dst, size_t *dlen,
|
||||
const unsigned char *src, size_t slen )
|
||||
{
|
||||
size_t i, n;
|
||||
int C1, C2, C3;
|
||||
unsigned char *p;
|
||||
|
||||
if( slen == 0 )
|
||||
return( 0 );
|
||||
|
||||
n = (slen << 3) / 6;
|
||||
|
||||
switch( (slen << 3) - (n * 6) )
|
||||
{
|
||||
case 2: n += 3; break;
|
||||
case 4: n += 2; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if( *dlen < n + 1 )
|
||||
{
|
||||
*dlen = n + 1;
|
||||
return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
|
||||
}
|
||||
|
||||
n = (slen / 3) * 3;
|
||||
|
||||
for( i = 0, p = dst; i < n; i += 3 )
|
||||
{
|
||||
C1 = *src++;
|
||||
C2 = *src++;
|
||||
C3 = *src++;
|
||||
|
||||
*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
|
||||
*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
|
||||
*p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
|
||||
*p++ = base64_enc_map[C3 & 0x3F];
|
||||
}
|
||||
|
||||
if( i < slen )
|
||||
{
|
||||
C1 = *src++;
|
||||
C2 = ((i + 1) < slen) ? *src++ : 0;
|
||||
|
||||
*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
|
||||
*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
|
||||
|
||||
if( (i + 1) < slen )
|
||||
*p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
|
||||
else *p++ = '=';
|
||||
|
||||
*p++ = '=';
|
||||
}
|
||||
|
||||
*dlen = p - dst;
|
||||
*p = 0;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode a base64-formatted buffer
|
||||
*/
|
||||
int base64_decode( unsigned char *dst, size_t *dlen,
|
||||
const unsigned char *src, size_t slen )
|
||||
{
|
||||
size_t i, n;
|
||||
uint32_t j, x;
|
||||
unsigned char *p;
|
||||
|
||||
for( i = j = n = 0; i < slen; i++ )
|
||||
{
|
||||
if( ( slen - i ) >= 2 &&
|
||||
src[i] == '\r' && src[i + 1] == '\n' )
|
||||
continue;
|
||||
|
||||
if( src[i] == '\n' )
|
||||
continue;
|
||||
|
||||
if( src[i] == '=' && ++j > 2 ){
|
||||
printf("err 0 char[%d] = '%c' (0x%x)\n",i,src[i],src[i]);
|
||||
return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
|
||||
}
|
||||
|
||||
if( src[i] > 127 || base64_dec_map[src[i]] == 127 ){
|
||||
printf("err 1 char[%d] = '%c' (0x%x)\n",i,src[i],src[i]);
|
||||
return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
|
||||
}
|
||||
|
||||
if( base64_dec_map[src[i]] < 64 && j != 0 ){
|
||||
printf("err 2 char[%d] = '%c' (0x%x)\n",i,src[i],src[i]);
|
||||
return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
|
||||
}
|
||||
|
||||
n++;
|
||||
}
|
||||
|
||||
if( n == 0 )
|
||||
return( 0 );
|
||||
|
||||
|
||||
n = ((n * 6) + 7) >> 3;
|
||||
|
||||
if( (*dlen+4) < n )
|
||||
{
|
||||
*dlen = n;
|
||||
return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
|
||||
}
|
||||
|
||||
for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
|
||||
{
|
||||
if( *src == '\r' || *src == '\n' )
|
||||
continue;
|
||||
|
||||
j -= ( base64_dec_map[*src] == 64 );
|
||||
x = (x << 6) | ( base64_dec_map[*src] & 0x3F );
|
||||
|
||||
if( ++n == 4 )
|
||||
{
|
||||
n = 0;
|
||||
if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
|
||||
if( j > 1 ) *p++ = (unsigned char)( x >> 8 );
|
||||
if( j > 2 ) *p++ = (unsigned char)( x );
|
||||
}
|
||||
}
|
||||
|
||||
*dlen = p - dst;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_SELF_TEST)
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static const unsigned char base64_test_dec[64] =
|
||||
{
|
||||
0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
|
||||
0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
|
||||
0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
|
||||
0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
|
||||
0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
|
||||
0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
|
||||
0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
|
||||
0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
|
||||
};
|
||||
|
||||
static const unsigned char base64_test_enc[] =
|
||||
"JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
|
||||
"swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
|
||||
|
||||
/*
|
||||
* Checkup routine
|
||||
*/
|
||||
int base64_self_test( int verbose )
|
||||
{
|
||||
size_t len;
|
||||
const unsigned char *src;
|
||||
unsigned char buffer[128];
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( " Base64 encoding test: " );
|
||||
|
||||
len = sizeof( buffer );
|
||||
src = base64_test_dec;
|
||||
|
||||
if( base64_encode( buffer, &len, src, 64 ) != 0 ||
|
||||
memcmp( base64_test_enc, buffer, 88 ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "passed\n Base64 decoding test: " );
|
||||
|
||||
len = sizeof( buffer );
|
||||
src = base64_test_enc;
|
||||
|
||||
if( base64_decode( buffer, &len, src, 88 ) != 0 ||
|
||||
memcmp( base64_test_dec, buffer, 64 ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "passed\n\n" );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* \file base64.h
|
||||
*
|
||||
* \brief RFC 1521 base64 encoding/decoding
|
||||
*
|
||||
* 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_BASE64_H
|
||||
#define POLARSSL_BASE64_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL -0x002A /**< Output buffer too small. */
|
||||
#define POLARSSL_ERR_BASE64_INVALID_CHARACTER -0x002C /**< Invalid character in input. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Encode a buffer into base64 format
|
||||
*
|
||||
* \param dst destination buffer
|
||||
* \param dlen size of the buffer
|
||||
* \param src source buffer
|
||||
* \param slen amount of data to be encoded
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL.
|
||||
* *dlen is always updated to reflect the amount
|
||||
* of data that has (or would have) been written.
|
||||
*
|
||||
* \note Call this function with *dlen = 0 to obtain the
|
||||
* required buffer size in *dlen
|
||||
*/
|
||||
int base64_encode( unsigned char *dst, size_t *dlen,
|
||||
const unsigned char *src, size_t slen );
|
||||
|
||||
/**
|
||||
* \brief Decode a base64-formatted buffer
|
||||
*
|
||||
* \param dst destination buffer
|
||||
* \param dlen size of the buffer
|
||||
* \param src source buffer
|
||||
* \param slen amount of data to be decoded
|
||||
*
|
||||
* \return 0 if successful, POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL, or
|
||||
* POLARSSL_ERR_BASE64_INVALID_CHARACTER if the input data is
|
||||
* not correct. *dlen is always updated to reflect the amount
|
||||
* of data that has (or would have) been written.
|
||||
*
|
||||
* \note Call this function with *dlen = 0 to obtain the
|
||||
* required buffer size in *dlen
|
||||
*/
|
||||
int base64_decode( unsigned char *dst, size_t *dlen,
|
||||
const unsigned char *src, size_t slen );
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int base64_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* base64.h */
|
||||
+2135
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,685 @@
|
||||
/**
|
||||
* \file bignum.h
|
||||
*
|
||||
* \brief Multi-precision integer library
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef POLARSSL_BIGNUM_H
|
||||
#define POLARSSL_BIGNUM_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <basetsd.h>
|
||||
#if (_MSC_VER <= 1200)
|
||||
typedef signed short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
#else
|
||||
typedef INT16 int16_t;
|
||||
typedef UINT16 uint16_t;
|
||||
#endif
|
||||
typedef INT32 int32_t;
|
||||
typedef INT64 int64_t;
|
||||
typedef UINT32 uint32_t;
|
||||
typedef UINT64 uint64_t;
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#define POLARSSL_ERR_MPI_FILE_IO_ERROR -0x0002 /**< An error occurred while reading from or writing to a file. */
|
||||
#define POLARSSL_ERR_MPI_BAD_INPUT_DATA -0x0004 /**< Bad input parameters to function. */
|
||||
#define POLARSSL_ERR_MPI_INVALID_CHARACTER -0x0006 /**< There is an invalid character in the digit string. */
|
||||
#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL -0x0008 /**< The buffer is too small to write to. */
|
||||
#define POLARSSL_ERR_MPI_NEGATIVE_VALUE -0x000A /**< The input arguments are negative or result in illegal output. */
|
||||
#define POLARSSL_ERR_MPI_DIVISION_BY_ZERO -0x000C /**< The input argument for division is zero, which is not allowed. */
|
||||
#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE -0x000E /**< The input arguments are not acceptable. */
|
||||
#define POLARSSL_ERR_MPI_MALLOC_FAILED -0x0010 /**< Memory allocation failed. */
|
||||
|
||||
#define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup
|
||||
|
||||
/*
|
||||
* Maximum size MPIs are allowed to grow to in number of limbs.
|
||||
*/
|
||||
#define POLARSSL_MPI_MAX_LIMBS 10000
|
||||
|
||||
#if !defined(POLARSSL_CONFIG_OPTIONS)
|
||||
/*
|
||||
* Maximum window size used for modular exponentiation. Default: 6
|
||||
* Minimum value: 1. Maximum value: 6.
|
||||
*
|
||||
* Result is an array of ( 2 << POLARSSL_MPI_WINDOW_SIZE ) MPIs used
|
||||
* for the sliding window calculation. (So 64 by default)
|
||||
*
|
||||
* Reduction in size, reduces speed.
|
||||
*/
|
||||
#define POLARSSL_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */
|
||||
|
||||
/*
|
||||
* Maximum size of MPIs allowed in bits and bytes for user-MPIs.
|
||||
* ( Default: 512 bytes => 4096 bits, Maximum tested: 2048 bytes => 16384 bits )
|
||||
*
|
||||
* Note: Calculations can results temporarily in larger MPIs. So the number
|
||||
* of limbs required (POLARSSL_MPI_MAX_LIMBS) is higher.
|
||||
*/
|
||||
#define POLARSSL_MPI_MAX_SIZE 512 /**< Maximum number of bytes for usable MPIs. */
|
||||
|
||||
#endif /* !POLARSSL_CONFIG_OPTIONS */
|
||||
|
||||
#define POLARSSL_MPI_MAX_BITS ( 8 * POLARSSL_MPI_MAX_SIZE ) /**< Maximum number of bits for usable MPIs. */
|
||||
|
||||
/*
|
||||
* When reading from files with mpi_read_file() and writing to files with
|
||||
* mpi_write_file() the buffer should have space
|
||||
* for a (short) label, the MPI (in the provided radix), the newline
|
||||
* characters and the '\0'.
|
||||
*
|
||||
* By default we assume at least a 10 char label, a minimum radix of 10
|
||||
* (decimal) and a maximum of 4096 bit numbers (1234 decimal chars).
|
||||
* Autosized at compile time for at least a 10 char label, a minimum radix
|
||||
* of 10 (decimal) for a number of POLARSSL_MPI_MAX_BITS size.
|
||||
*
|
||||
* This used to be statically sized to 1250 for a maximum of 4096 bit
|
||||
* numbers (1234 decimal chars).
|
||||
*
|
||||
* Calculate using the formula:
|
||||
* POLARSSL_MPI_RW_BUFFER_SIZE = ceil(POLARSSL_MPI_MAX_BITS / ln(10) * ln(2)) +
|
||||
* LabelSize + 6
|
||||
*/
|
||||
#define POLARSSL_MPI_MAX_BITS_SCALE100 ( 100 * POLARSSL_MPI_MAX_BITS )
|
||||
#define LN_2_DIV_LN_10_SCALE100 332
|
||||
#define POLARSSL_MPI_RW_BUFFER_SIZE ( ((POLARSSL_MPI_MAX_BITS_SCALE100 + LN_2_DIV_LN_10_SCALE100 - 1) / LN_2_DIV_LN_10_SCALE100) + 10 + 6 )
|
||||
|
||||
/*
|
||||
* Define the base integer type, architecture-wise
|
||||
*/
|
||||
#if defined(POLARSSL_HAVE_INT8)
|
||||
typedef signed char t_sint;
|
||||
typedef unsigned char t_uint;
|
||||
typedef uint16_t t_udbl;
|
||||
#define POLARSSL_HAVE_UDBL
|
||||
#else
|
||||
#if defined(POLARSSL_HAVE_INT16)
|
||||
typedef int16_t t_sint;
|
||||
typedef uint16_t t_uint;
|
||||
typedef uint32_t t_udbl;
|
||||
#define POLARSSL_HAVE_UDBL
|
||||
#else
|
||||
#if ( defined(_MSC_VER) && defined(_M_AMD64) )
|
||||
typedef int64_t t_sint;
|
||||
typedef uint64_t t_uint;
|
||||
#else
|
||||
#if ( defined(__GNUC__) && ( \
|
||||
defined(__amd64__) || defined(__x86_64__) || \
|
||||
defined(__ppc64__) || defined(__powerpc64__) || \
|
||||
defined(__ia64__) || defined(__alpha__) || \
|
||||
(defined(__sparc__) && defined(__arch64__)) || \
|
||||
defined(__s390x__) ) )
|
||||
typedef int64_t t_sint;
|
||||
typedef uint64_t t_uint;
|
||||
typedef unsigned int t_udbl __attribute__((mode(TI)));
|
||||
#define POLARSSL_HAVE_UDBL
|
||||
#else
|
||||
typedef int32_t t_sint;
|
||||
typedef uint32_t t_uint;
|
||||
#if ( defined(_MSC_VER) && defined(_M_IX86) )
|
||||
typedef uint64_t t_udbl;
|
||||
#define POLARSSL_HAVE_UDBL
|
||||
#else
|
||||
#if defined( POLARSSL_HAVE_LONGLONG )
|
||||
typedef unsigned long long t_udbl;
|
||||
#define POLARSSL_HAVE_UDBL
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif /* POLARSSL_HAVE_INT16 */
|
||||
#endif /* POLARSSL_HAVE_INT8 */
|
||||
|
||||
/**
|
||||
* \brief MPI structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int s; /*!< integer sign */
|
||||
size_t n; /*!< total # of limbs */
|
||||
t_uint *p; /*!< pointer to limbs */
|
||||
}
|
||||
mpi;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Initialize one MPI
|
||||
*
|
||||
* \param X One MPI to initialize.
|
||||
*/
|
||||
void mpi_init( mpi *X );
|
||||
|
||||
/**
|
||||
* \brief Unallocate one MPI
|
||||
*
|
||||
* \param X One MPI to unallocate.
|
||||
*/
|
||||
void mpi_free( mpi *X );
|
||||
|
||||
/**
|
||||
* \brief Enlarge to the specified number of limbs
|
||||
*
|
||||
* \param X MPI to grow
|
||||
* \param nblimbs The target number of limbs
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
|
||||
*/
|
||||
int mpi_grow( mpi *X, size_t nblimbs );
|
||||
|
||||
/**
|
||||
* \brief Copy the contents of Y into X
|
||||
*
|
||||
* \param X Destination MPI
|
||||
* \param Y Source MPI
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
|
||||
*/
|
||||
int mpi_copy( mpi *X, const mpi *Y );
|
||||
|
||||
/**
|
||||
* \brief Swap the contents of X and Y
|
||||
*
|
||||
* \param X First MPI value
|
||||
* \param Y Second MPI value
|
||||
*/
|
||||
void mpi_swap( mpi *X, mpi *Y );
|
||||
|
||||
/**
|
||||
* \brief Set value from integer
|
||||
*
|
||||
* \param X MPI to set
|
||||
* \param z Value to use
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
|
||||
*/
|
||||
int mpi_lset( mpi *X, t_sint z );
|
||||
|
||||
/**
|
||||
* \brief Get a specific bit from X
|
||||
*
|
||||
* \param X MPI to use
|
||||
* \param pos Zero-based index of the bit in X
|
||||
*
|
||||
* \return Either a 0 or a 1
|
||||
*/
|
||||
int mpi_get_bit( const mpi *X, size_t pos );
|
||||
|
||||
/**
|
||||
* \brief Set a bit of X to a specific value of 0 or 1
|
||||
*
|
||||
* \note Will grow X if necessary to set a bit to 1 in a not yet
|
||||
* existing limb. Will not grow if bit should be set to 0
|
||||
*
|
||||
* \param X MPI to use
|
||||
* \param pos Zero-based index of the bit in X
|
||||
* \param val The value to set the bit to (0 or 1)
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
|
||||
* POLARSSL_ERR_MPI_BAD_INPUT_DATA if val is not 0 or 1
|
||||
*/
|
||||
int mpi_set_bit( mpi *X, size_t pos, unsigned char val );
|
||||
|
||||
/**
|
||||
* \brief Return the number of zero-bits before the least significant
|
||||
* '1' bit
|
||||
*
|
||||
* Note: Thus also the zero-based index of the least significant '1' bit
|
||||
*
|
||||
* \param X MPI to use
|
||||
*/
|
||||
size_t mpi_lsb( const mpi *X );
|
||||
|
||||
/**
|
||||
* \brief Return the number of bits up to and including the most
|
||||
* significant '1' bit'
|
||||
*
|
||||
* Note: Thus also the one-based index of the most significant '1' bit
|
||||
*
|
||||
* \param X MPI to use
|
||||
*/
|
||||
size_t mpi_msb( const mpi *X );
|
||||
|
||||
/**
|
||||
* \brief Return the total size in bytes
|
||||
*
|
||||
* \param X MPI to use
|
||||
*/
|
||||
size_t mpi_size( const mpi *X );
|
||||
|
||||
/**
|
||||
* \brief Import from an ASCII string
|
||||
*
|
||||
* \param X Destination MPI
|
||||
* \param radix Input numeric base
|
||||
* \param s Null-terminated string buffer
|
||||
*
|
||||
* \return 0 if successful, or a POLARSSL_ERR_MPI_XXX error code
|
||||
*/
|
||||
int mpi_read_string( mpi *X, int radix, const char *s );
|
||||
|
||||
/**
|
||||
* \brief Export into an ASCII string
|
||||
*
|
||||
* \param X Source MPI
|
||||
* \param radix Output numeric base
|
||||
* \param s String buffer
|
||||
* \param slen String buffer size
|
||||
*
|
||||
* \return 0 if successful, or a POLARSSL_ERR_MPI_XXX error code.
|
||||
* *slen is always updated to reflect the amount
|
||||
* of data that has (or would have) been written.
|
||||
*
|
||||
* \note Call this function with *slen = 0 to obtain the
|
||||
* minimum required buffer size in *slen.
|
||||
*/
|
||||
int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen );
|
||||
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
/**
|
||||
* \brief Read X from an opened file
|
||||
*
|
||||
* \param X Destination MPI
|
||||
* \param radix Input numeric base
|
||||
* \param fin Input file handle
|
||||
*
|
||||
* \return 0 if successful, POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if
|
||||
* the file read buffer is too small or a
|
||||
* POLARSSL_ERR_MPI_XXX error code
|
||||
*/
|
||||
int mpi_read_file( mpi *X, int radix, FILE *fin );
|
||||
|
||||
/**
|
||||
* \brief Write X into an opened file, or stdout if fout is NULL
|
||||
*
|
||||
* \param p Prefix, can be NULL
|
||||
* \param X Source MPI
|
||||
* \param radix Output numeric base
|
||||
* \param fout Output file handle (can be NULL)
|
||||
*
|
||||
* \return 0 if successful, or a POLARSSL_ERR_MPI_XXX error code
|
||||
*
|
||||
* \note Set fout == NULL to print X on the console.
|
||||
*/
|
||||
int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout );
|
||||
#endif /* POLARSSL_FS_IO */
|
||||
|
||||
/**
|
||||
* \brief Import X from unsigned binary data, big endian
|
||||
*
|
||||
* \param X Destination MPI
|
||||
* \param buf Input buffer
|
||||
* \param buflen Input buffer size
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
|
||||
*/
|
||||
int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen );
|
||||
|
||||
/**
|
||||
* \brief Export X into unsigned binary data, big endian
|
||||
*
|
||||
* \param X Source MPI
|
||||
* \param buf Output buffer
|
||||
* \param buflen Output buffer size
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough
|
||||
*/
|
||||
int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen );
|
||||
|
||||
/**
|
||||
* \brief Left-shift: X <<= count
|
||||
*
|
||||
* \param X MPI to shift
|
||||
* \param count Amount to shift
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
|
||||
*/
|
||||
int mpi_shift_l( mpi *X, size_t count );
|
||||
|
||||
/**
|
||||
* \brief Right-shift: X >>= count
|
||||
*
|
||||
* \param X MPI to shift
|
||||
* \param count Amount to shift
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
|
||||
*/
|
||||
int mpi_shift_r( mpi *X, size_t count );
|
||||
|
||||
/**
|
||||
* \brief Compare unsigned values
|
||||
*
|
||||
* \param X Left-hand MPI
|
||||
* \param Y Right-hand MPI
|
||||
*
|
||||
* \return 1 if |X| is greater than |Y|,
|
||||
* -1 if |X| is lesser than |Y| or
|
||||
* 0 if |X| is equal to |Y|
|
||||
*/
|
||||
int mpi_cmp_abs( const mpi *X, const mpi *Y );
|
||||
|
||||
/**
|
||||
* \brief Compare signed values
|
||||
*
|
||||
* \param X Left-hand MPI
|
||||
* \param Y Right-hand MPI
|
||||
*
|
||||
* \return 1 if X is greater than Y,
|
||||
* -1 if X is lesser than Y or
|
||||
* 0 if X is equal to Y
|
||||
*/
|
||||
int mpi_cmp_mpi( const mpi *X, const mpi *Y );
|
||||
|
||||
/**
|
||||
* \brief Compare signed values
|
||||
*
|
||||
* \param X Left-hand MPI
|
||||
* \param z The integer value to compare to
|
||||
*
|
||||
* \return 1 if X is greater than z,
|
||||
* -1 if X is lesser than z or
|
||||
* 0 if X is equal to z
|
||||
*/
|
||||
int mpi_cmp_int( const mpi *X, t_sint z );
|
||||
|
||||
/**
|
||||
* \brief Unsigned addition: X = |A| + |B|
|
||||
*
|
||||
* \param X Destination MPI
|
||||
* \param A Left-hand MPI
|
||||
* \param B Right-hand MPI
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
|
||||
*/
|
||||
int mpi_add_abs( mpi *X, const mpi *A, const mpi *B );
|
||||
|
||||
/**
|
||||
* \brief Unsigned substraction: X = |A| - |B|
|
||||
*
|
||||
* \param X Destination MPI
|
||||
* \param A Left-hand MPI
|
||||
* \param B Right-hand MPI
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A
|
||||
*/
|
||||
int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B );
|
||||
|
||||
/**
|
||||
* \brief Signed addition: X = A + B
|
||||
*
|
||||
* \param X Destination MPI
|
||||
* \param A Left-hand MPI
|
||||
* \param B Right-hand MPI
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
|
||||
*/
|
||||
int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B );
|
||||
|
||||
/**
|
||||
* \brief Signed substraction: X = A - B
|
||||
*
|
||||
* \param X Destination MPI
|
||||
* \param A Left-hand MPI
|
||||
* \param B Right-hand MPI
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
|
||||
*/
|
||||
int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B );
|
||||
|
||||
/**
|
||||
* \brief Signed addition: X = A + b
|
||||
*
|
||||
* \param X Destination MPI
|
||||
* \param A Left-hand MPI
|
||||
* \param b The integer value to add
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
|
||||
*/
|
||||
int mpi_add_int( mpi *X, const mpi *A, t_sint b );
|
||||
|
||||
/**
|
||||
* \brief Signed substraction: X = A - b
|
||||
*
|
||||
* \param X Destination MPI
|
||||
* \param A Left-hand MPI
|
||||
* \param b The integer value to subtract
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
|
||||
*/
|
||||
int mpi_sub_int( mpi *X, const mpi *A, t_sint b );
|
||||
|
||||
/**
|
||||
* \brief Baseline multiplication: X = A * B
|
||||
*
|
||||
* \param X Destination MPI
|
||||
* \param A Left-hand MPI
|
||||
* \param B Right-hand MPI
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
|
||||
*/
|
||||
int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B );
|
||||
|
||||
/**
|
||||
* \brief Baseline multiplication: X = A * b
|
||||
* Note: b is an unsigned integer type, thus
|
||||
* Negative values of b are ignored.
|
||||
*
|
||||
* \param X Destination MPI
|
||||
* \param A Left-hand MPI
|
||||
* \param b The integer value to multiply with
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
|
||||
*/
|
||||
int mpi_mul_int( mpi *X, const mpi *A, t_sint b );
|
||||
|
||||
/**
|
||||
* \brief Division by mpi: A = Q * B + R
|
||||
*
|
||||
* \param Q Destination MPI for the quotient
|
||||
* \param R Destination MPI for the rest value
|
||||
* \param A Left-hand MPI
|
||||
* \param B Right-hand MPI
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
|
||||
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0
|
||||
*
|
||||
* \note Either Q or R can be NULL.
|
||||
*/
|
||||
int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B );
|
||||
|
||||
/**
|
||||
* \brief Division by int: A = Q * b + R
|
||||
*
|
||||
* \param Q Destination MPI for the quotient
|
||||
* \param R Destination MPI for the rest value
|
||||
* \param A Left-hand MPI
|
||||
* \param b Integer to divide by
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
|
||||
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
|
||||
*
|
||||
* \note Either Q or R can be NULL.
|
||||
*/
|
||||
int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b );
|
||||
|
||||
/**
|
||||
* \brief Modulo: R = A mod B
|
||||
*
|
||||
* \param R Destination MPI for the rest value
|
||||
* \param A Left-hand MPI
|
||||
* \param B Right-hand MPI
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
|
||||
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0,
|
||||
* POLARSSL_ERR_MPI_NEGATIVE_VALUE if B < 0
|
||||
*/
|
||||
int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B );
|
||||
|
||||
/**
|
||||
* \brief Modulo: r = A mod b
|
||||
*
|
||||
* \param r Destination t_uint
|
||||
* \param A Left-hand MPI
|
||||
* \param b Integer to divide by
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
|
||||
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0,
|
||||
* POLARSSL_ERR_MPI_NEGATIVE_VALUE if b < 0
|
||||
*/
|
||||
int mpi_mod_int( t_uint *r, const mpi *A, t_sint b );
|
||||
|
||||
/**
|
||||
* \brief Sliding-window exponentiation: X = A^E mod N
|
||||
*
|
||||
* \param X Destination MPI
|
||||
* \param A Left-hand MPI
|
||||
* \param E Exponent MPI
|
||||
* \param N Modular MPI
|
||||
* \param _RR Speed-up MPI used for recalculations
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
|
||||
* POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even or if
|
||||
* E is negative
|
||||
*
|
||||
* \note _RR is used to avoid re-computing R*R mod N across
|
||||
* multiple calls, which speeds up things a bit. It can
|
||||
* be set to NULL if the extra performance is unneeded.
|
||||
*/
|
||||
int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR );
|
||||
|
||||
/**
|
||||
* \brief Fill an MPI X with size bytes of random
|
||||
*
|
||||
* \param X Destination MPI
|
||||
* \param size Size in bytes
|
||||
* \param f_rng RNG function
|
||||
* \param p_rng RNG parameter
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
|
||||
*/
|
||||
int mpi_fill_random( mpi *X, size_t size,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng );
|
||||
|
||||
/**
|
||||
* \brief Greatest common divisor: G = gcd(A, B)
|
||||
*
|
||||
* \param G Destination MPI
|
||||
* \param A Left-hand MPI
|
||||
* \param B Right-hand MPI
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
|
||||
*/
|
||||
int mpi_gcd( mpi *G, const mpi *A, const mpi *B );
|
||||
|
||||
/**
|
||||
* \brief Modular inverse: X = A^-1 mod N
|
||||
*
|
||||
* \param X Destination MPI
|
||||
* \param A Left-hand MPI
|
||||
* \param N Right-hand MPI
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
|
||||
* POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil
|
||||
POLARSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N
|
||||
*/
|
||||
int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N );
|
||||
|
||||
/**
|
||||
* \brief Miller-Rabin primality test
|
||||
*
|
||||
* \param X MPI to check
|
||||
* \param f_rng RNG function
|
||||
* \param p_rng RNG parameter
|
||||
*
|
||||
* \return 0 if successful (probably prime),
|
||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
|
||||
* POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime
|
||||
*/
|
||||
int mpi_is_prime( mpi *X,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng );
|
||||
|
||||
/**
|
||||
* \brief Prime number generation
|
||||
*
|
||||
* \param X Destination MPI
|
||||
* \param nbits Required size of X in bits ( 3 <= nbits <= POLARSSL_MPI_MAX_BITS )
|
||||
* \param dh_flag If 1, then (X-1)/2 will be prime too
|
||||
* \param f_rng RNG function
|
||||
* \param p_rng RNG parameter
|
||||
*
|
||||
* \return 0 if successful (probably prime),
|
||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
|
||||
* POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
|
||||
*/
|
||||
int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng );
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int mpi_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* bignum.h */
|
||||
@@ -0,0 +1,632 @@
|
||||
/*
|
||||
* Blowfish implementation
|
||||
*
|
||||
* Copyright (C) 2012-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
* The Blowfish block cipher was designed by Bruce Schneier in 1993.
|
||||
* http://www.schneier.com/blowfish.html
|
||||
* http://en.wikipedia.org/wiki/Blowfish_%28cipher%29
|
||||
*
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_BLOWFISH_C)
|
||||
|
||||
#include "polarssl/blowfish.h"
|
||||
|
||||
#if !defined(POLARSSL_BLOWFISH_ALT)
|
||||
|
||||
/*
|
||||
* 32-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
#ifndef GET_UINT32_BE
|
||||
#define GET_UINT32_BE(n,b,i) \
|
||||
{ \
|
||||
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
|
||||
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
|
||||
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
|
||||
| ( (uint32_t) (b)[(i) + 3] ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PUT_UINT32_BE
|
||||
#define PUT_UINT32_BE(n,b,i) \
|
||||
{ \
|
||||
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
static const uint32_t P[BLOWFISH_ROUNDS + 2] = {
|
||||
0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L,
|
||||
0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L,
|
||||
0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL,
|
||||
0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L,
|
||||
0x9216D5D9L, 0x8979FB1BL
|
||||
};
|
||||
|
||||
/* declarations of data at the end of this file */
|
||||
static const uint32_t S[4][256];
|
||||
|
||||
static uint32_t F(blowfish_context *ctx, uint32_t x)
|
||||
{
|
||||
unsigned short a, b, c, d;
|
||||
uint32_t y;
|
||||
|
||||
d = (unsigned short)(x & 0xFF);
|
||||
x >>= 8;
|
||||
c = (unsigned short)(x & 0xFF);
|
||||
x >>= 8;
|
||||
b = (unsigned short)(x & 0xFF);
|
||||
x >>= 8;
|
||||
a = (unsigned short)(x & 0xFF);
|
||||
y = ctx->S[0][a] + ctx->S[1][b];
|
||||
y = y ^ ctx->S[2][c];
|
||||
y = y + ctx->S[3][d];
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
static void blowfish_enc(blowfish_context *ctx, uint32_t *xl, uint32_t *xr)
|
||||
{
|
||||
uint32_t Xl, Xr, temp;
|
||||
short i;
|
||||
|
||||
Xl = *xl;
|
||||
Xr = *xr;
|
||||
|
||||
for (i = 0; i < BLOWFISH_ROUNDS; ++i)
|
||||
{
|
||||
Xl = Xl ^ ctx->P[i];
|
||||
Xr = F(ctx, Xl) ^ Xr;
|
||||
|
||||
temp = Xl;
|
||||
Xl = Xr;
|
||||
Xr = temp;
|
||||
}
|
||||
|
||||
temp = Xl;
|
||||
Xl = Xr;
|
||||
Xr = temp;
|
||||
|
||||
Xr = Xr ^ ctx->P[BLOWFISH_ROUNDS];
|
||||
Xl = Xl ^ ctx->P[BLOWFISH_ROUNDS + 1];
|
||||
|
||||
*xl = Xl;
|
||||
*xr = Xr;
|
||||
}
|
||||
|
||||
static void blowfish_dec(blowfish_context *ctx, uint32_t *xl, uint32_t *xr)
|
||||
{
|
||||
uint32_t Xl, Xr, temp;
|
||||
short i;
|
||||
|
||||
Xl = *xl;
|
||||
Xr = *xr;
|
||||
|
||||
for (i = BLOWFISH_ROUNDS + 1; i > 1; --i)
|
||||
{
|
||||
Xl = Xl ^ ctx->P[i];
|
||||
Xr = F(ctx, Xl) ^ Xr;
|
||||
|
||||
temp = Xl;
|
||||
Xl = Xr;
|
||||
Xr = temp;
|
||||
}
|
||||
|
||||
temp = Xl;
|
||||
Xl = Xr;
|
||||
Xr = temp;
|
||||
|
||||
Xr = Xr ^ ctx->P[1];
|
||||
Xl = Xl ^ ctx->P[0];
|
||||
|
||||
*xl = Xl;
|
||||
*xr = Xr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Blowfish key schedule
|
||||
*/
|
||||
int blowfish_setkey( blowfish_context *ctx, const unsigned char *key, unsigned int keysize )
|
||||
{
|
||||
unsigned int i, j, k;
|
||||
uint32_t data, datal, datar;
|
||||
|
||||
if( keysize < BLOWFISH_MIN_KEY || keysize > BLOWFISH_MAX_KEY ||
|
||||
( keysize % 8 ) )
|
||||
{
|
||||
return POLARSSL_ERR_BLOWFISH_INVALID_KEY_LENGTH;
|
||||
}
|
||||
|
||||
keysize >>= 3;
|
||||
|
||||
for( i = 0; i < 4; i++ )
|
||||
{
|
||||
for( j = 0; j < 256; j++ )
|
||||
ctx->S[i][j] = S[i][j];
|
||||
}
|
||||
|
||||
j = 0;
|
||||
for( i = 0; i < BLOWFISH_ROUNDS + 2; ++i )
|
||||
{
|
||||
data = 0x00000000;
|
||||
for( k = 0; k < 4; ++k )
|
||||
{
|
||||
data = ( data << 8 ) | key[j++];
|
||||
if( j >= keysize )
|
||||
j = 0;
|
||||
}
|
||||
ctx->P[i] = P[i] ^ data;
|
||||
}
|
||||
|
||||
datal = 0x00000000;
|
||||
datar = 0x00000000;
|
||||
|
||||
for( i = 0; i < BLOWFISH_ROUNDS + 2; i += 2 )
|
||||
{
|
||||
blowfish_enc( ctx, &datal, &datar );
|
||||
ctx->P[i] = datal;
|
||||
ctx->P[i + 1] = datar;
|
||||
}
|
||||
|
||||
for( i = 0; i < 4; i++ )
|
||||
{
|
||||
for( j = 0; j < 256; j += 2 )
|
||||
{
|
||||
blowfish_enc( ctx, &datal, &datar );
|
||||
ctx->S[i][j] = datal;
|
||||
ctx->S[i][j + 1] = datar;
|
||||
}
|
||||
}
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Blowfish-ECB block encryption/decryption
|
||||
*/
|
||||
int blowfish_crypt_ecb( blowfish_context *ctx,
|
||||
int mode,
|
||||
const unsigned char input[BLOWFISH_BLOCKSIZE],
|
||||
unsigned char output[BLOWFISH_BLOCKSIZE] )
|
||||
{
|
||||
uint32_t X0, X1;
|
||||
|
||||
GET_UINT32_BE( X0, input, 0 );
|
||||
GET_UINT32_BE( X1, input, 4 );
|
||||
|
||||
if( mode == BLOWFISH_DECRYPT )
|
||||
{
|
||||
blowfish_dec(ctx, &X0, &X1);
|
||||
}
|
||||
else /* BLOWFISH_ENCRYPT */
|
||||
{
|
||||
blowfish_enc(ctx, &X0, &X1);
|
||||
}
|
||||
|
||||
PUT_UINT32_BE( X0, output, 0 );
|
||||
PUT_UINT32_BE( X1, output, 4 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Blowfish-CBC buffer encryption/decryption
|
||||
*/
|
||||
int blowfish_crypt_cbc( blowfish_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[BLOWFISH_BLOCKSIZE],
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
int i;
|
||||
unsigned char temp[BLOWFISH_BLOCKSIZE];
|
||||
|
||||
if( length % BLOWFISH_BLOCKSIZE )
|
||||
return( POLARSSL_ERR_BLOWFISH_INVALID_INPUT_LENGTH );
|
||||
|
||||
if( mode == BLOWFISH_DECRYPT )
|
||||
{
|
||||
while( length > 0 )
|
||||
{
|
||||
memcpy( temp, input, BLOWFISH_BLOCKSIZE );
|
||||
blowfish_crypt_ecb( ctx, mode, input, output );
|
||||
|
||||
for( i = 0; i < BLOWFISH_BLOCKSIZE;i++ )
|
||||
output[i] = (unsigned char)( output[i] ^ iv[i] );
|
||||
|
||||
memcpy( iv, temp, BLOWFISH_BLOCKSIZE );
|
||||
|
||||
input += BLOWFISH_BLOCKSIZE;
|
||||
output += BLOWFISH_BLOCKSIZE;
|
||||
length -= BLOWFISH_BLOCKSIZE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while( length > 0 )
|
||||
{
|
||||
for( i = 0; i < BLOWFISH_BLOCKSIZE; i++ )
|
||||
output[i] = (unsigned char)( input[i] ^ iv[i] );
|
||||
|
||||
blowfish_crypt_ecb( ctx, mode, output, output );
|
||||
memcpy( iv, output, BLOWFISH_BLOCKSIZE );
|
||||
|
||||
input += BLOWFISH_BLOCKSIZE;
|
||||
output += BLOWFISH_BLOCKSIZE;
|
||||
length -= BLOWFISH_BLOCKSIZE;
|
||||
}
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CFB)
|
||||
/*
|
||||
* Blowfish CFB buffer encryption/decryption
|
||||
*/
|
||||
int blowfish_crypt_cfb64( blowfish_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[BLOWFISH_BLOCKSIZE],
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
int c;
|
||||
size_t n = *iv_off;
|
||||
|
||||
if( mode == BLOWFISH_DECRYPT )
|
||||
{
|
||||
while( length-- )
|
||||
{
|
||||
if( n == 0 )
|
||||
blowfish_crypt_ecb( ctx, BLOWFISH_ENCRYPT, iv, iv );
|
||||
|
||||
c = *input++;
|
||||
*output++ = (unsigned char)( c ^ iv[n] );
|
||||
iv[n] = (unsigned char) c;
|
||||
|
||||
n = (n + 1) % BLOWFISH_BLOCKSIZE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while( length-- )
|
||||
{
|
||||
if( n == 0 )
|
||||
blowfish_crypt_ecb( ctx, BLOWFISH_ENCRYPT, iv, iv );
|
||||
|
||||
iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
|
||||
|
||||
n = (n + 1) % BLOWFISH_BLOCKSIZE;
|
||||
}
|
||||
}
|
||||
|
||||
*iv_off = n;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /*POLARSSL_CIPHER_MODE_CFB */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CTR)
|
||||
/*
|
||||
* Blowfish CTR buffer encryption/decryption
|
||||
*/
|
||||
int blowfish_crypt_ctr( blowfish_context *ctx,
|
||||
size_t length,
|
||||
size_t *nc_off,
|
||||
unsigned char nonce_counter[BLOWFISH_BLOCKSIZE],
|
||||
unsigned char stream_block[BLOWFISH_BLOCKSIZE],
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
int c, i;
|
||||
size_t n = *nc_off;
|
||||
|
||||
while( length-- )
|
||||
{
|
||||
if( n == 0 ) {
|
||||
blowfish_crypt_ecb( ctx, BLOWFISH_ENCRYPT, nonce_counter, stream_block );
|
||||
|
||||
for( i = BLOWFISH_BLOCKSIZE; i > 0; i-- )
|
||||
if( ++nonce_counter[i - 1] != 0 )
|
||||
break;
|
||||
}
|
||||
c = *input++;
|
||||
*output++ = (unsigned char)( c ^ stream_block[n] );
|
||||
|
||||
n = (n + 1) % BLOWFISH_BLOCKSIZE;
|
||||
}
|
||||
|
||||
*nc_off = n;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* POLARSSL_CIPHER_MODE_CTR */
|
||||
|
||||
static const uint32_t S[4][256] = {
|
||||
{ 0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L,
|
||||
0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L,
|
||||
0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L,
|
||||
0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL,
|
||||
0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL,
|
||||
0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L,
|
||||
0xC5D1B023L, 0x286085F0L, 0xCA417918L, 0xB8DB38EFL,
|
||||
0x8E79DCB0L, 0x603A180EL, 0x6C9E0E8BL, 0xB01E8A3EL,
|
||||
0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL, 0x55605C60L,
|
||||
0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L,
|
||||
0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL,
|
||||
0xA15486AFL, 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL,
|
||||
0x2BA9C55DL, 0x741831F6L, 0xCE5C3E16L, 0x9B87931EL,
|
||||
0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L, 0x28958677L,
|
||||
0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L,
|
||||
0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L,
|
||||
0xEF845D5DL, 0xE98575B1L, 0xDC262302L, 0xEB651B88L,
|
||||
0x23893E81L, 0xD396ACC5L, 0x0F6D6FF3L, 0x83F44239L,
|
||||
0x2E0B4482L, 0xA4842004L, 0x69C8F04AL, 0x9E1F9B5EL,
|
||||
0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L,
|
||||
0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L,
|
||||
0x6EEF0B6CL, 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L,
|
||||
0xA1F1651DL, 0x39AF0176L, 0x66CA593EL, 0x82430E88L,
|
||||
0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L, 0x3B8B5EBEL,
|
||||
0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L,
|
||||
0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL,
|
||||
0x37D0D724L, 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL,
|
||||
0x075372C9L, 0x80991B7BL, 0x25D479D8L, 0xF6E8DEF7L,
|
||||
0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL, 0x04C006BAL,
|
||||
0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L,
|
||||
0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL,
|
||||
0x6DFC511FL, 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L,
|
||||
0xBEE3D004L, 0xDE334AFDL, 0x660F2807L, 0x192E4BB3L,
|
||||
0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L, 0xB9D3FBDBL,
|
||||
0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L,
|
||||
0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L,
|
||||
0x3C7516DFL, 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL,
|
||||
0x323DB5FAL, 0xFD238760L, 0x53317B48L, 0x3E00DF82L,
|
||||
0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL, 0xDF1769DBL,
|
||||
0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L,
|
||||
0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L,
|
||||
0x10FA3D98L, 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL,
|
||||
0x9A53E479L, 0xB6F84565L, 0xD28E49BCL, 0x4BFB9790L,
|
||||
0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L, 0xCEE4C6E8L,
|
||||
0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L,
|
||||
0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L,
|
||||
0xD08ED1D0L, 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L,
|
||||
0x8FF6E2FBL, 0xF2122B64L, 0x8888B812L, 0x900DF01CL,
|
||||
0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L, 0xB3A8C1ADL,
|
||||
0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L,
|
||||
0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L,
|
||||
0xB4A84FE0L, 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L,
|
||||
0x165FA266L, 0x80957705L, 0x93CC7314L, 0x211A1477L,
|
||||
0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L, 0xFB9D35CFL,
|
||||
0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L,
|
||||
0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL,
|
||||
0x2464369BL, 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL,
|
||||
0x78C14389L, 0xD95A537FL, 0x207D5BA2L, 0x02E5B9C5L,
|
||||
0x83260376L, 0x6295CFA9L, 0x11C81968L, 0x4E734A41L,
|
||||
0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L,
|
||||
0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L,
|
||||
0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L,
|
||||
0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L,
|
||||
0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL },
|
||||
{ 0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L,
|
||||
0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L,
|
||||
0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L,
|
||||
0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL,
|
||||
0x3F54989AL, 0x5B429D65L, 0x6B8FE4D6L, 0x99F73FD6L,
|
||||
0xA1D29C07L, 0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L,
|
||||
0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L, 0x021ECC5EL,
|
||||
0x09686B3FL, 0x3EBAEFC9L, 0x3C971814L, 0x6B6A70A1L,
|
||||
0x687F3584L, 0x52A0E286L, 0xB79C5305L, 0xAA500737L,
|
||||
0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL, 0x5716F2B8L,
|
||||
0xB03ADA37L, 0xF0500C0DL, 0xF01C1F04L, 0x0200B3FFL,
|
||||
0xAE0CF51AL, 0x3CB574B2L, 0x25837A58L, 0xDC0921BDL,
|
||||
0xD19113F9L, 0x7CA92FF6L, 0x94324773L, 0x22F54701L,
|
||||
0x3AE5E581L, 0x37C2DADCL, 0xC8B57634L, 0x9AF3DDA7L,
|
||||
0xA9446146L, 0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L,
|
||||
0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L, 0x183EB331L,
|
||||
0x4E548B38L, 0x4F6DB908L, 0x6F420D03L, 0xF60A04BFL,
|
||||
0x2CB81290L, 0x24977C79L, 0x5679B072L, 0xBCAF89AFL,
|
||||
0xDE9A771FL, 0xD9930810L, 0xB38BAE12L, 0xDCCF3F2EL,
|
||||
0x5512721FL, 0x2E6B7124L, 0x501ADDE6L, 0x9F84CD87L,
|
||||
0x7A584718L, 0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL,
|
||||
0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L, 0xC464C3D2L,
|
||||
0xEF1C1847L, 0x3215D908L, 0xDD433B37L, 0x24C2BA16L,
|
||||
0x12A14D43L, 0x2A65C451L, 0x50940002L, 0x133AE4DDL,
|
||||
0x71DFF89EL, 0x10314E55L, 0x81AC77D6L, 0x5F11199BL,
|
||||
0x043556F1L, 0xD7A3C76BL, 0x3C11183BL, 0x5924A509L,
|
||||
0xF28FE6EDL, 0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL,
|
||||
0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL, 0x5A3E2AB3L,
|
||||
0x771FE71CL, 0x4E3D06FAL, 0x2965DCB9L, 0x99E71D0FL,
|
||||
0x803E89D6L, 0x5266C825L, 0x2E4CC978L, 0x9C10B36AL,
|
||||
0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L, 0x1E0A2DF4L,
|
||||
0xF2F74EA7L, 0x361D2B3DL, 0x1939260FL, 0x19C27960L,
|
||||
0x5223A708L, 0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L,
|
||||
0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L, 0x018CFF28L,
|
||||
0xC332DDEFL, 0xBE6C5AA5L, 0x65582185L, 0x68AB9802L,
|
||||
0xEECEA50FL, 0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L,
|
||||
0x1521B628L, 0x29076170L, 0xECDD4775L, 0x619F1510L,
|
||||
0x13CCA830L, 0xEB61BD96L, 0x0334FE1EL, 0xAA0363CFL,
|
||||
0xB5735C90L, 0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L,
|
||||
0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL, 0xB2F3846EL,
|
||||
0x648B1EAFL, 0x19BDF0CAL, 0xA02369B9L, 0x655ABB50L,
|
||||
0x40685A32L, 0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L,
|
||||
0x9B540B19L, 0x875FA099L, 0x95F7997EL, 0x623D7DA8L,
|
||||
0xF837889AL, 0x97E32D77L, 0x11ED935FL, 0x16681281L,
|
||||
0x0E358829L, 0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L,
|
||||
0x57F584A5L, 0x1B227263L, 0x9B83C3FFL, 0x1AC24696L,
|
||||
0xCDB30AEBL, 0x532E3054L, 0x8FD948E4L, 0x6DBC3128L,
|
||||
0x58EBF2EFL, 0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L,
|
||||
0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L, 0x203E13E0L,
|
||||
0x45EEE2B6L, 0xA3AAABEAL, 0xDB6C4F15L, 0xFACB4FD0L,
|
||||
0xC742F442L, 0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L,
|
||||
0xD81E799EL, 0x86854DC7L, 0xE44B476AL, 0x3D816250L,
|
||||
0xCF62A1F2L, 0x5B8D2646L, 0xFC8883A0L, 0xC1C7B6A3L,
|
||||
0x7F1524C3L, 0x69CB7492L, 0x47848A0BL, 0x5692B285L,
|
||||
0x095BBF00L, 0xAD19489DL, 0x1462B174L, 0x23820E00L,
|
||||
0x58428D2AL, 0x0C55F5EAL, 0x1DADF43EL, 0x233F7061L,
|
||||
0x3372F092L, 0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL,
|
||||
0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L, 0xCE77326EL,
|
||||
0xA6078084L, 0x19F8509EL, 0xE8EFD855L, 0x61D99735L,
|
||||
0xA969A7AAL, 0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL,
|
||||
0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L,
|
||||
0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L,
|
||||
0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L,
|
||||
0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L },
|
||||
{ 0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L,
|
||||
0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L,
|
||||
0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL,
|
||||
0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L,
|
||||
0x4D95FC1DL, 0x96B591AFL, 0x70F4DDD3L, 0x66A02F45L,
|
||||
0xBFBC09ECL, 0x03BD9785L, 0x7FAC6DD0L, 0x31CB8504L,
|
||||
0x96EB27B3L, 0x55FD3941L, 0xDA2547E6L, 0xABCA0A9AL,
|
||||
0x28507825L, 0x530429F4L, 0x0A2C86DAL, 0xE9B66DFBL,
|
||||
0x68DC1462L, 0xD7486900L, 0x680EC0A4L, 0x27A18DEEL,
|
||||
0x4F3FFEA2L, 0xE887AD8CL, 0xB58CE006L, 0x7AF4D6B6L,
|
||||
0xAACE1E7CL, 0xD3375FECL, 0xCE78A399L, 0x406B2A42L,
|
||||
0x20FE9E35L, 0xD9F385B9L, 0xEE39D7ABL, 0x3B124E8BL,
|
||||
0x1DC9FAF7L, 0x4B6D1856L, 0x26A36631L, 0xEAE397B2L,
|
||||
0x3A6EFA74L, 0xDD5B4332L, 0x6841E7F7L, 0xCA7820FBL,
|
||||
0xFB0AF54EL, 0xD8FEB397L, 0x454056ACL, 0xBA489527L,
|
||||
0x55533A3AL, 0x20838D87L, 0xFE6BA9B7L, 0xD096954BL,
|
||||
0x55A867BCL, 0xA1159A58L, 0xCCA92963L, 0x99E1DB33L,
|
||||
0xA62A4A56L, 0x3F3125F9L, 0x5EF47E1CL, 0x9029317CL,
|
||||
0xFDF8E802L, 0x04272F70L, 0x80BB155CL, 0x05282CE3L,
|
||||
0x95C11548L, 0xE4C66D22L, 0x48C1133FL, 0xC70F86DCL,
|
||||
0x07F9C9EEL, 0x41041F0FL, 0x404779A4L, 0x5D886E17L,
|
||||
0x325F51EBL, 0xD59BC0D1L, 0xF2BCC18FL, 0x41113564L,
|
||||
0x257B7834L, 0x602A9C60L, 0xDFF8E8A3L, 0x1F636C1BL,
|
||||
0x0E12B4C2L, 0x02E1329EL, 0xAF664FD1L, 0xCAD18115L,
|
||||
0x6B2395E0L, 0x333E92E1L, 0x3B240B62L, 0xEEBEB922L,
|
||||
0x85B2A20EL, 0xE6BA0D99L, 0xDE720C8CL, 0x2DA2F728L,
|
||||
0xD0127845L, 0x95B794FDL, 0x647D0862L, 0xE7CCF5F0L,
|
||||
0x5449A36FL, 0x877D48FAL, 0xC39DFD27L, 0xF33E8D1EL,
|
||||
0x0A476341L, 0x992EFF74L, 0x3A6F6EABL, 0xF4F8FD37L,
|
||||
0xA812DC60L, 0xA1EBDDF8L, 0x991BE14CL, 0xDB6E6B0DL,
|
||||
0xC67B5510L, 0x6D672C37L, 0x2765D43BL, 0xDCD0E804L,
|
||||
0xF1290DC7L, 0xCC00FFA3L, 0xB5390F92L, 0x690FED0BL,
|
||||
0x667B9FFBL, 0xCEDB7D9CL, 0xA091CF0BL, 0xD9155EA3L,
|
||||
0xBB132F88L, 0x515BAD24L, 0x7B9479BFL, 0x763BD6EBL,
|
||||
0x37392EB3L, 0xCC115979L, 0x8026E297L, 0xF42E312DL,
|
||||
0x6842ADA7L, 0xC66A2B3BL, 0x12754CCCL, 0x782EF11CL,
|
||||
0x6A124237L, 0xB79251E7L, 0x06A1BBE6L, 0x4BFB6350L,
|
||||
0x1A6B1018L, 0x11CAEDFAL, 0x3D25BDD8L, 0xE2E1C3C9L,
|
||||
0x44421659L, 0x0A121386L, 0xD90CEC6EL, 0xD5ABEA2AL,
|
||||
0x64AF674EL, 0xDA86A85FL, 0xBEBFE988L, 0x64E4C3FEL,
|
||||
0x9DBC8057L, 0xF0F7C086L, 0x60787BF8L, 0x6003604DL,
|
||||
0xD1FD8346L, 0xF6381FB0L, 0x7745AE04L, 0xD736FCCCL,
|
||||
0x83426B33L, 0xF01EAB71L, 0xB0804187L, 0x3C005E5FL,
|
||||
0x77A057BEL, 0xBDE8AE24L, 0x55464299L, 0xBF582E61L,
|
||||
0x4E58F48FL, 0xF2DDFDA2L, 0xF474EF38L, 0x8789BDC2L,
|
||||
0x5366F9C3L, 0xC8B38E74L, 0xB475F255L, 0x46FCD9B9L,
|
||||
0x7AEB2661L, 0x8B1DDF84L, 0x846A0E79L, 0x915F95E2L,
|
||||
0x466E598EL, 0x20B45770L, 0x8CD55591L, 0xC902DE4CL,
|
||||
0xB90BACE1L, 0xBB8205D0L, 0x11A86248L, 0x7574A99EL,
|
||||
0xB77F19B6L, 0xE0A9DC09L, 0x662D09A1L, 0xC4324633L,
|
||||
0xE85A1F02L, 0x09F0BE8CL, 0x4A99A025L, 0x1D6EFE10L,
|
||||
0x1AB93D1DL, 0x0BA5A4DFL, 0xA186F20FL, 0x2868F169L,
|
||||
0xDCB7DA83L, 0x573906FEL, 0xA1E2CE9BL, 0x4FCD7F52L,
|
||||
0x50115E01L, 0xA70683FAL, 0xA002B5C4L, 0x0DE6D027L,
|
||||
0x9AF88C27L, 0x773F8641L, 0xC3604C06L, 0x61A806B5L,
|
||||
0xF0177A28L, 0xC0F586E0L, 0x006058AAL, 0x30DC7D62L,
|
||||
0x11E69ED7L, 0x2338EA63L, 0x53C2DD94L, 0xC2C21634L,
|
||||
0xBBCBEE56L, 0x90BCB6DEL, 0xEBFC7DA1L, 0xCE591D76L,
|
||||
0x6F05E409L, 0x4B7C0188L, 0x39720A3DL, 0x7C927C24L,
|
||||
0x86E3725FL, 0x724D9DB9L, 0x1AC15BB4L, 0xD39EB8FCL,
|
||||
0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L,
|
||||
0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL,
|
||||
0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L,
|
||||
0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L },
|
||||
{ 0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL,
|
||||
0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL,
|
||||
0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL,
|
||||
0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L,
|
||||
0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L,
|
||||
0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L,
|
||||
0x2939BBDBL, 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L,
|
||||
0xA1FAD5F0L, 0x6A2D519AL, 0x63EF8CE2L, 0x9A86EE22L,
|
||||
0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL, 0x9CF2D0A4L,
|
||||
0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L,
|
||||
0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L,
|
||||
0xC72FEFD3L, 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L,
|
||||
0x80E4A915L, 0x87B08601L, 0x9B09E6ADL, 0x3B3EE593L,
|
||||
0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L, 0x022B8B51L,
|
||||
0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L,
|
||||
0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL,
|
||||
0xE029AC71L, 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL,
|
||||
0xE8D3C48DL, 0x283B57CCL, 0xF8D56629L, 0x79132E28L,
|
||||
0x785F0191L, 0xED756055L, 0xF7960E44L, 0xE3D35E8CL,
|
||||
0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL,
|
||||
0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL,
|
||||
0x1B3F6D9BL, 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L,
|
||||
0x7533D928L, 0xB155FDF5L, 0x03563482L, 0x8ABA3CBBL,
|
||||
0x28517711L, 0xC20AD9F8L, 0xABCC5167L, 0xCCAD925FL,
|
||||
0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L,
|
||||
0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L,
|
||||
0xA8B6E37EL, 0xC3293D46L, 0x48DE5369L, 0x6413E680L,
|
||||
0xA2AE0810L, 0xDD6DB224L, 0x69852DFDL, 0x09072166L,
|
||||
0xB39A460AL, 0x6445C0DDL, 0x586CDECFL, 0x1C20C8AEL,
|
||||
0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL,
|
||||
0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L,
|
||||
0x72EACEA8L, 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L,
|
||||
0xD29BE463L, 0x542F5D9EL, 0xAEC2771BL, 0xF64E6370L,
|
||||
0x740E0D8DL, 0xE75B1357L, 0xF8721671L, 0xAF537D5DL,
|
||||
0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L,
|
||||
0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L,
|
||||
0x6F3F3B82L, 0x3520AB82L, 0x011A1D4BL, 0x277227F8L,
|
||||
0x611560B1L, 0xE7933FDCL, 0xBB3A792BL, 0x344525BDL,
|
||||
0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L, 0xA01FBAC9L,
|
||||
0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L,
|
||||
0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L,
|
||||
0x0339C32AL, 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL,
|
||||
0xF79E59B7L, 0x43F5BB3AL, 0xF2D519FFL, 0x27D9459CL,
|
||||
0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L, 0x9B941525L,
|
||||
0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L,
|
||||
0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L,
|
||||
0xE0EC6E0EL, 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L,
|
||||
0x9F1F9532L, 0xE0D392DFL, 0xD3A0342BL, 0x8971F21EL,
|
||||
0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L,
|
||||
0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL,
|
||||
0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL,
|
||||
0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L,
|
||||
0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L,
|
||||
0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL,
|
||||
0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L,
|
||||
0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL,
|
||||
0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L,
|
||||
0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL,
|
||||
0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L,
|
||||
0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L,
|
||||
0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL,
|
||||
0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L,
|
||||
0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL,
|
||||
0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L }
|
||||
};
|
||||
|
||||
#endif /* !POLARSSL_BLOWFISH_ALT */
|
||||
#endif /* POLARSSL_BLOWFISH_C */
|
||||
@@ -0,0 +1,171 @@
|
||||
/**
|
||||
* \file blowfish.h
|
||||
*
|
||||
* \brief Blowfish block cipher
|
||||
*
|
||||
* Copyright (C) 2012-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef POLARSSL_BLOWFISH_H
|
||||
#define POLARSSL_BLOWFISH_H
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <basetsd.h>
|
||||
typedef UINT32 uint32_t;
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#define BLOWFISH_ENCRYPT 1
|
||||
#define BLOWFISH_DECRYPT 0
|
||||
#define BLOWFISH_MAX_KEY 448
|
||||
#define BLOWFISH_MIN_KEY 32
|
||||
#define BLOWFISH_ROUNDS 16 /* when increasing this value, make sure to extend the initialisation vectors */
|
||||
#define BLOWFISH_BLOCKSIZE 8 /* Blowfish uses 64 bit blocks */
|
||||
|
||||
#define POLARSSL_ERR_BLOWFISH_INVALID_KEY_LENGTH -0x0016 /**< Invalid key length. */
|
||||
#define POLARSSL_ERR_BLOWFISH_INVALID_INPUT_LENGTH -0x0018 /**< Invalid data input length. */
|
||||
|
||||
#if !defined(POLARSSL_BLOWFISH_ALT)
|
||||
// Regular implementation
|
||||
//
|
||||
|
||||
/**
|
||||
* \brief Blowfish context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t P[BLOWFISH_ROUNDS + 2]; /*!< Blowfish round keys */
|
||||
uint32_t S[4][256]; /*!< key dependent S-boxes */
|
||||
}
|
||||
blowfish_context;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Blowfish key schedule
|
||||
*
|
||||
* \param ctx Blowfish context to be initialized
|
||||
* \param key encryption key
|
||||
* \param keysize must be between 32 and 448 bits
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_BLOWFISH_INVALID_KEY_LENGTH
|
||||
*/
|
||||
int blowfish_setkey( blowfish_context *ctx, const unsigned char *key, unsigned int keysize );
|
||||
|
||||
/**
|
||||
* \brief Blowfish-ECB block encryption/decryption
|
||||
*
|
||||
* \param ctx Blowfish context
|
||||
* \param mode BLOWFISH_ENCRYPT or BLOWFISH_DECRYPT
|
||||
* \param input 8-byte input block
|
||||
* \param output 8-byte output block
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int blowfish_crypt_ecb( blowfish_context *ctx,
|
||||
int mode,
|
||||
const unsigned char input[BLOWFISH_BLOCKSIZE],
|
||||
unsigned char output[BLOWFISH_BLOCKSIZE] );
|
||||
|
||||
/**
|
||||
* \brief Blowfish-CBC buffer encryption/decryption
|
||||
* Length should be a multiple of the block
|
||||
* size (8 bytes)
|
||||
*
|
||||
* \param ctx Blowfish context
|
||||
* \param mode BLOWFISH_ENCRYPT or BLOWFISH_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_BLOWFISH_INVALID_INPUT_LENGTH
|
||||
*/
|
||||
int blowfish_crypt_cbc( blowfish_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[BLOWFISH_BLOCKSIZE],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief Blowfish CFB buffer encryption/decryption.
|
||||
*
|
||||
* both
|
||||
* \param ctx Blowfish context
|
||||
* \param mode BLOWFISH_ENCRYPT or BLOWFISH_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv_off offset in IV (updated after use)
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int blowfish_crypt_cfb64( blowfish_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[BLOWFISH_BLOCKSIZE],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief Blowfish-CTR buffer encryption/decryption
|
||||
*
|
||||
* Warning: You have to keep the maximum use of your counter in mind!
|
||||
*
|
||||
* \param length The length of the data
|
||||
* \param nc_off The offset in the current stream_block (for resuming
|
||||
* within current cipher stream). The offset pointer to
|
||||
* should be 0 at the start of a stream.
|
||||
* \param nonce_counter The 64-bit nonce and counter.
|
||||
* \param stream_block The saved stream-block for resuming. Is overwritten
|
||||
* by the function.
|
||||
* \param input The input data stream
|
||||
* \param output The output data stream
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int blowfish_crypt_ctr( blowfish_context *ctx,
|
||||
size_t length,
|
||||
size_t *nc_off,
|
||||
unsigned char nonce_counter[BLOWFISH_BLOCKSIZE],
|
||||
unsigned char stream_block[BLOWFISH_BLOCKSIZE],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* POLARSSL_BLOWFISH_ALT */
|
||||
#include "polarssl/blowfish_alt.h"
|
||||
#endif /* POLARSSL_BLOWFISH_ALT */
|
||||
|
||||
#endif /* blowfish.h */
|
||||
@@ -0,0 +1,864 @@
|
||||
/**
|
||||
* \file bn_mul.h
|
||||
*
|
||||
* \brief Multi-precision integer library
|
||||
*
|
||||
* Copyright (C) 2006-2010, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
* Multiply source vector [s] with b, add result
|
||||
* to destination vector [d] and set carry c.
|
||||
*
|
||||
* Currently supports:
|
||||
*
|
||||
* . IA-32 (386+) . AMD64 / EM64T
|
||||
* . IA-32 (SSE2) . Motorola 68000
|
||||
* . PowerPC, 32-bit . MicroBlaze
|
||||
* . PowerPC, 64-bit . TriCore
|
||||
* . SPARC v8 . ARM v3+
|
||||
* . Alpha . MIPS32
|
||||
* . C, longlong . C, generic
|
||||
*/
|
||||
#ifndef POLARSSL_BN_MUL_H
|
||||
#define POLARSSL_BN_MUL_H
|
||||
|
||||
#include "polarssl/bignum.h"
|
||||
|
||||
#if defined(POLARSSL_HAVE_ASM)
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#if defined(__i386__)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
__asm__( " \
|
||||
movl %%ebx, %0; \
|
||||
movl %5, %%esi; \
|
||||
movl %6, %%edi; \
|
||||
movl %7, %%ecx; \
|
||||
movl %8, %%ebx; \
|
||||
"
|
||||
|
||||
#define MULADDC_CORE \
|
||||
" \
|
||||
lodsl; \
|
||||
mull %%ebx; \
|
||||
addl %%ecx, %%eax; \
|
||||
adcl $0, %%edx; \
|
||||
addl (%%edi), %%eax; \
|
||||
adcl $0, %%edx; \
|
||||
movl %%edx, %%ecx; \
|
||||
stosl; \
|
||||
"
|
||||
|
||||
#if defined(POLARSSL_HAVE_SSE2)
|
||||
|
||||
#define MULADDC_HUIT \
|
||||
" \
|
||||
movd %%ecx, %%mm1; \
|
||||
movd %%ebx, %%mm0; \
|
||||
movd (%%edi), %%mm3; \
|
||||
paddq %%mm3, %%mm1; \
|
||||
movd (%%esi), %%mm2; \
|
||||
pmuludq %%mm0, %%mm2; \
|
||||
movd 4(%%esi), %%mm4; \
|
||||
pmuludq %%mm0, %%mm4; \
|
||||
movd 8(%%esi), %%mm6; \
|
||||
pmuludq %%mm0, %%mm6; \
|
||||
movd 12(%%esi), %%mm7; \
|
||||
pmuludq %%mm0, %%mm7; \
|
||||
paddq %%mm2, %%mm1; \
|
||||
movd 4(%%edi), %%mm3; \
|
||||
paddq %%mm4, %%mm3; \
|
||||
movd 8(%%edi), %%mm5; \
|
||||
paddq %%mm6, %%mm5; \
|
||||
movd 12(%%edi), %%mm4; \
|
||||
paddq %%mm4, %%mm7; \
|
||||
movd %%mm1, (%%edi); \
|
||||
movd 16(%%esi), %%mm2; \
|
||||
pmuludq %%mm0, %%mm2; \
|
||||
psrlq $32, %%mm1; \
|
||||
movd 20(%%esi), %%mm4; \
|
||||
pmuludq %%mm0, %%mm4; \
|
||||
paddq %%mm3, %%mm1; \
|
||||
movd 24(%%esi), %%mm6; \
|
||||
pmuludq %%mm0, %%mm6; \
|
||||
movd %%mm1, 4(%%edi); \
|
||||
psrlq $32, %%mm1; \
|
||||
movd 28(%%esi), %%mm3; \
|
||||
pmuludq %%mm0, %%mm3; \
|
||||
paddq %%mm5, %%mm1; \
|
||||
movd 16(%%edi), %%mm5; \
|
||||
paddq %%mm5, %%mm2; \
|
||||
movd %%mm1, 8(%%edi); \
|
||||
psrlq $32, %%mm1; \
|
||||
paddq %%mm7, %%mm1; \
|
||||
movd 20(%%edi), %%mm5; \
|
||||
paddq %%mm5, %%mm4; \
|
||||
movd %%mm1, 12(%%edi); \
|
||||
psrlq $32, %%mm1; \
|
||||
paddq %%mm2, %%mm1; \
|
||||
movd 24(%%edi), %%mm5; \
|
||||
paddq %%mm5, %%mm6; \
|
||||
movd %%mm1, 16(%%edi); \
|
||||
psrlq $32, %%mm1; \
|
||||
paddq %%mm4, %%mm1; \
|
||||
movd 28(%%edi), %%mm5; \
|
||||
paddq %%mm5, %%mm3; \
|
||||
movd %%mm1, 20(%%edi); \
|
||||
psrlq $32, %%mm1; \
|
||||
paddq %%mm6, %%mm1; \
|
||||
movd %%mm1, 24(%%edi); \
|
||||
psrlq $32, %%mm1; \
|
||||
paddq %%mm3, %%mm1; \
|
||||
movd %%mm1, 28(%%edi); \
|
||||
addl $32, %%edi; \
|
||||
addl $32, %%esi; \
|
||||
psrlq $32, %%mm1; \
|
||||
movd %%mm1, %%ecx; \
|
||||
"
|
||||
|
||||
#define MULADDC_STOP \
|
||||
" \
|
||||
emms; \
|
||||
movl %4, %%ebx; \
|
||||
movl %%ecx, %1; \
|
||||
movl %%edi, %2; \
|
||||
movl %%esi, %3; \
|
||||
" \
|
||||
: "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
|
||||
: "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
|
||||
: "eax", "ecx", "edx", "esi", "edi" \
|
||||
);
|
||||
|
||||
#else
|
||||
|
||||
#define MULADDC_STOP \
|
||||
" \
|
||||
movl %4, %%ebx; \
|
||||
movl %%ecx, %1; \
|
||||
movl %%edi, %2; \
|
||||
movl %%esi, %3; \
|
||||
" \
|
||||
: "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
|
||||
: "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
|
||||
: "eax", "ecx", "edx", "esi", "edi" \
|
||||
);
|
||||
#endif /* SSE2 */
|
||||
#endif /* i386 */
|
||||
|
||||
#if defined(__amd64__) || defined (__x86_64__)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
__asm__( "movq %0, %%rsi " :: "m" (s)); \
|
||||
__asm__( "movq %0, %%rdi " :: "m" (d)); \
|
||||
__asm__( "movq %0, %%rcx " :: "m" (c)); \
|
||||
__asm__( "movq %0, %%rbx " :: "m" (b)); \
|
||||
__asm__( "xorq %r8, %r8 " );
|
||||
|
||||
#define MULADDC_CORE \
|
||||
__asm__( "movq (%rsi),%rax " ); \
|
||||
__asm__( "mulq %rbx " ); \
|
||||
__asm__( "addq $8, %rsi " ); \
|
||||
__asm__( "addq %rcx, %rax " ); \
|
||||
__asm__( "movq %r8, %rcx " ); \
|
||||
__asm__( "adcq $0, %rdx " ); \
|
||||
__asm__( "nop " ); \
|
||||
__asm__( "addq %rax, (%rdi) " ); \
|
||||
__asm__( "adcq %rdx, %rcx " ); \
|
||||
__asm__( "addq $8, %rdi " );
|
||||
|
||||
#define MULADDC_STOP \
|
||||
__asm__( "movq %%rcx, %0 " : "=m" (c)); \
|
||||
__asm__( "movq %%rdi, %0 " : "=m" (d)); \
|
||||
__asm__( "movq %%rsi, %0 " : "=m" (s) :: \
|
||||
"rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" );
|
||||
|
||||
#endif /* AMD64 */
|
||||
|
||||
#if defined(__mc68020__) || defined(__mcpu32__)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
__asm__( "movl %0, %%a2 " :: "m" (s)); \
|
||||
__asm__( "movl %0, %%a3 " :: "m" (d)); \
|
||||
__asm__( "movl %0, %%d3 " :: "m" (c)); \
|
||||
__asm__( "movl %0, %%d2 " :: "m" (b)); \
|
||||
__asm__( "moveq #0, %d0 " );
|
||||
|
||||
#define MULADDC_CORE \
|
||||
__asm__( "movel %a2@+, %d1 " ); \
|
||||
__asm__( "mulul %d2, %d4:%d1 " ); \
|
||||
__asm__( "addl %d3, %d1 " ); \
|
||||
__asm__( "addxl %d0, %d4 " ); \
|
||||
__asm__( "moveq #0, %d3 " ); \
|
||||
__asm__( "addl %d1, %a3@+ " ); \
|
||||
__asm__( "addxl %d4, %d3 " );
|
||||
|
||||
#define MULADDC_STOP \
|
||||
__asm__( "movl %%d3, %0 " : "=m" (c)); \
|
||||
__asm__( "movl %%a3, %0 " : "=m" (d)); \
|
||||
__asm__( "movl %%a2, %0 " : "=m" (s) :: \
|
||||
"d0", "d1", "d2", "d3", "d4", "a2", "a3" );
|
||||
|
||||
#define MULADDC_HUIT \
|
||||
__asm__( "movel %a2@+, %d1 " ); \
|
||||
__asm__( "mulul %d2, %d4:%d1 " ); \
|
||||
__asm__( "addxl %d3, %d1 " ); \
|
||||
__asm__( "addxl %d0, %d4 " ); \
|
||||
__asm__( "addl %d1, %a3@+ " ); \
|
||||
__asm__( "movel %a2@+, %d1 " ); \
|
||||
__asm__( "mulul %d2, %d3:%d1 " ); \
|
||||
__asm__( "addxl %d4, %d1 " ); \
|
||||
__asm__( "addxl %d0, %d3 " ); \
|
||||
__asm__( "addl %d1, %a3@+ " ); \
|
||||
__asm__( "movel %a2@+, %d1 " ); \
|
||||
__asm__( "mulul %d2, %d4:%d1 " ); \
|
||||
__asm__( "addxl %d3, %d1 " ); \
|
||||
__asm__( "addxl %d0, %d4 " ); \
|
||||
__asm__( "addl %d1, %a3@+ " ); \
|
||||
__asm__( "movel %a2@+, %d1 " ); \
|
||||
__asm__( "mulul %d2, %d3:%d1 " ); \
|
||||
__asm__( "addxl %d4, %d1 " ); \
|
||||
__asm__( "addxl %d0, %d3 " ); \
|
||||
__asm__( "addl %d1, %a3@+ " ); \
|
||||
__asm__( "movel %a2@+, %d1 " ); \
|
||||
__asm__( "mulul %d2, %d4:%d1 " ); \
|
||||
__asm__( "addxl %d3, %d1 " ); \
|
||||
__asm__( "addxl %d0, %d4 " ); \
|
||||
__asm__( "addl %d1, %a3@+ " ); \
|
||||
__asm__( "movel %a2@+, %d1 " ); \
|
||||
__asm__( "mulul %d2, %d3:%d1 " ); \
|
||||
__asm__( "addxl %d4, %d1 " ); \
|
||||
__asm__( "addxl %d0, %d3 " ); \
|
||||
__asm__( "addl %d1, %a3@+ " ); \
|
||||
__asm__( "movel %a2@+, %d1 " ); \
|
||||
__asm__( "mulul %d2, %d4:%d1 " ); \
|
||||
__asm__( "addxl %d3, %d1 " ); \
|
||||
__asm__( "addxl %d0, %d4 " ); \
|
||||
__asm__( "addl %d1, %a3@+ " ); \
|
||||
__asm__( "movel %a2@+, %d1 " ); \
|
||||
__asm__( "mulul %d2, %d3:%d1 " ); \
|
||||
__asm__( "addxl %d4, %d1 " ); \
|
||||
__asm__( "addxl %d0, %d3 " ); \
|
||||
__asm__( "addl %d1, %a3@+ " ); \
|
||||
__asm__( "addxl %d0, %d3 " );
|
||||
|
||||
#endif /* MC68000 */
|
||||
|
||||
#if defined(__powerpc__) || defined(__ppc__)
|
||||
#if defined(__powerpc64__) || defined(__ppc64__)
|
||||
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
__asm__( "ld r3, %0 " :: "m" (s)); \
|
||||
__asm__( "ld r4, %0 " :: "m" (d)); \
|
||||
__asm__( "ld r5, %0 " :: "m" (c)); \
|
||||
__asm__( "ld r6, %0 " :: "m" (b)); \
|
||||
__asm__( "addi r3, r3, -8 " ); \
|
||||
__asm__( "addi r4, r4, -8 " ); \
|
||||
__asm__( "addic r5, r5, 0 " );
|
||||
|
||||
#define MULADDC_CORE \
|
||||
__asm__( "ldu r7, 8(r3) " ); \
|
||||
__asm__( "mulld r8, r7, r6 " ); \
|
||||
__asm__( "mulhdu r9, r7, r6 " ); \
|
||||
__asm__( "adde r8, r8, r5 " ); \
|
||||
__asm__( "ld r7, 8(r4) " ); \
|
||||
__asm__( "addze r5, r9 " ); \
|
||||
__asm__( "addc r8, r8, r7 " ); \
|
||||
__asm__( "stdu r8, 8(r4) " );
|
||||
|
||||
#define MULADDC_STOP \
|
||||
__asm__( "addze r5, r5 " ); \
|
||||
__asm__( "addi r4, r4, 8 " ); \
|
||||
__asm__( "addi r3, r3, 8 " ); \
|
||||
__asm__( "std r5, %0 " : "=m" (c)); \
|
||||
__asm__( "std r4, %0 " : "=m" (d)); \
|
||||
__asm__( "std r3, %0 " : "=m" (s) :: \
|
||||
"r3", "r4", "r5", "r6", "r7", "r8", "r9" );
|
||||
|
||||
#else
|
||||
|
||||
#define MULADDC_INIT \
|
||||
__asm__( "ld %%r3, %0 " :: "m" (s)); \
|
||||
__asm__( "ld %%r4, %0 " :: "m" (d)); \
|
||||
__asm__( "ld %%r5, %0 " :: "m" (c)); \
|
||||
__asm__( "ld %%r6, %0 " :: "m" (b)); \
|
||||
__asm__( "addi %r3, %r3, -8 " ); \
|
||||
__asm__( "addi %r4, %r4, -8 " ); \
|
||||
__asm__( "addic %r5, %r5, 0 " );
|
||||
|
||||
#define MULADDC_CORE \
|
||||
__asm__( "ldu %r7, 8(%r3) " ); \
|
||||
__asm__( "mulld %r8, %r7, %r6 " ); \
|
||||
__asm__( "mulhdu %r9, %r7, %r6 " ); \
|
||||
__asm__( "adde %r8, %r8, %r5 " ); \
|
||||
__asm__( "ld %r7, 8(%r4) " ); \
|
||||
__asm__( "addze %r5, %r9 " ); \
|
||||
__asm__( "addc %r8, %r8, %r7 " ); \
|
||||
__asm__( "stdu %r8, 8(%r4) " );
|
||||
|
||||
#define MULADDC_STOP \
|
||||
__asm__( "addze %r5, %r5 " ); \
|
||||
__asm__( "addi %r4, %r4, 8 " ); \
|
||||
__asm__( "addi %r3, %r3, 8 " ); \
|
||||
__asm__( "std %%r5, %0 " : "=m" (c)); \
|
||||
__asm__( "std %%r4, %0 " : "=m" (d)); \
|
||||
__asm__( "std %%r3, %0 " : "=m" (s) :: \
|
||||
"r3", "r4", "r5", "r6", "r7", "r8", "r9" );
|
||||
|
||||
#endif
|
||||
|
||||
#else /* PPC32 */
|
||||
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
__asm__( "lwz r3, %0 " :: "m" (s)); \
|
||||
__asm__( "lwz r4, %0 " :: "m" (d)); \
|
||||
__asm__( "lwz r5, %0 " :: "m" (c)); \
|
||||
__asm__( "lwz r6, %0 " :: "m" (b)); \
|
||||
__asm__( "addi r3, r3, -4 " ); \
|
||||
__asm__( "addi r4, r4, -4 " ); \
|
||||
__asm__( "addic r5, r5, 0 " );
|
||||
|
||||
#define MULADDC_CORE \
|
||||
__asm__( "lwzu r7, 4(r3) " ); \
|
||||
__asm__( "mullw r8, r7, r6 " ); \
|
||||
__asm__( "mulhwu r9, r7, r6 " ); \
|
||||
__asm__( "adde r8, r8, r5 " ); \
|
||||
__asm__( "lwz r7, 4(r4) " ); \
|
||||
__asm__( "addze r5, r9 " ); \
|
||||
__asm__( "addc r8, r8, r7 " ); \
|
||||
__asm__( "stwu r8, 4(r4) " );
|
||||
|
||||
#define MULADDC_STOP \
|
||||
__asm__( "addze r5, r5 " ); \
|
||||
__asm__( "addi r4, r4, 4 " ); \
|
||||
__asm__( "addi r3, r3, 4 " ); \
|
||||
__asm__( "stw r5, %0 " : "=m" (c)); \
|
||||
__asm__( "stw r4, %0 " : "=m" (d)); \
|
||||
__asm__( "stw r3, %0 " : "=m" (s) :: \
|
||||
"r3", "r4", "r5", "r6", "r7", "r8", "r9" );
|
||||
|
||||
#else
|
||||
|
||||
#define MULADDC_INIT \
|
||||
__asm__( "lwz %%r3, %0 " :: "m" (s)); \
|
||||
__asm__( "lwz %%r4, %0 " :: "m" (d)); \
|
||||
__asm__( "lwz %%r5, %0 " :: "m" (c)); \
|
||||
__asm__( "lwz %%r6, %0 " :: "m" (b)); \
|
||||
__asm__( "addi %r3, %r3, -4 " ); \
|
||||
__asm__( "addi %r4, %r4, -4 " ); \
|
||||
__asm__( "addic %r5, %r5, 0 " );
|
||||
|
||||
#define MULADDC_CORE \
|
||||
__asm__( "lwzu %r7, 4(%r3) " ); \
|
||||
__asm__( "mullw %r8, %r7, %r6 " ); \
|
||||
__asm__( "mulhwu %r9, %r7, %r6 " ); \
|
||||
__asm__( "adde %r8, %r8, %r5 " ); \
|
||||
__asm__( "lwz %r7, 4(%r4) " ); \
|
||||
__asm__( "addze %r5, %r9 " ); \
|
||||
__asm__( "addc %r8, %r8, %r7 " ); \
|
||||
__asm__( "stwu %r8, 4(%r4) " );
|
||||
|
||||
#define MULADDC_STOP \
|
||||
__asm__( "addze %r5, %r5 " ); \
|
||||
__asm__( "addi %r4, %r4, 4 " ); \
|
||||
__asm__( "addi %r3, %r3, 4 " ); \
|
||||
__asm__( "stw %%r5, %0 " : "=m" (c)); \
|
||||
__asm__( "stw %%r4, %0 " : "=m" (d)); \
|
||||
__asm__( "stw %%r3, %0 " : "=m" (s) :: \
|
||||
"r3", "r4", "r5", "r6", "r7", "r8", "r9" );
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* PPC32 */
|
||||
#endif /* PPC64 */
|
||||
|
||||
#if defined(__sparc__) && defined(__sparc64__)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
__asm__( \
|
||||
" \
|
||||
ldx %3, %%o0; \
|
||||
ldx %4, %%o1; \
|
||||
ld %5, %%o2; \
|
||||
ld %6, %%o3; \
|
||||
"
|
||||
|
||||
#define MULADDC_CORE \
|
||||
" \
|
||||
ld [%%o0], %%o4; \
|
||||
inc 4, %%o0; \
|
||||
ld [%%o1], %%o5; \
|
||||
umul %%o3, %%o4, %%o4; \
|
||||
addcc %%o4, %%o2, %%o4; \
|
||||
rd %%y, %%g1; \
|
||||
addx %%g1, 0, %%g1; \
|
||||
addcc %%o4, %%o5, %%o4; \
|
||||
st %%o4, [%%o1]; \
|
||||
addx %%g1, 0, %%o2; \
|
||||
inc 4, %%o1; \
|
||||
"
|
||||
|
||||
#define MULADDC_STOP \
|
||||
" \
|
||||
st %%o2, %0; \
|
||||
stx %%o1, %1; \
|
||||
stx %%o0, %2; \
|
||||
" \
|
||||
: "=m" (c), "=m" (d), "=m" (s) \
|
||||
: "m" (s), "m" (d), "m" (c), "m" (b) \
|
||||
: "g1", "o0", "o1", "o2", "o3", "o4", \
|
||||
"o5" \
|
||||
);
|
||||
#endif /* SPARCv9 */
|
||||
|
||||
#if defined(__sparc__) && !defined(__sparc64__)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
__asm__( \
|
||||
" \
|
||||
ld %3, %%o0; \
|
||||
ld %4, %%o1; \
|
||||
ld %5, %%o2; \
|
||||
ld %6, %%o3; \
|
||||
"
|
||||
|
||||
#define MULADDC_CORE \
|
||||
" \
|
||||
ld [%%o0], %%o4; \
|
||||
inc 4, %%o0; \
|
||||
ld [%%o1], %%o5; \
|
||||
umul %%o3, %%o4, %%o4; \
|
||||
addcc %%o4, %%o2, %%o4; \
|
||||
rd %%y, %%g1; \
|
||||
addx %%g1, 0, %%g1; \
|
||||
addcc %%o4, %%o5, %%o4; \
|
||||
st %%o4, [%%o1]; \
|
||||
addx %%g1, 0, %%o2; \
|
||||
inc 4, %%o1; \
|
||||
"
|
||||
|
||||
#define MULADDC_STOP \
|
||||
" \
|
||||
st %%o2, %0; \
|
||||
st %%o1, %1; \
|
||||
st %%o0, %2; \
|
||||
" \
|
||||
: "=m" (c), "=m" (d), "=m" (s) \
|
||||
: "m" (s), "m" (d), "m" (c), "m" (b) \
|
||||
: "g1", "o0", "o1", "o2", "o3", "o4", \
|
||||
"o5" \
|
||||
);
|
||||
|
||||
#endif /* SPARCv8 */
|
||||
|
||||
#if defined(__microblaze__) || defined(microblaze)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
__asm__( "lwi r3, %0 " :: "m" (s)); \
|
||||
__asm__( "lwi r4, %0 " :: "m" (d)); \
|
||||
__asm__( "lwi r5, %0 " :: "m" (c)); \
|
||||
__asm__( "lwi r6, %0 " :: "m" (b)); \
|
||||
__asm__( "andi r7, r6, 0xffff" ); \
|
||||
__asm__( "bsrli r6, r6, 16 " );
|
||||
|
||||
#define MULADDC_CORE \
|
||||
__asm__( "lhui r8, r3, 0 " ); \
|
||||
__asm__( "addi r3, r3, 2 " ); \
|
||||
__asm__( "lhui r9, r3, 0 " ); \
|
||||
__asm__( "addi r3, r3, 2 " ); \
|
||||
__asm__( "mul r10, r9, r6 " ); \
|
||||
__asm__( "mul r11, r8, r7 " ); \
|
||||
__asm__( "mul r12, r9, r7 " ); \
|
||||
__asm__( "mul r13, r8, r6 " ); \
|
||||
__asm__( "bsrli r8, r10, 16 " ); \
|
||||
__asm__( "bsrli r9, r11, 16 " ); \
|
||||
__asm__( "add r13, r13, r8 " ); \
|
||||
__asm__( "add r13, r13, r9 " ); \
|
||||
__asm__( "bslli r10, r10, 16 " ); \
|
||||
__asm__( "bslli r11, r11, 16 " ); \
|
||||
__asm__( "add r12, r12, r10 " ); \
|
||||
__asm__( "addc r13, r13, r0 " ); \
|
||||
__asm__( "add r12, r12, r11 " ); \
|
||||
__asm__( "addc r13, r13, r0 " ); \
|
||||
__asm__( "lwi r10, r4, 0 " ); \
|
||||
__asm__( "add r12, r12, r10 " ); \
|
||||
__asm__( "addc r13, r13, r0 " ); \
|
||||
__asm__( "add r12, r12, r5 " ); \
|
||||
__asm__( "addc r5, r13, r0 " ); \
|
||||
__asm__( "swi r12, r4, 0 " ); \
|
||||
__asm__( "addi r4, r4, 4 " );
|
||||
|
||||
#define MULADDC_STOP \
|
||||
__asm__( "swi r5, %0 " : "=m" (c)); \
|
||||
__asm__( "swi r4, %0 " : "=m" (d)); \
|
||||
__asm__( "swi r3, %0 " : "=m" (s) :: \
|
||||
"r3", "r4" , "r5" , "r6" , "r7" , "r8" , \
|
||||
"r9", "r10", "r11", "r12", "r13" );
|
||||
|
||||
#endif /* MicroBlaze */
|
||||
|
||||
#if defined(__tricore__)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
__asm__( "ld.a %%a2, %0 " :: "m" (s)); \
|
||||
__asm__( "ld.a %%a3, %0 " :: "m" (d)); \
|
||||
__asm__( "ld.w %%d4, %0 " :: "m" (c)); \
|
||||
__asm__( "ld.w %%d1, %0 " :: "m" (b)); \
|
||||
__asm__( "xor %d5, %d5 " );
|
||||
|
||||
#define MULADDC_CORE \
|
||||
__asm__( "ld.w %d0, [%a2+] " ); \
|
||||
__asm__( "madd.u %e2, %e4, %d0, %d1 " ); \
|
||||
__asm__( "ld.w %d0, [%a3] " ); \
|
||||
__asm__( "addx %d2, %d2, %d0 " ); \
|
||||
__asm__( "addc %d3, %d3, 0 " ); \
|
||||
__asm__( "mov %d4, %d3 " ); \
|
||||
__asm__( "st.w [%a3+], %d2 " );
|
||||
|
||||
#define MULADDC_STOP \
|
||||
__asm__( "st.w %0, %%d4 " : "=m" (c)); \
|
||||
__asm__( "st.a %0, %%a3 " : "=m" (d)); \
|
||||
__asm__( "st.a %0, %%a2 " : "=m" (s) :: \
|
||||
"d0", "d1", "e2", "d4", "a2", "a3" );
|
||||
|
||||
#endif /* TriCore */
|
||||
|
||||
#if defined(__arm__)
|
||||
|
||||
#if defined(__thumb__) && !defined(__thumb2__)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
__asm__( \
|
||||
" \
|
||||
ldr r0, %3; \
|
||||
ldr r1, %4; \
|
||||
ldr r2, %5; \
|
||||
ldr r3, %6; \
|
||||
lsr r7, r3, #16; \
|
||||
mov r9, r7; \
|
||||
lsl r7, r3, #16; \
|
||||
lsr r7, r7, #16; \
|
||||
mov r8, r7; \
|
||||
"
|
||||
|
||||
#define MULADDC_CORE \
|
||||
" \
|
||||
ldmia r0!, {r6}; \
|
||||
lsr r7, r6, #16; \
|
||||
lsl r6, r6, #16; \
|
||||
lsr r6, r6, #16; \
|
||||
mov r4, r8; \
|
||||
mul r4, r6; \
|
||||
mov r3, r9; \
|
||||
mul r6, r3; \
|
||||
mov r5, r9; \
|
||||
mul r5, r7; \
|
||||
mov r3, r8; \
|
||||
mul r7, r3; \
|
||||
lsr r3, r6, #16; \
|
||||
add r5, r5, r3; \
|
||||
lsr r3, r7, #16; \
|
||||
add r5, r5, r3; \
|
||||
add r4, r4, r2; \
|
||||
mov r2, #0; \
|
||||
adc r5, r2; \
|
||||
lsl r3, r6, #16; \
|
||||
add r4, r4, r3; \
|
||||
adc r5, r2; \
|
||||
lsl r3, r7, #16; \
|
||||
add r4, r4, r3; \
|
||||
adc r5, r2; \
|
||||
ldr r3, [r1]; \
|
||||
add r4, r4, r3; \
|
||||
adc r2, r5; \
|
||||
stmia r1!, {r4}; \
|
||||
"
|
||||
|
||||
#define MULADDC_STOP \
|
||||
" \
|
||||
str r2, %0; \
|
||||
str r1, %1; \
|
||||
str r0, %2; \
|
||||
" \
|
||||
: "=m" (c), "=m" (d), "=m" (s) \
|
||||
: "m" (s), "m" (d), "m" (c), "m" (b) \
|
||||
: "r0", "r1", "r2", "r3", "r4", "r5", \
|
||||
"r6", "r7", "r8", "r9", "cc" \
|
||||
);
|
||||
|
||||
#else
|
||||
|
||||
#define MULADDC_INIT \
|
||||
__asm__( \
|
||||
" \
|
||||
ldr r0, %3; \
|
||||
ldr r1, %4; \
|
||||
ldr r2, %5; \
|
||||
ldr r3, %6; \
|
||||
"
|
||||
|
||||
#define MULADDC_CORE \
|
||||
" \
|
||||
ldr r4, [r0], #4; \
|
||||
mov r5, #0; \
|
||||
ldr r6, [r1]; \
|
||||
umlal r2, r5, r3, r4; \
|
||||
adds r7, r6, r2; \
|
||||
adc r2, r5, #0; \
|
||||
str r7, [r1], #4; \
|
||||
"
|
||||
|
||||
#define MULADDC_STOP \
|
||||
" \
|
||||
str r2, %0; \
|
||||
str r1, %1; \
|
||||
str r0, %2; \
|
||||
" \
|
||||
: "=m" (c), "=m" (d), "=m" (s) \
|
||||
: "m" (s), "m" (d), "m" (c), "m" (b) \
|
||||
: "r0", "r1", "r2", "r3", "r4", "r5", \
|
||||
"r6", "r7", "cc" \
|
||||
);
|
||||
|
||||
#endif /* Thumb */
|
||||
|
||||
#endif /* ARMv3 */
|
||||
|
||||
#if defined(__alpha__)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
__asm__( "ldq $1, %0 " :: "m" (s)); \
|
||||
__asm__( "ldq $2, %0 " :: "m" (d)); \
|
||||
__asm__( "ldq $3, %0 " :: "m" (c)); \
|
||||
__asm__( "ldq $4, %0 " :: "m" (b));
|
||||
|
||||
#define MULADDC_CORE \
|
||||
__asm__( "ldq $6, 0($1) " ); \
|
||||
__asm__( "addq $1, 8, $1 " ); \
|
||||
__asm__( "mulq $6, $4, $7 " ); \
|
||||
__asm__( "umulh $6, $4, $6 " ); \
|
||||
__asm__( "addq $7, $3, $7 " ); \
|
||||
__asm__( "cmpult $7, $3, $3 " ); \
|
||||
__asm__( "ldq $5, 0($2) " ); \
|
||||
__asm__( "addq $7, $5, $7 " ); \
|
||||
__asm__( "cmpult $7, $5, $5 " ); \
|
||||
__asm__( "stq $7, 0($2) " ); \
|
||||
__asm__( "addq $2, 8, $2 " ); \
|
||||
__asm__( "addq $6, $3, $3 " ); \
|
||||
__asm__( "addq $5, $3, $3 " );
|
||||
|
||||
#define MULADDC_STOP \
|
||||
__asm__( "stq $3, %0 " : "=m" (c)); \
|
||||
__asm__( "stq $2, %0 " : "=m" (d)); \
|
||||
__asm__( "stq $1, %0 " : "=m" (s) :: \
|
||||
"$1", "$2", "$3", "$4", "$5", "$6", "$7" );
|
||||
|
||||
#endif /* Alpha */
|
||||
|
||||
#if defined(__mips__)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
__asm__( "lw $10, %0 " :: "m" (s)); \
|
||||
__asm__( "lw $11, %0 " :: "m" (d)); \
|
||||
__asm__( "lw $12, %0 " :: "m" (c)); \
|
||||
__asm__( "lw $13, %0 " :: "m" (b));
|
||||
|
||||
#define MULADDC_CORE \
|
||||
__asm__( "lw $14, 0($10) " ); \
|
||||
__asm__( "multu $13, $14 " ); \
|
||||
__asm__( "addi $10, $10, 4 " ); \
|
||||
__asm__( "mflo $14 " ); \
|
||||
__asm__( "mfhi $9 " ); \
|
||||
__asm__( "addu $14, $12, $14 " ); \
|
||||
__asm__( "lw $15, 0($11) " ); \
|
||||
__asm__( "sltu $12, $14, $12 " ); \
|
||||
__asm__( "addu $15, $14, $15 " ); \
|
||||
__asm__( "sltu $14, $15, $14 " ); \
|
||||
__asm__( "addu $12, $12, $9 " ); \
|
||||
__asm__( "sw $15, 0($11) " ); \
|
||||
__asm__( "addu $12, $12, $14 " ); \
|
||||
__asm__( "addi $11, $11, 4 " );
|
||||
|
||||
#define MULADDC_STOP \
|
||||
__asm__( "sw $12, %0 " : "=m" (c)); \
|
||||
__asm__( "sw $11, %0 " : "=m" (d)); \
|
||||
__asm__( "sw $10, %0 " : "=m" (s) :: \
|
||||
"$9", "$10", "$11", "$12", "$13", "$14", "$15" );
|
||||
|
||||
#endif /* MIPS */
|
||||
#endif /* GNUC */
|
||||
|
||||
#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
____asm__ mov esi, s \
|
||||
____asm__ mov edi, d \
|
||||
____asm__ mov ecx, c \
|
||||
____asm__ mov ebx, b
|
||||
|
||||
#define MULADDC_CORE \
|
||||
____asm__ lodsd \
|
||||
____asm__ mul ebx \
|
||||
____asm__ add eax, ecx \
|
||||
____asm__ adc edx, 0 \
|
||||
____asm__ add eax, [edi] \
|
||||
____asm__ adc edx, 0 \
|
||||
____asm__ mov ecx, edx \
|
||||
____asm__ stosd
|
||||
|
||||
#if defined(POLARSSL_HAVE_SSE2)
|
||||
|
||||
#define EMIT ____asm__ _emit
|
||||
|
||||
#define MULADDC_HUIT \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0xC9 \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0xC3 \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x1F \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x16 \
|
||||
EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \
|
||||
EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \
|
||||
EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \
|
||||
EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xDC \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xEE \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xFC \
|
||||
EMIT 0x0F EMIT 0x7E EMIT 0x0F \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \
|
||||
EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
|
||||
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \
|
||||
EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \
|
||||
EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
|
||||
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \
|
||||
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \
|
||||
EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xCD \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \
|
||||
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \
|
||||
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xCF \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \
|
||||
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \
|
||||
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \
|
||||
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \
|
||||
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xCC \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xDD \
|
||||
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \
|
||||
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xCE \
|
||||
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \
|
||||
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
|
||||
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \
|
||||
EMIT 0x83 EMIT 0xC7 EMIT 0x20 \
|
||||
EMIT 0x83 EMIT 0xC6 EMIT 0x20 \
|
||||
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
|
||||
EMIT 0x0F EMIT 0x7E EMIT 0xC9
|
||||
|
||||
#define MULADDC_STOP \
|
||||
EMIT 0x0F EMIT 0x77 \
|
||||
____asm__ mov c, ecx \
|
||||
____asm__ mov d, edi \
|
||||
____asm__ mov s, esi \
|
||||
|
||||
#else
|
||||
|
||||
#define MULADDC_STOP \
|
||||
____asm__ mov c, ecx \
|
||||
____asm__ mov d, edi \
|
||||
____asm__ mov s, esi \
|
||||
|
||||
#endif /* SSE2 */
|
||||
#endif /* MSVC */
|
||||
|
||||
#endif /* POLARSSL_HAVE_ASM */
|
||||
|
||||
#if !defined(MULADDC_CORE)
|
||||
#if defined(POLARSSL_HAVE_UDBL)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
{ \
|
||||
t_udbl r; \
|
||||
t_uint r0, r1;
|
||||
|
||||
#define MULADDC_CORE \
|
||||
r = *(s++) * (t_udbl) b; \
|
||||
r0 = r; \
|
||||
r1 = r >> biL; \
|
||||
r0 += c; r1 += (r0 < c); \
|
||||
r0 += *d; r1 += (r0 < *d); \
|
||||
c = r1; *(d++) = r0;
|
||||
|
||||
#define MULADDC_STOP \
|
||||
}
|
||||
|
||||
#else
|
||||
#define MULADDC_INIT \
|
||||
{ \
|
||||
t_uint s0, s1, b0, b1; \
|
||||
t_uint r0, r1, rx, ry; \
|
||||
b0 = ( b << biH ) >> biH; \
|
||||
b1 = ( b >> biH );
|
||||
|
||||
#define MULADDC_CORE \
|
||||
s0 = ( *s << biH ) >> biH; \
|
||||
s1 = ( *s >> biH ); s++; \
|
||||
rx = s0 * b1; r0 = s0 * b0; \
|
||||
ry = s1 * b0; r1 = s1 * b1; \
|
||||
r1 += ( rx >> biH ); \
|
||||
r1 += ( ry >> biH ); \
|
||||
rx <<= biH; ry <<= biH; \
|
||||
r0 += rx; r1 += (r0 < rx); \
|
||||
r0 += ry; r1 += (r0 < ry); \
|
||||
r0 += c; r1 += (r0 < c); \
|
||||
r0 += *d; r1 += (r0 < *d); \
|
||||
c = r1; *(d++) = r0;
|
||||
|
||||
#define MULADDC_STOP \
|
||||
}
|
||||
|
||||
#endif /* C (generic) */
|
||||
#endif /* C (longlong) */
|
||||
|
||||
#endif /* bn_mul.h */
|
||||
+1035
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,200 @@
|
||||
/**
|
||||
* \file camellia.h
|
||||
*
|
||||
* \brief Camellia block cipher
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef POLARSSL_CAMELLIA_H
|
||||
#define POLARSSL_CAMELLIA_H
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <basetsd.h>
|
||||
typedef UINT32 uint32_t;
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#define CAMELLIA_ENCRYPT 1
|
||||
#define CAMELLIA_DECRYPT 0
|
||||
|
||||
#define POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH -0x0024 /**< Invalid key length. */
|
||||
#define POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH -0x0026 /**< Invalid data input length. */
|
||||
|
||||
#if !defined(POLARSSL_CAMELLIA_ALT)
|
||||
// Regular implementation
|
||||
//
|
||||
|
||||
/**
|
||||
* \brief CAMELLIA context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int nr; /*!< number of rounds */
|
||||
uint32_t rk[68]; /*!< CAMELLIA round keys */
|
||||
}
|
||||
camellia_context;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief CAMELLIA key schedule (encryption)
|
||||
*
|
||||
* \param ctx CAMELLIA context to be initialized
|
||||
* \param key encryption key
|
||||
* \param keysize must be 128, 192 or 256
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH
|
||||
*/
|
||||
int camellia_setkey_enc( camellia_context *ctx, const unsigned char *key, unsigned int keysize );
|
||||
|
||||
/**
|
||||
* \brief CAMELLIA key schedule (decryption)
|
||||
*
|
||||
* \param ctx CAMELLIA context to be initialized
|
||||
* \param key decryption key
|
||||
* \param keysize must be 128, 192 or 256
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH
|
||||
*/
|
||||
int camellia_setkey_dec( camellia_context *ctx, const unsigned char *key, unsigned int keysize );
|
||||
|
||||
/**
|
||||
* \brief CAMELLIA-ECB block encryption/decryption
|
||||
*
|
||||
* \param ctx CAMELLIA context
|
||||
* \param mode CAMELLIA_ENCRYPT or CAMELLIA_DECRYPT
|
||||
* \param input 16-byte input block
|
||||
* \param output 16-byte output block
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int camellia_crypt_ecb( camellia_context *ctx,
|
||||
int mode,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] );
|
||||
|
||||
/**
|
||||
* \brief CAMELLIA-CBC buffer encryption/decryption
|
||||
* Length should be a multiple of the block
|
||||
* size (16 bytes)
|
||||
*
|
||||
* \param ctx CAMELLIA context
|
||||
* \param mode CAMELLIA_ENCRYPT or CAMELLIA_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH
|
||||
*/
|
||||
int camellia_crypt_cbc( camellia_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief CAMELLIA-CFB128 buffer encryption/decryption
|
||||
*
|
||||
* Note: Due to the nature of CFB you should use the same key schedule for
|
||||
* both encryption and decryption. So a context initialized with
|
||||
* camellia_setkey_enc() for both CAMELLIA_ENCRYPT and CAMELLIE_DECRYPT.
|
||||
*
|
||||
* \param ctx CAMELLIA context
|
||||
* \param mode CAMELLIA_ENCRYPT or CAMELLIA_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv_off offset in IV (updated after use)
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH
|
||||
*/
|
||||
int camellia_crypt_cfb128( camellia_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief CAMELLIA-CTR buffer encryption/decryption
|
||||
*
|
||||
* Warning: You have to keep the maximum use of your counter in mind!
|
||||
*
|
||||
* Note: Due to the nature of CTR you should use the same key schedule for
|
||||
* both encryption and decryption. So a context initialized with
|
||||
* camellia_setkey_enc() for both CAMELLIA_ENCRYPT and CAMELLIA_DECRYPT.
|
||||
*
|
||||
* \param length The length of the data
|
||||
* \param nc_off The offset in the current stream_block (for resuming
|
||||
* within current cipher stream). The offset pointer to
|
||||
* should be 0 at the start of a stream.
|
||||
* \param nonce_counter The 128-bit nonce and counter.
|
||||
* \param stream_block The saved stream-block for resuming. Is overwritten
|
||||
* by the function.
|
||||
* \param input The input data stream
|
||||
* \param output The output data stream
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int camellia_crypt_ctr( camellia_context *ctx,
|
||||
size_t length,
|
||||
size_t *nc_off,
|
||||
unsigned char nonce_counter[16],
|
||||
unsigned char stream_block[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* POLARSSL_CAMELLIA_ALT */
|
||||
#include "polarssl/camellia_alt.h"
|
||||
#endif /* POLARSSL_CAMELLIA_ALT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int camellia_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* camellia.h */
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* X.509 test certificates
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_CERTS_C)
|
||||
|
||||
const char test_ca_crt[] =
|
||||
"-----BEGIN CERTIFICATE-----\r\n"
|
||||
"MIIDhzCCAm+gAwIBAgIBADANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n"
|
||||
"MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n"
|
||||
"MTEwMjEyMTQ0NDAwWhcNMjEwMjEyMTQ0NDAwWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n"
|
||||
"A1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n"
|
||||
"CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n"
|
||||
"mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n"
|
||||
"50BwFMtEonILwuVA+T7lpg6z+exKY8C4KQB0nFc7qKUEkHHxvYPZP9al4jwqj+8n\r\n"
|
||||
"YMPGn8u67GB9t+aEMr5P+1gmIgNb1LTV+/Xjli5wwOQuvfwu7uJBVcA0Ln0kcmnL\r\n"
|
||||
"R7EUQIN9Z/SG9jGr8XmksrUuEvmEF/Bibyc+E1ixVA0hmnM3oTDPb5Lc9un8rNsu\r\n"
|
||||
"KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n"
|
||||
"gZUwgZIwDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUtFrkpbPe0lL2udWmlQ/rPrzH\r\n"
|
||||
"/f8wYwYDVR0jBFwwWoAUtFrkpbPe0lL2udWmlQ/rPrzH/f+hP6Q9MDsxCzAJBgNV\r\n"
|
||||
"BAYTAk5MMREwDwYDVQQKEwhQb2xhclNTTDEZMBcGA1UEAxMQUG9sYXJTU0wgVGVz\r\n"
|
||||
"dCBDQYIBADANBgkqhkiG9w0BAQUFAAOCAQEAuP1U2ABUkIslsCfdlc2i94QHHYeJ\r\n"
|
||||
"SsR4EdgHtdciUI5I62J6Mom+Y0dT/7a+8S6MVMCZP6C5NyNyXw1GWY/YR82XTJ8H\r\n"
|
||||
"DBJiCTok5DbZ6SzaONBzdWHXwWwmi5vg1dxn7YxrM9d0IjxM27WNKs4sDQhZBQkF\r\n"
|
||||
"pjmfs2cb4oPl4Y9T9meTx/lvdkRYEug61Jfn6cA+qHpyPYdTH+UshITnmp5/Ztkf\r\n"
|
||||
"m/UTSLBNFNHesiTZeH31NcxYGdHSme9Nc/gfidRa0FLOCfWxRlFqAI47zG9jAQCZ\r\n"
|
||||
"7Z2mCGDNMhjQc+BYcdnl0lPXjdDK6V0qCg1dVewhUBcW5gZKzV7e9+DpVA==\r\n"
|
||||
"-----END CERTIFICATE-----\r\n";
|
||||
|
||||
const char test_ca_key[] =
|
||||
"-----BEGIN RSA PRIVATE KEY-----\r\n"
|
||||
"Proc-Type: 4,ENCRYPTED\r\n"
|
||||
"DEK-Info: DES-EDE3-CBC,A8A95B05D5B7206B\r\n"
|
||||
"\r\n"
|
||||
"9Qd9GeArejl1GDVh2lLV1bHt0cPtfbh5h/5zVpAVaFpqtSPMrElp50Rntn9et+JA\r\n"
|
||||
"7VOyboR+Iy2t/HU4WvA687k3Bppe9GwKHjHhtl//8xFKwZr3Xb5yO5JUP8AUctQq\r\n"
|
||||
"Nb8CLlZyuUC+52REAAthdWgsX+7dJO4yabzUcQ22Tp9JSD0hiL43BlkWYUNK3dAo\r\n"
|
||||
"PZlmiptjnzVTjg1MxsBSydZinWOLBV8/JQgxSPo2yD4uEfig28qbvQ2wNIn0pnAb\r\n"
|
||||
"GxnSAOazkongEGfvcjIIs+LZN9gXFhxcOh6kc4Q/c99B7QWETwLLkYgZ+z1a9VY9\r\n"
|
||||
"gEU7CwCxYCD+h9hY6FPmsK0/lC4O7aeRKpYq00rPPxs6i7phiexg6ax6yTMmArQq\r\n"
|
||||
"QmK3TAsJm8V/J5AWpLEV6jAFgRGymGGHnof0DXzVWZidrcZJWTNuGEX90nB3ee2w\r\n"
|
||||
"PXJEFWKoD3K3aFcSLdHYr3mLGxP7H9ThQai9VsycxZKS5kwvBKQ//YMrmFfwPk8x\r\n"
|
||||
"vTeY4KZMaUrveEel5tWZC94RSMKgxR6cyE1nBXyTQnDOGbfpNNgBKxyKbINWoOJU\r\n"
|
||||
"WJZAwlsQn+QzCDwpri7+sV1mS3gBE6UY7aQmnmiiaC2V3Hbphxct/en5QsfDOt1X\r\n"
|
||||
"JczSfpRWLlbPznZg8OQh/VgCMA58N5DjOzTIK7sJJ5r+94ZBTCpgAMbF588f0NTR\r\n"
|
||||
"KCe4yrxGJR7X02M4nvD4IwOlpsQ8xQxZtOSgXv4LkxvdU9XJJKWZ/XNKJeWztxSe\r\n"
|
||||
"Z1vdTc2YfsDBA2SEv33vxHx2g1vqtw8SjDRT2RaQSS0QuSaMJimdOX6mTOCBKk1J\r\n"
|
||||
"9Q5mXTrER+/LnK0jEmXsBXWA5bqqVZIyahXSx4VYZ7l7w/PHiUDtDgyRhMMKi4n2\r\n"
|
||||
"iQvQcWSQTjrpnlJbca1/DkpRt3YwrvJwdqb8asZU2VrNETh5x0QVefDRLFiVpif/\r\n"
|
||||
"tUaeAe/P1F8OkS7OIZDs1SUbv/sD2vMbhNkUoCms3/PvNtdnvgL4F0zhaDpKCmlT\r\n"
|
||||
"P8vx49E7v5CyRNmED9zZg4o3wmMqrQO93PtTug3Eu9oVx1zPQM1NVMyBa2+f29DL\r\n"
|
||||
"1nuTCeXdo9+ni45xx+jAI4DCwrRdhJ9uzZyC6962H37H6D+5naNvClFR1s6li1Gb\r\n"
|
||||
"nqPoiy/OBsEx9CaDGcqQBp5Wme/3XW+6z1ISOx+igwNTVCT14mHdBMbya0eIKft5\r\n"
|
||||
"X+GnwtgEMyCYyyWuUct8g4RzErcY9+yW9Om5Hzpx4zOuW4NPZgPDTgK+t2RSL/Yq\r\n"
|
||||
"rE1njrgeGYcVeG3f+OftH4s6fPbq7t1A5ZgUscbLMBqr9tK+OqygR4EgKBPsH6Cz\r\n"
|
||||
"L6zlv/2RV0qAHvVuDJcIDIgwY5rJtINEm32rhOeFNJwZS5MNIC1czXZx5//ugX7l\r\n"
|
||||
"I4sy5nbVhwSjtAk8Xg5dZbdTZ6mIrb7xqH+fdakZor1khG7bC2uIwibD3cSl2XkR\r\n"
|
||||
"wN48lslbHnqqagr6Xm1nNOSVl8C/6kbJEsMpLhAezfRtGwvOucoaE+WbeUNolGde\r\n"
|
||||
"P/eQiddSf0brnpiLJRh7qZrl9XuqYdpUqnoEdMAfotDOID8OtV7gt8a48ad8VPW2\r\n"
|
||||
"-----END RSA PRIVATE KEY-----\r\n";
|
||||
|
||||
const char test_ca_pwd[] = "PolarSSLTest";
|
||||
|
||||
const char test_srv_crt[] =
|
||||
"-----BEGIN CERTIFICATE-----\r\n"
|
||||
"MIIDPzCCAiegAwIBAgIBATANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n"
|
||||
"MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n"
|
||||
"MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA8MQswCQYDVQQGEwJOTDERMA8G\r\n"
|
||||
"A1UEChMIUG9sYXJTU0wxGjAYBgNVBAMTEVBvbGFyU1NMIFNlcnZlciAxMIIBIjAN\r\n"
|
||||
"BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqQIfPUBq1VVTi/027oJlLhVhXom/\r\n"
|
||||
"uOhFkNvuiBZS0/FDUEeWEllkh2v9K+BG+XO+3c+S4ZFb7Wagb4kpeUWA0INq1UFD\r\n"
|
||||
"d185fAkER4KwVzlw7aPsFRkeqDMIR8EFQqn9TMO0390GH00QUUBncxMPQPhtgSVf\r\n"
|
||||
"CrFTxjB+FTms+Vruf5KepgVb5xOXhbUjktnUJAbVCSWJdQfdphqPPwkZvq1lLGTr\r\n"
|
||||
"lZvc/kFeF6babFtpzAK6FCwWJJxK3M3Q91Jnc/EtoCP9fvQxyi1wyokLBNsupk9w\r\n"
|
||||
"bp7OvViJ4lNZnm5akmXiiD8MlBmj3eXonZUT7Snbq3AS3FrKaxerUoJUsQIDAQAB\r\n"
|
||||
"o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBQfdNY/KcF0dEU7BRIsPai9Q1kCpjAf\r\n"
|
||||
"BgNVHSMEGDAWgBS0WuSls97SUva51aaVD+s+vMf9/zANBgkqhkiG9w0BAQUFAAOC\r\n"
|
||||
"AQEAvc+WwZUemsJu2IiI2Cp6liA+UAvIx98dQe3kZs2zAoF9VwQbXcYzWQ/BILkj\r\n"
|
||||
"NImKbPL9x0g2jIDn4ZvGYFywMwIO/d++YbwYiQw42/v7RiMy94zBPnzeHi86dy/0\r\n"
|
||||
"jpOOJUx3IXRsGLdyjb/1T11klcFqGnARiK+8VYolMPP6afKvLXX7K4kiUpsFQhUp\r\n"
|
||||
"E5VeM5pV1Mci2ETOJau2cO40FJvI/C9W/wR+GAArMaw2fxG77E3laaa0LAOlexM6\r\n"
|
||||
"A4KOb5f5cGTM5Ih6tEF5FVq3/9vzNIYMa1FqzacBLZF8zSHYLEimXBdzjBoN4qDU\r\n"
|
||||
"/WzRyYRBRjAI49mzHX6raleqnw==\r\n"
|
||||
"-----END CERTIFICATE-----\r\n";
|
||||
|
||||
const char test_srv_key[] =
|
||||
"-----BEGIN RSA PRIVATE KEY-----\r\n"
|
||||
"MIIEogIBAAKCAQEAqQIfPUBq1VVTi/027oJlLhVhXom/uOhFkNvuiBZS0/FDUEeW\r\n"
|
||||
"Ellkh2v9K+BG+XO+3c+S4ZFb7Wagb4kpeUWA0INq1UFDd185fAkER4KwVzlw7aPs\r\n"
|
||||
"FRkeqDMIR8EFQqn9TMO0390GH00QUUBncxMPQPhtgSVfCrFTxjB+FTms+Vruf5Ke\r\n"
|
||||
"pgVb5xOXhbUjktnUJAbVCSWJdQfdphqPPwkZvq1lLGTrlZvc/kFeF6babFtpzAK6\r\n"
|
||||
"FCwWJJxK3M3Q91Jnc/EtoCP9fvQxyi1wyokLBNsupk9wbp7OvViJ4lNZnm5akmXi\r\n"
|
||||
"iD8MlBmj3eXonZUT7Snbq3AS3FrKaxerUoJUsQIDAQABAoIBABaJ9eiRQq4Ypv+w\r\n"
|
||||
"UTcVpLC0oTueWzcpor1i1zjG4Vzqe/Ok2FqyGToGKMlFK7Hwwa+LEyeJ3xyV5yd4\r\n"
|
||||
"v1Mw9bDZFdJC1eCBjoUAHtX6k9HOE0Vd6woVQ4Vi6OPI1g7B5Mnr/58rNrnN6TMs\r\n"
|
||||
"x58NF6euecwTU811QJrZtLbX7j2Cr28yB2Vs8qyYlHwVw5jbDOv43D7vU5gmlIDN\r\n"
|
||||
"0JQRuWAnOuPzZNoJr4SfJKqHNGxYYY6pHZ1s0dOTLIDb/B8KQWapA2kRmZyid2EH\r\n"
|
||||
"nwzgLbAsHJCf+bQnhXjXuxtUsrcIL8noZLazlOMxwNEammglVWW23Ud/QRnFgJg5\r\n"
|
||||
"UgcAcRECgYEA19uYetht5qmwdJ+12oC6zeO+vXLcyD9gon23T5J6w2YThld7/OW0\r\n"
|
||||
"oArQJGgkAdaq0pcTyOIjtTQVMFygdVmCEJmxh/3RutPcTeydqW9fphKDMej32J8e\r\n"
|
||||
"GniGmNGiclbcfNOS8E5TGp445yZb9P1+7AHng16bGg3Ykj5EA4G+HCcCgYEAyHAl\r\n"
|
||||
"//ekk8YjQElm+8izLtFkymIK0aCtEe9C/RIRhFYBeFaotC5dStNhBOncn4ovMAPD\r\n"
|
||||
"lX/92yDi9OP8PPLN3a4B9XpW3k/SS5GrbT5cwOivBHNllZSmu/2qz5WPGcjVCOrB\r\n"
|
||||
"LYl3YWr2h3EGKICT03kEoTkiDBvCeOpW7cCGl2cCgYBD5whoXHz1+ptPlI4YVjZt\r\n"
|
||||
"Xh86aU+ajpVPiEyJ84I6xXmO4SZXv8q6LaycR0ZMbcL+zBelMb4Z2nBv7jNrtuR7\r\n"
|
||||
"ZF28cdPv+YVr3esaybZE/73VjXup4SQPH6r3l7qKTVi+y6+FeJ4b2Xn8/MwgnT23\r\n"
|
||||
"8EFrye7wmzpthrjOgZnUMQKBgE9Lhsz/5J0Nis6Y+2Pqn3CLKEukg9Ewtqdct2y0\r\n"
|
||||
"5Dcta0F3TyCRIxlCDKTL/BslqMtfAdY4H268UO0+8IAQMn9boqzBrHIgs/pvc5kx\r\n"
|
||||
"TbKHmw2wtWR6vYersBKVgVpbCGSRssDYHGFu1n74qM4HJ/RGcR1zI9QUe1gopSFD\r\n"
|
||||
"xDtLAoGAVAdWvrqDwgoL2hHW3scGpxdE/ygJDOwHnf+1B9goKAOP5lf2FJaiAxf3\r\n"
|
||||
"ectoPOgZbCmm/iiDmigu703ld3O+VoCLDD4qx3R+KyALL78gtVJYzSRiKhzgCZ3g\r\n"
|
||||
"mKsIVRBq4IfwiwyMNG2BYZQAwbSDjjPtn/kPBduPzPj7eriByhI=\r\n"
|
||||
"-----END RSA PRIVATE KEY-----\r\n";
|
||||
|
||||
const char test_cli_crt[] =
|
||||
"-----BEGIN CERTIFICATE-----\r\n"
|
||||
"MIIDPzCCAiegAwIBAgIBBDANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n"
|
||||
"MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n"
|
||||
"MTEwMjEyMTQ0NDA3WhcNMjEwMjEyMTQ0NDA3WjA8MQswCQYDVQQGEwJOTDERMA8G\r\n"
|
||||
"A1UEChMIUG9sYXJTU0wxGjAYBgNVBAMTEVBvbGFyU1NMIENsaWVudCAyMIIBIjAN\r\n"
|
||||
"BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6f\r\n"
|
||||
"M60Nj4o8VmXl3ETZzGaFB9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu\r\n"
|
||||
"1C93KYRhTYJQj6eVSHD1bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEw\r\n"
|
||||
"MjDV0/YI0FZPRo7yX/k9Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v\r\n"
|
||||
"4Jv4EFbMs44TFeY0BGbH7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx/\r\n"
|
||||
"/DZrtenNLQNiTrM9AM+vdqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQAB\r\n"
|
||||
"o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBRxoQBzckAvVHZeM/xSj7zx3WtGITAf\r\n"
|
||||
"BgNVHSMEGDAWgBS0WuSls97SUva51aaVD+s+vMf9/zANBgkqhkiG9w0BAQUFAAOC\r\n"
|
||||
"AQEAAn86isAM8X+mVwJqeItt6E9slhEQbAofyk+diH1Lh8Y9iLlWQSKbw/UXYjx5\r\n"
|
||||
"LLPZcniovxIcARC/BjyZR9g3UwTHNGNm+rwrqa15viuNOFBchykX/Orsk02EH7NR\r\n"
|
||||
"Alw5WLPorYjED6cdVQgBl9ot93HdJogRiXCxErM7NC8/eP511mjq+uLDjLKH8ZPQ\r\n"
|
||||
"8I4ekHJnroLsDkIwXKGIsvIBHQy2ac/NwHLCQOK6mfum1pRx52V4Utu5dLLjD5bM\r\n"
|
||||
"xOBC7KU4xZKuMXXZM6/93Yb51K/J4ahf1TxJlTWXtnzDr9saEYdNy2SKY/6ZiDNH\r\n"
|
||||
"D+stpAKiQLAWaAusIWKYEyw9MQ==\r\n"
|
||||
"-----END CERTIFICATE-----\r\n";
|
||||
|
||||
const char test_cli_key[] =
|
||||
"-----BEGIN RSA PRIVATE KEY-----\r\n"
|
||||
"MIIEpAIBAAKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6fM60Nj4o8VmXl3ETZzGaF\r\n"
|
||||
"B9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu1C93KYRhTYJQj6eVSHD1\r\n"
|
||||
"bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEwMjDV0/YI0FZPRo7yX/k9\r\n"
|
||||
"Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v4Jv4EFbMs44TFeY0BGbH\r\n"
|
||||
"7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx//DZrtenNLQNiTrM9AM+v\r\n"
|
||||
"dqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQABAoIBAGdNtfYDiap6bzst\r\n"
|
||||
"yhCiI8m9TtrhZw4MisaEaN/ll3XSjaOG2dvV6xMZCMV+5TeXDHOAZnY18Yi18vzz\r\n"
|
||||
"4Ut2TnNFzizCECYNaA2fST3WgInnxUkV3YXAyP6CNxJaCmv2aA0yFr2kFVSeaKGt\r\n"
|
||||
"ymvljNp2NVkvm7Th8fBQBO7I7AXhz43k0mR7XmPgewe8ApZOG3hstkOaMvbWAvWA\r\n"
|
||||
"zCZupdDjZYjOJqlA4eEA4H8/w7F83r5CugeBE8LgEREjLPiyejrU5H1fubEY+h0d\r\n"
|
||||
"l5HZBJ68ybTXfQ5U9o/QKA3dd0toBEhhdRUDGzWtjvwkEQfqF1reGWj/tod/gCpf\r\n"
|
||||
"DFi6X0ECgYEA4wOv/pjSC3ty6TuOvKX2rOUiBrLXXv2JSxZnMoMiWI5ipLQt+RYT\r\n"
|
||||
"VPafL/m7Dn6MbwjayOkcZhBwk5CNz5A6Q4lJ64Mq/lqHznRCQQ2Mc1G8eyDF/fYL\r\n"
|
||||
"Ze2pLvwP9VD5jTc2miDfw+MnvJhywRRLcemDFP8k4hQVtm8PMp3ZmNECgYEA4gz7\r\n"
|
||||
"wzObR4gn8ibe617uQPZjWzUj9dUHYd+in1gwBCIrtNnaRn9I9U/Q6tegRYpii4ys\r\n"
|
||||
"c176NmU+umy6XmuSKV5qD9bSpZWG2nLFnslrN15Lm3fhZxoeMNhBaEDTnLT26yoi\r\n"
|
||||
"33gp0mSSWy94ZEqipms+ULF6sY1ZtFW6tpGFoy8CgYAQHhnnvJflIs2ky4q10B60\r\n"
|
||||
"ZcxFp3rtDpkp0JxhFLhiizFrujMtZSjYNm5U7KkgPVHhLELEUvCmOnKTt4ap/vZ0\r\n"
|
||||
"BxJNe1GZH3pW6SAvGDQpl9sG7uu/vTFP+lCxukmzxB0DrrDcvorEkKMom7ZCCRvW\r\n"
|
||||
"KZsZ6YeH2Z81BauRj218kQKBgQCUV/DgKP2985xDTT79N08jUo3hTP5MVYCCuj/+\r\n"
|
||||
"UeEw1TvZcx3LJby7P6Xad6a1/BqveaGyFKIfEFIaBUBItk801sDDpDaYc4gL00Xc\r\n"
|
||||
"7lFuBHOZkxJYlss5QrGpuOEl9ZwUt5IrFLBdYaKqNHzNVC1pCPfb/JyH6Dr2HUxq\r\n"
|
||||
"gxUwAQKBgQCcU6G2L8AG9d9c0UpOyL1tMvFe5Ttw0KjlQVdsh1MP6yigYo9DYuwu\r\n"
|
||||
"bHFVW2r0dBTqegP2/KTOxKzaHfC1qf0RGDsUoJCNJrd1cwoCLG8P2EF4w3OBrKqv\r\n"
|
||||
"8u4ytY0F+Vlanj5lm3TaoHSVF1+NWPyOTiwevIECGKwSxvlki4fDAA==\r\n"
|
||||
"-----END RSA PRIVATE KEY-----\r\n";
|
||||
|
||||
const char test_dhm_params[] =
|
||||
"-----BEGIN DH PARAMETERS-----\r\n"
|
||||
"MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n"
|
||||
"1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n"
|
||||
"9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n"
|
||||
"-----END DH PARAMETERS-----\r\n";
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* \file certs.h
|
||||
*
|
||||
* \brief Sample certificates and DHM parameters for testing
|
||||
*
|
||||
* 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_CERTS_H
|
||||
#define POLARSSL_CERTS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const char test_ca_crt[];
|
||||
extern const char test_ca_key[];
|
||||
extern const char test_ca_pwd[];
|
||||
extern const char test_srv_crt[];
|
||||
extern const char test_srv_key[];
|
||||
extern const char test_cli_crt[];
|
||||
extern const char test_cli_key[];
|
||||
extern const char test_dhm_params[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* certs.h */
|
||||
@@ -0,0 +1,601 @@
|
||||
/**
|
||||
* \file cipher.c
|
||||
*
|
||||
* \brief Generic cipher wrapper for PolarSSL
|
||||
*
|
||||
* \author Adriaan de Jong <dejong@fox-it.com>
|
||||
*
|
||||
* Copyright (C) 2006-2012, 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.
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_CIPHER_C)
|
||||
|
||||
#include "polarssl/cipher.h"
|
||||
#include "polarssl/cipher_wrap.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined _MSC_VER && !defined strcasecmp
|
||||
#define strcasecmp _stricmp
|
||||
#endif
|
||||
|
||||
static const int supported_ciphers[] = {
|
||||
|
||||
#if defined(POLARSSL_AES_C)
|
||||
POLARSSL_CIPHER_AES_128_CBC,
|
||||
POLARSSL_CIPHER_AES_192_CBC,
|
||||
POLARSSL_CIPHER_AES_256_CBC,
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CFB)
|
||||
POLARSSL_CIPHER_AES_128_CFB128,
|
||||
POLARSSL_CIPHER_AES_192_CFB128,
|
||||
POLARSSL_CIPHER_AES_256_CFB128,
|
||||
#endif /* defined(POLARSSL_CIPHER_MODE_CFB) */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CTR)
|
||||
POLARSSL_CIPHER_AES_128_CTR,
|
||||
POLARSSL_CIPHER_AES_192_CTR,
|
||||
POLARSSL_CIPHER_AES_256_CTR,
|
||||
#endif /* defined(POLARSSL_CIPHER_MODE_CTR) */
|
||||
|
||||
#endif /* defined(POLARSSL_AES_C) */
|
||||
|
||||
#if defined(POLARSSL_CAMELLIA_C)
|
||||
POLARSSL_CIPHER_CAMELLIA_128_CBC,
|
||||
POLARSSL_CIPHER_CAMELLIA_192_CBC,
|
||||
POLARSSL_CIPHER_CAMELLIA_256_CBC,
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CFB)
|
||||
POLARSSL_CIPHER_CAMELLIA_128_CFB128,
|
||||
POLARSSL_CIPHER_CAMELLIA_192_CFB128,
|
||||
POLARSSL_CIPHER_CAMELLIA_256_CFB128,
|
||||
#endif /* defined(POLARSSL_CIPHER_MODE_CFB) */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CTR)
|
||||
POLARSSL_CIPHER_CAMELLIA_128_CTR,
|
||||
POLARSSL_CIPHER_CAMELLIA_192_CTR,
|
||||
POLARSSL_CIPHER_CAMELLIA_256_CTR,
|
||||
#endif /* defined(POLARSSL_CIPHER_MODE_CTR) */
|
||||
|
||||
#endif /* defined(POLARSSL_CAMELLIA_C) */
|
||||
|
||||
#if defined(POLARSSL_DES_C)
|
||||
POLARSSL_CIPHER_DES_CBC,
|
||||
POLARSSL_CIPHER_DES_EDE_CBC,
|
||||
POLARSSL_CIPHER_DES_EDE3_CBC,
|
||||
#endif /* defined(POLARSSL_DES_C) */
|
||||
|
||||
#if defined(POLARSSL_BLOWFISH_C)
|
||||
POLARSSL_CIPHER_BLOWFISH_CBC,
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CFB)
|
||||
POLARSSL_CIPHER_BLOWFISH_CFB64,
|
||||
#endif /* defined(POLARSSL_CIPHER_MODE_CFB) */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CTR)
|
||||
POLARSSL_CIPHER_BLOWFISH_CTR,
|
||||
#endif /* defined(POLARSSL_CIPHER_MODE_CTR) */
|
||||
|
||||
#endif /* defined(POLARSSL_BLOWFISH_C) */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_NULL_CIPHER)
|
||||
POLARSSL_CIPHER_NULL,
|
||||
#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
|
||||
|
||||
0
|
||||
};
|
||||
|
||||
const int *cipher_list( void )
|
||||
{
|
||||
return supported_ciphers;
|
||||
}
|
||||
|
||||
const cipher_info_t *cipher_info_from_type( const cipher_type_t cipher_type )
|
||||
{
|
||||
/* Find static cipher information */
|
||||
switch ( cipher_type )
|
||||
{
|
||||
#if defined(POLARSSL_AES_C)
|
||||
case POLARSSL_CIPHER_AES_128_CBC:
|
||||
return &aes_128_cbc_info;
|
||||
case POLARSSL_CIPHER_AES_192_CBC:
|
||||
return &aes_192_cbc_info;
|
||||
case POLARSSL_CIPHER_AES_256_CBC:
|
||||
return &aes_256_cbc_info;
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CFB)
|
||||
case POLARSSL_CIPHER_AES_128_CFB128:
|
||||
return &aes_128_cfb128_info;
|
||||
case POLARSSL_CIPHER_AES_192_CFB128:
|
||||
return &aes_192_cfb128_info;
|
||||
case POLARSSL_CIPHER_AES_256_CFB128:
|
||||
return &aes_256_cfb128_info;
|
||||
#endif /* defined(POLARSSL_CIPHER_MODE_CFB) */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CTR)
|
||||
case POLARSSL_CIPHER_AES_128_CTR:
|
||||
return &aes_128_ctr_info;
|
||||
case POLARSSL_CIPHER_AES_192_CTR:
|
||||
return &aes_192_ctr_info;
|
||||
case POLARSSL_CIPHER_AES_256_CTR:
|
||||
return &aes_256_ctr_info;
|
||||
#endif /* defined(POLARSSL_CIPHER_MODE_CTR) */
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_CAMELLIA_C)
|
||||
case POLARSSL_CIPHER_CAMELLIA_128_CBC:
|
||||
return &camellia_128_cbc_info;
|
||||
case POLARSSL_CIPHER_CAMELLIA_192_CBC:
|
||||
return &camellia_192_cbc_info;
|
||||
case POLARSSL_CIPHER_CAMELLIA_256_CBC:
|
||||
return &camellia_256_cbc_info;
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CFB)
|
||||
case POLARSSL_CIPHER_CAMELLIA_128_CFB128:
|
||||
return &camellia_128_cfb128_info;
|
||||
case POLARSSL_CIPHER_CAMELLIA_192_CFB128:
|
||||
return &camellia_192_cfb128_info;
|
||||
case POLARSSL_CIPHER_CAMELLIA_256_CFB128:
|
||||
return &camellia_256_cfb128_info;
|
||||
#endif /* defined(POLARSSL_CIPHER_MODE_CFB) */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CTR)
|
||||
case POLARSSL_CIPHER_CAMELLIA_128_CTR:
|
||||
return &camellia_128_ctr_info;
|
||||
case POLARSSL_CIPHER_CAMELLIA_192_CTR:
|
||||
return &camellia_192_ctr_info;
|
||||
case POLARSSL_CIPHER_CAMELLIA_256_CTR:
|
||||
return &camellia_256_ctr_info;
|
||||
#endif /* defined(POLARSSL_CIPHER_MODE_CTR) */
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_DES_C)
|
||||
case POLARSSL_CIPHER_DES_CBC:
|
||||
return &des_cbc_info;
|
||||
case POLARSSL_CIPHER_DES_EDE_CBC:
|
||||
return &des_ede_cbc_info;
|
||||
case POLARSSL_CIPHER_DES_EDE3_CBC:
|
||||
return &des_ede3_cbc_info;
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_BLOWFISH_C)
|
||||
case POLARSSL_CIPHER_BLOWFISH_CBC:
|
||||
return &blowfish_cbc_info;
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CFB)
|
||||
case POLARSSL_CIPHER_BLOWFISH_CFB64:
|
||||
return &blowfish_cfb64_info;
|
||||
#endif /* defined(POLARSSL_CIPHER_MODE_CFB) */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CTR)
|
||||
case POLARSSL_CIPHER_BLOWFISH_CTR:
|
||||
return &blowfish_ctr_info;
|
||||
#endif /* defined(POLARSSL_CIPHER_MODE_CTR) */
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_CIPHER_NULL_CIPHER)
|
||||
case POLARSSL_CIPHER_NULL:
|
||||
return &null_cipher_info;
|
||||
#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const cipher_info_t *cipher_info_from_string( const char *cipher_name )
|
||||
{
|
||||
if( NULL == cipher_name )
|
||||
return NULL;
|
||||
|
||||
/* Get the appropriate cipher information */
|
||||
#if defined(POLARSSL_CAMELLIA_C)
|
||||
if( !strcasecmp( "CAMELLIA-128-CBC", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_CAMELLIA_128_CBC );
|
||||
if( !strcasecmp( "CAMELLIA-192-CBC", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_CAMELLIA_192_CBC );
|
||||
if( !strcasecmp( "CAMELLIA-256-CBC", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_CAMELLIA_256_CBC );
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CFB)
|
||||
if( !strcasecmp( "CAMELLIA-128-CFB128", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_CAMELLIA_128_CFB128 );
|
||||
if( !strcasecmp( "CAMELLIA-192-CFB128", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_CAMELLIA_192_CFB128 );
|
||||
if( !strcasecmp( "CAMELLIA-256-CFB128", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_CAMELLIA_256_CFB128 );
|
||||
#endif /* defined(POLARSSL_CIPHER_MODE_CFB) */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CTR)
|
||||
if( !strcasecmp( "CAMELLIA-128-CTR", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_CAMELLIA_128_CTR );
|
||||
if( !strcasecmp( "CAMELLIA-192-CTR", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_CAMELLIA_192_CTR );
|
||||
if( !strcasecmp( "CAMELLIA-256-CTR", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_CAMELLIA_256_CTR );
|
||||
#endif /* defined(POLARSSL_CIPHER_MODE_CTR) */
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_AES_C)
|
||||
if( !strcasecmp( "AES-128-CBC", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_AES_128_CBC );
|
||||
if( !strcasecmp( "AES-192-CBC", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_AES_192_CBC );
|
||||
if( !strcasecmp( "AES-256-CBC", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_AES_256_CBC );
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CFB)
|
||||
if( !strcasecmp( "AES-128-CFB128", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_AES_128_CFB128 );
|
||||
if( !strcasecmp( "AES-192-CFB128", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_AES_192_CFB128 );
|
||||
if( !strcasecmp( "AES-256-CFB128", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_AES_256_CFB128 );
|
||||
#endif /* defined(POLARSSL_CIPHER_MODE_CFB) */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CTR)
|
||||
if( !strcasecmp( "AES-128-CTR", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_AES_128_CTR );
|
||||
if( !strcasecmp( "AES-192-CTR", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_AES_192_CTR );
|
||||
if( !strcasecmp( "AES-256-CTR", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_AES_256_CTR );
|
||||
#endif /* defined(POLARSSL_CIPHER_MODE_CTR) */
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_DES_C)
|
||||
if( !strcasecmp( "DES-CBC", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_DES_CBC );
|
||||
if( !strcasecmp( "DES-EDE-CBC", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_DES_EDE_CBC );
|
||||
if( !strcasecmp( "DES-EDE3-CBC", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_DES_EDE3_CBC );
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_BLOWFISH_C)
|
||||
if( !strcasecmp( "BLOWFISH-CBC", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_BLOWFISH_CBC );
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CFB)
|
||||
if( !strcasecmp( "BLOWFISH-CFB64", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_BLOWFISH_CFB64 );
|
||||
#endif /* defined(POLARSSL_CIPHER_MODE_CFB) */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CTR)
|
||||
if( !strcasecmp( "BLOWFISH-CTR", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_BLOWFISH_CTR );
|
||||
#endif /* defined(POLARSSL_CIPHER_MODE_CTR) */
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_CIPHER_NULL_CIPHER)
|
||||
if( !strcasecmp( "NULL", cipher_name ) )
|
||||
return cipher_info_from_type( POLARSSL_CIPHER_NULL );
|
||||
#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int cipher_init_ctx( cipher_context_t *ctx, const cipher_info_t *cipher_info )
|
||||
{
|
||||
if( NULL == cipher_info || NULL == ctx )
|
||||
return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
|
||||
|
||||
memset( ctx, 0, sizeof( cipher_context_t ) );
|
||||
|
||||
if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) )
|
||||
return POLARSSL_ERR_CIPHER_ALLOC_FAILED;
|
||||
|
||||
ctx->cipher_info = cipher_info;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cipher_free_ctx( cipher_context_t *ctx )
|
||||
{
|
||||
if( ctx == NULL || ctx->cipher_info == NULL )
|
||||
return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
|
||||
|
||||
ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cipher_setkey( cipher_context_t *ctx, const unsigned char *key,
|
||||
int key_length, const operation_t operation )
|
||||
{
|
||||
if( NULL == ctx || NULL == ctx->cipher_info )
|
||||
return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
|
||||
|
||||
ctx->key_length = key_length;
|
||||
ctx->operation = operation;
|
||||
|
||||
#if defined(POLARSSL_CIPHER_NULL_CIPHER)
|
||||
if( ctx->cipher_info->mode == POLARSSL_MODE_NULL )
|
||||
return 0;
|
||||
#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
|
||||
|
||||
/*
|
||||
* For CFB and CTR mode always use the encryption key schedule
|
||||
*/
|
||||
if( POLARSSL_ENCRYPT == operation ||
|
||||
POLARSSL_MODE_CFB == ctx->cipher_info->mode ||
|
||||
POLARSSL_MODE_CTR == ctx->cipher_info->mode )
|
||||
{
|
||||
return ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key,
|
||||
ctx->key_length );
|
||||
}
|
||||
|
||||
if( POLARSSL_DECRYPT == operation )
|
||||
return ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key,
|
||||
ctx->key_length );
|
||||
|
||||
return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
int cipher_reset( cipher_context_t *ctx, const unsigned char *iv )
|
||||
{
|
||||
if( NULL == ctx || NULL == ctx->cipher_info || NULL == iv )
|
||||
return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
|
||||
|
||||
ctx->unprocessed_len = 0;
|
||||
|
||||
memcpy( ctx->iv, iv, cipher_get_iv_size( ctx ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cipher_update( cipher_context_t *ctx, const unsigned char *input, size_t ilen,
|
||||
unsigned char *output, size_t *olen )
|
||||
{
|
||||
int ret;
|
||||
size_t copy_len = 0;
|
||||
|
||||
if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ||
|
||||
input == output )
|
||||
{
|
||||
return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
*olen = 0;
|
||||
|
||||
#if defined(POLARSSL_CIPHER_NULL_CIPHER)
|
||||
if( ctx->cipher_info->mode == POLARSSL_MODE_NULL )
|
||||
{
|
||||
memcpy( output, input, ilen );
|
||||
*olen = ilen;
|
||||
return 0;
|
||||
}
|
||||
#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
|
||||
|
||||
if( ctx->cipher_info->mode == POLARSSL_MODE_CBC )
|
||||
{
|
||||
/*
|
||||
* If there is not enough data for a full block, cache it.
|
||||
*/
|
||||
if( ( ctx->operation == POLARSSL_DECRYPT &&
|
||||
ilen + ctx->unprocessed_len <= cipher_get_block_size( ctx ) ) ||
|
||||
( ctx->operation == POLARSSL_ENCRYPT &&
|
||||
ilen + ctx->unprocessed_len < cipher_get_block_size( ctx ) ) )
|
||||
{
|
||||
memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
|
||||
ilen );
|
||||
|
||||
ctx->unprocessed_len += ilen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process cached data first
|
||||
*/
|
||||
if( ctx->unprocessed_len != 0 )
|
||||
{
|
||||
copy_len = cipher_get_block_size( ctx ) - ctx->unprocessed_len;
|
||||
|
||||
memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
|
||||
copy_len );
|
||||
|
||||
if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
|
||||
ctx->operation, cipher_get_block_size( ctx ), ctx->iv,
|
||||
ctx->unprocessed_data, output ) ) )
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
*olen += cipher_get_block_size( ctx );
|
||||
output += cipher_get_block_size( ctx );
|
||||
ctx->unprocessed_len = 0;
|
||||
|
||||
input += copy_len;
|
||||
ilen -= copy_len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cache final, incomplete block
|
||||
*/
|
||||
if( 0 != ilen )
|
||||
{
|
||||
copy_len = ilen % cipher_get_block_size( ctx );
|
||||
if( copy_len == 0 && ctx->operation == POLARSSL_DECRYPT )
|
||||
copy_len = cipher_get_block_size(ctx);
|
||||
|
||||
memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
|
||||
copy_len );
|
||||
|
||||
ctx->unprocessed_len += copy_len;
|
||||
ilen -= copy_len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process remaining full blocks
|
||||
*/
|
||||
if( ilen )
|
||||
{
|
||||
if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
|
||||
ctx->operation, ilen, ctx->iv, input, output ) ) )
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
*olen += ilen;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( ctx->cipher_info->mode == POLARSSL_MODE_CFB )
|
||||
{
|
||||
if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx,
|
||||
ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv,
|
||||
input, output ) ) )
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
*olen = ilen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( ctx->cipher_info->mode == POLARSSL_MODE_CTR )
|
||||
{
|
||||
if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx,
|
||||
ilen, &ctx->unprocessed_len, ctx->iv,
|
||||
ctx->unprocessed_data, input, output ) ) )
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
*olen = ilen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
|
||||
static void add_pkcs_padding( unsigned char *output, size_t output_len,
|
||||
size_t data_len )
|
||||
{
|
||||
size_t padding_len = output_len - data_len;
|
||||
unsigned char i = 0;
|
||||
|
||||
for( i = 0; i < padding_len; i++ )
|
||||
output[data_len + i] = (unsigned char) padding_len;
|
||||
}
|
||||
|
||||
static int get_pkcs_padding( unsigned char *input, unsigned int input_len,
|
||||
size_t *data_len)
|
||||
{
|
||||
unsigned int i, padding_len = 0;
|
||||
|
||||
if( NULL == input || NULL == data_len )
|
||||
return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
|
||||
|
||||
padding_len = input[input_len - 1];
|
||||
|
||||
if( padding_len > input_len )
|
||||
return POLARSSL_ERR_CIPHER_INVALID_PADDING;
|
||||
|
||||
for( i = input_len - padding_len; i < input_len; i++ )
|
||||
if( input[i] != padding_len )
|
||||
return POLARSSL_ERR_CIPHER_INVALID_PADDING;
|
||||
|
||||
*data_len = input_len - padding_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cipher_finish( cipher_context_t *ctx, unsigned char *output, size_t *olen)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
|
||||
return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
|
||||
|
||||
*olen = 0;
|
||||
|
||||
if( POLARSSL_MODE_CFB == ctx->cipher_info->mode ||
|
||||
POLARSSL_MODE_CTR == ctx->cipher_info->mode ||
|
||||
POLARSSL_MODE_NULL == ctx->cipher_info->mode )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( POLARSSL_MODE_CBC == ctx->cipher_info->mode )
|
||||
{
|
||||
if( POLARSSL_ENCRYPT == ctx->operation )
|
||||
{
|
||||
add_pkcs_padding( ctx->unprocessed_data, cipher_get_iv_size( ctx ),
|
||||
ctx->unprocessed_len );
|
||||
}
|
||||
else if ( cipher_get_block_size( ctx ) != ctx->unprocessed_len )
|
||||
{
|
||||
/* For decrypt operations, expect a full block */
|
||||
return POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED;
|
||||
}
|
||||
|
||||
/* cipher block */
|
||||
if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
|
||||
ctx->operation, cipher_get_block_size( ctx ), ctx->iv,
|
||||
ctx->unprocessed_data, output ) ) )
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set output size for decryption */
|
||||
if( POLARSSL_DECRYPT == ctx->operation )
|
||||
return get_pkcs_padding( output, cipher_get_block_size( ctx ), olen );
|
||||
|
||||
/* Set output size for encryption */
|
||||
*olen = cipher_get_block_size( ctx );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_SELF_TEST)
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define ASSERT(x) if (!(x)) { \
|
||||
printf( "failed with %i at %s\n", value, (#x) ); \
|
||||
return( 1 ); \
|
||||
}
|
||||
/*
|
||||
* Checkup routine
|
||||
*/
|
||||
|
||||
int cipher_self_test( int verbose )
|
||||
{
|
||||
((void) verbose);
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,463 @@
|
||||
/**
|
||||
* \file cipher.h
|
||||
*
|
||||
* \brief Generic cipher wrapper.
|
||||
*
|
||||
* \author Adriaan de Jong <dejong@fox-it.com>
|
||||
*
|
||||
* Copyright (C) 2006-2012, 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_CIPHER_H
|
||||
#define POLARSSL_CIPHER_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_MSC_VER) && !defined(inline)
|
||||
#define inline _inline
|
||||
#else
|
||||
#if defined(__ARMCC_VERSION) && !defined(inline)
|
||||
#define inline __inline
|
||||
#endif /* __ARMCC_VERSION */
|
||||
#endif /*_MSC_VER */
|
||||
|
||||
#define POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE -0x6080 /**< The selected feature is not available. */
|
||||
#define POLARSSL_ERR_CIPHER_BAD_INPUT_DATA -0x6100 /**< Bad input parameters to function. */
|
||||
#define POLARSSL_ERR_CIPHER_ALLOC_FAILED -0x6180 /**< Failed to allocate memory. */
|
||||
#define POLARSSL_ERR_CIPHER_INVALID_PADDING -0x6200 /**< Input data contains invalid padding and is rejected. */
|
||||
#define POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 /**< Decryption of block requires a full block. */
|
||||
|
||||
typedef enum {
|
||||
POLARSSL_CIPHER_ID_NONE = 0,
|
||||
POLARSSL_CIPHER_ID_NULL,
|
||||
POLARSSL_CIPHER_ID_AES,
|
||||
POLARSSL_CIPHER_ID_DES,
|
||||
POLARSSL_CIPHER_ID_3DES,
|
||||
POLARSSL_CIPHER_ID_CAMELLIA,
|
||||
POLARSSL_CIPHER_ID_BLOWFISH,
|
||||
} cipher_id_t;
|
||||
|
||||
typedef enum {
|
||||
POLARSSL_CIPHER_NONE = 0,
|
||||
POLARSSL_CIPHER_NULL,
|
||||
POLARSSL_CIPHER_AES_128_CBC,
|
||||
POLARSSL_CIPHER_AES_192_CBC,
|
||||
POLARSSL_CIPHER_AES_256_CBC,
|
||||
POLARSSL_CIPHER_AES_128_CFB128,
|
||||
POLARSSL_CIPHER_AES_192_CFB128,
|
||||
POLARSSL_CIPHER_AES_256_CFB128,
|
||||
POLARSSL_CIPHER_AES_128_CTR,
|
||||
POLARSSL_CIPHER_AES_192_CTR,
|
||||
POLARSSL_CIPHER_AES_256_CTR,
|
||||
POLARSSL_CIPHER_CAMELLIA_128_CBC,
|
||||
POLARSSL_CIPHER_CAMELLIA_192_CBC,
|
||||
POLARSSL_CIPHER_CAMELLIA_256_CBC,
|
||||
POLARSSL_CIPHER_CAMELLIA_128_CFB128,
|
||||
POLARSSL_CIPHER_CAMELLIA_192_CFB128,
|
||||
POLARSSL_CIPHER_CAMELLIA_256_CFB128,
|
||||
POLARSSL_CIPHER_CAMELLIA_128_CTR,
|
||||
POLARSSL_CIPHER_CAMELLIA_192_CTR,
|
||||
POLARSSL_CIPHER_CAMELLIA_256_CTR,
|
||||
POLARSSL_CIPHER_DES_CBC,
|
||||
POLARSSL_CIPHER_DES_EDE_CBC,
|
||||
POLARSSL_CIPHER_DES_EDE3_CBC,
|
||||
POLARSSL_CIPHER_BLOWFISH_CBC,
|
||||
POLARSSL_CIPHER_BLOWFISH_CFB64,
|
||||
POLARSSL_CIPHER_BLOWFISH_CTR,
|
||||
} cipher_type_t;
|
||||
|
||||
typedef enum {
|
||||
POLARSSL_MODE_NONE = 0,
|
||||
POLARSSL_MODE_NULL,
|
||||
POLARSSL_MODE_CBC,
|
||||
POLARSSL_MODE_CFB,
|
||||
POLARSSL_MODE_OFB,
|
||||
POLARSSL_MODE_CTR,
|
||||
} cipher_mode_t;
|
||||
|
||||
typedef enum {
|
||||
POLARSSL_OPERATION_NONE = -1,
|
||||
POLARSSL_DECRYPT = 0,
|
||||
POLARSSL_ENCRYPT,
|
||||
} operation_t;
|
||||
|
||||
enum {
|
||||
/** Undefined key length */
|
||||
POLARSSL_KEY_LENGTH_NONE = 0,
|
||||
/** Key length, in bits (including parity), for DES keys */
|
||||
POLARSSL_KEY_LENGTH_DES = 64,
|
||||
/** Key length, in bits (including parity), for DES in two key EDE */
|
||||
POLARSSL_KEY_LENGTH_DES_EDE = 128,
|
||||
/** Key length, in bits (including parity), for DES in three-key EDE */
|
||||
POLARSSL_KEY_LENGTH_DES_EDE3 = 192,
|
||||
/** Maximum length of any IV, in bytes */
|
||||
POLARSSL_MAX_IV_LENGTH = 16,
|
||||
};
|
||||
|
||||
/**
|
||||
* Base cipher information. The non-mode specific functions and values.
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
/** Base Cipher type (e.g. POLARSSL_CIPHER_ID_AES) */
|
||||
cipher_id_t cipher;
|
||||
|
||||
/** Encrypt using CBC */
|
||||
int (*cbc_func)( void *ctx, operation_t mode, size_t length, unsigned char *iv,
|
||||
const unsigned char *input, unsigned char *output );
|
||||
|
||||
/** Encrypt using CFB (Full length) */
|
||||
int (*cfb_func)( void *ctx, operation_t mode, size_t length, size_t *iv_off,
|
||||
unsigned char *iv, const unsigned char *input, unsigned char *output );
|
||||
|
||||
/** Encrypt using CTR */
|
||||
int (*ctr_func)( void *ctx, size_t length, size_t *nc_off, unsigned char *nonce_counter,
|
||||
unsigned char *stream_block, const unsigned char *input, unsigned char *output );
|
||||
|
||||
/** Set key for encryption purposes */
|
||||
int (*setkey_enc_func)( void *ctx, const unsigned char *key, unsigned int key_length);
|
||||
|
||||
/** Set key for decryption purposes */
|
||||
int (*setkey_dec_func)( void *ctx, const unsigned char *key, unsigned int key_length);
|
||||
|
||||
/** Allocate a new context */
|
||||
void * (*ctx_alloc_func)( void );
|
||||
|
||||
/** Free the given context */
|
||||
void (*ctx_free_func)( void *ctx );
|
||||
|
||||
} cipher_base_t;
|
||||
|
||||
/**
|
||||
* Cipher information. Allows cipher functions to be called in a generic way.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Full cipher identifier (e.g. POLARSSL_CIPHER_AES_256_CBC) */
|
||||
cipher_type_t type;
|
||||
|
||||
/** Cipher mode (e.g. POLARSSL_MODE_CBC) */
|
||||
cipher_mode_t mode;
|
||||
|
||||
/** Cipher key length, in bits (default length for variable sized ciphers)
|
||||
* (Includes parity bits for ciphers like DES) */
|
||||
unsigned int key_length;
|
||||
|
||||
/** Name of the cipher */
|
||||
const char * name;
|
||||
|
||||
/** IV size, in bytes */
|
||||
unsigned int iv_size;
|
||||
|
||||
/** block size, in bytes */
|
||||
unsigned int block_size;
|
||||
|
||||
/** Base cipher information and functions */
|
||||
const cipher_base_t *base;
|
||||
|
||||
} cipher_info_t;
|
||||
|
||||
/**
|
||||
* Generic cipher context.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Information about the associated cipher */
|
||||
const cipher_info_t *cipher_info;
|
||||
|
||||
/** Key length to use */
|
||||
int key_length;
|
||||
|
||||
/** Operation that the context's key has been initialised for */
|
||||
operation_t operation;
|
||||
|
||||
/** Buffer for data that hasn't been encrypted yet */
|
||||
unsigned char unprocessed_data[POLARSSL_MAX_IV_LENGTH];
|
||||
|
||||
/** Number of bytes that still need processing */
|
||||
size_t unprocessed_len;
|
||||
|
||||
/** Current IV or NONCE_COUNTER for CTR-mode */
|
||||
unsigned char iv[POLARSSL_MAX_IV_LENGTH];
|
||||
|
||||
/** Cipher-specific context */
|
||||
void *cipher_ctx;
|
||||
} cipher_context_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Returns the list of ciphers supported by the generic cipher module.
|
||||
*
|
||||
* \return a statically allocated array of ciphers, the last entry
|
||||
* is 0.
|
||||
*/
|
||||
const int *cipher_list( void );
|
||||
|
||||
/**
|
||||
* \brief Returns the cipher information structure associated
|
||||
* with the given cipher name.
|
||||
*
|
||||
* \param cipher_name Name of the cipher to search for.
|
||||
*
|
||||
* \return the cipher information structure associated with the
|
||||
* given cipher_name, or NULL if not found.
|
||||
*/
|
||||
const cipher_info_t *cipher_info_from_string( const char *cipher_name );
|
||||
|
||||
/**
|
||||
* \brief Returns the cipher information structure associated
|
||||
* with the given cipher type.
|
||||
*
|
||||
* \param cipher_type Type of the cipher to search for.
|
||||
*
|
||||
* \return the cipher information structure associated with the
|
||||
* given cipher_type, or NULL if not found.
|
||||
*/
|
||||
const cipher_info_t *cipher_info_from_type( const cipher_type_t cipher_type );
|
||||
|
||||
/**
|
||||
* \brief Initialises and fills the cipher context structure with
|
||||
* the appropriate values.
|
||||
*
|
||||
* \param ctx context to initialise. May not be NULL.
|
||||
* \param cipher_info cipher to use.
|
||||
*
|
||||
* \return \c 0 on success,
|
||||
* \c POLARSSL_ERR_CIPHER_BAD_INPUT_DATA on parameter failure,
|
||||
* \c POLARSSL_ERR_CIPHER_ALLOC_FAILED if allocation of the
|
||||
* cipher-specific context failed.
|
||||
*/
|
||||
int cipher_init_ctx( cipher_context_t *ctx, const cipher_info_t *cipher_info );
|
||||
|
||||
/**
|
||||
* \brief Free the cipher-specific context of ctx. Freeing ctx
|
||||
* itself remains the responsibility of the caller.
|
||||
*
|
||||
* \param ctx Free the cipher-specific context
|
||||
*
|
||||
* \returns 0 on success, POLARSSL_ERR_CIPHER_BAD_INPUT_DATA if
|
||||
* parameter verification fails.
|
||||
*/
|
||||
int cipher_free_ctx( cipher_context_t *ctx );
|
||||
|
||||
/**
|
||||
* \brief Returns the block size of the given cipher.
|
||||
*
|
||||
* \param ctx cipher's context. Must have been initialised.
|
||||
*
|
||||
* \return size of the cipher's blocks, or 0 if ctx has not been
|
||||
* initialised.
|
||||
*/
|
||||
static inline unsigned int cipher_get_block_size( const cipher_context_t *ctx )
|
||||
{
|
||||
if( NULL == ctx || NULL == ctx->cipher_info )
|
||||
return 0;
|
||||
|
||||
return ctx->cipher_info->block_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the mode of operation for the cipher.
|
||||
* (e.g. POLARSSL_MODE_CBC)
|
||||
*
|
||||
* \param ctx cipher's context. Must have been initialised.
|
||||
*
|
||||
* \return mode of operation, or POLARSSL_MODE_NONE if ctx
|
||||
* has not been initialised.
|
||||
*/
|
||||
static inline cipher_mode_t cipher_get_cipher_mode( const cipher_context_t *ctx )
|
||||
{
|
||||
if( NULL == ctx || NULL == ctx->cipher_info )
|
||||
return POLARSSL_MODE_NONE;
|
||||
|
||||
return ctx->cipher_info->mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the size of the cipher's IV.
|
||||
*
|
||||
* \param ctx cipher's context. Must have been initialised.
|
||||
*
|
||||
* \return size of the cipher's IV, or 0 if ctx has not been
|
||||
* initialised.
|
||||
*/
|
||||
static inline int cipher_get_iv_size( const cipher_context_t *ctx )
|
||||
{
|
||||
if( NULL == ctx || NULL == ctx->cipher_info )
|
||||
return 0;
|
||||
|
||||
return ctx->cipher_info->iv_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the type of the given cipher.
|
||||
*
|
||||
* \param ctx cipher's context. Must have been initialised.
|
||||
*
|
||||
* \return type of the cipher, or POLARSSL_CIPHER_NONE if ctx has
|
||||
* not been initialised.
|
||||
*/
|
||||
static inline cipher_type_t cipher_get_type( const cipher_context_t *ctx )
|
||||
{
|
||||
if( NULL == ctx || NULL == ctx->cipher_info )
|
||||
return POLARSSL_CIPHER_NONE;
|
||||
|
||||
return ctx->cipher_info->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the name of the given cipher, as a string.
|
||||
*
|
||||
* \param ctx cipher's context. Must have been initialised.
|
||||
*
|
||||
* \return name of the cipher, or NULL if ctx was not initialised.
|
||||
*/
|
||||
static inline const char *cipher_get_name( const cipher_context_t *ctx )
|
||||
{
|
||||
if( NULL == ctx || NULL == ctx->cipher_info )
|
||||
return 0;
|
||||
|
||||
return ctx->cipher_info->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the key length of the cipher.
|
||||
*
|
||||
* \param ctx cipher's context. Must have been initialised.
|
||||
*
|
||||
* \return cipher's key length, in bits, or
|
||||
* POLARSSL_KEY_LENGTH_NONE if ctx has not been
|
||||
* initialised.
|
||||
*/
|
||||
static inline int cipher_get_key_size ( const cipher_context_t *ctx )
|
||||
{
|
||||
if( NULL == ctx )
|
||||
return POLARSSL_KEY_LENGTH_NONE;
|
||||
|
||||
return ctx->key_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the operation of the given cipher.
|
||||
*
|
||||
* \param ctx cipher's context. Must have been initialised.
|
||||
*
|
||||
* \return operation (POLARSSL_ENCRYPT or POLARSSL_DECRYPT),
|
||||
* or POLARSSL_OPERATION_NONE if ctx has not been
|
||||
* initialised.
|
||||
*/
|
||||
static inline operation_t cipher_get_operation( const cipher_context_t *ctx )
|
||||
{
|
||||
if( NULL == ctx || NULL == ctx->cipher_info )
|
||||
return POLARSSL_OPERATION_NONE;
|
||||
|
||||
return ctx->operation;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the key to use with the given context.
|
||||
*
|
||||
* \param ctx generic cipher context. May not be NULL. Must have been
|
||||
* initialised using cipher_context_from_type or
|
||||
* cipher_context_from_string.
|
||||
* \param key The key to use.
|
||||
* \param key_length key length to use, in bits.
|
||||
* \param operation Operation that the key will be used for, either
|
||||
* POLARSSL_ENCRYPT or POLARSSL_DECRYPT.
|
||||
*
|
||||
* \returns 0 on success, POLARSSL_ERR_CIPHER_BAD_INPUT_DATA if
|
||||
* parameter verification fails or a cipher specific
|
||||
* error code.
|
||||
*/
|
||||
int cipher_setkey( cipher_context_t *ctx, const unsigned char *key, int key_length,
|
||||
const operation_t operation );
|
||||
|
||||
/**
|
||||
* \brief Reset the given context, setting the IV to iv
|
||||
*
|
||||
* \param ctx generic cipher context
|
||||
* \param iv IV to use or NONCE_COUNTER in the case of a CTR-mode cipher
|
||||
*
|
||||
* \returns 0 on success, POLARSSL_ERR_CIPHER_BAD_INPUT_DATA
|
||||
* if parameter verification fails.
|
||||
*/
|
||||
int cipher_reset( cipher_context_t *ctx, const unsigned char *iv );
|
||||
|
||||
/**
|
||||
* \brief Generic cipher update function. Encrypts/decrypts
|
||||
* using the given cipher context. Writes as many block
|
||||
* size'd blocks of data as possible to output. Any data
|
||||
* that cannot be written immediately will either be added
|
||||
* to the next block, or flushed when cipher_final is
|
||||
* called.
|
||||
*
|
||||
* \param ctx generic cipher context
|
||||
* \param input buffer holding the input data
|
||||
* \param ilen length of the input data
|
||||
* \param output buffer for the output data. Should be able to hold at
|
||||
* least ilen + block_size. Cannot be the same buffer as
|
||||
* input!
|
||||
* \param olen length of the output data, will be filled with the
|
||||
* actual number of bytes written.
|
||||
*
|
||||
* \returns 0 on success, POLARSSL_ERR_CIPHER_BAD_INPUT_DATA if
|
||||
* parameter verification fails,
|
||||
* POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE on an
|
||||
* unsupported mode for a cipher or a cipher specific
|
||||
* error code.
|
||||
*/
|
||||
int cipher_update( cipher_context_t *ctx, const unsigned char *input, size_t ilen,
|
||||
unsigned char *output, size_t *olen );
|
||||
|
||||
/**
|
||||
* \brief Generic cipher finalisation function. If data still
|
||||
* needs to be flushed from an incomplete block, data
|
||||
* contained within it will be padded with the size of
|
||||
* the last block, and written to the output buffer.
|
||||
*
|
||||
* \param ctx Generic cipher context
|
||||
* \param output buffer to write data to. Needs block_size data available.
|
||||
* \param olen length of the data written to the output buffer.
|
||||
*
|
||||
* \returns 0 on success, POLARSSL_ERR_CIPHER_BAD_INPUT_DATA if
|
||||
* parameter verification fails,
|
||||
* POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption
|
||||
* expected a full block but was not provided one,
|
||||
* POLARSSL_ERR_CIPHER_INVALID_PADDING on invalid padding
|
||||
* while decrypting or a cipher specific error code.
|
||||
*/
|
||||
int cipher_finish( cipher_context_t *ctx, unsigned char *output, size_t *olen);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int cipher_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* POLARSSL_MD_H */
|
||||
@@ -0,0 +1,711 @@
|
||||
/**
|
||||
* \file md_wrap.c
|
||||
*
|
||||
* \brief Generic cipher wrapper for PolarSSL
|
||||
*
|
||||
* \author Adriaan de Jong <dejong@fox-it.com>
|
||||
*
|
||||
* Copyright (C) 2006-2012, 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.
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_CIPHER_C)
|
||||
|
||||
#include "polarssl/cipher_wrap.h"
|
||||
|
||||
#if defined(POLARSSL_AES_C)
|
||||
#include "polarssl/aes.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_CAMELLIA_C)
|
||||
#include "polarssl/camellia.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_DES_C)
|
||||
#include "polarssl/des.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_BLOWFISH_C)
|
||||
#include "polarssl/blowfish.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(POLARSSL_AES_C)
|
||||
|
||||
int aes_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
|
||||
unsigned char *iv, const unsigned char *input, unsigned char *output )
|
||||
{
|
||||
return aes_crypt_cbc( (aes_context *) ctx, operation, length, iv, input, output );
|
||||
}
|
||||
|
||||
int aes_crypt_cfb128_wrap( void *ctx, operation_t operation, size_t length,
|
||||
size_t *iv_off, unsigned char *iv, const unsigned char *input, unsigned char *output )
|
||||
{
|
||||
#if defined(POLARSSL_CIPHER_MODE_CFB)
|
||||
return aes_crypt_cfb128( (aes_context *) ctx, operation, length, iv_off, iv, input, output );
|
||||
#else
|
||||
((void) ctx);
|
||||
((void) operation);
|
||||
((void) length);
|
||||
((void) iv_off);
|
||||
((void) iv);
|
||||
((void) input);
|
||||
((void) output);
|
||||
|
||||
return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
int aes_crypt_ctr_wrap( void *ctx, size_t length,
|
||||
size_t *nc_off, unsigned char *nonce_counter, unsigned char *stream_block,
|
||||
const unsigned char *input, unsigned char *output )
|
||||
{
|
||||
#if defined(POLARSSL_CIPHER_MODE_CTR)
|
||||
return aes_crypt_ctr( (aes_context *) ctx, length, nc_off, nonce_counter,
|
||||
stream_block, input, output );
|
||||
#else
|
||||
((void) ctx);
|
||||
((void) length);
|
||||
((void) nc_off);
|
||||
((void) nonce_counter);
|
||||
((void) stream_block);
|
||||
((void) input);
|
||||
((void) output);
|
||||
|
||||
return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
int aes_setkey_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
|
||||
{
|
||||
return aes_setkey_dec( (aes_context *) ctx, key, key_length );
|
||||
}
|
||||
|
||||
int aes_setkey_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
|
||||
{
|
||||
return aes_setkey_enc( (aes_context *) ctx, key, key_length );
|
||||
}
|
||||
|
||||
static void * aes_ctx_alloc( void )
|
||||
{
|
||||
return malloc( sizeof( aes_context ) );
|
||||
}
|
||||
|
||||
static void aes_ctx_free( void *ctx )
|
||||
{
|
||||
free( ctx );
|
||||
}
|
||||
|
||||
const cipher_base_t aes_info = {
|
||||
POLARSSL_CIPHER_ID_AES,
|
||||
aes_crypt_cbc_wrap,
|
||||
aes_crypt_cfb128_wrap,
|
||||
aes_crypt_ctr_wrap,
|
||||
aes_setkey_enc_wrap,
|
||||
aes_setkey_dec_wrap,
|
||||
aes_ctx_alloc,
|
||||
aes_ctx_free
|
||||
};
|
||||
|
||||
const cipher_info_t aes_128_cbc_info = {
|
||||
POLARSSL_CIPHER_AES_128_CBC,
|
||||
POLARSSL_MODE_CBC,
|
||||
128,
|
||||
"AES-128-CBC",
|
||||
16,
|
||||
16,
|
||||
&aes_info
|
||||
};
|
||||
|
||||
const cipher_info_t aes_192_cbc_info = {
|
||||
POLARSSL_CIPHER_AES_192_CBC,
|
||||
POLARSSL_MODE_CBC,
|
||||
192,
|
||||
"AES-192-CBC",
|
||||
16,
|
||||
16,
|
||||
&aes_info
|
||||
};
|
||||
|
||||
const cipher_info_t aes_256_cbc_info = {
|
||||
POLARSSL_CIPHER_AES_256_CBC,
|
||||
POLARSSL_MODE_CBC,
|
||||
256,
|
||||
"AES-256-CBC",
|
||||
16,
|
||||
16,
|
||||
&aes_info
|
||||
};
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CFB)
|
||||
const cipher_info_t aes_128_cfb128_info = {
|
||||
POLARSSL_CIPHER_AES_128_CFB128,
|
||||
POLARSSL_MODE_CFB,
|
||||
128,
|
||||
"AES-128-CFB128",
|
||||
16,
|
||||
16,
|
||||
&aes_info
|
||||
};
|
||||
|
||||
const cipher_info_t aes_192_cfb128_info = {
|
||||
POLARSSL_CIPHER_AES_192_CFB128,
|
||||
POLARSSL_MODE_CFB,
|
||||
192,
|
||||
"AES-192-CFB128",
|
||||
16,
|
||||
16,
|
||||
&aes_info
|
||||
};
|
||||
|
||||
const cipher_info_t aes_256_cfb128_info = {
|
||||
POLARSSL_CIPHER_AES_256_CFB128,
|
||||
POLARSSL_MODE_CFB,
|
||||
256,
|
||||
"AES-256-CFB128",
|
||||
16,
|
||||
16,
|
||||
&aes_info
|
||||
};
|
||||
#endif /* POLARSSL_CIPHER_MODE_CFB */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CTR)
|
||||
const cipher_info_t aes_128_ctr_info = {
|
||||
POLARSSL_CIPHER_AES_128_CTR,
|
||||
POLARSSL_MODE_CTR,
|
||||
128,
|
||||
"AES-128-CTR",
|
||||
16,
|
||||
16,
|
||||
&aes_info
|
||||
};
|
||||
|
||||
const cipher_info_t aes_192_ctr_info = {
|
||||
POLARSSL_CIPHER_AES_192_CTR,
|
||||
POLARSSL_MODE_CTR,
|
||||
192,
|
||||
"AES-192-CTR",
|
||||
16,
|
||||
16,
|
||||
&aes_info
|
||||
};
|
||||
|
||||
const cipher_info_t aes_256_ctr_info = {
|
||||
POLARSSL_CIPHER_AES_256_CTR,
|
||||
POLARSSL_MODE_CTR,
|
||||
256,
|
||||
"AES-256-CTR",
|
||||
16,
|
||||
16,
|
||||
&aes_info
|
||||
};
|
||||
#endif /* POLARSSL_CIPHER_MODE_CTR */
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_CAMELLIA_C)
|
||||
|
||||
int camellia_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
|
||||
unsigned char *iv, const unsigned char *input, unsigned char *output )
|
||||
{
|
||||
return camellia_crypt_cbc( (camellia_context *) ctx, operation, length, iv, input, output );
|
||||
}
|
||||
|
||||
int camellia_crypt_cfb128_wrap( void *ctx, operation_t operation, size_t length,
|
||||
size_t *iv_off, unsigned char *iv, const unsigned char *input, unsigned char *output )
|
||||
{
|
||||
#if defined(POLARSSL_CIPHER_MODE_CFB)
|
||||
return camellia_crypt_cfb128( (camellia_context *) ctx, operation, length, iv_off, iv, input, output );
|
||||
#else
|
||||
((void) ctx);
|
||||
((void) operation);
|
||||
((void) length);
|
||||
((void) iv_off);
|
||||
((void) iv);
|
||||
((void) input);
|
||||
((void) output);
|
||||
|
||||
return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
int camellia_crypt_ctr_wrap( void *ctx, size_t length,
|
||||
size_t *nc_off, unsigned char *nonce_counter, unsigned char *stream_block,
|
||||
const unsigned char *input, unsigned char *output )
|
||||
{
|
||||
#if defined(POLARSSL_CIPHER_MODE_CTR)
|
||||
return camellia_crypt_ctr( (camellia_context *) ctx, length, nc_off, nonce_counter,
|
||||
stream_block, input, output );
|
||||
#else
|
||||
((void) ctx);
|
||||
((void) length);
|
||||
((void) nc_off);
|
||||
((void) nonce_counter);
|
||||
((void) stream_block);
|
||||
((void) input);
|
||||
((void) output);
|
||||
|
||||
return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
int camellia_setkey_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
|
||||
{
|
||||
return camellia_setkey_dec( (camellia_context *) ctx, key, key_length );
|
||||
}
|
||||
|
||||
int camellia_setkey_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
|
||||
{
|
||||
return camellia_setkey_enc( (camellia_context *) ctx, key, key_length );
|
||||
}
|
||||
|
||||
static void * camellia_ctx_alloc( void )
|
||||
{
|
||||
return malloc( sizeof( camellia_context ) );
|
||||
}
|
||||
|
||||
static void camellia_ctx_free( void *ctx )
|
||||
{
|
||||
free( ctx );
|
||||
}
|
||||
|
||||
const cipher_base_t camellia_info = {
|
||||
POLARSSL_CIPHER_ID_CAMELLIA,
|
||||
camellia_crypt_cbc_wrap,
|
||||
camellia_crypt_cfb128_wrap,
|
||||
camellia_crypt_ctr_wrap,
|
||||
camellia_setkey_enc_wrap,
|
||||
camellia_setkey_dec_wrap,
|
||||
camellia_ctx_alloc,
|
||||
camellia_ctx_free
|
||||
};
|
||||
|
||||
const cipher_info_t camellia_128_cbc_info = {
|
||||
POLARSSL_CIPHER_CAMELLIA_128_CBC,
|
||||
POLARSSL_MODE_CBC,
|
||||
128,
|
||||
"CAMELLIA-128-CBC",
|
||||
16,
|
||||
16,
|
||||
&camellia_info
|
||||
};
|
||||
|
||||
const cipher_info_t camellia_192_cbc_info = {
|
||||
POLARSSL_CIPHER_CAMELLIA_192_CBC,
|
||||
POLARSSL_MODE_CBC,
|
||||
192,
|
||||
"CAMELLIA-192-CBC",
|
||||
16,
|
||||
16,
|
||||
&camellia_info
|
||||
};
|
||||
|
||||
const cipher_info_t camellia_256_cbc_info = {
|
||||
POLARSSL_CIPHER_CAMELLIA_256_CBC,
|
||||
POLARSSL_MODE_CBC,
|
||||
256,
|
||||
"CAMELLIA-256-CBC",
|
||||
16,
|
||||
16,
|
||||
&camellia_info
|
||||
};
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CFB)
|
||||
const cipher_info_t camellia_128_cfb128_info = {
|
||||
POLARSSL_CIPHER_CAMELLIA_128_CFB128,
|
||||
POLARSSL_MODE_CFB,
|
||||
128,
|
||||
"CAMELLIA-128-CFB128",
|
||||
16,
|
||||
16,
|
||||
&camellia_info
|
||||
};
|
||||
|
||||
const cipher_info_t camellia_192_cfb128_info = {
|
||||
POLARSSL_CIPHER_CAMELLIA_192_CFB128,
|
||||
POLARSSL_MODE_CFB,
|
||||
192,
|
||||
"CAMELLIA-192-CFB128",
|
||||
16,
|
||||
16,
|
||||
&camellia_info
|
||||
};
|
||||
|
||||
const cipher_info_t camellia_256_cfb128_info = {
|
||||
POLARSSL_CIPHER_CAMELLIA_256_CFB128,
|
||||
POLARSSL_MODE_CFB,
|
||||
256,
|
||||
"CAMELLIA-256-CFB128",
|
||||
16,
|
||||
16,
|
||||
&camellia_info
|
||||
};
|
||||
#endif /* POLARSSL_CIPHER_MODE_CFB */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CTR)
|
||||
const cipher_info_t camellia_128_ctr_info = {
|
||||
POLARSSL_CIPHER_CAMELLIA_128_CTR,
|
||||
POLARSSL_MODE_CTR,
|
||||
128,
|
||||
"CAMELLIA-128-CTR",
|
||||
16,
|
||||
16,
|
||||
&camellia_info
|
||||
};
|
||||
|
||||
const cipher_info_t camellia_192_ctr_info = {
|
||||
POLARSSL_CIPHER_CAMELLIA_192_CTR,
|
||||
POLARSSL_MODE_CTR,
|
||||
192,
|
||||
"CAMELLIA-192-CTR",
|
||||
16,
|
||||
16,
|
||||
&camellia_info
|
||||
};
|
||||
|
||||
const cipher_info_t camellia_256_ctr_info = {
|
||||
POLARSSL_CIPHER_CAMELLIA_256_CTR,
|
||||
POLARSSL_MODE_CTR,
|
||||
256,
|
||||
"CAMELLIA-256-CTR",
|
||||
16,
|
||||
16,
|
||||
&camellia_info
|
||||
};
|
||||
#endif /* POLARSSL_CIPHER_MODE_CTR */
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_DES_C)
|
||||
|
||||
int des_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
|
||||
unsigned char *iv, const unsigned char *input, unsigned char *output )
|
||||
{
|
||||
return des_crypt_cbc( (des_context *) ctx, operation, length, iv, input, output );
|
||||
}
|
||||
|
||||
int des3_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
|
||||
unsigned char *iv, const unsigned char *input, unsigned char *output )
|
||||
{
|
||||
return des3_crypt_cbc( (des3_context *) ctx, operation, length, iv, input, output );
|
||||
}
|
||||
|
||||
int des_crypt_cfb128_wrap( void *ctx, operation_t operation, size_t length,
|
||||
size_t *iv_off, unsigned char *iv, const unsigned char *input, unsigned char *output )
|
||||
{
|
||||
((void) ctx);
|
||||
((void) operation);
|
||||
((void) length);
|
||||
((void) iv_off);
|
||||
((void) iv);
|
||||
((void) input);
|
||||
((void) output);
|
||||
|
||||
return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
|
||||
int des_crypt_ctr_wrap( void *ctx, size_t length,
|
||||
size_t *nc_off, unsigned char *nonce_counter, unsigned char *stream_block,
|
||||
const unsigned char *input, unsigned char *output )
|
||||
{
|
||||
((void) ctx);
|
||||
((void) length);
|
||||
((void) nc_off);
|
||||
((void) nonce_counter);
|
||||
((void) stream_block);
|
||||
((void) input);
|
||||
((void) output);
|
||||
|
||||
return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
|
||||
|
||||
int des_setkey_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
|
||||
{
|
||||
((void) key_length);
|
||||
|
||||
return des_setkey_dec( (des_context *) ctx, key );
|
||||
}
|
||||
|
||||
int des_setkey_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
|
||||
{
|
||||
((void) key_length);
|
||||
|
||||
return des_setkey_enc( (des_context *) ctx, key );
|
||||
}
|
||||
|
||||
int des3_set2key_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
|
||||
{
|
||||
((void) key_length);
|
||||
|
||||
return des3_set2key_dec( (des3_context *) ctx, key );
|
||||
}
|
||||
|
||||
int des3_set2key_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
|
||||
{
|
||||
((void) key_length);
|
||||
|
||||
return des3_set2key_enc( (des3_context *) ctx, key );
|
||||
}
|
||||
|
||||
int des3_set3key_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
|
||||
{
|
||||
((void) key_length);
|
||||
|
||||
return des3_set3key_dec( (des3_context *) ctx, key );
|
||||
}
|
||||
|
||||
int des3_set3key_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
|
||||
{
|
||||
((void) key_length);
|
||||
|
||||
return des3_set3key_enc( (des3_context *) ctx, key );
|
||||
}
|
||||
|
||||
static void * des_ctx_alloc( void )
|
||||
{
|
||||
return malloc( sizeof( des_context ) );
|
||||
}
|
||||
|
||||
static void * des3_ctx_alloc( void )
|
||||
{
|
||||
return malloc( sizeof( des3_context ) );
|
||||
}
|
||||
|
||||
static void des_ctx_free( void *ctx )
|
||||
{
|
||||
free( ctx );
|
||||
}
|
||||
|
||||
const cipher_base_t des_info = {
|
||||
POLARSSL_CIPHER_ID_DES,
|
||||
des_crypt_cbc_wrap,
|
||||
des_crypt_cfb128_wrap,
|
||||
des_crypt_ctr_wrap,
|
||||
des_setkey_enc_wrap,
|
||||
des_setkey_dec_wrap,
|
||||
des_ctx_alloc,
|
||||
des_ctx_free
|
||||
};
|
||||
|
||||
const cipher_info_t des_cbc_info = {
|
||||
POLARSSL_CIPHER_DES_CBC,
|
||||
POLARSSL_MODE_CBC,
|
||||
POLARSSL_KEY_LENGTH_DES,
|
||||
"DES-CBC",
|
||||
8,
|
||||
8,
|
||||
&des_info
|
||||
};
|
||||
|
||||
const cipher_base_t des_ede_info = {
|
||||
POLARSSL_CIPHER_ID_DES,
|
||||
des3_crypt_cbc_wrap,
|
||||
des_crypt_cfb128_wrap,
|
||||
des_crypt_ctr_wrap,
|
||||
des3_set2key_enc_wrap,
|
||||
des3_set2key_dec_wrap,
|
||||
des3_ctx_alloc,
|
||||
des_ctx_free
|
||||
};
|
||||
|
||||
const cipher_info_t des_ede_cbc_info = {
|
||||
POLARSSL_CIPHER_DES_EDE_CBC,
|
||||
POLARSSL_MODE_CBC,
|
||||
POLARSSL_KEY_LENGTH_DES_EDE,
|
||||
"DES-EDE-CBC",
|
||||
8,
|
||||
8,
|
||||
&des_ede_info
|
||||
};
|
||||
|
||||
const cipher_base_t des_ede3_info = {
|
||||
POLARSSL_CIPHER_ID_DES,
|
||||
des3_crypt_cbc_wrap,
|
||||
des_crypt_cfb128_wrap,
|
||||
des_crypt_ctr_wrap,
|
||||
des3_set3key_enc_wrap,
|
||||
des3_set3key_dec_wrap,
|
||||
des3_ctx_alloc,
|
||||
des_ctx_free
|
||||
};
|
||||
|
||||
const cipher_info_t des_ede3_cbc_info = {
|
||||
POLARSSL_CIPHER_DES_EDE3_CBC,
|
||||
POLARSSL_MODE_CBC,
|
||||
POLARSSL_KEY_LENGTH_DES_EDE3,
|
||||
"DES-EDE3-CBC",
|
||||
8,
|
||||
8,
|
||||
&des_ede3_info
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_BLOWFISH_C)
|
||||
|
||||
int blowfish_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
|
||||
unsigned char *iv, const unsigned char *input, unsigned char *output )
|
||||
{
|
||||
return blowfish_crypt_cbc( (blowfish_context *) ctx, operation, length, iv, input, output );
|
||||
}
|
||||
|
||||
int blowfish_crypt_cfb64_wrap( void *ctx, operation_t operation, size_t length,
|
||||
size_t *iv_off, unsigned char *iv, const unsigned char *input, unsigned char *output )
|
||||
{
|
||||
#if defined(POLARSSL_CIPHER_MODE_CFB)
|
||||
return blowfish_crypt_cfb64( (blowfish_context *) ctx, operation, length, iv_off, iv, input, output );
|
||||
#else
|
||||
((void) ctx);
|
||||
((void) operation);
|
||||
((void) length);
|
||||
((void) iv_off);
|
||||
((void) iv);
|
||||
((void) input);
|
||||
((void) output);
|
||||
|
||||
return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
int blowfish_crypt_ctr_wrap( void *ctx, size_t length,
|
||||
size_t *nc_off, unsigned char *nonce_counter, unsigned char *stream_block,
|
||||
const unsigned char *input, unsigned char *output )
|
||||
{
|
||||
#if defined(POLARSSL_CIPHER_MODE_CTR)
|
||||
return blowfish_crypt_ctr( (blowfish_context *) ctx, length, nc_off, nonce_counter,
|
||||
stream_block, input, output );
|
||||
#else
|
||||
((void) ctx);
|
||||
((void) length);
|
||||
((void) nc_off);
|
||||
((void) nonce_counter);
|
||||
((void) stream_block);
|
||||
((void) input);
|
||||
((void) output);
|
||||
|
||||
return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
int blowfish_setkey_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
|
||||
{
|
||||
return blowfish_setkey( (blowfish_context *) ctx, key, key_length );
|
||||
}
|
||||
|
||||
int blowfish_setkey_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
|
||||
{
|
||||
return blowfish_setkey( (blowfish_context *) ctx, key, key_length );
|
||||
}
|
||||
|
||||
static void * blowfish_ctx_alloc( void )
|
||||
{
|
||||
return malloc( sizeof( blowfish_context ) );
|
||||
}
|
||||
|
||||
static void blowfish_ctx_free( void *ctx )
|
||||
{
|
||||
free( ctx );
|
||||
}
|
||||
|
||||
const cipher_base_t blowfish_info = {
|
||||
POLARSSL_CIPHER_ID_BLOWFISH,
|
||||
blowfish_crypt_cbc_wrap,
|
||||
blowfish_crypt_cfb64_wrap,
|
||||
blowfish_crypt_ctr_wrap,
|
||||
blowfish_setkey_enc_wrap,
|
||||
blowfish_setkey_dec_wrap,
|
||||
blowfish_ctx_alloc,
|
||||
blowfish_ctx_free
|
||||
};
|
||||
|
||||
const cipher_info_t blowfish_cbc_info = {
|
||||
POLARSSL_CIPHER_BLOWFISH_CBC,
|
||||
POLARSSL_MODE_CBC,
|
||||
128,
|
||||
"BLOWFISH-CBC",
|
||||
8,
|
||||
8,
|
||||
&blowfish_info
|
||||
};
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CFB)
|
||||
const cipher_info_t blowfish_cfb64_info = {
|
||||
POLARSSL_CIPHER_BLOWFISH_CFB64,
|
||||
POLARSSL_MODE_CFB,
|
||||
128,
|
||||
"BLOWFISH-CFB64",
|
||||
8,
|
||||
8,
|
||||
&blowfish_info
|
||||
};
|
||||
#endif /* POLARSSL_CIPHER_MODE_CFB */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CTR)
|
||||
const cipher_info_t blowfish_ctr_info = {
|
||||
POLARSSL_CIPHER_BLOWFISH_CTR,
|
||||
POLARSSL_MODE_CTR,
|
||||
128,
|
||||
"BLOWFISH-CTR",
|
||||
8,
|
||||
8,
|
||||
&blowfish_info
|
||||
};
|
||||
#endif /* POLARSSL_CIPHER_MODE_CTR */
|
||||
#endif /* POLARSSL_BLOWFISH_C */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_NULL_CIPHER)
|
||||
static void * null_ctx_alloc( void )
|
||||
{
|
||||
return (void *) 1;
|
||||
}
|
||||
|
||||
|
||||
static void null_ctx_free( void *ctx )
|
||||
{
|
||||
((void) ctx);
|
||||
}
|
||||
|
||||
const cipher_base_t null_base_info = {
|
||||
POLARSSL_CIPHER_ID_NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
null_ctx_alloc,
|
||||
null_ctx_free
|
||||
};
|
||||
|
||||
const cipher_info_t null_cipher_info = {
|
||||
POLARSSL_CIPHER_NULL,
|
||||
POLARSSL_MODE_NULL,
|
||||
0,
|
||||
"NULL",
|
||||
1,
|
||||
1,
|
||||
&null_base_info
|
||||
};
|
||||
#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* \file cipher_wrap.h
|
||||
*
|
||||
* \brief Cipher wrappers.
|
||||
*
|
||||
* \author Adriaan de Jong <dejong@fox-it.com>
|
||||
*
|
||||
* Copyright (C) 2006-2012, 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_CIPHER_WRAP_H
|
||||
#define POLARSSL_CIPHER_WRAP_H
|
||||
|
||||
#include "polarssl/config.h"
|
||||
#include "polarssl/cipher.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_AES_C)
|
||||
|
||||
extern const cipher_info_t aes_128_cbc_info;
|
||||
extern const cipher_info_t aes_192_cbc_info;
|
||||
extern const cipher_info_t aes_256_cbc_info;
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CFB)
|
||||
extern const cipher_info_t aes_128_cfb128_info;
|
||||
extern const cipher_info_t aes_192_cfb128_info;
|
||||
extern const cipher_info_t aes_256_cfb128_info;
|
||||
#endif /* POLARSSL_CIPHER_MODE_CFB */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CTR)
|
||||
extern const cipher_info_t aes_128_ctr_info;
|
||||
extern const cipher_info_t aes_192_ctr_info;
|
||||
extern const cipher_info_t aes_256_ctr_info;
|
||||
#endif /* POLARSSL_CIPHER_MODE_CTR */
|
||||
|
||||
#endif /* defined(POLARSSL_AES_C) */
|
||||
|
||||
#if defined(POLARSSL_CAMELLIA_C)
|
||||
|
||||
extern const cipher_info_t camellia_128_cbc_info;
|
||||
extern const cipher_info_t camellia_192_cbc_info;
|
||||
extern const cipher_info_t camellia_256_cbc_info;
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CFB)
|
||||
extern const cipher_info_t camellia_128_cfb128_info;
|
||||
extern const cipher_info_t camellia_192_cfb128_info;
|
||||
extern const cipher_info_t camellia_256_cfb128_info;
|
||||
#endif /* POLARSSL_CIPHER_MODE_CFB */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CTR)
|
||||
extern const cipher_info_t camellia_128_ctr_info;
|
||||
extern const cipher_info_t camellia_192_ctr_info;
|
||||
extern const cipher_info_t camellia_256_ctr_info;
|
||||
#endif /* POLARSSL_CIPHER_MODE_CTR */
|
||||
|
||||
#endif /* defined(POLARSSL_CAMELLIA_C) */
|
||||
|
||||
#if defined(POLARSSL_DES_C)
|
||||
|
||||
extern const cipher_info_t des_cbc_info;
|
||||
extern const cipher_info_t des_ede_cbc_info;
|
||||
extern const cipher_info_t des_ede3_cbc_info;
|
||||
|
||||
#endif /* defined(POLARSSL_DES_C) */
|
||||
|
||||
#if defined(POLARSSL_BLOWFISH_C)
|
||||
extern const cipher_info_t blowfish_cbc_info;
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CFB)
|
||||
extern const cipher_info_t blowfish_cfb64_info;
|
||||
#endif /* POLARSSL_CIPHER_MODE_CFB */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CTR)
|
||||
extern const cipher_info_t blowfish_ctr_info;
|
||||
#endif /* POLARSSL_CIPHER_MODE_CTR */
|
||||
#endif /* defined(POLARSSL_BLOWFISH_C) */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_NULL_CIPHER)
|
||||
extern const cipher_info_t null_cipher_info;
|
||||
#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* POLARSSL_CIPHER_WRAP_H */
|
||||
+1012
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,562 @@
|
||||
/*
|
||||
* CTR_DRBG implementation based on AES-256 (NIST SP 800-90)
|
||||
*
|
||||
* Copyright (C) 2006-2011, 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 NIST SP 800-90 DRBGs are described in the following publucation.
|
||||
*
|
||||
* http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_CTR_DRBG_C)
|
||||
|
||||
#include "polarssl/ctr_drbg.h"
|
||||
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Non-public function wrapped by ctr_crbg_init(). Necessary to allow NIST
|
||||
* tests to succeed (which require known length fixed entropy)
|
||||
*/
|
||||
int ctr_drbg_init_entropy_len(
|
||||
ctr_drbg_context *ctx,
|
||||
int (*f_entropy)(void *, unsigned char *, size_t),
|
||||
void *p_entropy,
|
||||
const unsigned char *custom,
|
||||
size_t len,
|
||||
size_t entropy_len )
|
||||
{
|
||||
int ret;
|
||||
unsigned char key[CTR_DRBG_KEYSIZE];
|
||||
|
||||
memset( ctx, 0, sizeof(ctr_drbg_context) );
|
||||
memset( key, 0, CTR_DRBG_KEYSIZE );
|
||||
|
||||
ctx->f_entropy = f_entropy;
|
||||
ctx->p_entropy = p_entropy;
|
||||
|
||||
ctx->entropy_len = entropy_len;
|
||||
ctx->reseed_interval = CTR_DRBG_RESEED_INTERVAL;
|
||||
|
||||
/*
|
||||
* Initialize with an empty key
|
||||
*/
|
||||
aes_setkey_enc( &ctx->aes_ctx, key, CTR_DRBG_KEYBITS );
|
||||
|
||||
if( ( ret = ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int ctr_drbg_init( ctr_drbg_context *ctx,
|
||||
int (*f_entropy)(void *, unsigned char *, size_t),
|
||||
void *p_entropy,
|
||||
const unsigned char *custom,
|
||||
size_t len )
|
||||
{
|
||||
return( ctr_drbg_init_entropy_len( ctx, f_entropy, p_entropy, custom, len,
|
||||
CTR_DRBG_ENTROPY_LEN ) );
|
||||
}
|
||||
|
||||
void ctr_drbg_set_prediction_resistance( ctr_drbg_context *ctx, int resistance )
|
||||
{
|
||||
ctx->prediction_resistance = resistance;
|
||||
}
|
||||
|
||||
void ctr_drbg_set_entropy_len( ctr_drbg_context *ctx, size_t len )
|
||||
{
|
||||
ctx->entropy_len = len;
|
||||
}
|
||||
|
||||
void ctr_drbg_set_reseed_interval( ctr_drbg_context *ctx, int interval )
|
||||
{
|
||||
ctx->reseed_interval = interval;
|
||||
}
|
||||
|
||||
int block_cipher_df( unsigned char *output,
|
||||
const unsigned char *data, size_t data_len )
|
||||
{
|
||||
unsigned char buf[CTR_DRBG_MAX_SEED_INPUT + CTR_DRBG_BLOCKSIZE + 16];
|
||||
unsigned char tmp[CTR_DRBG_SEEDLEN];
|
||||
unsigned char key[CTR_DRBG_KEYSIZE];
|
||||
unsigned char chain[CTR_DRBG_BLOCKSIZE];
|
||||
unsigned char *p = buf, *iv;
|
||||
aes_context aes_ctx;
|
||||
|
||||
int i, j, buf_len, use_len;
|
||||
|
||||
memset( buf, 0, CTR_DRBG_MAX_SEED_INPUT + CTR_DRBG_BLOCKSIZE + 16 );
|
||||
|
||||
/*
|
||||
* Construct IV (16 bytes) and S in buffer
|
||||
* IV = Counter (in 32-bits) padded to 16 with zeroes
|
||||
* S = Length input string (in 32-bits) || Length of output (in 32-bits) ||
|
||||
* data || 0x80
|
||||
* (Total is padded to a multiple of 16-bytes with zeroes)
|
||||
*/
|
||||
p = buf + CTR_DRBG_BLOCKSIZE;
|
||||
*p++ = ( data_len >> 24 ) & 0xff;
|
||||
*p++ = ( data_len >> 16 ) & 0xff;
|
||||
*p++ = ( data_len >> 8 ) & 0xff;
|
||||
*p++ = ( data_len ) & 0xff;
|
||||
p += 3;
|
||||
*p++ = CTR_DRBG_SEEDLEN;
|
||||
memcpy( p, data, data_len );
|
||||
p[data_len] = 0x80;
|
||||
|
||||
buf_len = CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;
|
||||
|
||||
for( i = 0; i < CTR_DRBG_KEYSIZE; i++ )
|
||||
key[i] = i;
|
||||
|
||||
aes_setkey_enc( &aes_ctx, key, CTR_DRBG_KEYBITS );
|
||||
|
||||
/*
|
||||
* Reduce data to POLARSSL_CTR_DRBG_SEEDLEN bytes of data
|
||||
*/
|
||||
for( j = 0; j < CTR_DRBG_SEEDLEN; j += CTR_DRBG_BLOCKSIZE )
|
||||
{
|
||||
p = buf;
|
||||
memset( chain, 0, CTR_DRBG_BLOCKSIZE );
|
||||
use_len = buf_len;
|
||||
|
||||
while( use_len > 0 )
|
||||
{
|
||||
for( i = 0; i < CTR_DRBG_BLOCKSIZE; i++ )
|
||||
chain[i] ^= p[i];
|
||||
p += CTR_DRBG_BLOCKSIZE;
|
||||
use_len -= CTR_DRBG_BLOCKSIZE;
|
||||
|
||||
aes_crypt_ecb( &aes_ctx, AES_ENCRYPT, chain, chain );
|
||||
}
|
||||
|
||||
memcpy( tmp + j, chain, CTR_DRBG_BLOCKSIZE );
|
||||
|
||||
/*
|
||||
* Update IV
|
||||
*/
|
||||
buf[3]++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do final encryption with reduced data
|
||||
*/
|
||||
aes_setkey_enc( &aes_ctx, tmp, CTR_DRBG_KEYBITS );
|
||||
iv = tmp + CTR_DRBG_KEYSIZE;
|
||||
p = output;
|
||||
|
||||
for( j = 0; j < CTR_DRBG_SEEDLEN; j += CTR_DRBG_BLOCKSIZE )
|
||||
{
|
||||
aes_crypt_ecb( &aes_ctx, AES_ENCRYPT, iv, iv );
|
||||
memcpy( p, iv, CTR_DRBG_BLOCKSIZE );
|
||||
p += CTR_DRBG_BLOCKSIZE;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int ctr_drbg_update_internal( ctr_drbg_context *ctx,
|
||||
const unsigned char data[CTR_DRBG_SEEDLEN] )
|
||||
{
|
||||
unsigned char tmp[CTR_DRBG_SEEDLEN];
|
||||
unsigned char *p = tmp;
|
||||
int i, j;
|
||||
|
||||
memset( tmp, 0, CTR_DRBG_SEEDLEN );
|
||||
|
||||
for( j = 0; j < CTR_DRBG_SEEDLEN; j += CTR_DRBG_BLOCKSIZE )
|
||||
{
|
||||
/*
|
||||
* Increase counter
|
||||
*/
|
||||
for( i = CTR_DRBG_BLOCKSIZE; i > 0; i-- )
|
||||
if( ++ctx->counter[i - 1] != 0 )
|
||||
break;
|
||||
|
||||
/*
|
||||
* Crypt counter block
|
||||
*/
|
||||
aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->counter, p );
|
||||
|
||||
p += CTR_DRBG_BLOCKSIZE;
|
||||
}
|
||||
|
||||
for( i = 0; i < CTR_DRBG_SEEDLEN; i++ )
|
||||
tmp[i] ^= data[i];
|
||||
|
||||
/*
|
||||
* Update key and counter
|
||||
*/
|
||||
aes_setkey_enc( &ctx->aes_ctx, tmp, CTR_DRBG_KEYBITS );
|
||||
memcpy( ctx->counter, tmp + CTR_DRBG_KEYSIZE, CTR_DRBG_BLOCKSIZE );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
void ctr_drbg_update( ctr_drbg_context *ctx,
|
||||
const unsigned char *additional, size_t add_len )
|
||||
{
|
||||
unsigned char add_input[CTR_DRBG_SEEDLEN];
|
||||
|
||||
if( add_len > 0 )
|
||||
{
|
||||
block_cipher_df( add_input, additional, add_len );
|
||||
ctr_drbg_update_internal( ctx, add_input );
|
||||
}
|
||||
}
|
||||
|
||||
int ctr_drbg_reseed( ctr_drbg_context *ctx,
|
||||
const unsigned char *additional, size_t len )
|
||||
{
|
||||
unsigned char seed[CTR_DRBG_MAX_SEED_INPUT];
|
||||
size_t seedlen = 0;
|
||||
|
||||
if( ctx->entropy_len + len > CTR_DRBG_MAX_SEED_INPUT )
|
||||
return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG );
|
||||
|
||||
memset( seed, 0, CTR_DRBG_MAX_SEED_INPUT );
|
||||
|
||||
/*
|
||||
* Gather enropy_len bytes of entropy to seed state
|
||||
*/
|
||||
if( 0 != ctx->f_entropy( ctx->p_entropy, seed,
|
||||
ctx->entropy_len ) )
|
||||
{
|
||||
return( POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
|
||||
}
|
||||
|
||||
seedlen += ctx->entropy_len;
|
||||
|
||||
/*
|
||||
* Add additional data
|
||||
*/
|
||||
if( additional && len )
|
||||
{
|
||||
memcpy( seed + seedlen, additional, len );
|
||||
seedlen += len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reduce to 384 bits
|
||||
*/
|
||||
block_cipher_df( seed, seed, seedlen );
|
||||
|
||||
/*
|
||||
* Update state
|
||||
*/
|
||||
ctr_drbg_update_internal( ctx, seed );
|
||||
ctx->reseed_counter = 1;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int ctr_drbg_random_with_add( void *p_rng,
|
||||
unsigned char *output, size_t output_len,
|
||||
const unsigned char *additional, size_t add_len )
|
||||
{
|
||||
int ret = 0;
|
||||
ctr_drbg_context *ctx = (ctr_drbg_context *) p_rng;
|
||||
unsigned char add_input[CTR_DRBG_SEEDLEN];
|
||||
unsigned char *p = output;
|
||||
unsigned char tmp[CTR_DRBG_BLOCKSIZE];
|
||||
int i;
|
||||
size_t use_len;
|
||||
|
||||
if( output_len > CTR_DRBG_MAX_REQUEST )
|
||||
return( POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG );
|
||||
|
||||
if( add_len > CTR_DRBG_MAX_INPUT )
|
||||
return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG );
|
||||
|
||||
memset( add_input, 0, CTR_DRBG_SEEDLEN );
|
||||
|
||||
if( ctx->reseed_counter > ctx->reseed_interval ||
|
||||
ctx->prediction_resistance )
|
||||
{
|
||||
if( ( ret = ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
add_len = 0;
|
||||
}
|
||||
|
||||
if( add_len > 0 )
|
||||
{
|
||||
block_cipher_df( add_input, additional, add_len );
|
||||
ctr_drbg_update_internal( ctx, add_input );
|
||||
}
|
||||
|
||||
while( output_len > 0 )
|
||||
{
|
||||
/*
|
||||
* Increase counter
|
||||
*/
|
||||
for( i = CTR_DRBG_BLOCKSIZE; i > 0; i-- )
|
||||
if( ++ctx->counter[i - 1] != 0 )
|
||||
break;
|
||||
|
||||
/*
|
||||
* Crypt counter block
|
||||
*/
|
||||
aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->counter, tmp );
|
||||
|
||||
use_len = (output_len > CTR_DRBG_BLOCKSIZE ) ? CTR_DRBG_BLOCKSIZE : output_len;
|
||||
/*
|
||||
* Copy random block to destination
|
||||
*/
|
||||
memcpy( p, tmp, use_len );
|
||||
p += use_len;
|
||||
output_len -= use_len;
|
||||
}
|
||||
|
||||
ctr_drbg_update_internal( ctx, add_input );
|
||||
|
||||
ctx->reseed_counter++;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
|
||||
{
|
||||
return ctr_drbg_random_with_add( p_rng, output, output_len, NULL, 0 );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
int ctr_drbg_write_seed_file( ctr_drbg_context *ctx, const char *path )
|
||||
{
|
||||
int ret;
|
||||
FILE *f;
|
||||
unsigned char buf[ CTR_DRBG_MAX_INPUT ];
|
||||
|
||||
if( ( f = fopen( path, "wb" ) ) == NULL )
|
||||
return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR );
|
||||
|
||||
if( ( ret = ctr_drbg_random( ctx, buf, CTR_DRBG_MAX_INPUT ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( fwrite( buf, 1, CTR_DRBG_MAX_INPUT, f ) != CTR_DRBG_MAX_INPUT )
|
||||
{
|
||||
fclose( f );
|
||||
return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR );
|
||||
}
|
||||
|
||||
fclose( f );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int ctr_drbg_update_seed_file( ctr_drbg_context *ctx, const char *path )
|
||||
{
|
||||
FILE *f;
|
||||
size_t n;
|
||||
unsigned char buf[ CTR_DRBG_MAX_INPUT ];
|
||||
|
||||
if( ( f = fopen( path, "rb" ) ) == NULL )
|
||||
return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR );
|
||||
|
||||
fseek( f, 0, SEEK_END );
|
||||
n = (size_t) ftell( f );
|
||||
fseek( f, 0, SEEK_SET );
|
||||
|
||||
if( n > CTR_DRBG_MAX_INPUT )
|
||||
return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG );
|
||||
|
||||
if( fread( buf, 1, n, f ) != n )
|
||||
{
|
||||
fclose( f );
|
||||
return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR );
|
||||
}
|
||||
|
||||
ctr_drbg_update( ctx, buf, n );
|
||||
|
||||
fclose( f );
|
||||
|
||||
return( ctr_drbg_write_seed_file( ctx, path ) );
|
||||
}
|
||||
#endif /* POLARSSL_FS_IO */
|
||||
|
||||
#if defined(POLARSSL_SELF_TEST)
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
unsigned char entropy_source_pr[96] =
|
||||
{ 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16,
|
||||
0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02,
|
||||
0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b,
|
||||
0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb,
|
||||
0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9,
|
||||
0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95,
|
||||
0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63,
|
||||
0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3,
|
||||
0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31,
|
||||
0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4,
|
||||
0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56,
|
||||
0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
|
||||
|
||||
unsigned char entropy_source_nopr[64] =
|
||||
{ 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14,
|
||||
0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe,
|
||||
0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d,
|
||||
0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20,
|
||||
0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9,
|
||||
0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46,
|
||||
0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e,
|
||||
0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e };
|
||||
|
||||
unsigned char nonce_pers_pr[16] =
|
||||
{ 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2,
|
||||
0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };
|
||||
|
||||
unsigned char nonce_pers_nopr[16] =
|
||||
{ 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5,
|
||||
0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f };
|
||||
|
||||
unsigned char result_pr[16] =
|
||||
{ 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f,
|
||||
0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 };
|
||||
|
||||
unsigned char result_nopr[16] =
|
||||
{ 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88,
|
||||
0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f };
|
||||
|
||||
int test_offset;
|
||||
int ctr_drbg_self_test_entropy( void *data, unsigned char *buf, size_t len )
|
||||
{
|
||||
unsigned char *p = data;
|
||||
memcpy( buf, p + test_offset, len );
|
||||
test_offset += 32;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Checkup routine
|
||||
*/
|
||||
int ctr_drbg_self_test( int verbose )
|
||||
{
|
||||
ctr_drbg_context ctx;
|
||||
unsigned char buf[16];
|
||||
|
||||
/*
|
||||
* Based on a NIST CTR_DRBG test vector (PR = True)
|
||||
*/
|
||||
if( verbose != 0 )
|
||||
printf( " CTR_DRBG (PR = TRUE) : " );
|
||||
|
||||
test_offset = 0;
|
||||
if( ctr_drbg_init_entropy_len( &ctx, ctr_drbg_self_test_entropy, entropy_source_pr, nonce_pers_pr, 16, 32 ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
ctr_drbg_set_prediction_resistance( &ctx, CTR_DRBG_PR_ON );
|
||||
|
||||
if( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( memcmp( buf, result_pr, CTR_DRBG_BLOCKSIZE ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "passed\n" );
|
||||
|
||||
/*
|
||||
* Based on a NIST CTR_DRBG test vector (PR = FALSE)
|
||||
*/
|
||||
if( verbose != 0 )
|
||||
printf( " CTR_DRBG (PR = FALSE): " );
|
||||
|
||||
test_offset = 0;
|
||||
if( ctr_drbg_init_entropy_len( &ctx, ctr_drbg_self_test_entropy, entropy_source_nopr, nonce_pers_nopr, 16, 32 ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( ctr_drbg_random( &ctx, buf, 16 ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( ctr_drbg_reseed( &ctx, NULL, 0 ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( ctr_drbg_random( &ctx, buf, 16 ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( memcmp( buf, result_nopr, 16 ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "passed\n" );
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "\n" );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,231 @@
|
||||
/**
|
||||
* \file ctr_drbg.h
|
||||
*
|
||||
* \brief CTR_DRBG based on AES-256 (NIST SP 800-90)
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef POLARSSL_CTR_DRBG_H
|
||||
#define POLARSSL_CTR_DRBG_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "polarssl/aes.h"
|
||||
|
||||
#define POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED -0x0034 /**< The entropy source failed. */
|
||||
#define POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG -0x0036 /**< Too many random requested in single call. */
|
||||
#define POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG -0x0038 /**< Input too large (Entropy + additional). */
|
||||
#define POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR -0x003A /**< Read/write error in file. */
|
||||
|
||||
#define CTR_DRBG_BLOCKSIZE 16 /**< Block size used by the cipher */
|
||||
#define CTR_DRBG_KEYSIZE 32 /**< Key size used by the cipher */
|
||||
#define CTR_DRBG_KEYBITS ( CTR_DRBG_KEYSIZE * 8 )
|
||||
#define CTR_DRBG_SEEDLEN ( CTR_DRBG_KEYSIZE + CTR_DRBG_BLOCKSIZE )
|
||||
/**< The seed length (counter + AES key) */
|
||||
|
||||
#if !defined(POLARSSL_CONFIG_OPTIONS)
|
||||
#define CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default */
|
||||
#define CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */
|
||||
#define CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */
|
||||
#define CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */
|
||||
#define CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */
|
||||
#endif /* !POLARSSL_CONFIG_OPTIONS */
|
||||
|
||||
#define CTR_DRBG_PR_OFF 0 /**< No prediction resistance */
|
||||
#define CTR_DRBG_PR_ON 1 /**< Prediction resistance enabled */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief CTR_DRBG context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned char counter[16]; /*!< counter (V) */
|
||||
int reseed_counter; /*!< reseed counter */
|
||||
int prediction_resistance; /*!< enable prediction resistance (Automatic
|
||||
reseed before every random generation) */
|
||||
size_t entropy_len; /*!< amount of entropy grabbed on each (re)seed */
|
||||
int reseed_interval; /*!< reseed interval */
|
||||
|
||||
aes_context aes_ctx; /*!< AES context */
|
||||
|
||||
/*
|
||||
* Callbacks (Entropy)
|
||||
*/
|
||||
int (*f_entropy)(void *, unsigned char *, size_t);
|
||||
|
||||
void *p_entropy; /*!< context for the entropy function */
|
||||
}
|
||||
ctr_drbg_context;
|
||||
|
||||
/**
|
||||
* \brief CTR_DRBG initialization
|
||||
*
|
||||
* Note: Personalization data can be provided in addition to the more generic
|
||||
* entropy source to make this instantiation as unique as possible.
|
||||
*
|
||||
* \param ctx CTR_DRBG context to be initialized
|
||||
* \param f_entropy Entropy callback (p_entropy, buffer to fill, buffer
|
||||
* length)
|
||||
* \param p_entropy Entropy context
|
||||
* \param custom Personalization data (Device specific identifiers)
|
||||
* (Can be NULL)
|
||||
* \param len Length of personalization data
|
||||
*
|
||||
* \return 0 if successful, or
|
||||
* POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED
|
||||
*/
|
||||
int ctr_drbg_init( ctr_drbg_context *ctx,
|
||||
int (*f_entropy)(void *, unsigned char *, size_t),
|
||||
void *p_entropy,
|
||||
const unsigned char *custom,
|
||||
size_t len );
|
||||
|
||||
/**
|
||||
* \brief Enable / disable prediction resistance (Default: Off)
|
||||
*
|
||||
* Note: If enabled, entropy is used for ctx->entropy_len before each call!
|
||||
* Only use this if you have ample supply of good entropy!
|
||||
*
|
||||
* \param ctx CTR_DRBG context
|
||||
* \param resistance CTR_DRBG_PR_ON or CTR_DRBG_PR_OFF
|
||||
*/
|
||||
void ctr_drbg_set_prediction_resistance( ctr_drbg_context *ctx,
|
||||
int resistance );
|
||||
|
||||
/**
|
||||
* \brief Set the amount of entropy grabbed on each (re)seed
|
||||
* (Default: CTR_DRBG_ENTROPY_LEN)
|
||||
*
|
||||
* \param ctx CTR_DRBG context
|
||||
* \param len Amount of entropy to grab
|
||||
*/
|
||||
void ctr_drbg_set_entropy_len( ctr_drbg_context *ctx,
|
||||
size_t len );
|
||||
|
||||
/**
|
||||
* \brief Set the reseed interval
|
||||
* (Default: CTR_DRBG_RESEED_INTERVAL)
|
||||
*
|
||||
* \param ctx CTR_DRBG context
|
||||
* \param interval Reseed interval
|
||||
*/
|
||||
void ctr_drbg_set_reseed_interval( ctr_drbg_context *ctx,
|
||||
int interval );
|
||||
|
||||
/**
|
||||
* \brief CTR_DRBG reseeding (extracts data from entropy source)
|
||||
*
|
||||
* \param ctx CTR_DRBG context
|
||||
* \param additional Additional data to add to state (Can be NULL)
|
||||
* \param len Length of additional data
|
||||
*
|
||||
* \return 0 if successful, or
|
||||
* POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED
|
||||
*/
|
||||
int ctr_drbg_reseed( ctr_drbg_context *ctx,
|
||||
const unsigned char *additional, size_t len );
|
||||
|
||||
/**
|
||||
* \brief CTR_DRBG update state
|
||||
*
|
||||
* \param ctx CTR_DRBG context
|
||||
* \param additional Additional data to update state with
|
||||
* \param add_len Length of additional data
|
||||
*/
|
||||
void ctr_drbg_update( ctr_drbg_context *ctx,
|
||||
const unsigned char *additional, size_t add_len );
|
||||
|
||||
/**
|
||||
* \brief CTR_DRBG generate random with additional update input
|
||||
*
|
||||
* Note: Automatically reseeds if reseed_counter is reached.
|
||||
*
|
||||
* \param p_rng CTR_DRBG context
|
||||
* \param output Buffer to fill
|
||||
* \param output_len Length of the buffer
|
||||
* \param additional Additional data to update with (Can be NULL)
|
||||
* \param add_len Length of additional data
|
||||
*
|
||||
* \return 0 if successful, or
|
||||
* POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED, or
|
||||
* POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG
|
||||
*/
|
||||
int ctr_drbg_random_with_add( void *p_rng,
|
||||
unsigned char *output, size_t output_len,
|
||||
const unsigned char *additional, size_t add_len );
|
||||
|
||||
/**
|
||||
* \brief CTR_DRBG generate random
|
||||
*
|
||||
* Note: Automatically reseeds if reseed_counter is reached.
|
||||
*
|
||||
* \param p_rng CTR_DRBG context
|
||||
* \param output Buffer to fill
|
||||
* \param output_len Length of the buffer
|
||||
*
|
||||
* \return 0 if successful, or
|
||||
* POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED, or
|
||||
* POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG
|
||||
*/
|
||||
int ctr_drbg_random( void *p_rng,
|
||||
unsigned char *output, size_t output_len );
|
||||
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
/**
|
||||
* \brief Write a seed file
|
||||
*
|
||||
* \param path Name of the file
|
||||
*
|
||||
* \return 0 if successful, 1 on file error, or
|
||||
* POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED
|
||||
*/
|
||||
int ctr_drbg_write_seed_file( ctr_drbg_context *ctx, const char *path );
|
||||
|
||||
/**
|
||||
* \brief Read and update a seed file. Seed is added to this
|
||||
* instance
|
||||
*
|
||||
* \param path Name of the file
|
||||
*
|
||||
* \return 0 if successful, 1 on file error,
|
||||
* POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
|
||||
* POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG
|
||||
*/
|
||||
int ctr_drbg_update_seed_file( ctr_drbg_context *ctx, const char *path );
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int ctr_drbg_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ctr_drbg.h */
|
||||
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Debugging routines
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_DEBUG_C)
|
||||
|
||||
#include "polarssl/debug.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined _MSC_VER && !defined snprintf
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
#if defined _MSC_VER && !defined vsnprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
|
||||
char *debug_fmt( const char *format, ... )
|
||||
{
|
||||
va_list argp;
|
||||
static char str[512];
|
||||
int maxlen = sizeof( str ) - 1;
|
||||
|
||||
va_start( argp, format );
|
||||
vsnprintf( str, maxlen, format, argp );
|
||||
va_end( argp );
|
||||
|
||||
str[maxlen] = '\0';
|
||||
return( str );
|
||||
}
|
||||
|
||||
void debug_print_msg( const ssl_context *ssl, int level,
|
||||
const char *file, int line, const char *text )
|
||||
{
|
||||
char str[512];
|
||||
int maxlen = sizeof( str ) - 1;
|
||||
|
||||
if( ssl->f_dbg == NULL )
|
||||
return;
|
||||
|
||||
snprintf( str, maxlen, "%s(%04d): %s\n", file, line, text );
|
||||
str[maxlen] = '\0';
|
||||
ssl->f_dbg( ssl->p_dbg, level, str );
|
||||
}
|
||||
|
||||
void debug_print_ret( const ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *text, int ret )
|
||||
{
|
||||
char str[512];
|
||||
int maxlen = sizeof( str ) - 1;
|
||||
|
||||
if( ssl->f_dbg == NULL )
|
||||
return;
|
||||
|
||||
snprintf( str, maxlen, "%s(%04d): %s() returned %d (0x%x)\n",
|
||||
file, line, text, ret, ret );
|
||||
|
||||
str[maxlen] = '\0';
|
||||
ssl->f_dbg( ssl->p_dbg, level, str );
|
||||
}
|
||||
|
||||
void debug_print_buf( const ssl_context *ssl, int level,
|
||||
const char *file, int line, const char *text,
|
||||
unsigned char *buf, size_t len )
|
||||
{
|
||||
char str[512];
|
||||
size_t i, maxlen = sizeof( str ) - 1;
|
||||
|
||||
if( ssl->f_dbg == NULL )
|
||||
return;
|
||||
|
||||
snprintf( str, maxlen, "%s(%04d): dumping '%s' (%d bytes)\n",
|
||||
file, line, text, (unsigned int) len );
|
||||
|
||||
str[maxlen] = '\0';
|
||||
ssl->f_dbg( ssl->p_dbg, level, str );
|
||||
|
||||
for( i = 0; i < len; i++ )
|
||||
{
|
||||
if( i >= 4096 )
|
||||
break;
|
||||
|
||||
if( i % 16 == 0 )
|
||||
{
|
||||
if( i > 0 )
|
||||
ssl->f_dbg( ssl->p_dbg, level, "\n" );
|
||||
|
||||
snprintf( str, maxlen, "%s(%04d): %04x: ", file, line,
|
||||
(unsigned int) i );
|
||||
|
||||
str[maxlen] = '\0';
|
||||
ssl->f_dbg( ssl->p_dbg, level, str );
|
||||
}
|
||||
|
||||
snprintf( str, maxlen, " %02x", (unsigned int) buf[i] );
|
||||
|
||||
str[maxlen] = '\0';
|
||||
ssl->f_dbg( ssl->p_dbg, level, str );
|
||||
}
|
||||
|
||||
if( len > 0 )
|
||||
ssl->f_dbg( ssl->p_dbg, level, "\n" );
|
||||
}
|
||||
|
||||
void debug_print_mpi( const ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *text, const mpi *X )
|
||||
{
|
||||
char str[512];
|
||||
int j, k, maxlen = sizeof( str ) - 1, zeros = 1;
|
||||
size_t i, n;
|
||||
|
||||
if( ssl->f_dbg == NULL || X == NULL )
|
||||
return;
|
||||
|
||||
for( n = X->n - 1; n > 0; n-- )
|
||||
if( X->p[n] != 0 )
|
||||
break;
|
||||
|
||||
for( j = ( sizeof(t_uint) << 3 ) - 1; j >= 0; j-- )
|
||||
if( ( ( X->p[n] >> j ) & 1 ) != 0 )
|
||||
break;
|
||||
|
||||
snprintf( str, maxlen, "%s(%04d): value of '%s' (%d bits) is:\n",
|
||||
file, line, text,
|
||||
(int) ( ( n * ( sizeof(t_uint) << 3 ) ) + j + 1 ) );
|
||||
|
||||
str[maxlen] = '\0';
|
||||
ssl->f_dbg( ssl->p_dbg, level, str );
|
||||
|
||||
for( i = n + 1, j = 0; i > 0; i-- )
|
||||
{
|
||||
if( zeros && X->p[i - 1] == 0 )
|
||||
continue;
|
||||
|
||||
for( k = sizeof( t_uint ) - 1; k >= 0; k-- )
|
||||
{
|
||||
if( zeros && ( ( X->p[i - 1] >> (k << 3) ) & 0xFF ) == 0 )
|
||||
continue;
|
||||
else
|
||||
zeros = 0;
|
||||
|
||||
if( j % 16 == 0 )
|
||||
{
|
||||
if( j > 0 )
|
||||
ssl->f_dbg( ssl->p_dbg, level, "\n" );
|
||||
|
||||
snprintf( str, maxlen, "%s(%04d): ", file, line );
|
||||
|
||||
str[maxlen] = '\0';
|
||||
ssl->f_dbg( ssl->p_dbg, level, str );
|
||||
}
|
||||
|
||||
snprintf( str, maxlen, " %02x", (unsigned int)
|
||||
( X->p[i - 1] >> (k << 3) ) & 0xFF );
|
||||
|
||||
str[maxlen] = '\0';
|
||||
ssl->f_dbg( ssl->p_dbg, level, str );
|
||||
|
||||
j++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( zeros == 1 )
|
||||
{
|
||||
snprintf( str, maxlen, "%s(%04d): ", file, line );
|
||||
|
||||
str[maxlen] = '\0';
|
||||
ssl->f_dbg( ssl->p_dbg, level, str );
|
||||
ssl->f_dbg( ssl->p_dbg, level, " 00" );
|
||||
}
|
||||
|
||||
ssl->f_dbg( ssl->p_dbg, level, "\n" );
|
||||
}
|
||||
|
||||
void debug_print_crt( const ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *text, const x509_cert *crt )
|
||||
{
|
||||
char str[1024], prefix[64];
|
||||
int i = 0, maxlen = sizeof( prefix ) - 1;
|
||||
|
||||
if( ssl->f_dbg == NULL || crt == NULL )
|
||||
return;
|
||||
|
||||
snprintf( prefix, maxlen, "%s(%04d): ", file, line );
|
||||
prefix[maxlen] = '\0';
|
||||
maxlen = sizeof( str ) - 1;
|
||||
|
||||
while( crt != NULL )
|
||||
{
|
||||
char buf[1024];
|
||||
x509parse_cert_info( buf, sizeof( buf ) - 1, prefix, crt );
|
||||
|
||||
snprintf( str, maxlen, "%s(%04d): %s #%d:\n%s",
|
||||
file, line, text, ++i, buf );
|
||||
|
||||
str[maxlen] = '\0';
|
||||
ssl->f_dbg( ssl->p_dbg, level, str );
|
||||
|
||||
debug_print_mpi( ssl, level, file, line,
|
||||
"crt->rsa.N", &crt->rsa.N );
|
||||
|
||||
debug_print_mpi( ssl, level, file, line,
|
||||
"crt->rsa.E", &crt->rsa.E );
|
||||
|
||||
crt = crt->next;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* \file debug.h
|
||||
*
|
||||
* \brief Debug functions
|
||||
*
|
||||
* Copyright (C) 2006-2011, 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_DEBUG_H
|
||||
#define POLARSSL_DEBUG_H
|
||||
|
||||
#include "polarssl/config.h"
|
||||
#include "polarssl/ssl.h"
|
||||
|
||||
#if defined(POLARSSL_DEBUG_C)
|
||||
|
||||
#define SSL_DEBUG_MSG( level, args ) \
|
||||
debug_print_msg( ssl, level, __FILE__, __LINE__, debug_fmt args );
|
||||
|
||||
#define SSL_DEBUG_RET( level, text, ret ) \
|
||||
debug_print_ret( ssl, level, __FILE__, __LINE__, text, ret );
|
||||
|
||||
#define SSL_DEBUG_BUF( level, text, buf, len ) \
|
||||
debug_print_buf( ssl, level, __FILE__, __LINE__, text, buf, len );
|
||||
|
||||
#define SSL_DEBUG_MPI( level, text, X ) \
|
||||
debug_print_mpi( ssl, level, __FILE__, __LINE__, text, X );
|
||||
|
||||
#define SSL_DEBUG_CRT( level, text, crt ) \
|
||||
debug_print_crt( ssl, level, __FILE__, __LINE__, text, crt );
|
||||
|
||||
#else
|
||||
|
||||
#define SSL_DEBUG_MSG( level, args ) do { } while( 0 )
|
||||
#define SSL_DEBUG_RET( level, text, ret ) do { } while( 0 )
|
||||
#define SSL_DEBUG_BUF( level, text, buf, len ) do { } while( 0 )
|
||||
#define SSL_DEBUG_MPI( level, text, X ) do { } while( 0 )
|
||||
#define SSL_DEBUG_CRT( level, text, crt ) do { } while( 0 )
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
char *debug_fmt( const char *format, ... );
|
||||
|
||||
void debug_print_msg( const ssl_context *ssl, int level,
|
||||
const char *file, int line, const char *text );
|
||||
|
||||
void debug_print_ret( const ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *text, int ret );
|
||||
|
||||
void debug_print_buf( const ssl_context *ssl, int level,
|
||||
const char *file, int line, const char *text,
|
||||
unsigned char *buf, size_t len );
|
||||
|
||||
void debug_print_mpi( const ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *text, const mpi *X );
|
||||
|
||||
void debug_print_crt( const ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *text, const x509_cert *crt );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* debug.h */
|
||||
+997
@@ -0,0 +1,997 @@
|
||||
/*
|
||||
* FIPS-46-3 compliant Triple-DES implementation
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
* DES, on which TDES is based, was originally designed by Horst Feistel
|
||||
* at IBM in 1974, and was adopted as a standard by NIST (formerly NBS).
|
||||
*
|
||||
* http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_DES_C)
|
||||
|
||||
#include "polarssl/des.h"
|
||||
|
||||
#if !defined(POLARSSL_DES_ALT)
|
||||
|
||||
/*
|
||||
* 32-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
#ifndef GET_UINT32_BE
|
||||
#define GET_UINT32_BE(n,b,i) \
|
||||
{ \
|
||||
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
|
||||
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
|
||||
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
|
||||
| ( (uint32_t) (b)[(i) + 3] ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PUT_UINT32_BE
|
||||
#define PUT_UINT32_BE(n,b,i) \
|
||||
{ \
|
||||
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Expanded DES S-boxes
|
||||
*/
|
||||
static const uint32_t SB1[64] =
|
||||
{
|
||||
0x01010400, 0x00000000, 0x00010000, 0x01010404,
|
||||
0x01010004, 0x00010404, 0x00000004, 0x00010000,
|
||||
0x00000400, 0x01010400, 0x01010404, 0x00000400,
|
||||
0x01000404, 0x01010004, 0x01000000, 0x00000004,
|
||||
0x00000404, 0x01000400, 0x01000400, 0x00010400,
|
||||
0x00010400, 0x01010000, 0x01010000, 0x01000404,
|
||||
0x00010004, 0x01000004, 0x01000004, 0x00010004,
|
||||
0x00000000, 0x00000404, 0x00010404, 0x01000000,
|
||||
0x00010000, 0x01010404, 0x00000004, 0x01010000,
|
||||
0x01010400, 0x01000000, 0x01000000, 0x00000400,
|
||||
0x01010004, 0x00010000, 0x00010400, 0x01000004,
|
||||
0x00000400, 0x00000004, 0x01000404, 0x00010404,
|
||||
0x01010404, 0x00010004, 0x01010000, 0x01000404,
|
||||
0x01000004, 0x00000404, 0x00010404, 0x01010400,
|
||||
0x00000404, 0x01000400, 0x01000400, 0x00000000,
|
||||
0x00010004, 0x00010400, 0x00000000, 0x01010004
|
||||
};
|
||||
|
||||
static const uint32_t SB2[64] =
|
||||
{
|
||||
0x80108020, 0x80008000, 0x00008000, 0x00108020,
|
||||
0x00100000, 0x00000020, 0x80100020, 0x80008020,
|
||||
0x80000020, 0x80108020, 0x80108000, 0x80000000,
|
||||
0x80008000, 0x00100000, 0x00000020, 0x80100020,
|
||||
0x00108000, 0x00100020, 0x80008020, 0x00000000,
|
||||
0x80000000, 0x00008000, 0x00108020, 0x80100000,
|
||||
0x00100020, 0x80000020, 0x00000000, 0x00108000,
|
||||
0x00008020, 0x80108000, 0x80100000, 0x00008020,
|
||||
0x00000000, 0x00108020, 0x80100020, 0x00100000,
|
||||
0x80008020, 0x80100000, 0x80108000, 0x00008000,
|
||||
0x80100000, 0x80008000, 0x00000020, 0x80108020,
|
||||
0x00108020, 0x00000020, 0x00008000, 0x80000000,
|
||||
0x00008020, 0x80108000, 0x00100000, 0x80000020,
|
||||
0x00100020, 0x80008020, 0x80000020, 0x00100020,
|
||||
0x00108000, 0x00000000, 0x80008000, 0x00008020,
|
||||
0x80000000, 0x80100020, 0x80108020, 0x00108000
|
||||
};
|
||||
|
||||
static const uint32_t SB3[64] =
|
||||
{
|
||||
0x00000208, 0x08020200, 0x00000000, 0x08020008,
|
||||
0x08000200, 0x00000000, 0x00020208, 0x08000200,
|
||||
0x00020008, 0x08000008, 0x08000008, 0x00020000,
|
||||
0x08020208, 0x00020008, 0x08020000, 0x00000208,
|
||||
0x08000000, 0x00000008, 0x08020200, 0x00000200,
|
||||
0x00020200, 0x08020000, 0x08020008, 0x00020208,
|
||||
0x08000208, 0x00020200, 0x00020000, 0x08000208,
|
||||
0x00000008, 0x08020208, 0x00000200, 0x08000000,
|
||||
0x08020200, 0x08000000, 0x00020008, 0x00000208,
|
||||
0x00020000, 0x08020200, 0x08000200, 0x00000000,
|
||||
0x00000200, 0x00020008, 0x08020208, 0x08000200,
|
||||
0x08000008, 0x00000200, 0x00000000, 0x08020008,
|
||||
0x08000208, 0x00020000, 0x08000000, 0x08020208,
|
||||
0x00000008, 0x00020208, 0x00020200, 0x08000008,
|
||||
0x08020000, 0x08000208, 0x00000208, 0x08020000,
|
||||
0x00020208, 0x00000008, 0x08020008, 0x00020200
|
||||
};
|
||||
|
||||
static const uint32_t SB4[64] =
|
||||
{
|
||||
0x00802001, 0x00002081, 0x00002081, 0x00000080,
|
||||
0x00802080, 0x00800081, 0x00800001, 0x00002001,
|
||||
0x00000000, 0x00802000, 0x00802000, 0x00802081,
|
||||
0x00000081, 0x00000000, 0x00800080, 0x00800001,
|
||||
0x00000001, 0x00002000, 0x00800000, 0x00802001,
|
||||
0x00000080, 0x00800000, 0x00002001, 0x00002080,
|
||||
0x00800081, 0x00000001, 0x00002080, 0x00800080,
|
||||
0x00002000, 0x00802080, 0x00802081, 0x00000081,
|
||||
0x00800080, 0x00800001, 0x00802000, 0x00802081,
|
||||
0x00000081, 0x00000000, 0x00000000, 0x00802000,
|
||||
0x00002080, 0x00800080, 0x00800081, 0x00000001,
|
||||
0x00802001, 0x00002081, 0x00002081, 0x00000080,
|
||||
0x00802081, 0x00000081, 0x00000001, 0x00002000,
|
||||
0x00800001, 0x00002001, 0x00802080, 0x00800081,
|
||||
0x00002001, 0x00002080, 0x00800000, 0x00802001,
|
||||
0x00000080, 0x00800000, 0x00002000, 0x00802080
|
||||
};
|
||||
|
||||
static const uint32_t SB5[64] =
|
||||
{
|
||||
0x00000100, 0x02080100, 0x02080000, 0x42000100,
|
||||
0x00080000, 0x00000100, 0x40000000, 0x02080000,
|
||||
0x40080100, 0x00080000, 0x02000100, 0x40080100,
|
||||
0x42000100, 0x42080000, 0x00080100, 0x40000000,
|
||||
0x02000000, 0x40080000, 0x40080000, 0x00000000,
|
||||
0x40000100, 0x42080100, 0x42080100, 0x02000100,
|
||||
0x42080000, 0x40000100, 0x00000000, 0x42000000,
|
||||
0x02080100, 0x02000000, 0x42000000, 0x00080100,
|
||||
0x00080000, 0x42000100, 0x00000100, 0x02000000,
|
||||
0x40000000, 0x02080000, 0x42000100, 0x40080100,
|
||||
0x02000100, 0x40000000, 0x42080000, 0x02080100,
|
||||
0x40080100, 0x00000100, 0x02000000, 0x42080000,
|
||||
0x42080100, 0x00080100, 0x42000000, 0x42080100,
|
||||
0x02080000, 0x00000000, 0x40080000, 0x42000000,
|
||||
0x00080100, 0x02000100, 0x40000100, 0x00080000,
|
||||
0x00000000, 0x40080000, 0x02080100, 0x40000100
|
||||
};
|
||||
|
||||
static const uint32_t SB6[64] =
|
||||
{
|
||||
0x20000010, 0x20400000, 0x00004000, 0x20404010,
|
||||
0x20400000, 0x00000010, 0x20404010, 0x00400000,
|
||||
0x20004000, 0x00404010, 0x00400000, 0x20000010,
|
||||
0x00400010, 0x20004000, 0x20000000, 0x00004010,
|
||||
0x00000000, 0x00400010, 0x20004010, 0x00004000,
|
||||
0x00404000, 0x20004010, 0x00000010, 0x20400010,
|
||||
0x20400010, 0x00000000, 0x00404010, 0x20404000,
|
||||
0x00004010, 0x00404000, 0x20404000, 0x20000000,
|
||||
0x20004000, 0x00000010, 0x20400010, 0x00404000,
|
||||
0x20404010, 0x00400000, 0x00004010, 0x20000010,
|
||||
0x00400000, 0x20004000, 0x20000000, 0x00004010,
|
||||
0x20000010, 0x20404010, 0x00404000, 0x20400000,
|
||||
0x00404010, 0x20404000, 0x00000000, 0x20400010,
|
||||
0x00000010, 0x00004000, 0x20400000, 0x00404010,
|
||||
0x00004000, 0x00400010, 0x20004010, 0x00000000,
|
||||
0x20404000, 0x20000000, 0x00400010, 0x20004010
|
||||
};
|
||||
|
||||
static const uint32_t SB7[64] =
|
||||
{
|
||||
0x00200000, 0x04200002, 0x04000802, 0x00000000,
|
||||
0x00000800, 0x04000802, 0x00200802, 0x04200800,
|
||||
0x04200802, 0x00200000, 0x00000000, 0x04000002,
|
||||
0x00000002, 0x04000000, 0x04200002, 0x00000802,
|
||||
0x04000800, 0x00200802, 0x00200002, 0x04000800,
|
||||
0x04000002, 0x04200000, 0x04200800, 0x00200002,
|
||||
0x04200000, 0x00000800, 0x00000802, 0x04200802,
|
||||
0x00200800, 0x00000002, 0x04000000, 0x00200800,
|
||||
0x04000000, 0x00200800, 0x00200000, 0x04000802,
|
||||
0x04000802, 0x04200002, 0x04200002, 0x00000002,
|
||||
0x00200002, 0x04000000, 0x04000800, 0x00200000,
|
||||
0x04200800, 0x00000802, 0x00200802, 0x04200800,
|
||||
0x00000802, 0x04000002, 0x04200802, 0x04200000,
|
||||
0x00200800, 0x00000000, 0x00000002, 0x04200802,
|
||||
0x00000000, 0x00200802, 0x04200000, 0x00000800,
|
||||
0x04000002, 0x04000800, 0x00000800, 0x00200002
|
||||
};
|
||||
|
||||
static const uint32_t SB8[64] =
|
||||
{
|
||||
0x10001040, 0x00001000, 0x00040000, 0x10041040,
|
||||
0x10000000, 0x10001040, 0x00000040, 0x10000000,
|
||||
0x00040040, 0x10040000, 0x10041040, 0x00041000,
|
||||
0x10041000, 0x00041040, 0x00001000, 0x00000040,
|
||||
0x10040000, 0x10000040, 0x10001000, 0x00001040,
|
||||
0x00041000, 0x00040040, 0x10040040, 0x10041000,
|
||||
0x00001040, 0x00000000, 0x00000000, 0x10040040,
|
||||
0x10000040, 0x10001000, 0x00041040, 0x00040000,
|
||||
0x00041040, 0x00040000, 0x10041000, 0x00001000,
|
||||
0x00000040, 0x10040040, 0x00001000, 0x00041040,
|
||||
0x10001000, 0x00000040, 0x10000040, 0x10040000,
|
||||
0x10040040, 0x10000000, 0x00040000, 0x10001040,
|
||||
0x00000000, 0x10041040, 0x00040040, 0x10000040,
|
||||
0x10040000, 0x10001000, 0x10001040, 0x00000000,
|
||||
0x10041040, 0x00041000, 0x00041000, 0x00001040,
|
||||
0x00001040, 0x00040040, 0x10000000, 0x10041000
|
||||
};
|
||||
|
||||
/*
|
||||
* PC1: left and right halves bit-swap
|
||||
*/
|
||||
static const uint32_t LHs[16] =
|
||||
{
|
||||
0x00000000, 0x00000001, 0x00000100, 0x00000101,
|
||||
0x00010000, 0x00010001, 0x00010100, 0x00010101,
|
||||
0x01000000, 0x01000001, 0x01000100, 0x01000101,
|
||||
0x01010000, 0x01010001, 0x01010100, 0x01010101
|
||||
};
|
||||
|
||||
static const uint32_t RHs[16] =
|
||||
{
|
||||
0x00000000, 0x01000000, 0x00010000, 0x01010000,
|
||||
0x00000100, 0x01000100, 0x00010100, 0x01010100,
|
||||
0x00000001, 0x01000001, 0x00010001, 0x01010001,
|
||||
0x00000101, 0x01000101, 0x00010101, 0x01010101,
|
||||
};
|
||||
|
||||
/*
|
||||
* Initial Permutation macro
|
||||
*/
|
||||
#define DES_IP(X,Y) \
|
||||
{ \
|
||||
T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
|
||||
T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
|
||||
T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
|
||||
T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
|
||||
Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \
|
||||
T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \
|
||||
X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Final Permutation macro
|
||||
*/
|
||||
#define DES_FP(X,Y) \
|
||||
{ \
|
||||
X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \
|
||||
T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \
|
||||
Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \
|
||||
T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
|
||||
T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
|
||||
T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
|
||||
T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
|
||||
}
|
||||
|
||||
/*
|
||||
* DES round macro
|
||||
*/
|
||||
#define DES_ROUND(X,Y) \
|
||||
{ \
|
||||
T = *SK++ ^ X; \
|
||||
Y ^= SB8[ (T ) & 0x3F ] ^ \
|
||||
SB6[ (T >> 8) & 0x3F ] ^ \
|
||||
SB4[ (T >> 16) & 0x3F ] ^ \
|
||||
SB2[ (T >> 24) & 0x3F ]; \
|
||||
\
|
||||
T = *SK++ ^ ((X << 28) | (X >> 4)); \
|
||||
Y ^= SB7[ (T ) & 0x3F ] ^ \
|
||||
SB5[ (T >> 8) & 0x3F ] ^ \
|
||||
SB3[ (T >> 16) & 0x3F ] ^ \
|
||||
SB1[ (T >> 24) & 0x3F ]; \
|
||||
}
|
||||
|
||||
#define SWAP(a,b) { uint32_t t = a; a = b; b = t; t = 0; }
|
||||
|
||||
static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
|
||||
11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44,
|
||||
47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81,
|
||||
82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112,
|
||||
115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140,
|
||||
143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168,
|
||||
171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196,
|
||||
199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224,
|
||||
227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253,
|
||||
254 };
|
||||
|
||||
void des_key_set_parity( unsigned char key[DES_KEY_SIZE] )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < DES_KEY_SIZE; i++ )
|
||||
key[i] = odd_parity_table[key[i] / 2];
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the given key's parity, returns 1 on failure, 0 on SUCCESS
|
||||
*/
|
||||
int des_key_check_key_parity( const unsigned char key[DES_KEY_SIZE] )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < DES_KEY_SIZE; i++ )
|
||||
if ( key[i] != odd_parity_table[key[i] / 2] )
|
||||
return( 1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Table of weak and semi-weak keys
|
||||
*
|
||||
* Source: http://en.wikipedia.org/wiki/Weak_key
|
||||
*
|
||||
* Weak:
|
||||
* Alternating ones + zeros (0x0101010101010101)
|
||||
* Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
|
||||
* '0xE0E0E0E0F1F1F1F1'
|
||||
* '0x1F1F1F1F0E0E0E0E'
|
||||
*
|
||||
* Semi-weak:
|
||||
* 0x011F011F010E010E and 0x1F011F010E010E01
|
||||
* 0x01E001E001F101F1 and 0xE001E001F101F101
|
||||
* 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
|
||||
* 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
|
||||
* 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
|
||||
* 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
|
||||
*
|
||||
*/
|
||||
|
||||
#define WEAK_KEY_COUNT 16
|
||||
|
||||
static const unsigned char weak_key_table[WEAK_KEY_COUNT][DES_KEY_SIZE] =
|
||||
{
|
||||
{ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
|
||||
{ 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
|
||||
{ 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
|
||||
{ 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
|
||||
|
||||
{ 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
|
||||
{ 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
|
||||
{ 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
|
||||
{ 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
|
||||
{ 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
|
||||
{ 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
|
||||
{ 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
|
||||
{ 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
|
||||
{ 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
|
||||
{ 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
|
||||
{ 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
|
||||
{ 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
|
||||
};
|
||||
|
||||
int des_key_check_weak( const unsigned char key[DES_KEY_SIZE] )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < WEAK_KEY_COUNT; i++ )
|
||||
if( memcmp( weak_key_table[i], key, DES_KEY_SIZE) == 0)
|
||||
return( 1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static void des_setkey( uint32_t SK[32], const unsigned char key[DES_KEY_SIZE] )
|
||||
{
|
||||
int i;
|
||||
uint32_t X, Y, T;
|
||||
|
||||
GET_UINT32_BE( X, key, 0 );
|
||||
GET_UINT32_BE( Y, key, 4 );
|
||||
|
||||
/*
|
||||
* Permuted Choice 1
|
||||
*/
|
||||
T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
|
||||
T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
|
||||
|
||||
X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
|
||||
| (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
|
||||
| (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
|
||||
| (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
|
||||
|
||||
Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
|
||||
| (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
|
||||
| (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
|
||||
| (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
|
||||
|
||||
X &= 0x0FFFFFFF;
|
||||
Y &= 0x0FFFFFFF;
|
||||
|
||||
/*
|
||||
* calculate subkeys
|
||||
*/
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
if( i < 2 || i == 8 || i == 15 )
|
||||
{
|
||||
X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
|
||||
Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
|
||||
Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
|
||||
}
|
||||
|
||||
*SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
|
||||
| ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
|
||||
| ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
|
||||
| ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
|
||||
| ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
|
||||
| ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
|
||||
| ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
|
||||
| ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
|
||||
| ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
|
||||
| ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
|
||||
| ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
|
||||
|
||||
*SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
|
||||
| ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
|
||||
| ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
|
||||
| ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
|
||||
| ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
|
||||
| ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
|
||||
| ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
|
||||
| ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
|
||||
| ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
|
||||
| ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
|
||||
| ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* DES key schedule (56-bit, encryption)
|
||||
*/
|
||||
int des_setkey_enc( des_context *ctx, const unsigned char key[DES_KEY_SIZE] )
|
||||
{
|
||||
des_setkey( ctx->sk, key );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* DES key schedule (56-bit, decryption)
|
||||
*/
|
||||
int des_setkey_dec( des_context *ctx, const unsigned char key[DES_KEY_SIZE] )
|
||||
{
|
||||
int i;
|
||||
|
||||
des_setkey( ctx->sk, key );
|
||||
|
||||
for( i = 0; i < 16; i += 2 )
|
||||
{
|
||||
SWAP( ctx->sk[i ], ctx->sk[30 - i] );
|
||||
SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static void des3_set2key( uint32_t esk[96],
|
||||
uint32_t dsk[96],
|
||||
const unsigned char key[DES_KEY_SIZE*2] )
|
||||
{
|
||||
int i;
|
||||
|
||||
des_setkey( esk, key );
|
||||
des_setkey( dsk + 32, key + 8 );
|
||||
|
||||
for( i = 0; i < 32; i += 2 )
|
||||
{
|
||||
dsk[i ] = esk[30 - i];
|
||||
dsk[i + 1] = esk[31 - i];
|
||||
|
||||
esk[i + 32] = dsk[62 - i];
|
||||
esk[i + 33] = dsk[63 - i];
|
||||
|
||||
esk[i + 64] = esk[i ];
|
||||
esk[i + 65] = esk[i + 1];
|
||||
|
||||
dsk[i + 64] = dsk[i ];
|
||||
dsk[i + 65] = dsk[i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Triple-DES key schedule (112-bit, encryption)
|
||||
*/
|
||||
int des3_set2key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 2] )
|
||||
{
|
||||
uint32_t sk[96];
|
||||
|
||||
des3_set2key( ctx->sk, sk, key );
|
||||
memset( sk, 0, sizeof( sk ) );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Triple-DES key schedule (112-bit, decryption)
|
||||
*/
|
||||
int des3_set2key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 2] )
|
||||
{
|
||||
uint32_t sk[96];
|
||||
|
||||
des3_set2key( sk, ctx->sk, key );
|
||||
memset( sk, 0, sizeof( sk ) );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static void des3_set3key( uint32_t esk[96],
|
||||
uint32_t dsk[96],
|
||||
const unsigned char key[24] )
|
||||
{
|
||||
int i;
|
||||
|
||||
des_setkey( esk, key );
|
||||
des_setkey( dsk + 32, key + 8 );
|
||||
des_setkey( esk + 64, key + 16 );
|
||||
|
||||
for( i = 0; i < 32; i += 2 )
|
||||
{
|
||||
dsk[i ] = esk[94 - i];
|
||||
dsk[i + 1] = esk[95 - i];
|
||||
|
||||
esk[i + 32] = dsk[62 - i];
|
||||
esk[i + 33] = dsk[63 - i];
|
||||
|
||||
dsk[i + 64] = esk[30 - i];
|
||||
dsk[i + 65] = esk[31 - i];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Triple-DES key schedule (168-bit, encryption)
|
||||
*/
|
||||
int des3_set3key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 3] )
|
||||
{
|
||||
uint32_t sk[96];
|
||||
|
||||
des3_set3key( ctx->sk, sk, key );
|
||||
memset( sk, 0, sizeof( sk ) );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Triple-DES key schedule (168-bit, decryption)
|
||||
*/
|
||||
int des3_set3key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 3] )
|
||||
{
|
||||
uint32_t sk[96];
|
||||
|
||||
des3_set3key( sk, ctx->sk, key );
|
||||
memset( sk, 0, sizeof( sk ) );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* DES-ECB block encryption/decryption
|
||||
*/
|
||||
int des_crypt_ecb( des_context *ctx,
|
||||
const unsigned char input[8],
|
||||
unsigned char output[8] )
|
||||
{
|
||||
int i;
|
||||
uint32_t X, Y, T, *SK;
|
||||
|
||||
SK = ctx->sk;
|
||||
|
||||
GET_UINT32_BE( X, input, 0 );
|
||||
GET_UINT32_BE( Y, input, 4 );
|
||||
|
||||
DES_IP( X, Y );
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
DES_ROUND( Y, X );
|
||||
DES_ROUND( X, Y );
|
||||
}
|
||||
|
||||
DES_FP( Y, X );
|
||||
|
||||
PUT_UINT32_BE( Y, output, 0 );
|
||||
PUT_UINT32_BE( X, output, 4 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* DES-CBC buffer encryption/decryption
|
||||
*/
|
||||
int des_crypt_cbc( des_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[8],
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
int i;
|
||||
unsigned char temp[8];
|
||||
|
||||
if( length % 8 )
|
||||
return( POLARSSL_ERR_DES_INVALID_INPUT_LENGTH );
|
||||
|
||||
if( mode == DES_ENCRYPT )
|
||||
{
|
||||
while( length > 0 )
|
||||
{
|
||||
for( i = 0; i < 8; i++ )
|
||||
output[i] = (unsigned char)( input[i] ^ iv[i] );
|
||||
|
||||
des_crypt_ecb( ctx, output, output );
|
||||
memcpy( iv, output, 8 );
|
||||
|
||||
input += 8;
|
||||
output += 8;
|
||||
length -= 8;
|
||||
}
|
||||
}
|
||||
else /* DES_DECRYPT */
|
||||
{
|
||||
while( length > 0 )
|
||||
{
|
||||
memcpy( temp, input, 8 );
|
||||
des_crypt_ecb( ctx, input, output );
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
output[i] = (unsigned char)( output[i] ^ iv[i] );
|
||||
|
||||
memcpy( iv, temp, 8 );
|
||||
|
||||
input += 8;
|
||||
output += 8;
|
||||
length -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* 3DES-ECB block encryption/decryption
|
||||
*/
|
||||
int des3_crypt_ecb( des3_context *ctx,
|
||||
const unsigned char input[8],
|
||||
unsigned char output[8] )
|
||||
{
|
||||
int i;
|
||||
uint32_t X, Y, T, *SK;
|
||||
|
||||
SK = ctx->sk;
|
||||
|
||||
GET_UINT32_BE( X, input, 0 );
|
||||
GET_UINT32_BE( Y, input, 4 );
|
||||
|
||||
DES_IP( X, Y );
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
DES_ROUND( Y, X );
|
||||
DES_ROUND( X, Y );
|
||||
}
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
DES_ROUND( X, Y );
|
||||
DES_ROUND( Y, X );
|
||||
}
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
DES_ROUND( Y, X );
|
||||
DES_ROUND( X, Y );
|
||||
}
|
||||
|
||||
DES_FP( Y, X );
|
||||
|
||||
PUT_UINT32_BE( Y, output, 0 );
|
||||
PUT_UINT32_BE( X, output, 4 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* 3DES-CBC buffer encryption/decryption
|
||||
*/
|
||||
int des3_crypt_cbc( des3_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[8],
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
int i;
|
||||
unsigned char temp[8];
|
||||
|
||||
if( length % 8 )
|
||||
return( POLARSSL_ERR_DES_INVALID_INPUT_LENGTH );
|
||||
|
||||
if( mode == DES_ENCRYPT )
|
||||
{
|
||||
while( length > 0 )
|
||||
{
|
||||
for( i = 0; i < 8; i++ )
|
||||
output[i] = (unsigned char)( input[i] ^ iv[i] );
|
||||
|
||||
des3_crypt_ecb( ctx, output, output );
|
||||
memcpy( iv, output, 8 );
|
||||
|
||||
input += 8;
|
||||
output += 8;
|
||||
length -= 8;
|
||||
}
|
||||
}
|
||||
else /* DES_DECRYPT */
|
||||
{
|
||||
while( length > 0 )
|
||||
{
|
||||
memcpy( temp, input, 8 );
|
||||
des3_crypt_ecb( ctx, input, output );
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
output[i] = (unsigned char)( output[i] ^ iv[i] );
|
||||
|
||||
memcpy( iv, temp, 8 );
|
||||
|
||||
input += 8;
|
||||
output += 8;
|
||||
length -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif /* !POLARSSL_DES_ALT */
|
||||
|
||||
#if defined(POLARSSL_SELF_TEST)
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* DES and 3DES test vectors from:
|
||||
*
|
||||
* http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
|
||||
*/
|
||||
static const unsigned char des3_test_keys[24] =
|
||||
{
|
||||
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
|
||||
0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
|
||||
0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
|
||||
};
|
||||
|
||||
static const unsigned char des3_test_iv[8] =
|
||||
{
|
||||
0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
|
||||
};
|
||||
|
||||
static const unsigned char des3_test_buf[8] =
|
||||
{
|
||||
0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
|
||||
};
|
||||
|
||||
static const unsigned char des3_test_ecb_dec[3][8] =
|
||||
{
|
||||
{ 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D },
|
||||
{ 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB },
|
||||
{ 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A }
|
||||
};
|
||||
|
||||
static const unsigned char des3_test_ecb_enc[3][8] =
|
||||
{
|
||||
{ 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B },
|
||||
{ 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 },
|
||||
{ 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 }
|
||||
};
|
||||
|
||||
static const unsigned char des3_test_cbc_dec[3][8] =
|
||||
{
|
||||
{ 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 },
|
||||
{ 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 },
|
||||
{ 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C }
|
||||
};
|
||||
|
||||
static const unsigned char des3_test_cbc_enc[3][8] =
|
||||
{
|
||||
{ 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 },
|
||||
{ 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D },
|
||||
{ 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 }
|
||||
};
|
||||
|
||||
/*
|
||||
* Checkup routine
|
||||
*/
|
||||
int des_self_test( int verbose )
|
||||
{
|
||||
int i, j, u, v;
|
||||
des_context ctx;
|
||||
des3_context ctx3;
|
||||
unsigned char key[24];
|
||||
unsigned char buf[8];
|
||||
unsigned char prv[8];
|
||||
unsigned char iv[8];
|
||||
|
||||
memset( key, 0, 24 );
|
||||
|
||||
/*
|
||||
* ECB mode
|
||||
*/
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
u = i >> 1;
|
||||
v = i & 1;
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( " DES%c-ECB-%3d (%s): ",
|
||||
( u == 0 ) ? ' ' : '3', 56 + u * 56,
|
||||
( v == DES_DECRYPT ) ? "dec" : "enc" );
|
||||
|
||||
memcpy( buf, des3_test_buf, 8 );
|
||||
|
||||
switch( i )
|
||||
{
|
||||
case 0:
|
||||
des_setkey_dec( &ctx, des3_test_keys );
|
||||
break;
|
||||
|
||||
case 1:
|
||||
des_setkey_enc( &ctx, des3_test_keys );
|
||||
break;
|
||||
|
||||
case 2:
|
||||
des3_set2key_dec( &ctx3, des3_test_keys );
|
||||
break;
|
||||
|
||||
case 3:
|
||||
des3_set2key_enc( &ctx3, des3_test_keys );
|
||||
break;
|
||||
|
||||
case 4:
|
||||
des3_set3key_dec( &ctx3, des3_test_keys );
|
||||
break;
|
||||
|
||||
case 5:
|
||||
des3_set3key_enc( &ctx3, des3_test_keys );
|
||||
break;
|
||||
|
||||
default:
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
for( j = 0; j < 10000; j++ )
|
||||
{
|
||||
if( u == 0 )
|
||||
des_crypt_ecb( &ctx, buf, buf );
|
||||
else
|
||||
des3_crypt_ecb( &ctx3, buf, buf );
|
||||
}
|
||||
|
||||
if( ( v == DES_DECRYPT &&
|
||||
memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
|
||||
( v != DES_DECRYPT &&
|
||||
memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "passed\n" );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "\n" );
|
||||
|
||||
/*
|
||||
* CBC mode
|
||||
*/
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
u = i >> 1;
|
||||
v = i & 1;
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( " DES%c-CBC-%3d (%s): ",
|
||||
( u == 0 ) ? ' ' : '3', 56 + u * 56,
|
||||
( v == DES_DECRYPT ) ? "dec" : "enc" );
|
||||
|
||||
memcpy( iv, des3_test_iv, 8 );
|
||||
memcpy( prv, des3_test_iv, 8 );
|
||||
memcpy( buf, des3_test_buf, 8 );
|
||||
|
||||
switch( i )
|
||||
{
|
||||
case 0:
|
||||
des_setkey_dec( &ctx, des3_test_keys );
|
||||
break;
|
||||
|
||||
case 1:
|
||||
des_setkey_enc( &ctx, des3_test_keys );
|
||||
break;
|
||||
|
||||
case 2:
|
||||
des3_set2key_dec( &ctx3, des3_test_keys );
|
||||
break;
|
||||
|
||||
case 3:
|
||||
des3_set2key_enc( &ctx3, des3_test_keys );
|
||||
break;
|
||||
|
||||
case 4:
|
||||
des3_set3key_dec( &ctx3, des3_test_keys );
|
||||
break;
|
||||
|
||||
case 5:
|
||||
des3_set3key_enc( &ctx3, des3_test_keys );
|
||||
break;
|
||||
|
||||
default:
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( v == DES_DECRYPT )
|
||||
{
|
||||
for( j = 0; j < 10000; j++ )
|
||||
{
|
||||
if( u == 0 )
|
||||
des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
|
||||
else
|
||||
des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( j = 0; j < 10000; j++ )
|
||||
{
|
||||
unsigned char tmp[8];
|
||||
|
||||
if( u == 0 )
|
||||
des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
|
||||
else
|
||||
des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
|
||||
|
||||
memcpy( tmp, prv, 8 );
|
||||
memcpy( prv, buf, 8 );
|
||||
memcpy( buf, tmp, 8 );
|
||||
}
|
||||
|
||||
memcpy( buf, prv, 8 );
|
||||
}
|
||||
|
||||
if( ( v == DES_DECRYPT &&
|
||||
memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) ||
|
||||
( v != DES_DECRYPT &&
|
||||
memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "passed\n" );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "\n" );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+252
@@ -0,0 +1,252 @@
|
||||
/**
|
||||
* \file des.h
|
||||
*
|
||||
* \brief DES block cipher
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef POLARSSL_DES_H
|
||||
#define POLARSSL_DES_H
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <basetsd.h>
|
||||
typedef UINT32 uint32_t;
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#define DES_ENCRYPT 1
|
||||
#define DES_DECRYPT 0
|
||||
|
||||
#define POLARSSL_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */
|
||||
|
||||
#define DES_KEY_SIZE 8
|
||||
|
||||
#if !defined(POLARSSL_DES_ALT)
|
||||
// Regular implementation
|
||||
//
|
||||
|
||||
/**
|
||||
* \brief DES context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int mode; /*!< encrypt/decrypt */
|
||||
uint32_t sk[32]; /*!< DES subkeys */
|
||||
}
|
||||
des_context;
|
||||
|
||||
/**
|
||||
* \brief Triple-DES context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int mode; /*!< encrypt/decrypt */
|
||||
uint32_t sk[96]; /*!< 3DES subkeys */
|
||||
}
|
||||
des3_context;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Set key parity on the given key to odd.
|
||||
*
|
||||
* DES keys are 56 bits long, but each byte is padded with
|
||||
* a parity bit to allow verification.
|
||||
*
|
||||
* \param key 8-byte secret key
|
||||
*/
|
||||
void des_key_set_parity( unsigned char key[DES_KEY_SIZE] );
|
||||
|
||||
/**
|
||||
* \brief Check that key parity on the given key is odd.
|
||||
*
|
||||
* DES keys are 56 bits long, but each byte is padded with
|
||||
* a parity bit to allow verification.
|
||||
*
|
||||
* \param key 8-byte secret key
|
||||
*
|
||||
* \return 0 is parity was ok, 1 if parity was not correct.
|
||||
*/
|
||||
int des_key_check_key_parity( const unsigned char key[DES_KEY_SIZE] );
|
||||
|
||||
/**
|
||||
* \brief Check that key is not a weak or semi-weak DES key
|
||||
*
|
||||
* \param key 8-byte secret key
|
||||
*
|
||||
* \return 0 if no weak key was found, 1 if a weak key was identified.
|
||||
*/
|
||||
int des_key_check_weak( const unsigned char key[DES_KEY_SIZE] );
|
||||
|
||||
/**
|
||||
* \brief DES key schedule (56-bit, encryption)
|
||||
*
|
||||
* \param ctx DES context to be initialized
|
||||
* \param key 8-byte secret key
|
||||
*
|
||||
* \return 0
|
||||
*/
|
||||
int des_setkey_enc( des_context *ctx, const unsigned char key[DES_KEY_SIZE] );
|
||||
|
||||
/**
|
||||
* \brief DES key schedule (56-bit, decryption)
|
||||
*
|
||||
* \param ctx DES context to be initialized
|
||||
* \param key 8-byte secret key
|
||||
*
|
||||
* \return 0
|
||||
*/
|
||||
int des_setkey_dec( des_context *ctx, const unsigned char key[DES_KEY_SIZE] );
|
||||
|
||||
/**
|
||||
* \brief Triple-DES key schedule (112-bit, encryption)
|
||||
*
|
||||
* \param ctx 3DES context to be initialized
|
||||
* \param key 16-byte secret key
|
||||
*
|
||||
* \return 0
|
||||
*/
|
||||
int des3_set2key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 2] );
|
||||
|
||||
/**
|
||||
* \brief Triple-DES key schedule (112-bit, decryption)
|
||||
*
|
||||
* \param ctx 3DES context to be initialized
|
||||
* \param key 16-byte secret key
|
||||
*
|
||||
* \return 0
|
||||
*/
|
||||
int des3_set2key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 2] );
|
||||
|
||||
/**
|
||||
* \brief Triple-DES key schedule (168-bit, encryption)
|
||||
*
|
||||
* \param ctx 3DES context to be initialized
|
||||
* \param key 24-byte secret key
|
||||
*
|
||||
* \return 0
|
||||
*/
|
||||
int des3_set3key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 3] );
|
||||
|
||||
/**
|
||||
* \brief Triple-DES key schedule (168-bit, decryption)
|
||||
*
|
||||
* \param ctx 3DES context to be initialized
|
||||
* \param key 24-byte secret key
|
||||
*
|
||||
* \return 0
|
||||
*/
|
||||
int des3_set3key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 3] );
|
||||
|
||||
/**
|
||||
* \brief DES-ECB block encryption/decryption
|
||||
*
|
||||
* \param ctx DES context
|
||||
* \param input 64-bit input block
|
||||
* \param output 64-bit output block
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int des_crypt_ecb( des_context *ctx,
|
||||
const unsigned char input[8],
|
||||
unsigned char output[8] );
|
||||
|
||||
/**
|
||||
* \brief DES-CBC buffer encryption/decryption
|
||||
*
|
||||
* \param ctx DES context
|
||||
* \param mode DES_ENCRYPT or DES_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*/
|
||||
int des_crypt_cbc( des_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[8],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief 3DES-ECB block encryption/decryption
|
||||
*
|
||||
* \param ctx 3DES context
|
||||
* \param input 64-bit input block
|
||||
* \param output 64-bit output block
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int des3_crypt_ecb( des3_context *ctx,
|
||||
const unsigned char input[8],
|
||||
unsigned char output[8] );
|
||||
|
||||
/**
|
||||
* \brief 3DES-CBC buffer encryption/decryption
|
||||
*
|
||||
* \param ctx 3DES context
|
||||
* \param mode DES_ENCRYPT or DES_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_DES_INVALID_INPUT_LENGTH
|
||||
*/
|
||||
int des3_crypt_cbc( des3_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[8],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* POLARSSL_DES_ALT */
|
||||
#include "polarssl/des_alt.h"
|
||||
#endif /* POLARSSL_DES_ALT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int des_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* des.h */
|
||||
+302
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
* Diffie-Hellman-Merkle key exchange
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Reference:
|
||||
*
|
||||
* http://www.cacr.math.uwaterloo.ca/hac/ (chapter 12)
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_DHM_C)
|
||||
|
||||
#include "polarssl/dhm.h"
|
||||
|
||||
/*
|
||||
* helper to validate the mpi size and import it
|
||||
*/
|
||||
static int dhm_read_bignum( mpi *X,
|
||||
unsigned char **p,
|
||||
const unsigned char *end )
|
||||
{
|
||||
int ret, n;
|
||||
|
||||
if( end - *p < 2 )
|
||||
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
|
||||
|
||||
n = ( (*p)[0] << 8 ) | (*p)[1];
|
||||
(*p) += 2;
|
||||
|
||||
if( (int)( end - *p ) < n )
|
||||
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
|
||||
|
||||
if( ( ret = mpi_read_binary( X, *p, n ) ) != 0 )
|
||||
return( POLARSSL_ERR_DHM_READ_PARAMS_FAILED + ret );
|
||||
|
||||
(*p) += n;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify sanity of parameter with regards to P
|
||||
*
|
||||
* Parameter should be: 2 <= public_param <= P - 2
|
||||
*
|
||||
* For more information on the attack, see:
|
||||
* http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
|
||||
* http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
|
||||
*/
|
||||
static int dhm_check_range( const mpi *param, const mpi *P )
|
||||
{
|
||||
mpi L, U;
|
||||
int ret = POLARSSL_ERR_DHM_BAD_INPUT_DATA;
|
||||
|
||||
mpi_init( &L ); mpi_init( &U );
|
||||
mpi_lset( &L, 2 );
|
||||
mpi_sub_int( &U, P, 2 );
|
||||
|
||||
if( mpi_cmp_mpi( param, &L ) >= 0 &&
|
||||
mpi_cmp_mpi( param, &U ) <= 0 )
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
mpi_free( &L ); mpi_free( &U );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the ServerKeyExchange parameters
|
||||
*/
|
||||
int dhm_read_params( dhm_context *ctx,
|
||||
unsigned char **p,
|
||||
const unsigned char *end )
|
||||
{
|
||||
int ret;
|
||||
|
||||
memset( ctx, 0, sizeof( dhm_context ) );
|
||||
|
||||
if( ( ret = dhm_read_bignum( &ctx->P, p, end ) ) != 0 ||
|
||||
( ret = dhm_read_bignum( &ctx->G, p, end ) ) != 0 ||
|
||||
( ret = dhm_read_bignum( &ctx->GY, p, end ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
ctx->len = mpi_size( &ctx->P );
|
||||
|
||||
if( end - *p < 2 )
|
||||
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup and write the ServerKeyExchange parameters
|
||||
*/
|
||||
int dhm_make_params( dhm_context *ctx, int x_size,
|
||||
unsigned char *output, size_t *olen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
int ret, count = 0;
|
||||
size_t n1, n2, n3;
|
||||
unsigned char *p;
|
||||
|
||||
if( mpi_cmp_int( &ctx->P, 0 ) == 0 )
|
||||
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
|
||||
|
||||
/*
|
||||
* Generate X as large as possible ( < P )
|
||||
*/
|
||||
do
|
||||
{
|
||||
mpi_fill_random( &ctx->X, x_size, f_rng, p_rng );
|
||||
|
||||
while( mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
|
||||
mpi_shift_r( &ctx->X, 1 );
|
||||
|
||||
if( count++ > 10 )
|
||||
return( POLARSSL_ERR_DHM_MAKE_PARAMS_FAILED );
|
||||
}
|
||||
while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
|
||||
|
||||
/*
|
||||
* Calculate GX = G^X mod P
|
||||
*/
|
||||
MPI_CHK( mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
|
||||
&ctx->P , &ctx->RP ) );
|
||||
|
||||
if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
/*
|
||||
* export P, G, GX
|
||||
*/
|
||||
#define DHM_MPI_EXPORT(X,n) \
|
||||
MPI_CHK( mpi_write_binary( X, p + 2, n ) ); \
|
||||
*p++ = (unsigned char)( n >> 8 ); \
|
||||
*p++ = (unsigned char)( n ); p += n;
|
||||
|
||||
n1 = mpi_size( &ctx->P );
|
||||
n2 = mpi_size( &ctx->G );
|
||||
n3 = mpi_size( &ctx->GX );
|
||||
|
||||
p = output;
|
||||
DHM_MPI_EXPORT( &ctx->P , n1 );
|
||||
DHM_MPI_EXPORT( &ctx->G , n2 );
|
||||
DHM_MPI_EXPORT( &ctx->GX, n3 );
|
||||
|
||||
*olen = p - output;
|
||||
|
||||
ctx->len = n1;
|
||||
|
||||
cleanup:
|
||||
|
||||
if( ret != 0 )
|
||||
return( POLARSSL_ERR_DHM_MAKE_PARAMS_FAILED + ret );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Import the peer's public value G^Y
|
||||
*/
|
||||
int dhm_read_public( dhm_context *ctx,
|
||||
const unsigned char *input, size_t ilen )
|
||||
{
|
||||
int ret;
|
||||
|
||||
if( ctx == NULL || ilen < 1 || ilen > ctx->len )
|
||||
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
|
||||
|
||||
if( ( ret = mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
|
||||
return( POLARSSL_ERR_DHM_READ_PUBLIC_FAILED + ret );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Create own private value X and export G^X
|
||||
*/
|
||||
int dhm_make_public( dhm_context *ctx, int x_size,
|
||||
unsigned char *output, size_t olen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
int ret, count = 0;
|
||||
|
||||
if( ctx == NULL || olen < 1 || olen > ctx->len )
|
||||
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
|
||||
|
||||
if( mpi_cmp_int( &ctx->P, 0 ) == 0 )
|
||||
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
|
||||
|
||||
/*
|
||||
* generate X and calculate GX = G^X mod P
|
||||
*/
|
||||
do
|
||||
{
|
||||
mpi_fill_random( &ctx->X, x_size, f_rng, p_rng );
|
||||
|
||||
while( mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
|
||||
mpi_shift_r( &ctx->X, 1 );
|
||||
|
||||
if( count++ > 10 )
|
||||
return( POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED );
|
||||
}
|
||||
while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
|
||||
|
||||
MPI_CHK( mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
|
||||
&ctx->P , &ctx->RP ) );
|
||||
|
||||
if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
MPI_CHK( mpi_write_binary( &ctx->GX, output, olen ) );
|
||||
|
||||
cleanup:
|
||||
|
||||
if( ret != 0 )
|
||||
return( POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED + ret );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Derive and export the shared secret (G^Y)^X mod P
|
||||
*/
|
||||
int dhm_calc_secret( dhm_context *ctx,
|
||||
unsigned char *output, size_t *olen )
|
||||
{
|
||||
int ret;
|
||||
|
||||
if( ctx == NULL || *olen < ctx->len )
|
||||
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
|
||||
|
||||
MPI_CHK( mpi_exp_mod( &ctx->K, &ctx->GY, &ctx->X,
|
||||
&ctx->P, &ctx->RP ) );
|
||||
|
||||
if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
*olen = mpi_size( &ctx->K );
|
||||
|
||||
MPI_CHK( mpi_write_binary( &ctx->K, output, *olen ) );
|
||||
|
||||
cleanup:
|
||||
|
||||
if( ret != 0 )
|
||||
return( POLARSSL_ERR_DHM_CALC_SECRET_FAILED + ret );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the components of a DHM key
|
||||
*/
|
||||
void dhm_free( dhm_context *ctx )
|
||||
{
|
||||
mpi_free( &ctx->RP ); mpi_free( &ctx->K ); mpi_free( &ctx->GY );
|
||||
mpi_free( &ctx->GX ); mpi_free( &ctx->X ); mpi_free( &ctx->G );
|
||||
mpi_free( &ctx->P );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_SELF_TEST)
|
||||
|
||||
/*
|
||||
* Checkup routine
|
||||
*/
|
||||
int dhm_self_test( int verbose )
|
||||
{
|
||||
return( verbose++ );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+244
@@ -0,0 +1,244 @@
|
||||
/**
|
||||
* \file dhm.h
|
||||
*
|
||||
* \brief Diffie-Hellman-Merkle key exchange
|
||||
*
|
||||
* 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_DHM_H
|
||||
#define POLARSSL_DHM_H
|
||||
|
||||
#include "polarssl/bignum.h"
|
||||
|
||||
/*
|
||||
* DHM Error codes
|
||||
*/
|
||||
#define POLARSSL_ERR_DHM_BAD_INPUT_DATA -0x3080 /**< Bad input parameters to function. */
|
||||
#define POLARSSL_ERR_DHM_READ_PARAMS_FAILED -0x3100 /**< Reading of the DHM parameters failed. */
|
||||
#define POLARSSL_ERR_DHM_MAKE_PARAMS_FAILED -0x3180 /**< Making of the DHM parameters failed. */
|
||||
#define POLARSSL_ERR_DHM_READ_PUBLIC_FAILED -0x3200 /**< Reading of the public values failed. */
|
||||
#define POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED -0x3280 /**< Making of the public value failed. */
|
||||
#define POLARSSL_ERR_DHM_CALC_SECRET_FAILED -0x3300 /**< Calculation of the DHM secret failed. */
|
||||
|
||||
/**
|
||||
* RFC 3526 defines a number of standardized Diffie-Hellman groups
|
||||
* for IKE.
|
||||
* RFC 5114 defines a number of standardized Diffie-Hellman groups
|
||||
* that can be used.
|
||||
*
|
||||
* Some are included here for convenience.
|
||||
*
|
||||
* Included are:
|
||||
* RFC 3526 3. 2048-bit MODP Group
|
||||
* RFC 3526 4. 3072-bit MODP Group
|
||||
* RFC 5114 2.1. 1024-bit MODP Group with 160-bit Prime Order Subgroup
|
||||
* RFC 5114 2.2. 2048-bit MODP Group with 224-bit Prime Order Subgroup
|
||||
*/
|
||||
#define POLARSSL_DHM_RFC3526_MODP_2048_P \
|
||||
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
|
||||
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
|
||||
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \
|
||||
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
|
||||
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \
|
||||
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \
|
||||
"83655D23DCA3AD961C62F356208552BB9ED529077096966D" \
|
||||
"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \
|
||||
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \
|
||||
"DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \
|
||||
"15728E5A8AACAA68FFFFFFFFFFFFFFFF"
|
||||
|
||||
#define POLARSSL_DHM_RFC3526_MODP_2048_G "02"
|
||||
|
||||
#define POLARSSL_DHM_RFC3526_MODP_3072_P \
|
||||
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
|
||||
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
|
||||
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \
|
||||
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
|
||||
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \
|
||||
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \
|
||||
"83655D23DCA3AD961C62F356208552BB9ED529077096966D" \
|
||||
"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \
|
||||
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \
|
||||
"DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \
|
||||
"15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" \
|
||||
"ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" \
|
||||
"ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" \
|
||||
"F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" \
|
||||
"BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" \
|
||||
"43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF"
|
||||
|
||||
#define POLARSSL_DHM_RFC3526_MODP_3072_G "02"
|
||||
|
||||
#define POLARSSL_DHM_RFC5114_MODP_1024_P \
|
||||
"B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C6" \
|
||||
"9A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C0" \
|
||||
"13ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD70" \
|
||||
"98488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0" \
|
||||
"A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708" \
|
||||
"DF1FB2BC2E4A4371"
|
||||
|
||||
#define POLARSSL_DHM_RFC5114_MODP_1024_G \
|
||||
"A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507F" \
|
||||
"D6406CFF14266D31266FEA1E5C41564B777E690F5504F213" \
|
||||
"160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1" \
|
||||
"909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28A" \
|
||||
"D662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24" \
|
||||
"855E6EEB22B3B2E5"
|
||||
|
||||
#define POLARSSL_DHM_RFC5114_MODP_2048_P \
|
||||
"AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1" \
|
||||
"B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15" \
|
||||
"EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC212" \
|
||||
"9037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207" \
|
||||
"C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708" \
|
||||
"B3BF8A317091883681286130BC8985DB1602E714415D9330" \
|
||||
"278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486D" \
|
||||
"CDF93ACC44328387315D75E198C641A480CD86A1B9E587E8" \
|
||||
"BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763" \
|
||||
"C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71" \
|
||||
"CF9DE5384E71B81C0AC4DFFE0C10E64F"
|
||||
|
||||
#define POLARSSL_DHM_RFC5114_MODP_2048_G \
|
||||
"AC4032EF4F2D9AE39DF30B5C8FFDAC506CDEBE7B89998CAF"\
|
||||
"74866A08CFE4FFE3A6824A4E10B9A6F0DD921F01A70C4AFA"\
|
||||
"AB739D7700C29F52C57DB17C620A8652BE5E9001A8D66AD7"\
|
||||
"C17669101999024AF4D027275AC1348BB8A762D0521BC98A"\
|
||||
"E247150422EA1ED409939D54DA7460CDB5F6C6B250717CBE"\
|
||||
"F180EB34118E98D119529A45D6F834566E3025E316A330EF"\
|
||||
"BB77A86F0C1AB15B051AE3D428C8F8ACB70A8137150B8EEB"\
|
||||
"10E183EDD19963DDD9E263E4770589EF6AA21E7F5F2FF381"\
|
||||
"B539CCE3409D13CD566AFBB48D6C019181E1BCFE94B30269"\
|
||||
"EDFE72FE9B6AA4BD7B5A0F1C71CFFF4C19C418E1F6EC0179"\
|
||||
"81BC087F2A7065B384B890D3191F2BFA"
|
||||
|
||||
/**
|
||||
* \brief DHM context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
size_t len; /*!< size(P) in chars */
|
||||
mpi P; /*!< prime modulus */
|
||||
mpi G; /*!< generator */
|
||||
mpi X; /*!< secret value */
|
||||
mpi GX; /*!< self = G^X mod P */
|
||||
mpi GY; /*!< peer = G^Y mod P */
|
||||
mpi K; /*!< key = GY^X mod P */
|
||||
mpi RP; /*!< cached R^2 mod P */
|
||||
}
|
||||
dhm_context;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Parse the ServerKeyExchange parameters
|
||||
*
|
||||
* \param ctx DHM context
|
||||
* \param p &(start of input buffer)
|
||||
* \param end end of buffer
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code
|
||||
*/
|
||||
int dhm_read_params( dhm_context *ctx,
|
||||
unsigned char **p,
|
||||
const unsigned char *end );
|
||||
|
||||
/**
|
||||
* \brief Setup and write the ServerKeyExchange parameters
|
||||
*
|
||||
* \param ctx DHM context
|
||||
* \param x_size private value size in bytes
|
||||
* \param output destination buffer
|
||||
* \param olen number of chars written
|
||||
* \param f_rng RNG function
|
||||
* \param p_rng RNG parameter
|
||||
*
|
||||
* \note This function assumes that ctx->P and ctx->G
|
||||
* have already been properly set (for example
|
||||
* using mpi_read_string or mpi_read_binary).
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code
|
||||
*/
|
||||
int dhm_make_params( dhm_context *ctx, int x_size,
|
||||
unsigned char *output, size_t *olen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng );
|
||||
|
||||
/**
|
||||
* \brief Import the peer's public value G^Y
|
||||
*
|
||||
* \param ctx DHM context
|
||||
* \param input input buffer
|
||||
* \param ilen size of buffer
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code
|
||||
*/
|
||||
int dhm_read_public( dhm_context *ctx,
|
||||
const unsigned char *input, size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief Create own private value X and export G^X
|
||||
*
|
||||
* \param ctx DHM context
|
||||
* \param x_size private value size in bytes
|
||||
* \param output destination buffer
|
||||
* \param olen must be equal to ctx->P.len
|
||||
* \param f_rng RNG function
|
||||
* \param p_rng RNG parameter
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code
|
||||
*/
|
||||
int dhm_make_public( dhm_context *ctx, int x_size,
|
||||
unsigned char *output, size_t olen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng );
|
||||
|
||||
/**
|
||||
* \brief Derive and export the shared secret (G^Y)^X mod P
|
||||
*
|
||||
* \param ctx DHM context
|
||||
* \param output destination buffer
|
||||
* \param olen number of chars written
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code
|
||||
*/
|
||||
int dhm_calc_secret( dhm_context *ctx,
|
||||
unsigned char *output, size_t *olen );
|
||||
|
||||
/**
|
||||
* \brief Free the components of a DHM key
|
||||
*/
|
||||
void dhm_free( dhm_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int dhm_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Entropy accumulator implementation
|
||||
*
|
||||
* Copyright (C) 2006-2011, 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.
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_ENTROPY_C)
|
||||
|
||||
#include "polarssl/entropy.h"
|
||||
#include "polarssl/entropy_poll.h"
|
||||
|
||||
#if defined(POLARSSL_HAVEGE_C)
|
||||
#include "polarssl/havege.h"
|
||||
#endif
|
||||
|
||||
#define ENTROPY_MAX_LOOP 256 /**< Maximum amount to loop before error */
|
||||
|
||||
void entropy_init( entropy_context *ctx )
|
||||
{
|
||||
memset( ctx, 0, sizeof(entropy_context) );
|
||||
|
||||
sha4_starts( &ctx->accumulator, 0 );
|
||||
#if defined(POLARSSL_HAVEGE_C)
|
||||
havege_init( &ctx->havege_data );
|
||||
#endif
|
||||
|
||||
#if !defined(POLARSSL_NO_DEFAULT_ENTROPY_SOURCES)
|
||||
#if !defined(POLARSSL_NO_PLATFORM_ENTROPY)
|
||||
entropy_add_source( ctx, platform_entropy_poll, NULL,
|
||||
ENTROPY_MIN_PLATFORM );
|
||||
#endif
|
||||
#if defined(POLARSSL_TIMING_C)
|
||||
entropy_add_source( ctx, hardclock_poll, NULL, ENTROPY_MIN_HARDCLOCK );
|
||||
#endif
|
||||
#if defined(POLARSSL_HAVEGE_C)
|
||||
entropy_add_source( ctx, havege_poll, &ctx->havege_data,
|
||||
ENTROPY_MIN_HAVEGE );
|
||||
#endif
|
||||
#endif /* POLARSSL_NO_DEFAULT_ENTROPY_SOURCES */
|
||||
}
|
||||
|
||||
int entropy_add_source( entropy_context *ctx,
|
||||
f_source_ptr f_source, void *p_source,
|
||||
size_t threshold )
|
||||
{
|
||||
int index = ctx->source_count;
|
||||
|
||||
if( index >= ENTROPY_MAX_SOURCES )
|
||||
return( POLARSSL_ERR_ENTROPY_MAX_SOURCES );
|
||||
|
||||
ctx->source[index].f_source = f_source;
|
||||
ctx->source[index].p_source = p_source;
|
||||
ctx->source[index].threshold = threshold;
|
||||
|
||||
ctx->source_count++;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Entropy accumulator update
|
||||
*/
|
||||
int entropy_update( entropy_context *ctx, unsigned char source_id,
|
||||
const unsigned char *data, size_t len )
|
||||
{
|
||||
unsigned char header[2];
|
||||
unsigned char tmp[ENTROPY_BLOCK_SIZE];
|
||||
size_t use_len = len;
|
||||
const unsigned char *p = data;
|
||||
|
||||
if( use_len > ENTROPY_BLOCK_SIZE )
|
||||
{
|
||||
sha4( data, len, tmp, 0 );
|
||||
|
||||
p = tmp;
|
||||
use_len = ENTROPY_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
header[0] = source_id;
|
||||
header[1] = use_len & 0xFF;
|
||||
|
||||
sha4_update( &ctx->accumulator, header, 2 );
|
||||
sha4_update( &ctx->accumulator, p, use_len );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int entropy_update_manual( entropy_context *ctx,
|
||||
const unsigned char *data, size_t len )
|
||||
{
|
||||
return entropy_update( ctx, ENTROPY_SOURCE_MANUAL, data, len );
|
||||
}
|
||||
|
||||
/*
|
||||
* Run through the different sources to add entropy to our accumulator
|
||||
*/
|
||||
int entropy_gather( entropy_context *ctx )
|
||||
{
|
||||
int ret, i;
|
||||
unsigned char buf[ENTROPY_MAX_GATHER];
|
||||
size_t olen;
|
||||
|
||||
if( ctx->source_count == 0 )
|
||||
return( POLARSSL_ERR_ENTROPY_NO_SOURCES_DEFINED );
|
||||
|
||||
/*
|
||||
* Run through our entropy sources
|
||||
*/
|
||||
for( i = 0; i < ctx->source_count; i++ )
|
||||
{
|
||||
olen = 0;
|
||||
if ( ( ret = ctx->source[i].f_source( ctx->source[i].p_source,
|
||||
buf, ENTROPY_MAX_GATHER, &olen ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Add if we actually gathered something
|
||||
*/
|
||||
if( olen > 0 )
|
||||
{
|
||||
entropy_update( ctx, (unsigned char) i, buf, olen );
|
||||
ctx->source[i].size += olen;
|
||||
}
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int entropy_func( void *data, unsigned char *output, size_t len )
|
||||
{
|
||||
int ret, count = 0, i, reached;
|
||||
entropy_context *ctx = (entropy_context *) data;
|
||||
unsigned char buf[ENTROPY_BLOCK_SIZE];
|
||||
|
||||
if( len > ENTROPY_BLOCK_SIZE )
|
||||
return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED );
|
||||
|
||||
/*
|
||||
* Always gather extra entropy before a call
|
||||
*/
|
||||
do
|
||||
{
|
||||
if( count++ > ENTROPY_MAX_LOOP )
|
||||
return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED );
|
||||
|
||||
if( ( ret = entropy_gather( ctx ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
reached = 0;
|
||||
|
||||
for( i = 0; i < ctx->source_count; i++ )
|
||||
if( ctx->source[i].size >= ctx->source[i].threshold )
|
||||
reached++;
|
||||
}
|
||||
while( reached != ctx->source_count );
|
||||
|
||||
memset( buf, 0, ENTROPY_BLOCK_SIZE );
|
||||
|
||||
sha4_finish( &ctx->accumulator, buf );
|
||||
|
||||
/*
|
||||
* Perform second SHA-512 on entropy
|
||||
*/
|
||||
sha4( buf, ENTROPY_BLOCK_SIZE, buf, 0 );
|
||||
|
||||
/*
|
||||
* Reset accumulator and counters and recycle existing entropy
|
||||
*/
|
||||
memset( &ctx->accumulator, 0, sizeof( sha4_context ) );
|
||||
sha4_starts( &ctx->accumulator, 0 );
|
||||
sha4_update( &ctx->accumulator, buf, ENTROPY_BLOCK_SIZE );
|
||||
|
||||
for( i = 0; i < ctx->source_count; i++ )
|
||||
ctx->source[i].size = 0;
|
||||
|
||||
memcpy( output, buf, len );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* \file entropy.h
|
||||
*
|
||||
* \brief Entropy accumulator implementation
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef POLARSSL_ENTROPY_H
|
||||
#define POLARSSL_ENTROPY_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#include "polarssl/sha4.h"
|
||||
#if defined(POLARSSL_HAVEGE_C)
|
||||
#include "polarssl/havege.h"
|
||||
#endif
|
||||
|
||||
#define POLARSSL_ERR_ENTROPY_SOURCE_FAILED -0x003C /**< Critical entropy source failure. */
|
||||
#define POLARSSL_ERR_ENTROPY_MAX_SOURCES -0x003E /**< No more sources can be added. */
|
||||
#define POLARSSL_ERR_ENTROPY_NO_SOURCES_DEFINED -0x0040 /**< No sources have been added to poll. */
|
||||
|
||||
#if !defined(POLARSSL_CONFIG_OPTIONS)
|
||||
#define ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */
|
||||
#define ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */
|
||||
#endif /* !POLARSSL_CONFIG_OPTIONS */
|
||||
|
||||
#define ENTROPY_BLOCK_SIZE 64 /**< Block size of entropy accumulator (SHA-512) */
|
||||
|
||||
#define ENTROPY_SOURCE_MANUAL ENTROPY_MAX_SOURCES
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Entropy poll callback pointer
|
||||
*
|
||||
* \param data Callback-specific data pointer
|
||||
* \param output Data to fill
|
||||
* \param len Maximum size to provide
|
||||
* \param olen The actual amount of bytes put into the buffer (Can be 0)
|
||||
*
|
||||
* \return 0 if no critical failures occurred,
|
||||
* POLARSSL_ERR_ENTROPY_SOURCE_FAILED otherwise
|
||||
*/
|
||||
typedef int (*f_source_ptr)(void *, unsigned char *, size_t, size_t *);
|
||||
|
||||
/**
|
||||
* \brief Entropy source state
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
f_source_ptr f_source; /**< The entropy source callback */
|
||||
void * p_source; /**< The callback data pointer */
|
||||
size_t size; /**< Amount received */
|
||||
size_t threshold; /**< Minimum level required before release */
|
||||
}
|
||||
source_state;
|
||||
|
||||
/**
|
||||
* \brief Entropy context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
sha4_context accumulator;
|
||||
int source_count;
|
||||
source_state source[ENTROPY_MAX_SOURCES];
|
||||
#if defined(POLARSSL_HAVEGE_C)
|
||||
havege_state havege_data;
|
||||
#endif
|
||||
}
|
||||
entropy_context;
|
||||
|
||||
/**
|
||||
* \brief Initialize the context
|
||||
*
|
||||
* \param ctx Entropy context to initialize
|
||||
*/
|
||||
void entropy_init( entropy_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Adds an entropy source to poll
|
||||
*
|
||||
* \param ctx Entropy context
|
||||
* \param f_source Entropy function
|
||||
* \param p_source Function data
|
||||
* \param threshold Minimum required from source before entropy is released
|
||||
* ( with entropy_func() )
|
||||
*
|
||||
* \return 0 if successful or POLARSSL_ERR_ENTROPY_MAX_SOURCES
|
||||
*/
|
||||
int entropy_add_source( entropy_context *ctx,
|
||||
f_source_ptr f_source, void *p_source,
|
||||
size_t threshold );
|
||||
|
||||
/**
|
||||
* \brief Trigger an extra gather poll for the accumulator
|
||||
*
|
||||
* \param ctx Entropy context
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_ENTROPY_SOURCE_FAILED
|
||||
*/
|
||||
int entropy_gather( entropy_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Retrieve entropy from the accumulator (Max ENTROPY_BLOCK_SIZE)
|
||||
*
|
||||
* \param data Entropy context
|
||||
* \param output Buffer to fill
|
||||
* \param len Length of buffer
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_ENTROPY_SOURCE_FAILED
|
||||
*/
|
||||
int entropy_func( void *data, unsigned char *output, size_t len );
|
||||
|
||||
/**
|
||||
* \brief Add data to the accumulator manually
|
||||
*
|
||||
* \param ctx Entropy context
|
||||
* \param data Data to add
|
||||
* \param len Length of data
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int entropy_update_manual( entropy_context *ctx,
|
||||
const unsigned char *data, size_t len );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* entropy.h */
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Platform-specific and custom entropy polling functions
|
||||
*
|
||||
* Copyright (C) 2006-2011, 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.
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_ENTROPY_C)
|
||||
|
||||
#include "polarssl/entropy.h"
|
||||
#include "polarssl/entropy_poll.h"
|
||||
|
||||
#if defined(POLARSSL_TIMING_C)
|
||||
#include "polarssl/timing.h"
|
||||
#endif
|
||||
#if defined(POLARSSL_HAVEGE_C)
|
||||
#include "polarssl/havege.h"
|
||||
#endif
|
||||
|
||||
#if !defined(POLARSSL_NO_PLATFORM_ENTROPY)
|
||||
#if defined(_WIN32)
|
||||
|
||||
#if !defined(_WIN32_WINNT)
|
||||
#define _WIN32_WINNT 0x0400
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
|
||||
int platform_entropy_poll( void *data, unsigned char *output, size_t len,
|
||||
size_t *olen )
|
||||
{
|
||||
HCRYPTPROV provider;
|
||||
((void) data);
|
||||
*olen = 0;
|
||||
|
||||
if( CryptAcquireContext( &provider, NULL, NULL,
|
||||
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE )
|
||||
{
|
||||
return POLARSSL_ERR_ENTROPY_SOURCE_FAILED;
|
||||
}
|
||||
|
||||
if( CryptGenRandom( provider, len, output ) == FALSE )
|
||||
return POLARSSL_ERR_ENTROPY_SOURCE_FAILED;
|
||||
|
||||
CryptReleaseContext( provider, 0 );
|
||||
*olen = len;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#else
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int platform_entropy_poll( void *data,
|
||||
unsigned char *output, size_t len, size_t *olen )
|
||||
{
|
||||
FILE *file;
|
||||
size_t ret;
|
||||
((void) data);
|
||||
|
||||
*olen = 0;
|
||||
|
||||
file = fopen( "/dev/urandom", "rb" );
|
||||
if( file == NULL )
|
||||
return POLARSSL_ERR_ENTROPY_SOURCE_FAILED;
|
||||
|
||||
ret = fread( output, 1, len, file );
|
||||
if( ret != len )
|
||||
{
|
||||
fclose( file );
|
||||
return POLARSSL_ERR_ENTROPY_SOURCE_FAILED;
|
||||
}
|
||||
|
||||
fclose( file );
|
||||
*olen = len;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_TIMING_C)
|
||||
int hardclock_poll( void *data,
|
||||
unsigned char *output, size_t len, size_t *olen )
|
||||
{
|
||||
unsigned long timer = hardclock();
|
||||
((void) data);
|
||||
*olen = 0;
|
||||
|
||||
if( len < sizeof(unsigned long) )
|
||||
return( 0 );
|
||||
|
||||
memcpy( output, &timer, sizeof(unsigned long) );
|
||||
*olen = sizeof(unsigned long);
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_HAVEGE_C)
|
||||
int havege_poll( void *data,
|
||||
unsigned char *output, size_t len, size_t *olen )
|
||||
{
|
||||
havege_state *hs = (havege_state *) data;
|
||||
*olen = 0;
|
||||
|
||||
if( havege_random( hs, output, len ) != 0 )
|
||||
return POLARSSL_ERR_ENTROPY_SOURCE_FAILED;
|
||||
|
||||
*olen = len;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* POLARSSL_ENTROPY_C */
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* \file entropy_poll.h
|
||||
*
|
||||
* \brief Platform-specific and custom entropy polling functions
|
||||
*
|
||||
* Copyright (C) 2006-2011, 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_ENTROPY_POLL_H
|
||||
#define POLARSSL_ENTROPY_POLL_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Default thresholds for built-in sources
|
||||
*/
|
||||
#define ENTROPY_MIN_PLATFORM 128 /**< Minimum for platform source */
|
||||
#define ENTROPY_MIN_HAVEGE 128 /**< Minimum for HAVEGE */
|
||||
#define ENTROPY_MIN_HARDCLOCK 32 /**< Minimum for hardclock() */
|
||||
|
||||
#if !defined(POLARSSL_NO_PLATFORM_ENTROPY)
|
||||
/**
|
||||
* \brief Platform-specific entropy poll callback
|
||||
*/
|
||||
int platform_entropy_poll( void *data,
|
||||
unsigned char *output, size_t len, size_t *olen );
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_HAVEGE_C)
|
||||
/**
|
||||
* \brief HAVEGE based entropy poll callback
|
||||
*
|
||||
* Requires an HAVEGE state as its data pointer.
|
||||
*/
|
||||
int havege_poll( void *data,
|
||||
unsigned char *output, size_t len, size_t *olen );
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_TIMING_C)
|
||||
/**
|
||||
* \brief hardclock-based entropy poll callback
|
||||
*/
|
||||
int hardclock_poll( void *data,
|
||||
unsigned char *output, size_t len, size_t *olen );
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* entropy_poll.h */
|
||||
@@ -0,0 +1,612 @@
|
||||
/*
|
||||
* Error message information
|
||||
*
|
||||
* Copyright (C) 2006-2012, 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.
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_ERROR_C)
|
||||
|
||||
#include "polarssl/error.h"
|
||||
|
||||
#if defined(POLARSSL_AES_C)
|
||||
#include "polarssl/aes.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_BASE64_C)
|
||||
#include "polarssl/base64.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_BIGNUM_C)
|
||||
#include "polarssl/bignum.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_BLOWFISH_C)
|
||||
#include "polarssl/blowfish.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_CAMELLIA_C)
|
||||
#include "polarssl/camellia.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_CIPHER_C)
|
||||
#include "polarssl/cipher.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_CTR_DRBG_C)
|
||||
#include "polarssl/ctr_drbg.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_DES_C)
|
||||
#include "polarssl/des.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_DHM_C)
|
||||
#include "polarssl/dhm.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_ENTROPY_C)
|
||||
#include "polarssl/entropy.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_GCM_C)
|
||||
#include "polarssl/gcm.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_MD_C)
|
||||
#include "polarssl/md.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_MD2_C)
|
||||
#include "polarssl/md2.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_MD4_C)
|
||||
#include "polarssl/md4.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_MD5_C)
|
||||
#include "polarssl/md5.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_NET_C)
|
||||
#include "polarssl/net.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_PADLOCK_C)
|
||||
#include "polarssl/padlock.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_PBKDF2_C)
|
||||
#include "polarssl/pbkdf2.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_PEM_C)
|
||||
#include "polarssl/pem.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_PKCS12_C)
|
||||
#include "polarssl/pkcs12.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_PKCS5_C)
|
||||
#include "polarssl/pkcs5.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_RSA_C)
|
||||
#include "polarssl/rsa.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_SHA1_C)
|
||||
#include "polarssl/sha1.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_SHA2_C)
|
||||
#include "polarssl/sha2.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_SHA4_C)
|
||||
#include "polarssl/sha4.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_SSL_TLS_C)
|
||||
#include "polarssl/ssl.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#include "polarssl/x509.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_XTEA_C)
|
||||
#include "polarssl/xtea.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined _MSC_VER && !defined snprintf
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
void error_strerror( int ret, char *buf, size_t buflen )
|
||||
{
|
||||
size_t len;
|
||||
int use_ret;
|
||||
|
||||
memset( buf, 0x00, buflen );
|
||||
|
||||
if( ret < 0 )
|
||||
ret = -ret;
|
||||
|
||||
if( ret & 0xFF80 )
|
||||
{
|
||||
use_ret = ret & 0xFF80;
|
||||
|
||||
// High level error codes
|
||||
//
|
||||
#if defined(POLARSSL_CIPHER_C)
|
||||
if( use_ret == -(POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE) )
|
||||
snprintf( buf, buflen, "CIPHER - The selected feature is not available" );
|
||||
if( use_ret == -(POLARSSL_ERR_CIPHER_BAD_INPUT_DATA) )
|
||||
snprintf( buf, buflen, "CIPHER - Bad input parameters to function" );
|
||||
if( use_ret == -(POLARSSL_ERR_CIPHER_ALLOC_FAILED) )
|
||||
snprintf( buf, buflen, "CIPHER - Failed to allocate memory" );
|
||||
if( use_ret == -(POLARSSL_ERR_CIPHER_INVALID_PADDING) )
|
||||
snprintf( buf, buflen, "CIPHER - Input data contains invalid padding and is rejected" );
|
||||
if( use_ret == -(POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED) )
|
||||
snprintf( buf, buflen, "CIPHER - Decryption of block requires a full block" );
|
||||
#endif /* POLARSSL_CIPHER_C */
|
||||
|
||||
#if defined(POLARSSL_DHM_C)
|
||||
if( use_ret == -(POLARSSL_ERR_DHM_BAD_INPUT_DATA) )
|
||||
snprintf( buf, buflen, "DHM - Bad input parameters to function" );
|
||||
if( use_ret == -(POLARSSL_ERR_DHM_READ_PARAMS_FAILED) )
|
||||
snprintf( buf, buflen, "DHM - Reading of the DHM parameters failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_DHM_MAKE_PARAMS_FAILED) )
|
||||
snprintf( buf, buflen, "DHM - Making of the DHM parameters failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_DHM_READ_PUBLIC_FAILED) )
|
||||
snprintf( buf, buflen, "DHM - Reading of the public values failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED) )
|
||||
snprintf( buf, buflen, "DHM - Making of the public value failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_DHM_CALC_SECRET_FAILED) )
|
||||
snprintf( buf, buflen, "DHM - Calculation of the DHM secret failed" );
|
||||
#endif /* POLARSSL_DHM_C */
|
||||
|
||||
#if defined(POLARSSL_MD_C)
|
||||
if( use_ret == -(POLARSSL_ERR_MD_FEATURE_UNAVAILABLE) )
|
||||
snprintf( buf, buflen, "MD - The selected feature is not available" );
|
||||
if( use_ret == -(POLARSSL_ERR_MD_BAD_INPUT_DATA) )
|
||||
snprintf( buf, buflen, "MD - Bad input parameters to function" );
|
||||
if( use_ret == -(POLARSSL_ERR_MD_ALLOC_FAILED) )
|
||||
snprintf( buf, buflen, "MD - Failed to allocate memory" );
|
||||
if( use_ret == -(POLARSSL_ERR_MD_FILE_IO_ERROR) )
|
||||
snprintf( buf, buflen, "MD - Opening or reading of file failed" );
|
||||
#endif /* POLARSSL_MD_C */
|
||||
|
||||
#if defined(POLARSSL_PEM_C)
|
||||
if( use_ret == -(POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT) )
|
||||
snprintf( buf, buflen, "PEM - No PEM header or footer found" );
|
||||
if( use_ret == -(POLARSSL_ERR_PEM_INVALID_DATA) )
|
||||
snprintf( buf, buflen, "PEM - PEM string is not as expected" );
|
||||
if( use_ret == -(POLARSSL_ERR_PEM_MALLOC_FAILED) )
|
||||
snprintf( buf, buflen, "PEM - Failed to allocate memory" );
|
||||
if( use_ret == -(POLARSSL_ERR_PEM_INVALID_ENC_IV) )
|
||||
snprintf( buf, buflen, "PEM - RSA IV is not in hex-format" );
|
||||
if( use_ret == -(POLARSSL_ERR_PEM_UNKNOWN_ENC_ALG) )
|
||||
snprintf( buf, buflen, "PEM - Unsupported key encryption algorithm" );
|
||||
if( use_ret == -(POLARSSL_ERR_PEM_PASSWORD_REQUIRED) )
|
||||
snprintf( buf, buflen, "PEM - Private key password can't be empty" );
|
||||
if( use_ret == -(POLARSSL_ERR_PEM_PASSWORD_MISMATCH) )
|
||||
snprintf( buf, buflen, "PEM - Given private key password does not allow for correct decryption" );
|
||||
if( use_ret == -(POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE) )
|
||||
snprintf( buf, buflen, "PEM - Unavailable feature, e.g. hashing/encryption combination" );
|
||||
if( use_ret == -(POLARSSL_ERR_PEM_BAD_INPUT_DATA) )
|
||||
snprintf( buf, buflen, "PEM - Bad input parameters to function" );
|
||||
#endif /* POLARSSL_PEM_C */
|
||||
|
||||
#if defined(POLARSSL_PKCS12_C)
|
||||
if( use_ret == -(POLARSSL_ERR_PKCS12_BAD_INPUT_DATA) )
|
||||
snprintf( buf, buflen, "PKCS12 - Bad input parameters to function" );
|
||||
if( use_ret == -(POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE) )
|
||||
snprintf( buf, buflen, "PKCS12 - Feature not available, e.g. unsupported encryption scheme" );
|
||||
if( use_ret == -(POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT) )
|
||||
snprintf( buf, buflen, "PKCS12 - PBE ASN.1 data not as expected" );
|
||||
if( use_ret == -(POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH) )
|
||||
snprintf( buf, buflen, "PKCS12 - Given private key password does not allow for correct decryption" );
|
||||
#endif /* POLARSSL_PKCS12_C */
|
||||
|
||||
#if defined(POLARSSL_PKCS5_C)
|
||||
if( use_ret == -(POLARSSL_ERR_PKCS5_BAD_INPUT_DATA) )
|
||||
snprintf( buf, buflen, "PKCS5 - Bad input parameters to function" );
|
||||
if( use_ret == -(POLARSSL_ERR_PKCS5_INVALID_FORMAT) )
|
||||
snprintf( buf, buflen, "PKCS5 - Unexpected ASN.1 data" );
|
||||
if( use_ret == -(POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE) )
|
||||
snprintf( buf, buflen, "PKCS5 - Requested encryption or digest alg not available" );
|
||||
if( use_ret == -(POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH) )
|
||||
snprintf( buf, buflen, "PKCS5 - Given private key password does not allow for correct decryption" );
|
||||
#endif /* POLARSSL_PKCS5_C */
|
||||
|
||||
#if defined(POLARSSL_RSA_C)
|
||||
if( use_ret == -(POLARSSL_ERR_RSA_BAD_INPUT_DATA) )
|
||||
snprintf( buf, buflen, "RSA - Bad input parameters to function" );
|
||||
if( use_ret == -(POLARSSL_ERR_RSA_INVALID_PADDING) )
|
||||
snprintf( buf, buflen, "RSA - Input data contains invalid padding and is rejected" );
|
||||
if( use_ret == -(POLARSSL_ERR_RSA_KEY_GEN_FAILED) )
|
||||
snprintf( buf, buflen, "RSA - Something failed during generation of a key" );
|
||||
if( use_ret == -(POLARSSL_ERR_RSA_KEY_CHECK_FAILED) )
|
||||
snprintf( buf, buflen, "RSA - Key failed to pass the libraries validity check" );
|
||||
if( use_ret == -(POLARSSL_ERR_RSA_PUBLIC_FAILED) )
|
||||
snprintf( buf, buflen, "RSA - The public key operation failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_RSA_PRIVATE_FAILED) )
|
||||
snprintf( buf, buflen, "RSA - The private key operation failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_RSA_VERIFY_FAILED) )
|
||||
snprintf( buf, buflen, "RSA - The PKCS#1 verification failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE) )
|
||||
snprintf( buf, buflen, "RSA - The output buffer for decryption is not large enough" );
|
||||
if( use_ret == -(POLARSSL_ERR_RSA_RNG_FAILED) )
|
||||
snprintf( buf, buflen, "RSA - The random generator failed to generate non-zeros" );
|
||||
#endif /* POLARSSL_RSA_C */
|
||||
|
||||
#if defined(POLARSSL_SSL_TLS_C)
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE) )
|
||||
snprintf( buf, buflen, "SSL - The requested feature is not available" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_BAD_INPUT_DATA) )
|
||||
snprintf( buf, buflen, "SSL - Bad input parameters to function" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_INVALID_MAC) )
|
||||
snprintf( buf, buflen, "SSL - Verification of the message MAC failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_INVALID_RECORD) )
|
||||
snprintf( buf, buflen, "SSL - An invalid SSL record was received" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_CONN_EOF) )
|
||||
snprintf( buf, buflen, "SSL - The connection indicated an EOF" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_UNKNOWN_CIPHER) )
|
||||
snprintf( buf, buflen, "SSL - An unknown cipher was received" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN) )
|
||||
snprintf( buf, buflen, "SSL - The server has no ciphersuites in common with the client" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_NO_SESSION_FOUND) )
|
||||
snprintf( buf, buflen, "SSL - No session to recover was found" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_NO_CLIENT_CERTIFICATE) )
|
||||
snprintf( buf, buflen, "SSL - No client certification received from the client, but required by the authentication mode" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_CERTIFICATE_TOO_LARGE) )
|
||||
snprintf( buf, buflen, "SSL - DESCRIPTION MISSING" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_CERTIFICATE_REQUIRED) )
|
||||
snprintf( buf, buflen, "SSL - The own certificate is not set, but needed by the server" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED) )
|
||||
snprintf( buf, buflen, "SSL - The own private key is not set, but needed" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_CA_CHAIN_REQUIRED) )
|
||||
snprintf( buf, buflen, "SSL - No CA Chain is set, but required to operate" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE) )
|
||||
snprintf( buf, buflen, "SSL - An unexpected message was received from our peer" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_FATAL_ALERT_MESSAGE) )
|
||||
{
|
||||
snprintf( buf, buflen, "SSL - A fatal alert message was received from our peer" );
|
||||
return;
|
||||
}
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_PEER_VERIFY_FAILED) )
|
||||
snprintf( buf, buflen, "SSL - Verification of our peer failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY) )
|
||||
snprintf( buf, buflen, "SSL - The peer notified us that the connection is going to be closed" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO) )
|
||||
snprintf( buf, buflen, "SSL - Processing of the ClientHello handshake message failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO) )
|
||||
snprintf( buf, buflen, "SSL - Processing of the ServerHello handshake message failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE) )
|
||||
snprintf( buf, buflen, "SSL - Processing of the Certificate handshake message failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST) )
|
||||
snprintf( buf, buflen, "SSL - Processing of the CertificateRequest handshake message failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE) )
|
||||
snprintf( buf, buflen, "SSL - Processing of the ServerKeyExchange handshake message failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO_DONE) )
|
||||
snprintf( buf, buflen, "SSL - Processing of the ServerHelloDone handshake message failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE) )
|
||||
snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_DHM_RP) )
|
||||
snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM Read Public" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_DHM_CS) )
|
||||
snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM Calculate Secret" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY) )
|
||||
snprintf( buf, buflen, "SSL - Processing of the CertificateVerify handshake message failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC) )
|
||||
snprintf( buf, buflen, "SSL - Processing of the ChangeCipherSpec handshake message failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_FINISHED) )
|
||||
snprintf( buf, buflen, "SSL - Processing of the Finished handshake message failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_MALLOC_FAILED) )
|
||||
snprintf( buf, buflen, "SSL - Memory allocation failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_HW_ACCEL_FAILED) )
|
||||
snprintf( buf, buflen, "SSL - Hardware acceleration function returned with error" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_HW_ACCEL_FALLTHROUGH) )
|
||||
snprintf( buf, buflen, "SSL - Hardware acceleration function skipped / left alone data" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_COMPRESSION_FAILED) )
|
||||
snprintf( buf, buflen, "SSL - Processing of the compression / decompression failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_PROTOCOL_VERSION) )
|
||||
snprintf( buf, buflen, "SSL - Handshake protocol not within min/max boundaries" );
|
||||
#endif /* POLARSSL_SSL_TLS_C */
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
if( use_ret == -(POLARSSL_ERR_X509_FEATURE_UNAVAILABLE) )
|
||||
snprintf( buf, buflen, "X509 - Unavailable feature, e.g. RSA hashing/encryption combination" );
|
||||
if( use_ret == -(POLARSSL_ERR_X509_CERT_INVALID_PEM) )
|
||||
snprintf( buf, buflen, "X509 - The PEM-encoded certificate contains invalid elements, e.g. invalid character" );
|
||||
if( use_ret == -(POLARSSL_ERR_X509_CERT_INVALID_FORMAT) )
|
||||
snprintf( buf, buflen, "X509 - The certificate format is invalid, e.g. different type expected" );
|
||||
if( use_ret == -(POLARSSL_ERR_X509_CERT_INVALID_VERSION) )
|
||||
snprintf( buf, buflen, "X509 - The certificate version element is invalid" );
|
||||
if( use_ret == -(POLARSSL_ERR_X509_CERT_INVALID_SERIAL) )
|
||||
snprintf( buf, buflen, "X509 - The serial tag or value is invalid" );
|
||||
if( use_ret == -(POLARSSL_ERR_X509_CERT_INVALID_ALG) )
|
||||
snprintf( buf, buflen, "X509 - The algorithm tag or value is invalid" );
|
||||
if( use_ret == -(POLARSSL_ERR_X509_CERT_INVALID_NAME) )
|
||||
snprintf( buf, buflen, "X509 - The name tag or value is invalid" );
|
||||
if( use_ret == -(POLARSSL_ERR_X509_CERT_INVALID_DATE) )
|
||||
snprintf( buf, buflen, "X509 - The date tag or value is invalid" );
|
||||
if( use_ret == -(POLARSSL_ERR_X509_CERT_INVALID_PUBKEY) )
|
||||
snprintf( buf, buflen, "X509 - The pubkey tag or value is invalid (only RSA is supported)" );
|
||||
if( use_ret == -(POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE) )
|
||||
snprintf( buf, buflen, "X509 - The signature tag or value invalid" );
|
||||
if( use_ret == -(POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS) )
|
||||
snprintf( buf, buflen, "X509 - The extension tag or value is invalid" );
|
||||
if( use_ret == -(POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION) )
|
||||
snprintf( buf, buflen, "X509 - Certificate or CRL has an unsupported version number" );
|
||||
if( use_ret == -(POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG) )
|
||||
snprintf( buf, buflen, "X509 - Signature algorithm (oid) is unsupported" );
|
||||
if( use_ret == -(POLARSSL_ERR_X509_UNKNOWN_PK_ALG) )
|
||||
snprintf( buf, buflen, "X509 - Key algorithm is unsupported (only RSA is supported)" );
|
||||
if( use_ret == -(POLARSSL_ERR_X509_CERT_SIG_MISMATCH) )
|
||||
snprintf( buf, buflen, "X509 - Certificate signature algorithms do not match. (see \\c ::x509_cert sig_oid)" );
|
||||
if( use_ret == -(POLARSSL_ERR_X509_CERT_VERIFY_FAILED) )
|
||||
snprintf( buf, buflen, "X509 - Certificate verification failed, e.g. CRL, CA or signature check failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_X509_KEY_INVALID_VERSION) )
|
||||
snprintf( buf, buflen, "X509 - Unsupported RSA key version" );
|
||||
if( use_ret == -(POLARSSL_ERR_X509_KEY_INVALID_FORMAT) )
|
||||
snprintf( buf, buflen, "X509 - Invalid RSA key tag or value" );
|
||||
if( use_ret == -(POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT) )
|
||||
snprintf( buf, buflen, "X509 - Format not recognized as DER or PEM" );
|
||||
if( use_ret == -(POLARSSL_ERR_X509_INVALID_INPUT) )
|
||||
snprintf( buf, buflen, "X509 - Input invalid" );
|
||||
if( use_ret == -(POLARSSL_ERR_X509_MALLOC_FAILED) )
|
||||
snprintf( buf, buflen, "X509 - Allocation of memory failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_X509_FILE_IO_ERROR) )
|
||||
snprintf( buf, buflen, "X509 - Read/write of file failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_X509_PASSWORD_REQUIRED) )
|
||||
snprintf( buf, buflen, "X509 - Private key password can't be empty" );
|
||||
if( use_ret == -(POLARSSL_ERR_X509_PASSWORD_MISMATCH) )
|
||||
snprintf( buf, buflen, "X509 - Given private key password does not allow for correct decryption" );
|
||||
#endif /* POLARSSL_X509_PARSE_C */
|
||||
|
||||
if( strlen( buf ) == 0 )
|
||||
snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
|
||||
}
|
||||
|
||||
use_ret = ret & ~0xFF80;
|
||||
|
||||
if( use_ret == 0 )
|
||||
return;
|
||||
|
||||
// If high level code is present, make a concatenation between both
|
||||
// error strings.
|
||||
//
|
||||
len = strlen( buf );
|
||||
|
||||
if( len > 0 )
|
||||
{
|
||||
if( buflen - len < 5 )
|
||||
return;
|
||||
|
||||
snprintf( buf + len, buflen - len, " : " );
|
||||
|
||||
buf += len + 3;
|
||||
buflen -= len + 3;
|
||||
}
|
||||
|
||||
// Low level error codes
|
||||
//
|
||||
#if defined(POLARSSL_AES_C)
|
||||
if( use_ret == -(POLARSSL_ERR_AES_INVALID_KEY_LENGTH) )
|
||||
snprintf( buf, buflen, "AES - Invalid key length" );
|
||||
if( use_ret == -(POLARSSL_ERR_AES_INVALID_INPUT_LENGTH) )
|
||||
snprintf( buf, buflen, "AES - Invalid data input length" );
|
||||
#endif /* POLARSSL_AES_C */
|
||||
|
||||
#if defined(POLARSSL_ASN1_PARSE_C)
|
||||
if( use_ret == -(POLARSSL_ERR_ASN1_OUT_OF_DATA) )
|
||||
snprintf( buf, buflen, "ASN1 - Out of data when parsing an ASN1 data structure" );
|
||||
if( use_ret == -(POLARSSL_ERR_ASN1_UNEXPECTED_TAG) )
|
||||
snprintf( buf, buflen, "ASN1 - ASN1 tag was of an unexpected value" );
|
||||
if( use_ret == -(POLARSSL_ERR_ASN1_INVALID_LENGTH) )
|
||||
snprintf( buf, buflen, "ASN1 - Error when trying to determine the length or invalid length" );
|
||||
if( use_ret == -(POLARSSL_ERR_ASN1_LENGTH_MISMATCH) )
|
||||
snprintf( buf, buflen, "ASN1 - Actual length differs from expected length" );
|
||||
if( use_ret == -(POLARSSL_ERR_ASN1_INVALID_DATA) )
|
||||
snprintf( buf, buflen, "ASN1 - Data is invalid. (not used)" );
|
||||
if( use_ret == -(POLARSSL_ERR_ASN1_MALLOC_FAILED) )
|
||||
snprintf( buf, buflen, "ASN1 - Memory allocation failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_ASN1_BUF_TOO_SMALL) )
|
||||
snprintf( buf, buflen, "ASN1 - Buffer too small when writing ASN.1 data structure" );
|
||||
#endif /* POLARSSL_ASN1_PARSE_C */
|
||||
|
||||
#if defined(POLARSSL_BASE64_C)
|
||||
if( use_ret == -(POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL) )
|
||||
snprintf( buf, buflen, "BASE64 - Output buffer too small" );
|
||||
if( use_ret == -(POLARSSL_ERR_BASE64_INVALID_CHARACTER) )
|
||||
snprintf( buf, buflen, "BASE64 - Invalid character in input" );
|
||||
#endif /* POLARSSL_BASE64_C */
|
||||
|
||||
#if defined(POLARSSL_BIGNUM_C)
|
||||
if( use_ret == -(POLARSSL_ERR_MPI_FILE_IO_ERROR) )
|
||||
snprintf( buf, buflen, "BIGNUM - An error occurred while reading from or writing to a file" );
|
||||
if( use_ret == -(POLARSSL_ERR_MPI_BAD_INPUT_DATA) )
|
||||
snprintf( buf, buflen, "BIGNUM - Bad input parameters to function" );
|
||||
if( use_ret == -(POLARSSL_ERR_MPI_INVALID_CHARACTER) )
|
||||
snprintf( buf, buflen, "BIGNUM - There is an invalid character in the digit string" );
|
||||
if( use_ret == -(POLARSSL_ERR_MPI_BUFFER_TOO_SMALL) )
|
||||
snprintf( buf, buflen, "BIGNUM - The buffer is too small to write to" );
|
||||
if( use_ret == -(POLARSSL_ERR_MPI_NEGATIVE_VALUE) )
|
||||
snprintf( buf, buflen, "BIGNUM - The input arguments are negative or result in illegal output" );
|
||||
if( use_ret == -(POLARSSL_ERR_MPI_DIVISION_BY_ZERO) )
|
||||
snprintf( buf, buflen, "BIGNUM - The input argument for division is zero, which is not allowed" );
|
||||
if( use_ret == -(POLARSSL_ERR_MPI_NOT_ACCEPTABLE) )
|
||||
snprintf( buf, buflen, "BIGNUM - The input arguments are not acceptable" );
|
||||
if( use_ret == -(POLARSSL_ERR_MPI_MALLOC_FAILED) )
|
||||
snprintf( buf, buflen, "BIGNUM - Memory allocation failed" );
|
||||
#endif /* POLARSSL_BIGNUM_C */
|
||||
|
||||
#if defined(POLARSSL_BLOWFISH_C)
|
||||
if( use_ret == -(POLARSSL_ERR_BLOWFISH_INVALID_KEY_LENGTH) )
|
||||
snprintf( buf, buflen, "BLOWFISH - Invalid key length" );
|
||||
if( use_ret == -(POLARSSL_ERR_BLOWFISH_INVALID_INPUT_LENGTH) )
|
||||
snprintf( buf, buflen, "BLOWFISH - Invalid data input length" );
|
||||
#endif /* POLARSSL_BLOWFISH_C */
|
||||
|
||||
#if defined(POLARSSL_CAMELLIA_C)
|
||||
if( use_ret == -(POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH) )
|
||||
snprintf( buf, buflen, "CAMELLIA - Invalid key length" );
|
||||
if( use_ret == -(POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH) )
|
||||
snprintf( buf, buflen, "CAMELLIA - Invalid data input length" );
|
||||
#endif /* POLARSSL_CAMELLIA_C */
|
||||
|
||||
#if defined(POLARSSL_CTR_DRBG_C)
|
||||
if( use_ret == -(POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED) )
|
||||
snprintf( buf, buflen, "CTR_DRBG - The entropy source failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG) )
|
||||
snprintf( buf, buflen, "CTR_DRBG - Too many random requested in single call" );
|
||||
if( use_ret == -(POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG) )
|
||||
snprintf( buf, buflen, "CTR_DRBG - Input too large (Entropy + additional)" );
|
||||
if( use_ret == -(POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR) )
|
||||
snprintf( buf, buflen, "CTR_DRBG - Read/write error in file" );
|
||||
#endif /* POLARSSL_CTR_DRBG_C */
|
||||
|
||||
#if defined(POLARSSL_DES_C)
|
||||
if( use_ret == -(POLARSSL_ERR_DES_INVALID_INPUT_LENGTH) )
|
||||
snprintf( buf, buflen, "DES - The data input has an invalid length" );
|
||||
#endif /* POLARSSL_DES_C */
|
||||
|
||||
#if defined(POLARSSL_ENTROPY_C)
|
||||
if( use_ret == -(POLARSSL_ERR_ENTROPY_SOURCE_FAILED) )
|
||||
snprintf( buf, buflen, "ENTROPY - Critical entropy source failure" );
|
||||
if( use_ret == -(POLARSSL_ERR_ENTROPY_MAX_SOURCES) )
|
||||
snprintf( buf, buflen, "ENTROPY - No more sources can be added" );
|
||||
if( use_ret == -(POLARSSL_ERR_ENTROPY_NO_SOURCES_DEFINED) )
|
||||
snprintf( buf, buflen, "ENTROPY - No sources have been added to poll" );
|
||||
#endif /* POLARSSL_ENTROPY_C */
|
||||
|
||||
#if defined(POLARSSL_GCM_C)
|
||||
if( use_ret == -(POLARSSL_ERR_GCM_AUTH_FAILED) )
|
||||
snprintf( buf, buflen, "GCM - Authenticated decryption failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_GCM_BAD_INPUT) )
|
||||
snprintf( buf, buflen, "GCM - Bad input parameters to function" );
|
||||
#endif /* POLARSSL_GCM_C */
|
||||
|
||||
#if defined(POLARSSL_MD2_C)
|
||||
if( use_ret == -(POLARSSL_ERR_MD2_FILE_IO_ERROR) )
|
||||
snprintf( buf, buflen, "MD2 - Read/write error in file" );
|
||||
#endif /* POLARSSL_MD2_C */
|
||||
|
||||
#if defined(POLARSSL_MD4_C)
|
||||
if( use_ret == -(POLARSSL_ERR_MD4_FILE_IO_ERROR) )
|
||||
snprintf( buf, buflen, "MD4 - Read/write error in file" );
|
||||
#endif /* POLARSSL_MD4_C */
|
||||
|
||||
#if defined(POLARSSL_MD5_C)
|
||||
if( use_ret == -(POLARSSL_ERR_MD5_FILE_IO_ERROR) )
|
||||
snprintf( buf, buflen, "MD5 - Read/write error in file" );
|
||||
#endif /* POLARSSL_MD5_C */
|
||||
|
||||
#if defined(POLARSSL_NET_C)
|
||||
if( use_ret == -(POLARSSL_ERR_NET_UNKNOWN_HOST) )
|
||||
snprintf( buf, buflen, "NET - Failed to get an IP address for the given hostname" );
|
||||
if( use_ret == -(POLARSSL_ERR_NET_SOCKET_FAILED) )
|
||||
snprintf( buf, buflen, "NET - Failed to open a socket" );
|
||||
if( use_ret == -(POLARSSL_ERR_NET_CONNECT_FAILED) )
|
||||
snprintf( buf, buflen, "NET - The connection to the given server / port failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_NET_BIND_FAILED) )
|
||||
snprintf( buf, buflen, "NET - Binding of the socket failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_NET_LISTEN_FAILED) )
|
||||
snprintf( buf, buflen, "NET - Could not listen on the socket" );
|
||||
if( use_ret == -(POLARSSL_ERR_NET_ACCEPT_FAILED) )
|
||||
snprintf( buf, buflen, "NET - Could not accept the incoming connection" );
|
||||
if( use_ret == -(POLARSSL_ERR_NET_RECV_FAILED) )
|
||||
snprintf( buf, buflen, "NET - Reading information from the socket failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_NET_SEND_FAILED) )
|
||||
snprintf( buf, buflen, "NET - Sending information through the socket failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_NET_CONN_RESET) )
|
||||
snprintf( buf, buflen, "NET - Connection was reset by peer" );
|
||||
if( use_ret == -(POLARSSL_ERR_NET_WANT_READ) )
|
||||
snprintf( buf, buflen, "NET - Connection requires a read call" );
|
||||
if( use_ret == -(POLARSSL_ERR_NET_WANT_WRITE) )
|
||||
snprintf( buf, buflen, "NET - Connection requires a write call" );
|
||||
#endif /* POLARSSL_NET_C */
|
||||
|
||||
#if defined(POLARSSL_PADLOCK_C)
|
||||
if( use_ret == -(POLARSSL_ERR_PADLOCK_DATA_MISALIGNED) )
|
||||
snprintf( buf, buflen, "PADLOCK - Input data should be aligned" );
|
||||
#endif /* POLARSSL_PADLOCK_C */
|
||||
|
||||
#if defined(POLARSSL_PBKDF2_C)
|
||||
if( use_ret == -(POLARSSL_ERR_PBKDF2_BAD_INPUT_DATA) )
|
||||
snprintf( buf, buflen, "PBKDF2 - Bad input parameters to function" );
|
||||
#endif /* POLARSSL_PBKDF2_C */
|
||||
|
||||
#if defined(POLARSSL_SHA1_C)
|
||||
if( use_ret == -(POLARSSL_ERR_SHA1_FILE_IO_ERROR) )
|
||||
snprintf( buf, buflen, "SHA1 - Read/write error in file" );
|
||||
#endif /* POLARSSL_SHA1_C */
|
||||
|
||||
#if defined(POLARSSL_SHA2_C)
|
||||
if( use_ret == -(POLARSSL_ERR_SHA2_FILE_IO_ERROR) )
|
||||
snprintf( buf, buflen, "SHA2 - Read/write error in file" );
|
||||
#endif /* POLARSSL_SHA2_C */
|
||||
|
||||
#if defined(POLARSSL_SHA4_C)
|
||||
if( use_ret == -(POLARSSL_ERR_SHA4_FILE_IO_ERROR) )
|
||||
snprintf( buf, buflen, "SHA4 - Read/write error in file" );
|
||||
#endif /* POLARSSL_SHA4_C */
|
||||
|
||||
#if defined(POLARSSL_XTEA_C)
|
||||
if( use_ret == -(POLARSSL_ERR_XTEA_INVALID_INPUT_LENGTH) )
|
||||
snprintf( buf, buflen, "XTEA - The data input has an invalid length" );
|
||||
#endif /* POLARSSL_XTEA_C */
|
||||
|
||||
if( strlen( buf ) != 0 )
|
||||
return;
|
||||
|
||||
snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
|
||||
}
|
||||
|
||||
#else /* POLARSSL_ERROR_C */
|
||||
|
||||
#if defined(POLARSSL_ERROR_STRERROR_DUMMY)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Provide an non-function in case POLARSSL_ERROR_C is not defined
|
||||
*/
|
||||
void error_strerror( int ret, char *buf, size_t buflen )
|
||||
{
|
||||
((void) ret);
|
||||
|
||||
if( buflen > 0 )
|
||||
buf[0] = '\0';
|
||||
}
|
||||
|
||||
#endif /* POLARSSL_ERROR_STRERROR_DUMMY */
|
||||
#endif /* POLARSSL_ERROR_C */
|
||||
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* \file error.h
|
||||
*
|
||||
* \brief Error to string translation
|
||||
*
|
||||
* 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_ERROR_H
|
||||
#define POLARSSL_ERROR_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Error code layout.
|
||||
*
|
||||
* Currently we try to keep all error codes within the negative space of 16
|
||||
* bytes signed integers to support all platforms (-0x0000 - -0x8000). In
|
||||
* addition we'd like to give two layers of information on the error if
|
||||
* possible.
|
||||
*
|
||||
* For that purpose the error codes are segmented in the following manner:
|
||||
*
|
||||
* 16 bit error code bit-segmentation
|
||||
*
|
||||
* 1 bit - Intentionally not used
|
||||
* 3 bits - High level module ID
|
||||
* 5 bits - Module-dependent error code
|
||||
* 6 bits - Low level module errors
|
||||
* 1 bit - Intentionally not used
|
||||
*
|
||||
* Low-level module errors (0x007E-0x0002)
|
||||
*
|
||||
* Module Nr Codes assigned
|
||||
* MPI 7 0x0002-0x0010
|
||||
* GCM 2 0x0012-0x0014
|
||||
* BLOWFISH 2 0x0016-0x0018
|
||||
* AES 2 0x0020-0x0022
|
||||
* CAMELLIA 2 0x0024-0x0026
|
||||
* XTEA 1 0x0028-0x0028
|
||||
* BASE64 2 0x002A-0x002C
|
||||
* PADLOCK 1 0x0030-0x0030
|
||||
* DES 1 0x0032-0x0032
|
||||
* CTR_DBRG 3 0x0034-0x003A
|
||||
* ENTROPY 3 0x003C-0x0040
|
||||
* NET 11 0x0042-0x0056
|
||||
* ASN1 7 0x0060-0x006C
|
||||
* MD2 1 0x0070-0x0070
|
||||
* MD4 1 0x0072-0x0072
|
||||
* MD5 1 0x0074-0x0074
|
||||
* SHA1 1 0x0076-0x0076
|
||||
* SHA2 1 0x0078-0x0078
|
||||
* SHA4 1 0x007A-0x007A
|
||||
*
|
||||
* High-level module nr (3 bits - 0x1...-0x8...)
|
||||
* Name ID Nr of Errors
|
||||
* PEM 1 9
|
||||
* PKCS#12 1 4 (Started from top)
|
||||
* X509 2 23
|
||||
* DHM 3 6
|
||||
* PKCS5 3 4 (Started from top)
|
||||
* RSA 4 9
|
||||
* MD 5 4
|
||||
* CIPHER 6 5
|
||||
* SSL 6 2 (Started from top)
|
||||
* SSL 7 31
|
||||
*
|
||||
* Module dependent error code (5 bits 0x.08.-0x.F8.)
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Translate a PolarSSL error code into a string representation,
|
||||
* Result is truncated if necessary and always includes a terminating
|
||||
* null byte.
|
||||
*
|
||||
* \param errnum error code
|
||||
* \param buffer buffer to place representation in
|
||||
* \param buflen length of the buffer
|
||||
*/
|
||||
void error_strerror( int errnum, char *buffer, size_t buflen );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* error.h */
|
||||
+621
@@ -0,0 +1,621 @@
|
||||
/*
|
||||
* NIST SP800-38D compliant GCM implementation
|
||||
*
|
||||
* Copyright (C) 2006-2012, 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.
|
||||
*/
|
||||
/*
|
||||
* http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
|
||||
*/
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_GCM_C)
|
||||
|
||||
#include "polarssl/gcm.h"
|
||||
|
||||
/*
|
||||
* 32-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
#ifndef GET_UINT32_BE
|
||||
#define GET_UINT32_BE(n,b,i) \
|
||||
{ \
|
||||
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
|
||||
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
|
||||
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
|
||||
| ( (uint32_t) (b)[(i) + 3] ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PUT_UINT32_BE
|
||||
#define PUT_UINT32_BE(n,b,i) \
|
||||
{ \
|
||||
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
static void gcm_gen_table( gcm_context *ctx )
|
||||
{
|
||||
int i, j;
|
||||
uint64_t hi, lo;
|
||||
uint64_t vl, vh;
|
||||
unsigned char h[16];
|
||||
|
||||
memset( h, 0, 16 );
|
||||
aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, h, h );
|
||||
|
||||
ctx->HH[0] = 0;
|
||||
ctx->HL[0] = 0;
|
||||
|
||||
GET_UINT32_BE( hi, h, 0 );
|
||||
GET_UINT32_BE( lo, h, 4 );
|
||||
vh = (uint64_t) hi << 32 | lo;
|
||||
|
||||
GET_UINT32_BE( hi, h, 8 );
|
||||
GET_UINT32_BE( lo, h, 12 );
|
||||
vl = (uint64_t) hi << 32 | lo;
|
||||
|
||||
ctx->HL[8] = vl;
|
||||
ctx->HH[8] = vh;
|
||||
|
||||
for( i = 4; i > 0; i >>= 1 )
|
||||
{
|
||||
uint32_t T = ( vl & 1 ) * 0xe1000000U;
|
||||
vl = ( vh << 63 ) | ( vl >> 1 );
|
||||
vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
|
||||
|
||||
ctx->HL[i] = vl;
|
||||
ctx->HH[i] = vh;
|
||||
}
|
||||
|
||||
for (i = 2; i < 16; i <<= 1 )
|
||||
{
|
||||
uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
|
||||
vh = *HiH;
|
||||
vl = *HiL;
|
||||
for( j = 1; j < i; j++ )
|
||||
{
|
||||
HiH[j] = vh ^ ctx->HH[j];
|
||||
HiL[j] = vl ^ ctx->HL[j];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int gcm_init( gcm_context *ctx, const unsigned char *key, unsigned int keysize )
|
||||
{
|
||||
int ret;
|
||||
|
||||
memset( ctx, 0, sizeof(gcm_context) );
|
||||
|
||||
if( ( ret = aes_setkey_enc( &ctx->aes_ctx, key, keysize ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
gcm_gen_table( ctx );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static const uint64_t last4[16] =
|
||||
{
|
||||
0x0000, 0x1c20, 0x3840, 0x2460,
|
||||
0x7080, 0x6ca0, 0x48c0, 0x54e0,
|
||||
0xe100, 0xfd20, 0xd940, 0xc560,
|
||||
0x9180, 0x8da0, 0xa9c0, 0xb5e0
|
||||
};
|
||||
|
||||
void gcm_mult( gcm_context *ctx, const unsigned char x[16], unsigned char output[16] )
|
||||
{
|
||||
int i = 0;
|
||||
unsigned char z[16];
|
||||
unsigned char lo, hi, rem;
|
||||
uint64_t zh, zl;
|
||||
|
||||
memset( z, 0x00, 16 );
|
||||
|
||||
lo = x[15] & 0xf;
|
||||
hi = x[15] >> 4;
|
||||
|
||||
zh = ctx->HH[lo];
|
||||
zl = ctx->HL[lo];
|
||||
|
||||
for( i = 15; i >= 0; i-- )
|
||||
{
|
||||
lo = x[i] & 0xf;
|
||||
hi = x[i] >> 4;
|
||||
|
||||
if( i != 15 )
|
||||
{
|
||||
rem = (unsigned char) zl & 0xf;
|
||||
zl = ( zh << 60 ) | ( zl >> 4 );
|
||||
zh = ( zh >> 4 );
|
||||
zh ^= (uint64_t) last4[rem] << 48;
|
||||
zh ^= ctx->HH[lo];
|
||||
zl ^= ctx->HL[lo];
|
||||
|
||||
}
|
||||
|
||||
rem = (unsigned char) zl & 0xf;
|
||||
zl = ( zh << 60 ) | ( zl >> 4 );
|
||||
zh = ( zh >> 4 );
|
||||
zh ^= (uint64_t) last4[rem] << 48;
|
||||
zh ^= ctx->HH[hi];
|
||||
zl ^= ctx->HL[hi];
|
||||
}
|
||||
|
||||
PUT_UINT32_BE( zh >> 32, output, 0 );
|
||||
PUT_UINT32_BE( zh, output, 4 );
|
||||
PUT_UINT32_BE( zl >> 32, output, 8 );
|
||||
PUT_UINT32_BE( zl, output, 12 );
|
||||
}
|
||||
|
||||
int gcm_crypt_and_tag( gcm_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
const unsigned char *iv,
|
||||
size_t iv_len,
|
||||
const unsigned char *add,
|
||||
size_t add_len,
|
||||
const unsigned char *input,
|
||||
unsigned char *output,
|
||||
size_t tag_len,
|
||||
unsigned char *tag )
|
||||
{
|
||||
unsigned char y[16];
|
||||
unsigned char ectr[16];
|
||||
unsigned char buf[16];
|
||||
unsigned char work_buf[16];
|
||||
size_t i;
|
||||
const unsigned char *p;
|
||||
unsigned char *out_p = output;
|
||||
size_t use_len;
|
||||
uint64_t orig_len = length * 8;
|
||||
uint64_t orig_add_len = add_len * 8;
|
||||
|
||||
memset( y, 0x00, 16 );
|
||||
memset( work_buf, 0x00, 16 );
|
||||
memset( tag, 0x00, tag_len );
|
||||
memset( buf, 0x00, 16 );
|
||||
|
||||
if( ( mode == GCM_DECRYPT && output <= input && ( input - output ) < 8 ) ||
|
||||
( output > input && (size_t) ( output - input ) < length ) )
|
||||
{
|
||||
return( POLARSSL_ERR_GCM_BAD_INPUT );
|
||||
}
|
||||
|
||||
if( iv_len == 12 )
|
||||
{
|
||||
memcpy( y, iv, iv_len );
|
||||
y[15] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset( work_buf, 0x00, 16 );
|
||||
PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
|
||||
|
||||
p = iv;
|
||||
while( iv_len > 0 )
|
||||
{
|
||||
use_len = ( iv_len < 16 ) ? iv_len : 16;
|
||||
|
||||
for( i = 0; i < use_len; i++ )
|
||||
y[i] ^= p[i];
|
||||
|
||||
gcm_mult( ctx, y, y );
|
||||
|
||||
iv_len -= use_len;
|
||||
p += use_len;
|
||||
}
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
y[i] ^= work_buf[i];
|
||||
|
||||
gcm_mult( ctx, y, y );
|
||||
}
|
||||
|
||||
aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
|
||||
memcpy( tag, ectr, tag_len );
|
||||
|
||||
p = add;
|
||||
while( add_len > 0 )
|
||||
{
|
||||
use_len = ( add_len < 16 ) ? add_len : 16;
|
||||
|
||||
for( i = 0; i < use_len; i++ )
|
||||
buf[i] ^= p[i];
|
||||
|
||||
gcm_mult( ctx, buf, buf );
|
||||
|
||||
add_len -= use_len;
|
||||
p += use_len;
|
||||
}
|
||||
|
||||
p = input;
|
||||
while( length > 0 )
|
||||
{
|
||||
use_len = ( length < 16 ) ? length : 16;
|
||||
|
||||
for( i = 16; i > 12; i-- )
|
||||
if( ++y[i - 1] != 0 )
|
||||
break;
|
||||
|
||||
aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
|
||||
|
||||
for( i = 0; i < use_len; i++ )
|
||||
{
|
||||
out_p[i] = ectr[i] ^ p[i];
|
||||
if( mode == GCM_ENCRYPT )
|
||||
buf[i] ^= out_p[i];
|
||||
else
|
||||
buf[i] ^= p[i];
|
||||
}
|
||||
|
||||
gcm_mult( ctx, buf, buf );
|
||||
|
||||
length -= use_len;
|
||||
p += use_len;
|
||||
out_p += use_len;
|
||||
}
|
||||
|
||||
if( orig_len || orig_add_len )
|
||||
{
|
||||
memset( work_buf, 0x00, 16 );
|
||||
|
||||
PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
|
||||
PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
|
||||
PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
|
||||
PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
buf[i] ^= work_buf[i];
|
||||
|
||||
gcm_mult( ctx, buf, buf );
|
||||
|
||||
for( i = 0; i < tag_len; i++ )
|
||||
tag[i] ^= buf[i];
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int gcm_auth_decrypt( gcm_context *ctx,
|
||||
size_t length,
|
||||
const unsigned char *iv,
|
||||
size_t iv_len,
|
||||
const unsigned char *add,
|
||||
size_t add_len,
|
||||
const unsigned char *tag,
|
||||
size_t tag_len,
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
unsigned char check_tag[16];
|
||||
|
||||
gcm_crypt_and_tag( ctx, GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, tag_len, check_tag );
|
||||
|
||||
if( memcmp( check_tag, tag, tag_len ) == 0 )
|
||||
return( 0 );
|
||||
|
||||
memset( output, 0, length );
|
||||
|
||||
return( POLARSSL_ERR_GCM_AUTH_FAILED );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_SELF_TEST)
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* GCM test vectors from:
|
||||
*
|
||||
* http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
|
||||
*/
|
||||
#define MAX_TESTS 6
|
||||
|
||||
int key_index[MAX_TESTS] =
|
||||
{ 0, 0, 1, 1, 1, 1 };
|
||||
|
||||
unsigned char key[MAX_TESTS][32] =
|
||||
{
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
|
||||
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
|
||||
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
|
||||
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
|
||||
};
|
||||
|
||||
size_t iv_len[MAX_TESTS] =
|
||||
{ 12, 12, 12, 12, 8, 60 };
|
||||
|
||||
int iv_index[MAX_TESTS] =
|
||||
{ 0, 0, 1, 1, 1, 2 };
|
||||
|
||||
unsigned char iv[MAX_TESTS][64] =
|
||||
{
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
|
||||
0xde, 0xca, 0xf8, 0x88 },
|
||||
{ 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
|
||||
0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
|
||||
0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
|
||||
0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
|
||||
0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
|
||||
0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
|
||||
0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
|
||||
0xa6, 0x37, 0xb3, 0x9b },
|
||||
};
|
||||
|
||||
size_t add_len[MAX_TESTS] =
|
||||
{ 0, 0, 0, 20, 20, 20 };
|
||||
|
||||
int add_index[MAX_TESTS] =
|
||||
{ 0, 0, 0, 1, 1, 1 };
|
||||
|
||||
unsigned char additional[MAX_TESTS][64] =
|
||||
{
|
||||
{ 0x00 },
|
||||
{ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xab, 0xad, 0xda, 0xd2 },
|
||||
};
|
||||
|
||||
size_t pt_len[MAX_TESTS] =
|
||||
{ 0, 16, 64, 60, 60, 60 };
|
||||
|
||||
int pt_index[MAX_TESTS] =
|
||||
{ 0, 0, 1, 1, 1, 1 };
|
||||
|
||||
unsigned char pt[MAX_TESTS][64] =
|
||||
{
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
|
||||
0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
|
||||
0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
|
||||
0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
|
||||
0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
|
||||
0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
|
||||
0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
|
||||
0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
|
||||
};
|
||||
|
||||
unsigned char ct[MAX_TESTS * 3][64] =
|
||||
{
|
||||
{ 0x00 },
|
||||
{ 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
|
||||
0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
|
||||
{ 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
|
||||
0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
|
||||
0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
|
||||
0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
|
||||
0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
|
||||
0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
|
||||
0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
|
||||
0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
|
||||
{ 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
|
||||
0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
|
||||
0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
|
||||
0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
|
||||
0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
|
||||
0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
|
||||
0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
|
||||
0x3d, 0x58, 0xe0, 0x91 },
|
||||
{ 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
|
||||
0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
|
||||
0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
|
||||
0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
|
||||
0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
|
||||
0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
|
||||
0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
|
||||
0xc2, 0x3f, 0x45, 0x98 },
|
||||
{ 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
|
||||
0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
|
||||
0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
|
||||
0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
|
||||
0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
|
||||
0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
|
||||
0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
|
||||
0x4c, 0x34, 0xae, 0xe5 },
|
||||
{ 0x00 },
|
||||
{ 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
|
||||
0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
|
||||
{ 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
|
||||
0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
|
||||
0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
|
||||
0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
|
||||
0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
|
||||
0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
|
||||
0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
|
||||
0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
|
||||
{ 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
|
||||
0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
|
||||
0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
|
||||
0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
|
||||
0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
|
||||
0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
|
||||
0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
|
||||
0xcc, 0xda, 0x27, 0x10 },
|
||||
{ 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
|
||||
0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
|
||||
0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
|
||||
0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
|
||||
0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
|
||||
0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
|
||||
0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
|
||||
0xa0, 0xf0, 0x62, 0xf7 },
|
||||
{ 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
|
||||
0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
|
||||
0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
|
||||
0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
|
||||
0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
|
||||
0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
|
||||
0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
|
||||
0xe9, 0xb7, 0x37, 0x3b },
|
||||
{ 0x00 },
|
||||
{ 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
|
||||
0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
|
||||
{ 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
|
||||
0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
|
||||
0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
|
||||
0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
|
||||
0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
|
||||
0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
|
||||
0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
|
||||
0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
|
||||
{ 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
|
||||
0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
|
||||
0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
|
||||
0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
|
||||
0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
|
||||
0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
|
||||
0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
|
||||
0xbc, 0xc9, 0xf6, 0x62 },
|
||||
{ 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
|
||||
0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
|
||||
0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
|
||||
0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
|
||||
0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
|
||||
0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
|
||||
0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
|
||||
0xf4, 0x7c, 0x9b, 0x1f },
|
||||
{ 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
|
||||
0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
|
||||
0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
|
||||
0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
|
||||
0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
|
||||
0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
|
||||
0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
|
||||
0x44, 0xae, 0x7e, 0x3f },
|
||||
};
|
||||
|
||||
unsigned char tag[MAX_TESTS * 3][16] =
|
||||
{
|
||||
{ 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
|
||||
0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
|
||||
{ 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
|
||||
0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
|
||||
{ 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
|
||||
0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
|
||||
{ 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
|
||||
0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
|
||||
{ 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
|
||||
0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
|
||||
{ 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
|
||||
0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
|
||||
{ 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
|
||||
0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
|
||||
{ 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
|
||||
0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
|
||||
{ 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
|
||||
0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
|
||||
{ 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
|
||||
0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
|
||||
{ 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
|
||||
0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
|
||||
{ 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
|
||||
0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
|
||||
{ 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
|
||||
0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
|
||||
{ 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
|
||||
0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
|
||||
{ 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
|
||||
0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
|
||||
{ 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
|
||||
0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
|
||||
{ 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
|
||||
0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
|
||||
{ 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
|
||||
0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
|
||||
};
|
||||
|
||||
int gcm_self_test( int verbose )
|
||||
{
|
||||
gcm_context ctx;
|
||||
unsigned char buf[64];
|
||||
unsigned char tag_buf[16];
|
||||
int i, j, ret;
|
||||
|
||||
for( j = 0; j < 3; j++ )
|
||||
{
|
||||
int key_len = 128 + 64 * j;
|
||||
|
||||
for( i = 0; i < MAX_TESTS; i++ )
|
||||
{
|
||||
printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "enc" );
|
||||
gcm_init( &ctx, key[key_index[i]], key_len );
|
||||
|
||||
ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
|
||||
pt_len[i],
|
||||
iv[iv_index[i]], iv_len[i],
|
||||
additional[add_index[i]], add_len[i],
|
||||
pt[pt_index[i]], buf, 16, tag_buf );
|
||||
|
||||
if( ret != 0 ||
|
||||
memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
|
||||
memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "passed\n" );
|
||||
|
||||
printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "dec" );
|
||||
gcm_init( &ctx, key[key_index[i]], key_len );
|
||||
|
||||
ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
|
||||
pt_len[i],
|
||||
iv[iv_index[i]], iv_len[i],
|
||||
additional[add_index[i]], add_len[i],
|
||||
ct[j * 6 + i], buf, 16, tag_buf );
|
||||
|
||||
if( ret != 0 ||
|
||||
memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
|
||||
memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "passed\n" );
|
||||
}
|
||||
}
|
||||
|
||||
printf( "\n" );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
/**
|
||||
* \file gcm.h
|
||||
*
|
||||
* \brief Galois/Counter mode for AES
|
||||
*
|
||||
* Copyright (C) 2006-2012, 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_GCM_H
|
||||
#define POLARSSL_GCM_H
|
||||
|
||||
#include "polarssl/aes.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <basetsd.h>
|
||||
typedef UINT64 uint64_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#define GCM_ENCRYPT 1
|
||||
#define GCM_DECRYPT 0
|
||||
|
||||
#define POLARSSL_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */
|
||||
#define POLARSSL_ERR_GCM_BAD_INPUT -0x0014 /**< Bad input parameters to function. */
|
||||
|
||||
/**
|
||||
* \brief GCM context structure
|
||||
*/
|
||||
typedef struct {
|
||||
aes_context aes_ctx; /*!< AES context used */
|
||||
uint64_t HL[16]; /*!< Precalculated HTable */
|
||||
uint64_t HH[16]; /*!< Precalculated HTable */
|
||||
}
|
||||
gcm_context;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief GCM initialization (encryption)
|
||||
*
|
||||
* \param ctx GCM 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 gcm_init( gcm_context *ctx, const unsigned char *key, unsigned int keysize );
|
||||
|
||||
/**
|
||||
* \brief GCM buffer encryption/decryption using AES
|
||||
*
|
||||
* \note On encryption, the output buffer can be the same as the input buffer.
|
||||
* On decryption, the output buffer cannot be the same as input buffer.
|
||||
* If buffers overlap, the output buffer must trail at least 8 bytes
|
||||
* behind the input buffer.
|
||||
*
|
||||
* \param ctx GCM context
|
||||
* \param mode GCM_ENCRYPT or GCM_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv initialization vector
|
||||
* \param iv_len length of IV
|
||||
* \param add additional data
|
||||
* \param add_len length of additional data
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer for holding the output data
|
||||
* \param tag_len length of the tag to generate
|
||||
* \param tag buffer for holding the tag
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int gcm_crypt_and_tag( gcm_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
const unsigned char *iv,
|
||||
size_t iv_len,
|
||||
const unsigned char *add,
|
||||
size_t add_len,
|
||||
const unsigned char *input,
|
||||
unsigned char *output,
|
||||
size_t tag_len,
|
||||
unsigned char *tag );
|
||||
|
||||
/**
|
||||
* \brief GCM buffer authenticated decryption using AES
|
||||
*
|
||||
* \note On decryption, the output buffer cannot be the same as input buffer.
|
||||
* If buffers overlap, the output buffer must trail at least 8 bytes
|
||||
* behind the input buffer.
|
||||
*
|
||||
* \param ctx GCM context
|
||||
* \param length length of the input data
|
||||
* \param iv initialization vector
|
||||
* \param iv_len length of IV
|
||||
* \param add additional data
|
||||
* \param add_len length of additional data
|
||||
* \param tag buffer holding the tag
|
||||
* \param tag_len length of the tag
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer for holding the output data
|
||||
*
|
||||
* \return 0 if successful and authenticated,
|
||||
* POLARSSL_ERR_GCM_AUTH_FAILED if tag does not match
|
||||
*/
|
||||
int gcm_auth_decrypt( gcm_context *ctx,
|
||||
size_t length,
|
||||
const unsigned char *iv,
|
||||
size_t iv_len,
|
||||
const unsigned char *add,
|
||||
size_t add_len,
|
||||
const unsigned char *tag,
|
||||
size_t tag_len,
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int gcm_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* gcm.h */
|
||||
@@ -0,0 +1,231 @@
|
||||
/**
|
||||
* \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion
|
||||
*
|
||||
* 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 HAVEGE RNG was designed by Andre Seznec in 2002.
|
||||
*
|
||||
* http://www.irisa.fr/caps/projects/hipsor/publi.php
|
||||
*
|
||||
* Contact: seznec(at)irisa_dot_fr - orocheco(at)irisa_dot_fr
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_HAVEGE_C)
|
||||
|
||||
#include "polarssl/havege.h"
|
||||
#include "polarssl/timing.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
* On average, one iteration accesses two 8-word blocks in the havege WALK
|
||||
* table, and generates 16 words in the RES array.
|
||||
*
|
||||
* The data read in the WALK table is updated and permuted after each use.
|
||||
* The result of the hardware clock counter read is used for this update.
|
||||
*
|
||||
* 25 conditional tests are present. The conditional tests are grouped in
|
||||
* two nested groups of 12 conditional tests and 1 test that controls the
|
||||
* permutation; on average, there should be 6 tests executed and 3 of them
|
||||
* should be mispredicted.
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define SWAP(X,Y) { int *T = X; X = Y; Y = T; }
|
||||
|
||||
#define TST1_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1;
|
||||
#define TST2_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1;
|
||||
|
||||
#define TST1_LEAVE U1++; }
|
||||
#define TST2_LEAVE U2++; }
|
||||
|
||||
#define ONE_ITERATION \
|
||||
\
|
||||
PTEST = PT1 >> 20; \
|
||||
\
|
||||
TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \
|
||||
TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \
|
||||
TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \
|
||||
\
|
||||
TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \
|
||||
TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \
|
||||
TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \
|
||||
\
|
||||
PTX = (PT1 >> 18) & 7; \
|
||||
PT1 &= 0x1FFF; \
|
||||
PT2 &= 0x1FFF; \
|
||||
CLK = (int) hardclock(); \
|
||||
\
|
||||
i = 0; \
|
||||
A = &WALK[PT1 ]; RES[i++] ^= *A; \
|
||||
B = &WALK[PT2 ]; RES[i++] ^= *B; \
|
||||
C = &WALK[PT1 ^ 1]; RES[i++] ^= *C; \
|
||||
D = &WALK[PT2 ^ 4]; RES[i++] ^= *D; \
|
||||
\
|
||||
IN = (*A >> (1)) ^ (*A << (31)) ^ CLK; \
|
||||
*A = (*B >> (2)) ^ (*B << (30)) ^ CLK; \
|
||||
*B = IN ^ U1; \
|
||||
*C = (*C >> (3)) ^ (*C << (29)) ^ CLK; \
|
||||
*D = (*D >> (4)) ^ (*D << (28)) ^ CLK; \
|
||||
\
|
||||
A = &WALK[PT1 ^ 2]; RES[i++] ^= *A; \
|
||||
B = &WALK[PT2 ^ 2]; RES[i++] ^= *B; \
|
||||
C = &WALK[PT1 ^ 3]; RES[i++] ^= *C; \
|
||||
D = &WALK[PT2 ^ 6]; RES[i++] ^= *D; \
|
||||
\
|
||||
if( PTEST & 1 ) SWAP( A, C ); \
|
||||
\
|
||||
IN = (*A >> (5)) ^ (*A << (27)) ^ CLK; \
|
||||
*A = (*B >> (6)) ^ (*B << (26)) ^ CLK; \
|
||||
*B = IN; CLK = (int) hardclock(); \
|
||||
*C = (*C >> (7)) ^ (*C << (25)) ^ CLK; \
|
||||
*D = (*D >> (8)) ^ (*D << (24)) ^ CLK; \
|
||||
\
|
||||
A = &WALK[PT1 ^ 4]; \
|
||||
B = &WALK[PT2 ^ 1]; \
|
||||
\
|
||||
PTEST = PT2 >> 1; \
|
||||
\
|
||||
PT2 = (RES[(i - 8) ^ PTY] ^ WALK[PT2 ^ PTY ^ 7]); \
|
||||
PT2 = ((PT2 & 0x1FFF) & (~8)) ^ ((PT1 ^ 8) & 0x8); \
|
||||
PTY = (PT2 >> 10) & 7; \
|
||||
\
|
||||
TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \
|
||||
TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \
|
||||
TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \
|
||||
\
|
||||
TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \
|
||||
TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \
|
||||
TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \
|
||||
\
|
||||
C = &WALK[PT1 ^ 5]; \
|
||||
D = &WALK[PT2 ^ 5]; \
|
||||
\
|
||||
RES[i++] ^= *A; \
|
||||
RES[i++] ^= *B; \
|
||||
RES[i++] ^= *C; \
|
||||
RES[i++] ^= *D; \
|
||||
\
|
||||
IN = (*A >> ( 9)) ^ (*A << (23)) ^ CLK; \
|
||||
*A = (*B >> (10)) ^ (*B << (22)) ^ CLK; \
|
||||
*B = IN ^ U2; \
|
||||
*C = (*C >> (11)) ^ (*C << (21)) ^ CLK; \
|
||||
*D = (*D >> (12)) ^ (*D << (20)) ^ CLK; \
|
||||
\
|
||||
A = &WALK[PT1 ^ 6]; RES[i++] ^= *A; \
|
||||
B = &WALK[PT2 ^ 3]; RES[i++] ^= *B; \
|
||||
C = &WALK[PT1 ^ 7]; RES[i++] ^= *C; \
|
||||
D = &WALK[PT2 ^ 7]; RES[i++] ^= *D; \
|
||||
\
|
||||
IN = (*A >> (13)) ^ (*A << (19)) ^ CLK; \
|
||||
*A = (*B >> (14)) ^ (*B << (18)) ^ CLK; \
|
||||
*B = IN; \
|
||||
*C = (*C >> (15)) ^ (*C << (17)) ^ CLK; \
|
||||
*D = (*D >> (16)) ^ (*D << (16)) ^ CLK; \
|
||||
\
|
||||
PT1 = ( RES[(i - 8) ^ PTX] ^ \
|
||||
WALK[PT1 ^ PTX ^ 7] ) & (~1); \
|
||||
PT1 ^= (PT2 ^ 0x10) & 0x10; \
|
||||
\
|
||||
for( n++, i = 0; i < 16; i++ ) \
|
||||
hs->pool[n % COLLECT_SIZE] ^= RES[i];
|
||||
|
||||
/*
|
||||
* Entropy gathering function
|
||||
*/
|
||||
static void havege_fill( havege_state *hs )
|
||||
{
|
||||
int i, n = 0;
|
||||
int U1, U2, *A, *B, *C, *D;
|
||||
int PT1, PT2, *WALK, RES[16];
|
||||
int PTX, PTY, CLK, PTEST, IN;
|
||||
|
||||
WALK = hs->WALK;
|
||||
PT1 = hs->PT1;
|
||||
PT2 = hs->PT2;
|
||||
|
||||
PTX = U1 = 0;
|
||||
PTY = U2 = 0;
|
||||
|
||||
memset( RES, 0, sizeof( RES ) );
|
||||
|
||||
while( n < COLLECT_SIZE * 4 )
|
||||
{
|
||||
ONE_ITERATION
|
||||
ONE_ITERATION
|
||||
ONE_ITERATION
|
||||
ONE_ITERATION
|
||||
}
|
||||
|
||||
hs->PT1 = PT1;
|
||||
hs->PT2 = PT2;
|
||||
|
||||
hs->offset[0] = 0;
|
||||
hs->offset[1] = COLLECT_SIZE / 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* HAVEGE initialization
|
||||
*/
|
||||
void havege_init( havege_state *hs )
|
||||
{
|
||||
memset( hs, 0, sizeof( havege_state ) );
|
||||
|
||||
havege_fill( hs );
|
||||
}
|
||||
|
||||
/*
|
||||
* HAVEGE rand function
|
||||
*/
|
||||
int havege_random( void *p_rng, unsigned char *buf, size_t len )
|
||||
{
|
||||
int val;
|
||||
size_t use_len;
|
||||
havege_state *hs = (havege_state *) p_rng;
|
||||
unsigned char *p = buf;
|
||||
|
||||
while( len > 0 )
|
||||
{
|
||||
use_len = len;
|
||||
if( use_len > sizeof(int) )
|
||||
use_len = sizeof(int);
|
||||
|
||||
if( hs->offset[1] >= COLLECT_SIZE )
|
||||
havege_fill( hs );
|
||||
|
||||
val = hs->pool[hs->offset[0]++];
|
||||
val ^= hs->pool[hs->offset[1]++];
|
||||
|
||||
memcpy( p, &val, use_len );
|
||||
|
||||
len -= use_len;
|
||||
p += use_len;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* \file havege.h
|
||||
*
|
||||
* \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion
|
||||
*
|
||||
* 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_HAVEGE_H
|
||||
#define POLARSSL_HAVEGE_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define COLLECT_SIZE 1024
|
||||
|
||||
/**
|
||||
* \brief HAVEGE state structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int PT1, PT2, offset[2];
|
||||
int pool[COLLECT_SIZE];
|
||||
int WALK[8192];
|
||||
}
|
||||
havege_state;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief HAVEGE initialization
|
||||
*
|
||||
* \param hs HAVEGE state to be initialized
|
||||
*/
|
||||
void havege_init( havege_state *hs );
|
||||
|
||||
/**
|
||||
* \brief HAVEGE rand function
|
||||
*
|
||||
* \param p_rng A HAVEGE state
|
||||
* \param output Buffer to fill
|
||||
* \param len Length of buffer
|
||||
*
|
||||
* \return 0
|
||||
*/
|
||||
int havege_random( void *p_rng, unsigned char *output, size_t len );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* havege.h */
|
||||
+298
@@ -0,0 +1,298 @@
|
||||
/**
|
||||
* \file md.c
|
||||
*
|
||||
* \brief Generic message digest wrapper for PolarSSL
|
||||
*
|
||||
* \author Adriaan de Jong <dejong@fox-it.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_MD_C)
|
||||
|
||||
#include "polarssl/md.h"
|
||||
#include "polarssl/md_wrap.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
|
||||
//#if defined _MSC_VER && !defined strcasecmp
|
||||
//#define strcasecmp _stricmp
|
||||
//#endif
|
||||
|
||||
static const int supported_digests[] = {
|
||||
|
||||
#if defined(POLARSSL_MD2_C)
|
||||
POLARSSL_MD_MD2,
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_MD4_C)
|
||||
POLARSSL_MD_MD4,
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_MD5_C)
|
||||
POLARSSL_MD_MD5,
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_SHA1_C)
|
||||
POLARSSL_MD_SHA1,
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_SHA2_C)
|
||||
POLARSSL_MD_SHA224,
|
||||
POLARSSL_MD_SHA256,
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_SHA4_C)
|
||||
POLARSSL_MD_SHA384,
|
||||
POLARSSL_MD_SHA512,
|
||||
#endif
|
||||
|
||||
0
|
||||
};
|
||||
|
||||
const int *md_list( void )
|
||||
{
|
||||
return supported_digests;
|
||||
}
|
||||
|
||||
const md_info_t *md_info_from_string( const char *md_name )
|
||||
{
|
||||
if( NULL == md_name )
|
||||
return NULL;
|
||||
|
||||
/* Get the appropriate digest information */
|
||||
#if defined(POLARSSL_MD2_C)
|
||||
if( !strcasecmp( "MD2", md_name ) )
|
||||
return md_info_from_type( POLARSSL_MD_MD2 );
|
||||
#endif
|
||||
#if defined(POLARSSL_MD4_C)
|
||||
if( !strcasecmp( "MD4", md_name ) )
|
||||
return md_info_from_type( POLARSSL_MD_MD4 );
|
||||
#endif
|
||||
#if defined(POLARSSL_MD5_C)
|
||||
if( !strcasecmp( "MD5", md_name ) )
|
||||
return md_info_from_type( POLARSSL_MD_MD5 );
|
||||
#endif
|
||||
#if defined(POLARSSL_SHA1_C)
|
||||
if( !strcasecmp( "SHA1", md_name ) || !strcasecmp( "SHA", md_name ) )
|
||||
return md_info_from_type( POLARSSL_MD_SHA1 );
|
||||
#endif
|
||||
#if defined(POLARSSL_SHA2_C)
|
||||
if( !strcasecmp( "SHA224", md_name ) )
|
||||
return md_info_from_type( POLARSSL_MD_SHA224 );
|
||||
if( !strcasecmp( "SHA256", md_name ) )
|
||||
return md_info_from_type( POLARSSL_MD_SHA256 );
|
||||
#endif
|
||||
#if defined(POLARSSL_SHA4_C)
|
||||
if( !strcasecmp( "SHA384", md_name ) )
|
||||
return md_info_from_type( POLARSSL_MD_SHA384 );
|
||||
if( !strcasecmp( "SHA512", md_name ) )
|
||||
return md_info_from_type( POLARSSL_MD_SHA512 );
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const md_info_t *md_info_from_type( md_type_t md_type )
|
||||
{
|
||||
switch( md_type )
|
||||
{
|
||||
#if defined(POLARSSL_MD2_C)
|
||||
case POLARSSL_MD_MD2:
|
||||
return &md2_info;
|
||||
#endif
|
||||
#if defined(POLARSSL_MD4_C)
|
||||
case POLARSSL_MD_MD4:
|
||||
return &md4_info;
|
||||
#endif
|
||||
#if defined(POLARSSL_MD5_C)
|
||||
case POLARSSL_MD_MD5:
|
||||
return &md5_info;
|
||||
#endif
|
||||
#if defined(POLARSSL_SHA1_C)
|
||||
case POLARSSL_MD_SHA1:
|
||||
return &sha1_info;
|
||||
#endif
|
||||
#if defined(POLARSSL_SHA2_C)
|
||||
case POLARSSL_MD_SHA224:
|
||||
return &sha224_info;
|
||||
case POLARSSL_MD_SHA256:
|
||||
return &sha256_info;
|
||||
#endif
|
||||
#if defined(POLARSSL_SHA4_C)
|
||||
case POLARSSL_MD_SHA384:
|
||||
return &sha384_info;
|
||||
case POLARSSL_MD_SHA512:
|
||||
return &sha512_info;
|
||||
#endif
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int md_init_ctx( md_context_t *ctx, const md_info_t *md_info )
|
||||
{
|
||||
if( md_info == NULL || ctx == NULL )
|
||||
return POLARSSL_ERR_MD_BAD_INPUT_DATA;
|
||||
|
||||
memset( ctx, 0, sizeof( md_context_t ) );
|
||||
|
||||
if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL )
|
||||
return POLARSSL_ERR_MD_ALLOC_FAILED;
|
||||
|
||||
ctx->md_info = md_info;
|
||||
|
||||
md_info->starts_func( ctx->md_ctx );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int md_free_ctx( md_context_t *ctx )
|
||||
{
|
||||
if( ctx == NULL || ctx->md_info == NULL )
|
||||
return POLARSSL_ERR_MD_BAD_INPUT_DATA;
|
||||
|
||||
ctx->md_info->ctx_free_func( ctx->md_ctx );
|
||||
ctx->md_ctx = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int md_starts( md_context_t *ctx )
|
||||
{
|
||||
if( ctx == NULL || ctx->md_info == NULL )
|
||||
return POLARSSL_ERR_MD_BAD_INPUT_DATA;
|
||||
|
||||
ctx->md_info->starts_func( ctx->md_ctx );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int md_update( md_context_t *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
if( ctx == NULL || ctx->md_info == NULL )
|
||||
return POLARSSL_ERR_MD_BAD_INPUT_DATA;
|
||||
|
||||
ctx->md_info->update_func( ctx->md_ctx, input, ilen );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int md_finish( md_context_t *ctx, unsigned char *output )
|
||||
{
|
||||
if( ctx == NULL || ctx->md_info == NULL )
|
||||
return POLARSSL_ERR_MD_BAD_INPUT_DATA;
|
||||
|
||||
ctx->md_info->finish_func( ctx->md_ctx, output );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int md( const md_info_t *md_info, const unsigned char *input, size_t ilen,
|
||||
unsigned char *output )
|
||||
{
|
||||
if ( md_info == NULL )
|
||||
return POLARSSL_ERR_MD_BAD_INPUT_DATA;
|
||||
|
||||
md_info->digest_func( input, ilen, output );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int md_file( const md_info_t *md_info, const char *path, unsigned char *output )
|
||||
{
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
int ret;
|
||||
#endif
|
||||
|
||||
if( md_info == NULL )
|
||||
return POLARSSL_ERR_MD_BAD_INPUT_DATA;
|
||||
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
ret = md_info->file_func( path, output );
|
||||
if( ret != 0 )
|
||||
return( POLARSSL_ERR_MD_FILE_IO_ERROR + ret );
|
||||
|
||||
return( ret );
|
||||
#else
|
||||
((void) path);
|
||||
((void) output);
|
||||
|
||||
return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
int md_hmac_starts( md_context_t *ctx, const unsigned char *key, size_t keylen )
|
||||
{
|
||||
if( ctx == NULL || ctx->md_info == NULL )
|
||||
return POLARSSL_ERR_MD_BAD_INPUT_DATA;
|
||||
|
||||
ctx->md_info->hmac_starts_func( ctx->md_ctx, key, keylen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int md_hmac_update( md_context_t *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
if( ctx == NULL || ctx->md_info == NULL )
|
||||
return POLARSSL_ERR_MD_BAD_INPUT_DATA;
|
||||
|
||||
ctx->md_info->hmac_update_func( ctx->md_ctx, input, ilen );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int md_hmac_finish( md_context_t *ctx, unsigned char *output)
|
||||
{
|
||||
if( ctx == NULL || ctx->md_info == NULL )
|
||||
return POLARSSL_ERR_MD_BAD_INPUT_DATA;
|
||||
|
||||
ctx->md_info->hmac_finish_func( ctx->md_ctx, output);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int md_hmac_reset( md_context_t *ctx )
|
||||
{
|
||||
if( ctx == NULL || ctx->md_info == NULL )
|
||||
return POLARSSL_ERR_MD_BAD_INPUT_DATA;
|
||||
|
||||
ctx->md_info->hmac_reset_func( ctx->md_ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int md_hmac( const md_info_t *md_info, const unsigned char *key, size_t keylen,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output )
|
||||
{
|
||||
if( md_info == NULL )
|
||||
return POLARSSL_ERR_MD_BAD_INPUT_DATA;
|
||||
|
||||
md_info->hmac_func( key, keylen, input, ilen, output );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
+363
@@ -0,0 +1,363 @@
|
||||
/**
|
||||
* \file md.h
|
||||
*
|
||||
* \brief Generic message digest wrapper
|
||||
*
|
||||
* \author Adriaan de Jong <dejong@fox-it.com>
|
||||
*
|
||||
* Copyright (C) 2006-2011, 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_MD_H
|
||||
#define POLARSSL_MD_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_MSC_VER) && !defined(inline)
|
||||
#define inline _inline
|
||||
#else
|
||||
#if defined(__ARMCC_VERSION) && !defined(inline)
|
||||
#define inline __inline
|
||||
#endif /* __ARMCC_VERSION */
|
||||
#endif /*_MSC_VER */
|
||||
|
||||
#define POLARSSL_ERR_MD_FEATURE_UNAVAILABLE -0x5080 /**< The selected feature is not available. */
|
||||
#define POLARSSL_ERR_MD_BAD_INPUT_DATA -0x5100 /**< Bad input parameters to function. */
|
||||
#define POLARSSL_ERR_MD_ALLOC_FAILED -0x5180 /**< Failed to allocate memory. */
|
||||
#define POLARSSL_ERR_MD_FILE_IO_ERROR -0x5200 /**< Opening or reading of file failed. */
|
||||
|
||||
typedef enum {
|
||||
POLARSSL_MD_NONE=0,
|
||||
POLARSSL_MD_MD2,
|
||||
POLARSSL_MD_MD4,
|
||||
POLARSSL_MD_MD5,
|
||||
POLARSSL_MD_SHA1,
|
||||
POLARSSL_MD_SHA224,
|
||||
POLARSSL_MD_SHA256,
|
||||
POLARSSL_MD_SHA384,
|
||||
POLARSSL_MD_SHA512,
|
||||
} md_type_t;
|
||||
|
||||
#define POLARSSL_MD_MAX_SIZE 64 /* longest known is SHA512 */
|
||||
|
||||
/**
|
||||
* Message digest information. Allows message digest functions to be called
|
||||
* in a generic way.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Digest identifier */
|
||||
md_type_t type;
|
||||
|
||||
/** Name of the message digest */
|
||||
const char * name;
|
||||
|
||||
/** Output length of the digest function */
|
||||
int size;
|
||||
|
||||
/** Digest initialisation function */
|
||||
void (*starts_func)( void *ctx );
|
||||
|
||||
/** Digest update function */
|
||||
void (*update_func)( void *ctx, const unsigned char *input, size_t ilen );
|
||||
|
||||
/** Digest finalisation function */
|
||||
void (*finish_func)( void *ctx, unsigned char *output );
|
||||
|
||||
/** Generic digest function */
|
||||
void (*digest_func)( const unsigned char *input, size_t ilen,
|
||||
unsigned char *output );
|
||||
|
||||
/** Generic file digest function */
|
||||
int (*file_func)( const char *path, unsigned char *output );
|
||||
|
||||
/** HMAC Initialisation function */
|
||||
void (*hmac_starts_func)( void *ctx, const unsigned char *key, size_t keylen );
|
||||
|
||||
/** HMAC update function */
|
||||
void (*hmac_update_func)( void *ctx, const unsigned char *input, size_t ilen );
|
||||
|
||||
/** HMAC finalisation function */
|
||||
void (*hmac_finish_func)( void *ctx, unsigned char *output);
|
||||
|
||||
/** HMAC context reset function */
|
||||
void (*hmac_reset_func)( void *ctx );
|
||||
|
||||
/** Generic HMAC function */
|
||||
void (*hmac_func)( const unsigned char *key, size_t keylen,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output );
|
||||
|
||||
/** Allocate a new context */
|
||||
void * (*ctx_alloc_func)( void );
|
||||
|
||||
/** Free the given context */
|
||||
void (*ctx_free_func)( void *ctx );
|
||||
|
||||
} md_info_t;
|
||||
|
||||
/**
|
||||
* Generic message digest context.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Information about the associated message digest */
|
||||
const md_info_t *md_info;
|
||||
|
||||
/** Digest-specific context */
|
||||
void *md_ctx;
|
||||
} md_context_t;
|
||||
|
||||
#define MD_CONTEXT_T_INIT { \
|
||||
NULL, /* md_info */ \
|
||||
NULL, /* md_ctx */ \
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Returns the list of digests supported by the generic digest module.
|
||||
*
|
||||
* \return a statically allocated array of digests, the last entry
|
||||
* is 0.
|
||||
*/
|
||||
const int *md_list( void );
|
||||
|
||||
/**
|
||||
* \brief Returns the message digest information associated with the
|
||||
* given digest name.
|
||||
*
|
||||
* \param md_name Name of the digest to search for.
|
||||
*
|
||||
* \return The message digest information associated with md_name or
|
||||
* NULL if not found.
|
||||
*/
|
||||
const md_info_t *md_info_from_string( const char *md_name );
|
||||
|
||||
/**
|
||||
* \brief Returns the message digest information associated with the
|
||||
* given digest type.
|
||||
*
|
||||
* \param md_type type of digest to search for.
|
||||
*
|
||||
* \return The message digest information associated with md_type or
|
||||
* NULL if not found.
|
||||
*/
|
||||
const md_info_t *md_info_from_type( md_type_t md_type );
|
||||
|
||||
/**
|
||||
* \brief Initialises and fills the message digest context structure with
|
||||
* the appropriate values.
|
||||
*
|
||||
* \param ctx context to initialise. May not be NULL. The
|
||||
* digest-specific context (ctx->md_ctx) must be NULL. It will
|
||||
* be allocated, and must be freed using md_free_ctx() later.
|
||||
* \param md_info message digest to use.
|
||||
*
|
||||
* \returns \c 0 on success, \c POLARSSL_ERR_MD_BAD_INPUT_DATA on
|
||||
* parameter failure, \c POLARSSL_ERR_MD_ALLOC_FAILED if
|
||||
* allocation of the digest-specific context failed.
|
||||
*/
|
||||
int md_init_ctx( md_context_t *ctx, const md_info_t *md_info );
|
||||
|
||||
/**
|
||||
* \brief Free the message-specific context of ctx. Freeing ctx itself
|
||||
* remains the responsibility of the caller.
|
||||
*
|
||||
* \param ctx Free the message-specific context
|
||||
*
|
||||
* \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
|
||||
* verification fails.
|
||||
*/
|
||||
int md_free_ctx( md_context_t *ctx );
|
||||
|
||||
/**
|
||||
* \brief Returns the size of the message digest output.
|
||||
*
|
||||
* \param md_info message digest info
|
||||
*
|
||||
* \return size of the message digest output.
|
||||
*/
|
||||
static inline unsigned char md_get_size( const md_info_t *md_info )
|
||||
{
|
||||
if( md_info == NULL )
|
||||
return( 0 );
|
||||
|
||||
return md_info->size;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the type of the message digest output.
|
||||
*
|
||||
* \param md_info message digest info
|
||||
*
|
||||
* \return type of the message digest output.
|
||||
*/
|
||||
static inline md_type_t md_get_type( const md_info_t *md_info )
|
||||
{
|
||||
if( md_info == NULL )
|
||||
return( POLARSSL_MD_NONE );
|
||||
|
||||
return md_info->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the name of the message digest output.
|
||||
*
|
||||
* \param md_info message digest info
|
||||
*
|
||||
* \return name of the message digest output.
|
||||
*/
|
||||
static inline const char *md_get_name( const md_info_t *md_info )
|
||||
{
|
||||
if( md_info == NULL )
|
||||
return( NULL );
|
||||
|
||||
return md_info->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set-up the given context for a new message digest
|
||||
*
|
||||
* \param ctx generic message digest context.
|
||||
*
|
||||
* \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
|
||||
* verification fails.
|
||||
*/
|
||||
int md_starts( md_context_t *ctx );
|
||||
|
||||
/**
|
||||
* \brief Generic message digest process buffer
|
||||
*
|
||||
* \param ctx Generic message digest context
|
||||
* \param input buffer holding the datal
|
||||
* \param ilen length of the input data
|
||||
*
|
||||
* \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
|
||||
* verification fails.
|
||||
*/
|
||||
int md_update( md_context_t *ctx, const unsigned char *input, size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief Generic message digest final digest
|
||||
*
|
||||
* \param ctx Generic message digest context
|
||||
* \param output Generic message digest checksum result
|
||||
*
|
||||
* \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
|
||||
* verification fails.
|
||||
*/
|
||||
int md_finish( md_context_t *ctx, unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief Output = message_digest( input buffer )
|
||||
*
|
||||
* \param md_info message digest info
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
* \param output Generic message digest checksum result
|
||||
*
|
||||
* \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
|
||||
* verification fails.
|
||||
*/
|
||||
int md( const md_info_t *md_info, const unsigned char *input, size_t ilen,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief Output = message_digest( file contents )
|
||||
*
|
||||
* \param md_info message digest info
|
||||
* \param path input file name
|
||||
* \param output generic message digest checksum result
|
||||
*
|
||||
* \return 0 if successful, POLARSSL_ERR_MD_FILE_OPEN_FAILED if fopen
|
||||
* failed, POLARSSL_ERR_MD_FILE_READ_FAILED if fread failed,
|
||||
* POLARSSL_ERR_MD_BAD_INPUT_DATA if md_info was NULL.
|
||||
*/
|
||||
int md_file( const md_info_t *md_info, const char *path, unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief Generic HMAC context setup
|
||||
*
|
||||
* \param ctx HMAC context to be initialized
|
||||
* \param key HMAC secret key
|
||||
* \param keylen length of the HMAC key
|
||||
*
|
||||
* \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
|
||||
* verification fails.
|
||||
*/
|
||||
int md_hmac_starts( md_context_t *ctx, const unsigned char *key, size_t keylen );
|
||||
|
||||
/**
|
||||
* \brief Generic HMAC process buffer
|
||||
*
|
||||
* \param ctx HMAC context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*
|
||||
* \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
|
||||
* verification fails.
|
||||
*/
|
||||
int md_hmac_update( md_context_t *ctx, const unsigned char *input, size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief Generic HMAC final digest
|
||||
*
|
||||
* \param ctx HMAC context
|
||||
* \param output Generic HMAC checksum result
|
||||
*
|
||||
* \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
|
||||
* verification fails.
|
||||
*/
|
||||
int md_hmac_finish( md_context_t *ctx, unsigned char *output);
|
||||
|
||||
/**
|
||||
* \brief Generic HMAC context reset
|
||||
*
|
||||
* \param ctx HMAC context to be reset
|
||||
*
|
||||
* \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
|
||||
* verification fails.
|
||||
*/
|
||||
int md_hmac_reset( md_context_t *ctx );
|
||||
|
||||
/**
|
||||
* \brief Output = Generic_HMAC( hmac key, input buffer )
|
||||
*
|
||||
* \param md_info message digest info
|
||||
* \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 Generic HMAC-result
|
||||
*
|
||||
* \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
|
||||
* verification fails.
|
||||
*/
|
||||
int md_hmac( const md_info_t *md_info, const unsigned char *key, size_t keylen,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* POLARSSL_MD_H */
|
||||
+368
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
* RFC 1115/1319 compliant MD2 implementation
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
* The MD2 algorithm was designed by Ron Rivest in 1989.
|
||||
*
|
||||
* http://www.ietf.org/rfc/rfc1115.txt
|
||||
* http://www.ietf.org/rfc/rfc1319.txt
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_MD2_C)
|
||||
|
||||
#include "polarssl/md2.h"
|
||||
|
||||
#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if !defined(POLARSSL_MD2_ALT)
|
||||
|
||||
static const unsigned char PI_SUBST[256] =
|
||||
{
|
||||
0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36,
|
||||
0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3,
|
||||
0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C,
|
||||
0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
|
||||
0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 0xBE, 0x4E,
|
||||
0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E,
|
||||
0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2,
|
||||
0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
|
||||
0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E,
|
||||
0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 0xFF, 0x19, 0x30, 0xB3,
|
||||
0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56,
|
||||
0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
|
||||
0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D,
|
||||
0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65,
|
||||
0xE6, 0x2D, 0xA8, 0x02, 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0,
|
||||
0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
|
||||
0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C,
|
||||
0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E,
|
||||
0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81,
|
||||
0x4D, 0x52, 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
|
||||
0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88,
|
||||
0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE,
|
||||
0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58,
|
||||
0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
|
||||
0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99,
|
||||
0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14
|
||||
};
|
||||
|
||||
/*
|
||||
* MD2 context setup
|
||||
*/
|
||||
void md2_starts( md2_context *ctx )
|
||||
{
|
||||
memset( ctx->cksum, 0, 16 );
|
||||
memset( ctx->state, 0, 46 );
|
||||
memset( ctx->buffer, 0, 16 );
|
||||
ctx->left = 0;
|
||||
}
|
||||
|
||||
static void md2_process( md2_context *ctx )
|
||||
{
|
||||
int i, j;
|
||||
unsigned char t = 0;
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
ctx->state[i + 16] = ctx->buffer[i];
|
||||
ctx->state[i + 32] =
|
||||
(unsigned char)( ctx->buffer[i] ^ ctx->state[i]);
|
||||
}
|
||||
|
||||
for( i = 0; i < 18; i++ )
|
||||
{
|
||||
for( j = 0; j < 48; j++ )
|
||||
{
|
||||
ctx->state[j] = (unsigned char)
|
||||
( ctx->state[j] ^ PI_SUBST[t] );
|
||||
t = ctx->state[j];
|
||||
}
|
||||
|
||||
t = (unsigned char)( t + i );
|
||||
}
|
||||
|
||||
t = ctx->cksum[15];
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
ctx->cksum[i] = (unsigned char)
|
||||
( ctx->cksum[i] ^ PI_SUBST[ctx->buffer[i] ^ t] );
|
||||
t = ctx->cksum[i];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* MD2 process buffer
|
||||
*/
|
||||
void md2_update( md2_context *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
size_t fill;
|
||||
|
||||
while( ilen > 0 )
|
||||
{
|
||||
if( ctx->left + ilen > 16 )
|
||||
fill = 16 - ctx->left;
|
||||
else
|
||||
fill = ilen;
|
||||
|
||||
memcpy( ctx->buffer + ctx->left, input, fill );
|
||||
|
||||
ctx->left += fill;
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
|
||||
if( ctx->left == 16 )
|
||||
{
|
||||
ctx->left = 0;
|
||||
md2_process( ctx );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* MD2 final digest
|
||||
*/
|
||||
void md2_finish( md2_context *ctx, unsigned char output[16] )
|
||||
{
|
||||
size_t i;
|
||||
unsigned char x;
|
||||
|
||||
x = (unsigned char)( 16 - ctx->left );
|
||||
|
||||
for( i = ctx->left; i < 16; i++ )
|
||||
ctx->buffer[i] = x;
|
||||
|
||||
md2_process( ctx );
|
||||
|
||||
memcpy( ctx->buffer, ctx->cksum, 16 );
|
||||
md2_process( ctx );
|
||||
|
||||
memcpy( output, ctx->state, 16 );
|
||||
}
|
||||
|
||||
#endif /* !POLARSSL_MD2_ALT */
|
||||
|
||||
/*
|
||||
* output = MD2( input buffer )
|
||||
*/
|
||||
void md2( const unsigned char *input, size_t ilen, unsigned char output[16] )
|
||||
{
|
||||
md2_context ctx;
|
||||
|
||||
md2_starts( &ctx );
|
||||
md2_update( &ctx, input, ilen );
|
||||
md2_finish( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( md2_context ) );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
/*
|
||||
* output = MD2( file contents )
|
||||
*/
|
||||
int md2_file( const char *path, unsigned char output[16] )
|
||||
{
|
||||
FILE *f;
|
||||
size_t n;
|
||||
md2_context ctx;
|
||||
unsigned char buf[1024];
|
||||
|
||||
if( ( f = fopen( path, "rb" ) ) == NULL )
|
||||
return( POLARSSL_ERR_MD2_FILE_IO_ERROR );
|
||||
|
||||
md2_starts( &ctx );
|
||||
|
||||
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
|
||||
md2_update( &ctx, buf, n );
|
||||
|
||||
md2_finish( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( md2_context ) );
|
||||
|
||||
if( ferror( f ) != 0 )
|
||||
{
|
||||
fclose( f );
|
||||
return( POLARSSL_ERR_MD2_FILE_IO_ERROR );
|
||||
}
|
||||
|
||||
fclose( f );
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* POLARSSL_FS_IO */
|
||||
|
||||
/*
|
||||
* MD2 HMAC context setup
|
||||
*/
|
||||
void md2_hmac_starts( md2_context *ctx, const unsigned char *key, size_t keylen )
|
||||
{
|
||||
size_t i;
|
||||
unsigned char sum[16];
|
||||
|
||||
if( keylen > 16 )
|
||||
{
|
||||
md2( key, keylen, sum );
|
||||
keylen = 16;
|
||||
key = sum;
|
||||
}
|
||||
|
||||
memset( ctx->ipad, 0x36, 16 );
|
||||
memset( ctx->opad, 0x5C, 16 );
|
||||
|
||||
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] );
|
||||
}
|
||||
|
||||
md2_starts( ctx );
|
||||
md2_update( ctx, ctx->ipad, 16 );
|
||||
|
||||
memset( sum, 0, sizeof( sum ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* MD2 HMAC process buffer
|
||||
*/
|
||||
void md2_hmac_update( md2_context *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
md2_update( ctx, input, ilen );
|
||||
}
|
||||
|
||||
/*
|
||||
* MD2 HMAC final digest
|
||||
*/
|
||||
void md2_hmac_finish( md2_context *ctx, unsigned char output[16] )
|
||||
{
|
||||
unsigned char tmpbuf[16];
|
||||
|
||||
md2_finish( ctx, tmpbuf );
|
||||
md2_starts( ctx );
|
||||
md2_update( ctx, ctx->opad, 16 );
|
||||
md2_update( ctx, tmpbuf, 16 );
|
||||
md2_finish( ctx, output );
|
||||
|
||||
memset( tmpbuf, 0, sizeof( tmpbuf ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* MD2 HMAC context reset
|
||||
*/
|
||||
void md2_hmac_reset( md2_context *ctx )
|
||||
{
|
||||
md2_starts( ctx );
|
||||
md2_update( ctx, ctx->ipad, 16 );
|
||||
}
|
||||
|
||||
/*
|
||||
* output = HMAC-MD2( hmac key, input buffer )
|
||||
*/
|
||||
void md2_hmac( const unsigned char *key, size_t keylen,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char output[16] )
|
||||
{
|
||||
md2_context ctx;
|
||||
|
||||
md2_hmac_starts( &ctx, key, keylen );
|
||||
md2_hmac_update( &ctx, input, ilen );
|
||||
md2_hmac_finish( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( md2_context ) );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_SELF_TEST)
|
||||
|
||||
/*
|
||||
* RFC 1319 test vectors
|
||||
*/
|
||||
static const char md2_test_str[7][81] =
|
||||
{
|
||||
{ "" },
|
||||
{ "a" },
|
||||
{ "abc" },
|
||||
{ "message digest" },
|
||||
{ "abcdefghijklmnopqrstuvwxyz" },
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
|
||||
{ "12345678901234567890123456789012345678901234567890123456789012" \
|
||||
"345678901234567890" }
|
||||
};
|
||||
|
||||
static const unsigned char md2_test_sum[7][16] =
|
||||
{
|
||||
{ 0x83, 0x50, 0xE5, 0xA3, 0xE2, 0x4C, 0x15, 0x3D,
|
||||
0xF2, 0x27, 0x5C, 0x9F, 0x80, 0x69, 0x27, 0x73 },
|
||||
{ 0x32, 0xEC, 0x01, 0xEC, 0x4A, 0x6D, 0xAC, 0x72,
|
||||
0xC0, 0xAB, 0x96, 0xFB, 0x34, 0xC0, 0xB5, 0xD1 },
|
||||
{ 0xDA, 0x85, 0x3B, 0x0D, 0x3F, 0x88, 0xD9, 0x9B,
|
||||
0x30, 0x28, 0x3A, 0x69, 0xE6, 0xDE, 0xD6, 0xBB },
|
||||
{ 0xAB, 0x4F, 0x49, 0x6B, 0xFB, 0x2A, 0x53, 0x0B,
|
||||
0x21, 0x9F, 0xF3, 0x30, 0x31, 0xFE, 0x06, 0xB0 },
|
||||
{ 0x4E, 0x8D, 0xDF, 0xF3, 0x65, 0x02, 0x92, 0xAB,
|
||||
0x5A, 0x41, 0x08, 0xC3, 0xAA, 0x47, 0x94, 0x0B },
|
||||
{ 0xDA, 0x33, 0xDE, 0xF2, 0xA4, 0x2D, 0xF1, 0x39,
|
||||
0x75, 0x35, 0x28, 0x46, 0xC3, 0x03, 0x38, 0xCD },
|
||||
{ 0xD5, 0x97, 0x6F, 0x79, 0xD8, 0x3D, 0x3A, 0x0D,
|
||||
0xC9, 0x80, 0x6C, 0x3C, 0x66, 0xF3, 0xEF, 0xD8 }
|
||||
};
|
||||
|
||||
/*
|
||||
* Checkup routine
|
||||
*/
|
||||
int md2_self_test( int verbose )
|
||||
{
|
||||
int i;
|
||||
unsigned char md2sum[16];
|
||||
|
||||
for( i = 0; i < 7; i++ )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( " MD2 test #%d: ", i + 1 );
|
||||
|
||||
md2( (unsigned char *) md2_test_str[i],
|
||||
strlen( md2_test_str[i] ), md2sum );
|
||||
|
||||
if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "passed\n" );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "\n" );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
/**
|
||||
* \file md2.h
|
||||
*
|
||||
* \brief MD2 message digest algorithm (hash function)
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef POLARSSL_MD2_H
|
||||
#define POLARSSL_MD2_H
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define POLARSSL_ERR_MD2_FILE_IO_ERROR -0x0070 /**< Read/write error in file. */
|
||||
|
||||
#if !defined(POLARSSL_MD2_ALT)
|
||||
// Regular implementation
|
||||
//
|
||||
|
||||
/**
|
||||
* \brief MD2 context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned char cksum[16]; /*!< checksum of the data block */
|
||||
unsigned char state[48]; /*!< intermediate digest state */
|
||||
unsigned char buffer[16]; /*!< data block being processed */
|
||||
|
||||
unsigned char ipad[16]; /*!< HMAC: inner padding */
|
||||
unsigned char opad[16]; /*!< HMAC: outer padding */
|
||||
size_t left; /*!< amount of data in buffer */
|
||||
}
|
||||
md2_context;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief MD2 context setup
|
||||
*
|
||||
* \param ctx context to be initialized
|
||||
*/
|
||||
void md2_starts( md2_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief MD2 process buffer
|
||||
*
|
||||
* \param ctx MD2 context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void md2_update( md2_context *ctx, const unsigned char *input, size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief MD2 final digest
|
||||
*
|
||||
* \param ctx MD2 context
|
||||
* \param output MD2 checksum result
|
||||
*/
|
||||
void md2_finish( md2_context *ctx, unsigned char output[16] );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* POLARSSL_MD2_ALT */
|
||||
#include "polarssl/md2_alt.h"
|
||||
#endif /* POLARSSL_MD2_ALT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Output = MD2( input buffer )
|
||||
*
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
* \param output MD2 checksum result
|
||||
*/
|
||||
void md2( const unsigned char *input, size_t ilen, unsigned char output[16] );
|
||||
|
||||
/**
|
||||
* \brief Output = MD2( file contents )
|
||||
*
|
||||
* \param path input file name
|
||||
* \param output MD2 checksum result
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_MD2_FILE_IO_ERROR
|
||||
*/
|
||||
int md2_file( const char *path, unsigned char output[16] );
|
||||
|
||||
/**
|
||||
* \brief MD2 HMAC context setup
|
||||
*
|
||||
* \param ctx HMAC context to be initialized
|
||||
* \param key HMAC secret key
|
||||
* \param keylen length of the HMAC key
|
||||
*/
|
||||
void md2_hmac_starts( md2_context *ctx, const unsigned char *key, size_t keylen );
|
||||
|
||||
/**
|
||||
* \brief MD2 HMAC process buffer
|
||||
*
|
||||
* \param ctx HMAC context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void md2_hmac_update( md2_context *ctx, const unsigned char *input, size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief MD2 HMAC final digest
|
||||
*
|
||||
* \param ctx HMAC context
|
||||
* \param output MD2 HMAC checksum result
|
||||
*/
|
||||
void md2_hmac_finish( md2_context *ctx, unsigned char output[16] );
|
||||
|
||||
/**
|
||||
* \brief MD2 HMAC context reset
|
||||
*
|
||||
* \param ctx HMAC context to be reset
|
||||
*/
|
||||
void md2_hmac_reset( md2_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Output = HMAC-MD2( 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-MD2 result
|
||||
*/
|
||||
void md2_hmac( const unsigned char *key, size_t keylen,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char output[16] );
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int md2_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* md2.h */
|
||||
+464
@@ -0,0 +1,464 @@
|
||||
/*
|
||||
* RFC 1186/1320 compliant MD4 implementation
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
* The MD4 algorithm was designed by Ron Rivest in 1990.
|
||||
*
|
||||
* http://www.ietf.org/rfc/rfc1186.txt
|
||||
* http://www.ietf.org/rfc/rfc1320.txt
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_MD4_C)
|
||||
|
||||
#include "polarssl/md4.h"
|
||||
|
||||
#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if !defined(POLARSSL_MD4_ALT)
|
||||
|
||||
/*
|
||||
* 32-bit integer manipulation macros (little endian)
|
||||
*/
|
||||
#ifndef GET_UINT32_LE
|
||||
#define GET_UINT32_LE(n,b,i) \
|
||||
{ \
|
||||
(n) = ( (uint32_t) (b)[(i) ] ) \
|
||||
| ( (uint32_t) (b)[(i) + 1] << 8 ) \
|
||||
| ( (uint32_t) (b)[(i) + 2] << 16 ) \
|
||||
| ( (uint32_t) (b)[(i) + 3] << 24 ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PUT_UINT32_LE
|
||||
#define PUT_UINT32_LE(n,b,i) \
|
||||
{ \
|
||||
(b)[(i) ] = (unsigned char) ( (n) ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MD4 context setup
|
||||
*/
|
||||
void md4_starts( md4_context *ctx )
|
||||
{
|
||||
ctx->total[0] = 0;
|
||||
ctx->total[1] = 0;
|
||||
|
||||
ctx->state[0] = 0x67452301;
|
||||
ctx->state[1] = 0xEFCDAB89;
|
||||
ctx->state[2] = 0x98BADCFE;
|
||||
ctx->state[3] = 0x10325476;
|
||||
}
|
||||
|
||||
static void md4_process( md4_context *ctx, const unsigned char data[64] )
|
||||
{
|
||||
uint32_t X[16], A, B, C, D;
|
||||
|
||||
GET_UINT32_LE( X[ 0], data, 0 );
|
||||
GET_UINT32_LE( X[ 1], data, 4 );
|
||||
GET_UINT32_LE( X[ 2], data, 8 );
|
||||
GET_UINT32_LE( X[ 3], data, 12 );
|
||||
GET_UINT32_LE( X[ 4], data, 16 );
|
||||
GET_UINT32_LE( X[ 5], data, 20 );
|
||||
GET_UINT32_LE( X[ 6], data, 24 );
|
||||
GET_UINT32_LE( X[ 7], data, 28 );
|
||||
GET_UINT32_LE( X[ 8], data, 32 );
|
||||
GET_UINT32_LE( X[ 9], data, 36 );
|
||||
GET_UINT32_LE( X[10], data, 40 );
|
||||
GET_UINT32_LE( X[11], data, 44 );
|
||||
GET_UINT32_LE( X[12], data, 48 );
|
||||
GET_UINT32_LE( X[13], data, 52 );
|
||||
GET_UINT32_LE( X[14], data, 56 );
|
||||
GET_UINT32_LE( X[15], data, 60 );
|
||||
|
||||
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
|
||||
|
||||
A = ctx->state[0];
|
||||
B = ctx->state[1];
|
||||
C = ctx->state[2];
|
||||
D = ctx->state[3];
|
||||
|
||||
#define F(x, y, z) ((x & y) | ((~x) & z))
|
||||
#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
|
||||
|
||||
P( A, B, C, D, X[ 0], 3 );
|
||||
P( D, A, B, C, X[ 1], 7 );
|
||||
P( C, D, A, B, X[ 2], 11 );
|
||||
P( B, C, D, A, X[ 3], 19 );
|
||||
P( A, B, C, D, X[ 4], 3 );
|
||||
P( D, A, B, C, X[ 5], 7 );
|
||||
P( C, D, A, B, X[ 6], 11 );
|
||||
P( B, C, D, A, X[ 7], 19 );
|
||||
P( A, B, C, D, X[ 8], 3 );
|
||||
P( D, A, B, C, X[ 9], 7 );
|
||||
P( C, D, A, B, X[10], 11 );
|
||||
P( B, C, D, A, X[11], 19 );
|
||||
P( A, B, C, D, X[12], 3 );
|
||||
P( D, A, B, C, X[13], 7 );
|
||||
P( C, D, A, B, X[14], 11 );
|
||||
P( B, C, D, A, X[15], 19 );
|
||||
|
||||
#undef P
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) ((x & y) | (x & z) | (y & z))
|
||||
#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
|
||||
|
||||
P( A, B, C, D, X[ 0], 3 );
|
||||
P( D, A, B, C, X[ 4], 5 );
|
||||
P( C, D, A, B, X[ 8], 9 );
|
||||
P( B, C, D, A, X[12], 13 );
|
||||
P( A, B, C, D, X[ 1], 3 );
|
||||
P( D, A, B, C, X[ 5], 5 );
|
||||
P( C, D, A, B, X[ 9], 9 );
|
||||
P( B, C, D, A, X[13], 13 );
|
||||
P( A, B, C, D, X[ 2], 3 );
|
||||
P( D, A, B, C, X[ 6], 5 );
|
||||
P( C, D, A, B, X[10], 9 );
|
||||
P( B, C, D, A, X[14], 13 );
|
||||
P( A, B, C, D, X[ 3], 3 );
|
||||
P( D, A, B, C, X[ 7], 5 );
|
||||
P( C, D, A, B, X[11], 9 );
|
||||
P( B, C, D, A, X[15], 13 );
|
||||
|
||||
#undef P
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) (x ^ y ^ z)
|
||||
#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
|
||||
|
||||
P( A, B, C, D, X[ 0], 3 );
|
||||
P( D, A, B, C, X[ 8], 9 );
|
||||
P( C, D, A, B, X[ 4], 11 );
|
||||
P( B, C, D, A, X[12], 15 );
|
||||
P( A, B, C, D, X[ 2], 3 );
|
||||
P( D, A, B, C, X[10], 9 );
|
||||
P( C, D, A, B, X[ 6], 11 );
|
||||
P( B, C, D, A, X[14], 15 );
|
||||
P( A, B, C, D, X[ 1], 3 );
|
||||
P( D, A, B, C, X[ 9], 9 );
|
||||
P( C, D, A, B, X[ 5], 11 );
|
||||
P( B, C, D, A, X[13], 15 );
|
||||
P( A, B, C, D, X[ 3], 3 );
|
||||
P( D, A, B, C, X[11], 9 );
|
||||
P( C, D, A, B, X[ 7], 11 );
|
||||
P( B, C, D, A, X[15], 15 );
|
||||
|
||||
#undef F
|
||||
#undef P
|
||||
|
||||
ctx->state[0] += A;
|
||||
ctx->state[1] += B;
|
||||
ctx->state[2] += C;
|
||||
ctx->state[3] += D;
|
||||
}
|
||||
|
||||
/*
|
||||
* MD4 process buffer
|
||||
*/
|
||||
void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
size_t fill;
|
||||
uint32_t left;
|
||||
|
||||
if( ilen <= 0 )
|
||||
return;
|
||||
|
||||
left = ctx->total[0] & 0x3F;
|
||||
fill = 64 - left;
|
||||
|
||||
ctx->total[0] += (uint32_t) ilen;
|
||||
ctx->total[0] &= 0xFFFFFFFF;
|
||||
|
||||
if( ctx->total[0] < (uint32_t) ilen )
|
||||
ctx->total[1]++;
|
||||
|
||||
if( left && ilen >= fill )
|
||||
{
|
||||
memcpy( (void *) (ctx->buffer + left),
|
||||
(void *) input, fill );
|
||||
md4_process( ctx, ctx->buffer );
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while( ilen >= 64 )
|
||||
{
|
||||
md4_process( ctx, input );
|
||||
input += 64;
|
||||
ilen -= 64;
|
||||
}
|
||||
|
||||
if( ilen > 0 )
|
||||
{
|
||||
memcpy( (void *) (ctx->buffer + left),
|
||||
(void *) input, ilen );
|
||||
}
|
||||
}
|
||||
|
||||
static const unsigned char md4_padding[64] =
|
||||
{
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* MD4 final digest
|
||||
*/
|
||||
void md4_finish( md4_context *ctx, unsigned char output[16] )
|
||||
{
|
||||
uint32_t last, padn;
|
||||
uint32_t high, low;
|
||||
unsigned char msglen[8];
|
||||
|
||||
high = ( ctx->total[0] >> 29 )
|
||||
| ( ctx->total[1] << 3 );
|
||||
low = ( ctx->total[0] << 3 );
|
||||
|
||||
PUT_UINT32_LE( low, msglen, 0 );
|
||||
PUT_UINT32_LE( high, msglen, 4 );
|
||||
|
||||
last = ctx->total[0] & 0x3F;
|
||||
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
|
||||
|
||||
md4_update( ctx, (unsigned char *) md4_padding, padn );
|
||||
md4_update( ctx, msglen, 8 );
|
||||
|
||||
PUT_UINT32_LE( ctx->state[0], output, 0 );
|
||||
PUT_UINT32_LE( ctx->state[1], output, 4 );
|
||||
PUT_UINT32_LE( ctx->state[2], output, 8 );
|
||||
PUT_UINT32_LE( ctx->state[3], output, 12 );
|
||||
}
|
||||
|
||||
#endif /* !POLARSSL_MD4_ALT */
|
||||
|
||||
/*
|
||||
* output = MD4( input buffer )
|
||||
*/
|
||||
void md4( const unsigned char *input, size_t ilen, unsigned char output[16] )
|
||||
{
|
||||
md4_context ctx;
|
||||
|
||||
md4_starts( &ctx );
|
||||
md4_update( &ctx, input, ilen );
|
||||
md4_finish( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( md4_context ) );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
/*
|
||||
* output = MD4( file contents )
|
||||
*/
|
||||
int md4_file( const char *path, unsigned char output[16] )
|
||||
{
|
||||
FILE *f;
|
||||
size_t n;
|
||||
md4_context ctx;
|
||||
unsigned char buf[1024];
|
||||
|
||||
if( ( f = fopen( path, "rb" ) ) == NULL )
|
||||
return( POLARSSL_ERR_MD4_FILE_IO_ERROR );
|
||||
|
||||
md4_starts( &ctx );
|
||||
|
||||
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
|
||||
md4_update( &ctx, buf, n );
|
||||
|
||||
md4_finish( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( md4_context ) );
|
||||
|
||||
if( ferror( f ) != 0 )
|
||||
{
|
||||
fclose( f );
|
||||
return( POLARSSL_ERR_MD4_FILE_IO_ERROR );
|
||||
}
|
||||
|
||||
fclose( f );
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* POLARSSL_FS_IO */
|
||||
|
||||
/*
|
||||
* MD4 HMAC context setup
|
||||
*/
|
||||
void md4_hmac_starts( md4_context *ctx, const unsigned char *key, size_t keylen )
|
||||
{
|
||||
size_t i;
|
||||
unsigned char sum[16];
|
||||
|
||||
if( keylen > 64 )
|
||||
{
|
||||
md4( key, keylen, sum );
|
||||
keylen = 16;
|
||||
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] );
|
||||
}
|
||||
|
||||
md4_starts( ctx );
|
||||
md4_update( ctx, ctx->ipad, 64 );
|
||||
|
||||
memset( sum, 0, sizeof( sum ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* MD4 HMAC process buffer
|
||||
*/
|
||||
void md4_hmac_update( md4_context *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
md4_update( ctx, input, ilen );
|
||||
}
|
||||
|
||||
/*
|
||||
* MD4 HMAC final digest
|
||||
*/
|
||||
void md4_hmac_finish( md4_context *ctx, unsigned char output[16] )
|
||||
{
|
||||
unsigned char tmpbuf[16];
|
||||
|
||||
md4_finish( ctx, tmpbuf );
|
||||
md4_starts( ctx );
|
||||
md4_update( ctx, ctx->opad, 64 );
|
||||
md4_update( ctx, tmpbuf, 16 );
|
||||
md4_finish( ctx, output );
|
||||
|
||||
memset( tmpbuf, 0, sizeof( tmpbuf ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* MD4 HMAC context reset
|
||||
*/
|
||||
void md4_hmac_reset( md4_context *ctx )
|
||||
{
|
||||
md4_starts( ctx );
|
||||
md4_update( ctx, ctx->ipad, 64 );
|
||||
}
|
||||
|
||||
/*
|
||||
* output = HMAC-MD4( hmac key, input buffer )
|
||||
*/
|
||||
void md4_hmac( const unsigned char *key, size_t keylen,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char output[16] )
|
||||
{
|
||||
md4_context ctx;
|
||||
|
||||
md4_hmac_starts( &ctx, key, keylen );
|
||||
md4_hmac_update( &ctx, input, ilen );
|
||||
md4_hmac_finish( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( md4_context ) );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_SELF_TEST)
|
||||
|
||||
/*
|
||||
* RFC 1320 test vectors
|
||||
*/
|
||||
static const char md4_test_str[7][81] =
|
||||
{
|
||||
{ "" },
|
||||
{ "a" },
|
||||
{ "abc" },
|
||||
{ "message digest" },
|
||||
{ "abcdefghijklmnopqrstuvwxyz" },
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
|
||||
{ "12345678901234567890123456789012345678901234567890123456789012" \
|
||||
"345678901234567890" }
|
||||
};
|
||||
|
||||
static const unsigned char md4_test_sum[7][16] =
|
||||
{
|
||||
{ 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
|
||||
0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
|
||||
{ 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
|
||||
0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
|
||||
{ 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
|
||||
0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
|
||||
{ 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
|
||||
0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
|
||||
{ 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
|
||||
0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
|
||||
{ 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
|
||||
0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
|
||||
{ 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
|
||||
0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
|
||||
};
|
||||
|
||||
/*
|
||||
* Checkup routine
|
||||
*/
|
||||
int md4_self_test( int verbose )
|
||||
{
|
||||
int i;
|
||||
unsigned char md4sum[16];
|
||||
|
||||
for( i = 0; i < 7; i++ )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( " MD4 test #%d: ", i + 1 );
|
||||
|
||||
md4( (unsigned char *) md4_test_str[i],
|
||||
strlen( md4_test_str[i] ), md4sum );
|
||||
|
||||
if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "passed\n" );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "\n" );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+177
@@ -0,0 +1,177 @@
|
||||
/**
|
||||
* \file md4.h
|
||||
*
|
||||
* \brief MD4 message digest algorithm (hash function)
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef POLARSSL_MD4_H
|
||||
#define POLARSSL_MD4_H
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <basetsd.h>
|
||||
typedef UINT32 uint32_t;
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#define POLARSSL_ERR_MD4_FILE_IO_ERROR -0x0072 /**< Read/write error in file. */
|
||||
|
||||
#if !defined(POLARSSL_MD4_ALT)
|
||||
// Regular implementation
|
||||
//
|
||||
|
||||
/**
|
||||
* \brief MD4 context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t total[2]; /*!< number of bytes processed */
|
||||
uint32_t state[4]; /*!< 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 */
|
||||
}
|
||||
md4_context;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief MD4 context setup
|
||||
*
|
||||
* \param ctx context to be initialized
|
||||
*/
|
||||
void md4_starts( md4_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief MD4 process buffer
|
||||
*
|
||||
* \param ctx MD4 context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief MD4 final digest
|
||||
*
|
||||
* \param ctx MD4 context
|
||||
* \param output MD4 checksum result
|
||||
*/
|
||||
void md4_finish( md4_context *ctx, unsigned char output[16] );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* POLARSSL_MD4_ALT */
|
||||
#include "polarssl/md4_alt.h"
|
||||
#endif /* POLARSSL_MD4_ALT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Output = MD4( input buffer )
|
||||
*
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
* \param output MD4 checksum result
|
||||
*/
|
||||
void md4( const unsigned char *input, size_t ilen, unsigned char output[16] );
|
||||
|
||||
/**
|
||||
* \brief Output = MD4( file contents )
|
||||
*
|
||||
* \param path input file name
|
||||
* \param output MD4 checksum result
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_MD4_FILE_IO_ERROR
|
||||
*/
|
||||
int md4_file( const char *path, unsigned char output[16] );
|
||||
|
||||
/**
|
||||
* \brief MD4 HMAC context setup
|
||||
*
|
||||
* \param ctx HMAC context to be initialized
|
||||
* \param key HMAC secret key
|
||||
* \param keylen length of the HMAC key
|
||||
*/
|
||||
void md4_hmac_starts( md4_context *ctx, const unsigned char *key, size_t keylen );
|
||||
|
||||
/**
|
||||
* \brief MD4 HMAC process buffer
|
||||
*
|
||||
* \param ctx HMAC context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void md4_hmac_update( md4_context *ctx, const unsigned char *input, size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief MD4 HMAC final digest
|
||||
*
|
||||
* \param ctx HMAC context
|
||||
* \param output MD4 HMAC checksum result
|
||||
*/
|
||||
void md4_hmac_finish( md4_context *ctx, unsigned char output[16] );
|
||||
|
||||
/**
|
||||
* \brief MD4 HMAC context reset
|
||||
*
|
||||
* \param ctx HMAC context to be reset
|
||||
*/
|
||||
void md4_hmac_reset( md4_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Output = HMAC-MD4( 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-MD4 result
|
||||
*/
|
||||
void md4_hmac( const unsigned char *key, size_t keylen,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char output[16] );
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int md4_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* md4.h */
|
||||
+585
@@ -0,0 +1,585 @@
|
||||
/*
|
||||
* RFC 1321 compliant MD5 implementation
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
* The MD5 algorithm was designed by Ron Rivest in 1991.
|
||||
*
|
||||
* http://www.ietf.org/rfc/rfc1321.txt
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_MD5_C)
|
||||
|
||||
#include "polarssl/md5.h"
|
||||
|
||||
#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if !defined(POLARSSL_MD5_ALT)
|
||||
|
||||
/*
|
||||
* 32-bit integer manipulation macros (little endian)
|
||||
*/
|
||||
#ifndef GET_UINT32_LE
|
||||
#define GET_UINT32_LE(n,b,i) \
|
||||
{ \
|
||||
(n) = ( (uint32_t) (b)[(i) ] ) \
|
||||
| ( (uint32_t) (b)[(i) + 1] << 8 ) \
|
||||
| ( (uint32_t) (b)[(i) + 2] << 16 ) \
|
||||
| ( (uint32_t) (b)[(i) + 3] << 24 ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PUT_UINT32_LE
|
||||
#define PUT_UINT32_LE(n,b,i) \
|
||||
{ \
|
||||
(b)[(i) ] = (unsigned char) ( (n) ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MD5 context setup
|
||||
*/
|
||||
void md5_starts( md5_context *ctx )
|
||||
{
|
||||
ctx->total[0] = 0;
|
||||
ctx->total[1] = 0;
|
||||
|
||||
ctx->state[0] = 0x67452301;
|
||||
ctx->state[1] = 0xEFCDAB89;
|
||||
ctx->state[2] = 0x98BADCFE;
|
||||
ctx->state[3] = 0x10325476;
|
||||
}
|
||||
|
||||
void md5_process( md5_context *ctx, const unsigned char data[64] )
|
||||
{
|
||||
uint32_t X[16], A, B, C, D;
|
||||
|
||||
GET_UINT32_LE( X[ 0], data, 0 );
|
||||
GET_UINT32_LE( X[ 1], data, 4 );
|
||||
GET_UINT32_LE( X[ 2], data, 8 );
|
||||
GET_UINT32_LE( X[ 3], data, 12 );
|
||||
GET_UINT32_LE( X[ 4], data, 16 );
|
||||
GET_UINT32_LE( X[ 5], data, 20 );
|
||||
GET_UINT32_LE( X[ 6], data, 24 );
|
||||
GET_UINT32_LE( X[ 7], data, 28 );
|
||||
GET_UINT32_LE( X[ 8], data, 32 );
|
||||
GET_UINT32_LE( X[ 9], data, 36 );
|
||||
GET_UINT32_LE( X[10], data, 40 );
|
||||
GET_UINT32_LE( X[11], data, 44 );
|
||||
GET_UINT32_LE( X[12], data, 48 );
|
||||
GET_UINT32_LE( X[13], data, 52 );
|
||||
GET_UINT32_LE( X[14], data, 56 );
|
||||
GET_UINT32_LE( X[15], data, 60 );
|
||||
|
||||
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
|
||||
|
||||
#define P(a,b,c,d,k,s,t) \
|
||||
{ \
|
||||
a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
|
||||
}
|
||||
|
||||
A = ctx->state[0];
|
||||
B = ctx->state[1];
|
||||
C = ctx->state[2];
|
||||
D = ctx->state[3];
|
||||
|
||||
#define F(x,y,z) (z ^ (x & (y ^ z)))
|
||||
|
||||
P( A, B, C, D, 0, 7, 0xD76AA478 );
|
||||
P( D, A, B, C, 1, 12, 0xE8C7B756 );
|
||||
P( C, D, A, B, 2, 17, 0x242070DB );
|
||||
P( B, C, D, A, 3, 22, 0xC1BDCEEE );
|
||||
P( A, B, C, D, 4, 7, 0xF57C0FAF );
|
||||
P( D, A, B, C, 5, 12, 0x4787C62A );
|
||||
P( C, D, A, B, 6, 17, 0xA8304613 );
|
||||
P( B, C, D, A, 7, 22, 0xFD469501 );
|
||||
P( A, B, C, D, 8, 7, 0x698098D8 );
|
||||
P( D, A, B, C, 9, 12, 0x8B44F7AF );
|
||||
P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
|
||||
P( B, C, D, A, 11, 22, 0x895CD7BE );
|
||||
P( A, B, C, D, 12, 7, 0x6B901122 );
|
||||
P( D, A, B, C, 13, 12, 0xFD987193 );
|
||||
P( C, D, A, B, 14, 17, 0xA679438E );
|
||||
P( B, C, D, A, 15, 22, 0x49B40821 );
|
||||
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) (y ^ (z & (x ^ y)))
|
||||
|
||||
P( A, B, C, D, 1, 5, 0xF61E2562 );
|
||||
P( D, A, B, C, 6, 9, 0xC040B340 );
|
||||
P( C, D, A, B, 11, 14, 0x265E5A51 );
|
||||
P( B, C, D, A, 0, 20, 0xE9B6C7AA );
|
||||
P( A, B, C, D, 5, 5, 0xD62F105D );
|
||||
P( D, A, B, C, 10, 9, 0x02441453 );
|
||||
P( C, D, A, B, 15, 14, 0xD8A1E681 );
|
||||
P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
|
||||
P( A, B, C, D, 9, 5, 0x21E1CDE6 );
|
||||
P( D, A, B, C, 14, 9, 0xC33707D6 );
|
||||
P( C, D, A, B, 3, 14, 0xF4D50D87 );
|
||||
P( B, C, D, A, 8, 20, 0x455A14ED );
|
||||
P( A, B, C, D, 13, 5, 0xA9E3E905 );
|
||||
P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
|
||||
P( C, D, A, B, 7, 14, 0x676F02D9 );
|
||||
P( B, C, D, A, 12, 20, 0x8D2A4C8A );
|
||||
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) (x ^ y ^ z)
|
||||
|
||||
P( A, B, C, D, 5, 4, 0xFFFA3942 );
|
||||
P( D, A, B, C, 8, 11, 0x8771F681 );
|
||||
P( C, D, A, B, 11, 16, 0x6D9D6122 );
|
||||
P( B, C, D, A, 14, 23, 0xFDE5380C );
|
||||
P( A, B, C, D, 1, 4, 0xA4BEEA44 );
|
||||
P( D, A, B, C, 4, 11, 0x4BDECFA9 );
|
||||
P( C, D, A, B, 7, 16, 0xF6BB4B60 );
|
||||
P( B, C, D, A, 10, 23, 0xBEBFBC70 );
|
||||
P( A, B, C, D, 13, 4, 0x289B7EC6 );
|
||||
P( D, A, B, C, 0, 11, 0xEAA127FA );
|
||||
P( C, D, A, B, 3, 16, 0xD4EF3085 );
|
||||
P( B, C, D, A, 6, 23, 0x04881D05 );
|
||||
P( A, B, C, D, 9, 4, 0xD9D4D039 );
|
||||
P( D, A, B, C, 12, 11, 0xE6DB99E5 );
|
||||
P( C, D, A, B, 15, 16, 0x1FA27CF8 );
|
||||
P( B, C, D, A, 2, 23, 0xC4AC5665 );
|
||||
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) (y ^ (x | ~z))
|
||||
|
||||
P( A, B, C, D, 0, 6, 0xF4292244 );
|
||||
P( D, A, B, C, 7, 10, 0x432AFF97 );
|
||||
P( C, D, A, B, 14, 15, 0xAB9423A7 );
|
||||
P( B, C, D, A, 5, 21, 0xFC93A039 );
|
||||
P( A, B, C, D, 12, 6, 0x655B59C3 );
|
||||
P( D, A, B, C, 3, 10, 0x8F0CCC92 );
|
||||
P( C, D, A, B, 10, 15, 0xFFEFF47D );
|
||||
P( B, C, D, A, 1, 21, 0x85845DD1 );
|
||||
P( A, B, C, D, 8, 6, 0x6FA87E4F );
|
||||
P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
|
||||
P( C, D, A, B, 6, 15, 0xA3014314 );
|
||||
P( B, C, D, A, 13, 21, 0x4E0811A1 );
|
||||
P( A, B, C, D, 4, 6, 0xF7537E82 );
|
||||
P( D, A, B, C, 11, 10, 0xBD3AF235 );
|
||||
P( C, D, A, B, 2, 15, 0x2AD7D2BB );
|
||||
P( B, C, D, A, 9, 21, 0xEB86D391 );
|
||||
|
||||
#undef F
|
||||
|
||||
ctx->state[0] += A;
|
||||
ctx->state[1] += B;
|
||||
ctx->state[2] += C;
|
||||
ctx->state[3] += D;
|
||||
}
|
||||
|
||||
/*
|
||||
* MD5 process buffer
|
||||
*/
|
||||
void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
size_t fill;
|
||||
uint32_t left;
|
||||
|
||||
if( ilen <= 0 )
|
||||
return;
|
||||
|
||||
left = ctx->total[0] & 0x3F;
|
||||
fill = 64 - left;
|
||||
|
||||
ctx->total[0] += (uint32_t) ilen;
|
||||
ctx->total[0] &= 0xFFFFFFFF;
|
||||
|
||||
if( ctx->total[0] < (uint32_t) ilen )
|
||||
ctx->total[1]++;
|
||||
|
||||
if( left && ilen >= fill )
|
||||
{
|
||||
memcpy( (void *) (ctx->buffer + left), input, fill );
|
||||
md5_process( ctx, ctx->buffer );
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while( ilen >= 64 )
|
||||
{
|
||||
md5_process( ctx, input );
|
||||
input += 64;
|
||||
ilen -= 64;
|
||||
}
|
||||
|
||||
if( ilen > 0 )
|
||||
{
|
||||
memcpy( (void *) (ctx->buffer + left), input, ilen );
|
||||
}
|
||||
}
|
||||
|
||||
static const unsigned char md5_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
|
||||
};
|
||||
|
||||
/*
|
||||
* MD5 final digest
|
||||
*/
|
||||
void md5_finish( md5_context *ctx, unsigned char output[16] )
|
||||
{
|
||||
uint32_t last, padn;
|
||||
uint32_t high, low;
|
||||
unsigned char msglen[8];
|
||||
|
||||
high = ( ctx->total[0] >> 29 )
|
||||
| ( ctx->total[1] << 3 );
|
||||
low = ( ctx->total[0] << 3 );
|
||||
|
||||
PUT_UINT32_LE( low, msglen, 0 );
|
||||
PUT_UINT32_LE( high, msglen, 4 );
|
||||
|
||||
last = ctx->total[0] & 0x3F;
|
||||
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
|
||||
|
||||
md5_update( ctx, md5_padding, padn );
|
||||
md5_update( ctx, msglen, 8 );
|
||||
|
||||
PUT_UINT32_LE( ctx->state[0], output, 0 );
|
||||
PUT_UINT32_LE( ctx->state[1], output, 4 );
|
||||
PUT_UINT32_LE( ctx->state[2], output, 8 );
|
||||
PUT_UINT32_LE( ctx->state[3], output, 12 );
|
||||
}
|
||||
|
||||
#endif /* !POLARSSL_MD5_ALT */
|
||||
|
||||
/*
|
||||
* output = MD5( input buffer )
|
||||
*/
|
||||
void md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
|
||||
{
|
||||
md5_context ctx;
|
||||
|
||||
md5_starts( &ctx );
|
||||
md5_update( &ctx, input, ilen );
|
||||
md5_finish( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( md5_context ) );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
/*
|
||||
* output = MD5( file contents )
|
||||
*/
|
||||
int md5_file( const char *path, unsigned char output[16] )
|
||||
{
|
||||
FILE *f;
|
||||
size_t n;
|
||||
md5_context ctx;
|
||||
unsigned char buf[1024];
|
||||
|
||||
if( ( f = fopen( path, "rb" ) ) == NULL )
|
||||
return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
|
||||
|
||||
md5_starts( &ctx );
|
||||
|
||||
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
|
||||
md5_update( &ctx, buf, n );
|
||||
|
||||
md5_finish( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( md5_context ) );
|
||||
|
||||
if( ferror( f ) != 0 )
|
||||
{
|
||||
fclose( f );
|
||||
return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
|
||||
}
|
||||
|
||||
fclose( f );
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* POLARSSL_FS_IO */
|
||||
|
||||
/*
|
||||
* MD5 HMAC context setup
|
||||
*/
|
||||
void md5_hmac_starts( md5_context *ctx, const unsigned char *key, size_t keylen )
|
||||
{
|
||||
size_t i;
|
||||
unsigned char sum[16];
|
||||
|
||||
if( keylen > 64 )
|
||||
{
|
||||
md5( key, keylen, sum );
|
||||
keylen = 16;
|
||||
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] );
|
||||
}
|
||||
|
||||
md5_starts( ctx );
|
||||
md5_update( ctx, ctx->ipad, 64 );
|
||||
|
||||
memset( sum, 0, sizeof( sum ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* MD5 HMAC process buffer
|
||||
*/
|
||||
void md5_hmac_update( md5_context *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
md5_update( ctx, input, ilen );
|
||||
}
|
||||
|
||||
/*
|
||||
* MD5 HMAC final digest
|
||||
*/
|
||||
void md5_hmac_finish( md5_context *ctx, unsigned char output[16] )
|
||||
{
|
||||
unsigned char tmpbuf[16];
|
||||
|
||||
md5_finish( ctx, tmpbuf );
|
||||
md5_starts( ctx );
|
||||
md5_update( ctx, ctx->opad, 64 );
|
||||
md5_update( ctx, tmpbuf, 16 );
|
||||
md5_finish( ctx, output );
|
||||
|
||||
memset( tmpbuf, 0, sizeof( tmpbuf ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* MD5 HMAC context reset
|
||||
*/
|
||||
void md5_hmac_reset( md5_context *ctx )
|
||||
{
|
||||
md5_starts( ctx );
|
||||
md5_update( ctx, ctx->ipad, 64 );
|
||||
}
|
||||
|
||||
/*
|
||||
* output = HMAC-MD5( hmac key, input buffer )
|
||||
*/
|
||||
void md5_hmac( const unsigned char *key, size_t keylen,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char output[16] )
|
||||
{
|
||||
md5_context ctx;
|
||||
|
||||
md5_hmac_starts( &ctx, key, keylen );
|
||||
md5_hmac_update( &ctx, input, ilen );
|
||||
md5_hmac_finish( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( md5_context ) );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_SELF_TEST)
|
||||
/*
|
||||
* RFC 1321 test vectors
|
||||
*/
|
||||
static unsigned char md5_test_buf[7][81] =
|
||||
{
|
||||
{ "" },
|
||||
{ "a" },
|
||||
{ "abc" },
|
||||
{ "message digest" },
|
||||
{ "abcdefghijklmnopqrstuvwxyz" },
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
|
||||
{ "12345678901234567890123456789012345678901234567890123456789012" \
|
||||
"345678901234567890" }
|
||||
};
|
||||
|
||||
static const int md5_test_buflen[7] =
|
||||
{
|
||||
0, 1, 3, 14, 26, 62, 80
|
||||
};
|
||||
|
||||
static const unsigned char md5_test_sum[7][16] =
|
||||
{
|
||||
{ 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
|
||||
0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
|
||||
{ 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
|
||||
0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
|
||||
{ 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
|
||||
0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
|
||||
{ 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
|
||||
0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
|
||||
{ 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
|
||||
0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
|
||||
{ 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
|
||||
0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
|
||||
{ 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
|
||||
0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
|
||||
};
|
||||
|
||||
/*
|
||||
* RFC 2202 test vectors
|
||||
*/
|
||||
static unsigned char md5_hmac_test_key[7][26] =
|
||||
{
|
||||
{ "\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" },
|
||||
{ "\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" },
|
||||
{ "" }, /* 0xAA 80 times */
|
||||
{ "" }
|
||||
};
|
||||
|
||||
static const int md5_hmac_test_keylen[7] =
|
||||
{
|
||||
16, 4, 16, 25, 16, 80, 80
|
||||
};
|
||||
|
||||
static unsigned char md5_hmac_test_buf[7][74] =
|
||||
{
|
||||
{ "Hi There" },
|
||||
{ "what do ya want for nothing?" },
|
||||
{ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
|
||||
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
|
||||
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
|
||||
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
|
||||
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
|
||||
{ "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
|
||||
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
|
||||
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
|
||||
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
|
||||
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
|
||||
{ "Test With Truncation" },
|
||||
{ "Test Using Larger Than Block-Size Key - Hash Key First" },
|
||||
{ "Test Using Larger Than Block-Size Key and Larger"
|
||||
" Than One Block-Size Data" }
|
||||
};
|
||||
|
||||
static const int md5_hmac_test_buflen[7] =
|
||||
{
|
||||
8, 28, 50, 50, 20, 54, 73
|
||||
};
|
||||
|
||||
static const unsigned char md5_hmac_test_sum[7][16] =
|
||||
{
|
||||
{ 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C,
|
||||
0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D },
|
||||
{ 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03,
|
||||
0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 },
|
||||
{ 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88,
|
||||
0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 },
|
||||
{ 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA,
|
||||
0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 },
|
||||
{ 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00,
|
||||
0xF9, 0xBA, 0xB9, 0x95 },
|
||||
{ 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F,
|
||||
0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD },
|
||||
{ 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE,
|
||||
0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E }
|
||||
};
|
||||
|
||||
/*
|
||||
* Checkup routine
|
||||
*/
|
||||
int md5_self_test( int verbose )
|
||||
{
|
||||
int i, buflen;
|
||||
unsigned char buf[1024];
|
||||
unsigned char md5sum[16];
|
||||
md5_context ctx;
|
||||
|
||||
for( i = 0; i < 7; i++ )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( " MD5 test #%d: ", i + 1 );
|
||||
|
||||
md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
|
||||
|
||||
if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "passed\n" );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "\n" );
|
||||
|
||||
for( i = 0; i < 7; i++ )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( " HMAC-MD5 test #%d: ", i + 1 );
|
||||
|
||||
if( i == 5 || i == 6 )
|
||||
{
|
||||
memset( buf, '\xAA', buflen = 80 );
|
||||
md5_hmac_starts( &ctx, buf, buflen );
|
||||
}
|
||||
else
|
||||
md5_hmac_starts( &ctx, md5_hmac_test_key[i],
|
||||
md5_hmac_test_keylen[i] );
|
||||
|
||||
md5_hmac_update( &ctx, md5_hmac_test_buf[i],
|
||||
md5_hmac_test_buflen[i] );
|
||||
|
||||
md5_hmac_finish( &ctx, md5sum );
|
||||
|
||||
buflen = ( i == 4 ) ? 12 : 16;
|
||||
|
||||
if( memcmp( md5sum, md5_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
|
||||
+182
@@ -0,0 +1,182 @@
|
||||
/**
|
||||
* \file md5.h
|
||||
*
|
||||
* \brief MD5 message digest algorithm (hash function)
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef POLARSSL_MD5_H
|
||||
#define POLARSSL_MD5_H
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <basetsd.h>
|
||||
typedef UINT32 uint32_t;
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#define POLARSSL_ERR_MD5_FILE_IO_ERROR -0x0074 /**< Read/write error in file. */
|
||||
|
||||
#if !defined(POLARSSL_MD5_ALT)
|
||||
// Regular implementation
|
||||
//
|
||||
|
||||
/**
|
||||
* \brief MD5 context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t total[2]; /*!< number of bytes processed */
|
||||
uint32_t state[4]; /*!< 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 */
|
||||
}
|
||||
md5_context;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief MD5 context setup
|
||||
*
|
||||
* \param ctx context to be initialized
|
||||
*/
|
||||
void md5_starts( md5_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief MD5 process buffer
|
||||
*
|
||||
* \param ctx MD5 context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief MD5 final digest
|
||||
*
|
||||
* \param ctx MD5 context
|
||||
* \param output MD5 checksum result
|
||||
*/
|
||||
void md5_finish( md5_context *ctx, unsigned char output[16] );
|
||||
|
||||
/* Internal use */
|
||||
void md5_process( md5_context *ctx, const unsigned char data[64] );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* POLARSSL_MD5_ALT */
|
||||
#include "polarssl/md5_alt.h"
|
||||
#endif /* POLARSSL_MD5_ALT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Output = MD5( input buffer )
|
||||
*
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
* \param output MD5 checksum result
|
||||
*/
|
||||
void md5( const unsigned char *input, size_t ilen, unsigned char output[16] );
|
||||
|
||||
/**
|
||||
* \brief Output = MD5( file contents )
|
||||
*
|
||||
* \param path input file name
|
||||
* \param output MD5 checksum result
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_MD5_FILE_IO_ERROR
|
||||
*/
|
||||
int md5_file( const char *path, unsigned char output[16] );
|
||||
|
||||
/**
|
||||
* \brief MD5 HMAC context setup
|
||||
*
|
||||
* \param ctx HMAC context to be initialized
|
||||
* \param key HMAC secret key
|
||||
* \param keylen length of the HMAC key
|
||||
*/
|
||||
void md5_hmac_starts( md5_context *ctx,
|
||||
const unsigned char *key, size_t keylen );
|
||||
|
||||
/**
|
||||
* \brief MD5 HMAC process buffer
|
||||
*
|
||||
* \param ctx HMAC context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void md5_hmac_update( md5_context *ctx,
|
||||
const unsigned char *input, size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief MD5 HMAC final digest
|
||||
*
|
||||
* \param ctx HMAC context
|
||||
* \param output MD5 HMAC checksum result
|
||||
*/
|
||||
void md5_hmac_finish( md5_context *ctx, unsigned char output[16] );
|
||||
|
||||
/**
|
||||
* \brief MD5 HMAC context reset
|
||||
*
|
||||
* \param ctx HMAC context to be reset
|
||||
*/
|
||||
void md5_hmac_reset( md5_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Output = HMAC-MD5( 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-MD5 result
|
||||
*/
|
||||
void md5_hmac( const unsigned char *key, size_t keylen,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char output[16] );
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int md5_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* md5.h */
|
||||
@@ -0,0 +1,733 @@
|
||||
/**
|
||||
* \file md_wrap.c
|
||||
|
||||
* \brief Generic message digest wrapper for PolarSSL
|
||||
*
|
||||
* \author Adriaan de Jong <dejong@fox-it.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_MD_C)
|
||||
|
||||
#include "polarssl/md_wrap.h"
|
||||
|
||||
#if defined(POLARSSL_MD2_C)
|
||||
#include "polarssl/md2.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_MD4_C)
|
||||
#include "polarssl/md4.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_MD5_C)
|
||||
#include "polarssl/md5.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_SHA1_C)
|
||||
#include "polarssl/sha1.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_SHA2_C)
|
||||
#include "polarssl/sha2.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_SHA4_C)
|
||||
#include "polarssl/sha4.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(POLARSSL_MD2_C)
|
||||
|
||||
static void md2_starts_wrap( void *ctx )
|
||||
{
|
||||
md2_starts( (md2_context *) ctx );
|
||||
}
|
||||
|
||||
static void md2_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
md2_update( (md2_context *) ctx, input, ilen );
|
||||
}
|
||||
|
||||
static void md2_finish_wrap( void *ctx, unsigned char *output )
|
||||
{
|
||||
md2_finish( (md2_context *) ctx, output );
|
||||
}
|
||||
|
||||
int md2_file_wrap( const char *path, unsigned char *output )
|
||||
{
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
return md2_file( path, output );
|
||||
#else
|
||||
((void) path);
|
||||
((void) output);
|
||||
return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void md2_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
|
||||
{
|
||||
md2_hmac_starts( (md2_context *) ctx, key, keylen );
|
||||
}
|
||||
|
||||
static void md2_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
md2_hmac_update( (md2_context *) ctx, input, ilen );
|
||||
}
|
||||
|
||||
static void md2_hmac_finish_wrap( void *ctx, unsigned char *output )
|
||||
{
|
||||
md2_hmac_finish( (md2_context *) ctx, output );
|
||||
}
|
||||
|
||||
static void md2_hmac_reset_wrap( void *ctx )
|
||||
{
|
||||
md2_hmac_reset( (md2_context *) ctx );
|
||||
}
|
||||
|
||||
static void * md2_ctx_alloc( void )
|
||||
{
|
||||
return malloc( sizeof( md2_context ) );
|
||||
}
|
||||
|
||||
static void md2_ctx_free( void *ctx )
|
||||
{
|
||||
free( ctx );
|
||||
}
|
||||
|
||||
const md_info_t md2_info = {
|
||||
POLARSSL_MD_MD2,
|
||||
"MD2",
|
||||
16,
|
||||
md2_starts_wrap,
|
||||
md2_update_wrap,
|
||||
md2_finish_wrap,
|
||||
md2,
|
||||
md2_file_wrap,
|
||||
md2_hmac_starts_wrap,
|
||||
md2_hmac_update_wrap,
|
||||
md2_hmac_finish_wrap,
|
||||
md2_hmac_reset_wrap,
|
||||
md2_hmac,
|
||||
md2_ctx_alloc,
|
||||
md2_ctx_free,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_MD4_C)
|
||||
|
||||
void md4_starts_wrap( void *ctx )
|
||||
{
|
||||
md4_starts( (md4_context *) ctx );
|
||||
}
|
||||
|
||||
void md4_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
md4_update( (md4_context *) ctx, input, ilen );
|
||||
}
|
||||
|
||||
void md4_finish_wrap( void *ctx, unsigned char *output )
|
||||
{
|
||||
md4_finish( (md4_context *) ctx, output );
|
||||
}
|
||||
|
||||
int md4_file_wrap( const char *path, unsigned char *output )
|
||||
{
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
return md4_file( path, output );
|
||||
#else
|
||||
((void) path);
|
||||
((void) output);
|
||||
return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
void md4_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
|
||||
{
|
||||
md4_hmac_starts( (md4_context *) ctx, key, keylen );
|
||||
}
|
||||
|
||||
void md4_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
md4_hmac_update( (md4_context *) ctx, input, ilen );
|
||||
}
|
||||
|
||||
void md4_hmac_finish_wrap( void *ctx, unsigned char *output )
|
||||
{
|
||||
md4_hmac_finish( (md4_context *) ctx, output );
|
||||
}
|
||||
|
||||
void md4_hmac_reset_wrap( void *ctx )
|
||||
{
|
||||
md4_hmac_reset( (md4_context *) ctx );
|
||||
}
|
||||
|
||||
void *md4_ctx_alloc( void )
|
||||
{
|
||||
return malloc( sizeof( md4_context ) );
|
||||
}
|
||||
|
||||
void md4_ctx_free( void *ctx )
|
||||
{
|
||||
free( ctx );
|
||||
}
|
||||
|
||||
const md_info_t md4_info = {
|
||||
POLARSSL_MD_MD4,
|
||||
"MD4",
|
||||
16,
|
||||
md4_starts_wrap,
|
||||
md4_update_wrap,
|
||||
md4_finish_wrap,
|
||||
md4,
|
||||
md4_file_wrap,
|
||||
md4_hmac_starts_wrap,
|
||||
md4_hmac_update_wrap,
|
||||
md4_hmac_finish_wrap,
|
||||
md4_hmac_reset_wrap,
|
||||
md4_hmac,
|
||||
md4_ctx_alloc,
|
||||
md4_ctx_free,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_MD5_C)
|
||||
|
||||
static void md5_starts_wrap( void *ctx )
|
||||
{
|
||||
md5_starts( (md5_context *) ctx );
|
||||
}
|
||||
|
||||
static void md5_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
md5_update( (md5_context *) ctx, input, ilen );
|
||||
}
|
||||
|
||||
static void md5_finish_wrap( void *ctx, unsigned char *output )
|
||||
{
|
||||
md5_finish( (md5_context *) ctx, output );
|
||||
}
|
||||
|
||||
int md5_file_wrap( const char *path, unsigned char *output )
|
||||
{
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
return md5_file( path, output );
|
||||
#else
|
||||
((void) path);
|
||||
((void) output);
|
||||
return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void md5_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
|
||||
{
|
||||
md5_hmac_starts( (md5_context *) ctx, key, keylen );
|
||||
}
|
||||
|
||||
static void md5_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
md5_hmac_update( (md5_context *) ctx, input, ilen );
|
||||
}
|
||||
|
||||
static void md5_hmac_finish_wrap( void *ctx, unsigned char *output )
|
||||
{
|
||||
md5_hmac_finish( (md5_context *) ctx, output );
|
||||
}
|
||||
|
||||
static void md5_hmac_reset_wrap( void *ctx )
|
||||
{
|
||||
md5_hmac_reset( (md5_context *) ctx );
|
||||
}
|
||||
|
||||
static void * md5_ctx_alloc( void )
|
||||
{
|
||||
return malloc( sizeof( md5_context ) );
|
||||
}
|
||||
|
||||
static void md5_ctx_free( void *ctx )
|
||||
{
|
||||
free( ctx );
|
||||
}
|
||||
|
||||
const md_info_t md5_info = {
|
||||
POLARSSL_MD_MD5,
|
||||
"MD5",
|
||||
16,
|
||||
md5_starts_wrap,
|
||||
md5_update_wrap,
|
||||
md5_finish_wrap,
|
||||
md5,
|
||||
md5_file_wrap,
|
||||
md5_hmac_starts_wrap,
|
||||
md5_hmac_update_wrap,
|
||||
md5_hmac_finish_wrap,
|
||||
md5_hmac_reset_wrap,
|
||||
md5_hmac,
|
||||
md5_ctx_alloc,
|
||||
md5_ctx_free,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_SHA1_C)
|
||||
|
||||
void sha1_starts_wrap( void *ctx )
|
||||
{
|
||||
sha1_starts( (sha1_context *) ctx );
|
||||
}
|
||||
|
||||
void sha1_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
sha1_update( (sha1_context *) ctx, input, ilen );
|
||||
}
|
||||
|
||||
void sha1_finish_wrap( void *ctx, unsigned char *output )
|
||||
{
|
||||
sha1_finish( (sha1_context *) ctx, output );
|
||||
}
|
||||
|
||||
int sha1_file_wrap( const char *path, unsigned char *output )
|
||||
{
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
return sha1_file( path, output );
|
||||
#else
|
||||
((void) path);
|
||||
((void) output);
|
||||
return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
void sha1_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
|
||||
{
|
||||
sha1_hmac_starts( (sha1_context *) ctx, key, keylen );
|
||||
}
|
||||
|
||||
void sha1_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
sha1_hmac_update( (sha1_context *) ctx, input, ilen );
|
||||
}
|
||||
|
||||
void sha1_hmac_finish_wrap( void *ctx, unsigned char *output )
|
||||
{
|
||||
sha1_hmac_finish( (sha1_context *) ctx, output );
|
||||
}
|
||||
|
||||
void sha1_hmac_reset_wrap( void *ctx )
|
||||
{
|
||||
sha1_hmac_reset( (sha1_context *) ctx );
|
||||
}
|
||||
|
||||
void * sha1_ctx_alloc( void )
|
||||
{
|
||||
return malloc( sizeof( sha1_context ) );
|
||||
}
|
||||
|
||||
void sha1_ctx_free( void *ctx )
|
||||
{
|
||||
free( ctx );
|
||||
}
|
||||
|
||||
const md_info_t sha1_info = {
|
||||
POLARSSL_MD_SHA1,
|
||||
"SHA1",
|
||||
20,
|
||||
sha1_starts_wrap,
|
||||
sha1_update_wrap,
|
||||
sha1_finish_wrap,
|
||||
sha1,
|
||||
sha1_file_wrap,
|
||||
sha1_hmac_starts_wrap,
|
||||
sha1_hmac_update_wrap,
|
||||
sha1_hmac_finish_wrap,
|
||||
sha1_hmac_reset_wrap,
|
||||
sha1_hmac,
|
||||
sha1_ctx_alloc,
|
||||
sha1_ctx_free,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Wrappers for generic message digests
|
||||
*/
|
||||
#if defined(POLARSSL_SHA2_C)
|
||||
|
||||
void sha224_starts_wrap( void *ctx )
|
||||
{
|
||||
sha2_starts( (sha2_context *) ctx, 1 );
|
||||
}
|
||||
|
||||
void sha224_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
sha2_update( (sha2_context *) ctx, input, ilen );
|
||||
}
|
||||
|
||||
void sha224_finish_wrap( void *ctx, unsigned char *output )
|
||||
{
|
||||
sha2_finish( (sha2_context *) ctx, output );
|
||||
}
|
||||
|
||||
void sha224_wrap( const unsigned char *input, size_t ilen,
|
||||
unsigned char *output )
|
||||
{
|
||||
sha2( input, ilen, output, 1 );
|
||||
}
|
||||
|
||||
int sha224_file_wrap( const char *path, unsigned char *output )
|
||||
{
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
return sha2_file( path, output, 1 );
|
||||
#else
|
||||
((void) path);
|
||||
((void) output);
|
||||
return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
void sha224_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
|
||||
{
|
||||
sha2_hmac_starts( (sha2_context *) ctx, key, keylen, 1 );
|
||||
}
|
||||
|
||||
void sha224_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
sha2_hmac_update( (sha2_context *) ctx, input, ilen );
|
||||
}
|
||||
|
||||
void sha224_hmac_finish_wrap( void *ctx, unsigned char *output )
|
||||
{
|
||||
sha2_hmac_finish( (sha2_context *) ctx, output );
|
||||
}
|
||||
|
||||
void sha224_hmac_reset_wrap( void *ctx )
|
||||
{
|
||||
sha2_hmac_reset( (sha2_context *) ctx );
|
||||
}
|
||||
|
||||
void sha224_hmac_wrap( const unsigned char *key, size_t keylen,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output )
|
||||
{
|
||||
sha2_hmac( key, keylen, input, ilen, output, 1 );
|
||||
}
|
||||
|
||||
void * sha224_ctx_alloc( void )
|
||||
{
|
||||
return malloc( sizeof( sha2_context ) );
|
||||
}
|
||||
|
||||
void sha224_ctx_free( void *ctx )
|
||||
{
|
||||
free( ctx );
|
||||
}
|
||||
|
||||
const md_info_t sha224_info = {
|
||||
POLARSSL_MD_SHA224,
|
||||
"SHA224",
|
||||
28,
|
||||
sha224_starts_wrap,
|
||||
sha224_update_wrap,
|
||||
sha224_finish_wrap,
|
||||
sha224_wrap,
|
||||
sha224_file_wrap,
|
||||
sha224_hmac_starts_wrap,
|
||||
sha224_hmac_update_wrap,
|
||||
sha224_hmac_finish_wrap,
|
||||
sha224_hmac_reset_wrap,
|
||||
sha224_hmac_wrap,
|
||||
sha224_ctx_alloc,
|
||||
sha224_ctx_free,
|
||||
};
|
||||
|
||||
void sha256_starts_wrap( void *ctx )
|
||||
{
|
||||
sha2_starts( (sha2_context *) ctx, 0 );
|
||||
}
|
||||
|
||||
void sha256_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
sha2_update( (sha2_context *) ctx, input, ilen );
|
||||
}
|
||||
|
||||
void sha256_finish_wrap( void *ctx, unsigned char *output )
|
||||
{
|
||||
sha2_finish( (sha2_context *) ctx, output );
|
||||
}
|
||||
|
||||
void sha256_wrap( const unsigned char *input, size_t ilen,
|
||||
unsigned char *output )
|
||||
{
|
||||
sha2( input, ilen, output, 0 );
|
||||
}
|
||||
|
||||
int sha256_file_wrap( const char *path, unsigned char *output )
|
||||
{
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
return sha2_file( path, output, 0 );
|
||||
#else
|
||||
((void) path);
|
||||
((void) output);
|
||||
return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
void sha256_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
|
||||
{
|
||||
sha2_hmac_starts( (sha2_context *) ctx, key, keylen, 0 );
|
||||
}
|
||||
|
||||
void sha256_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
sha2_hmac_update( (sha2_context *) ctx, input, ilen );
|
||||
}
|
||||
|
||||
void sha256_hmac_finish_wrap( void *ctx, unsigned char *output )
|
||||
{
|
||||
sha2_hmac_finish( (sha2_context *) ctx, output );
|
||||
}
|
||||
|
||||
void sha256_hmac_reset_wrap( void *ctx )
|
||||
{
|
||||
sha2_hmac_reset( (sha2_context *) ctx );
|
||||
}
|
||||
|
||||
void sha256_hmac_wrap( const unsigned char *key, size_t keylen,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output )
|
||||
{
|
||||
sha2_hmac( key, keylen, input, ilen, output, 0 );
|
||||
}
|
||||
|
||||
void * sha256_ctx_alloc( void )
|
||||
{
|
||||
return malloc( sizeof( sha2_context ) );
|
||||
}
|
||||
|
||||
void sha256_ctx_free( void *ctx )
|
||||
{
|
||||
free( ctx );
|
||||
}
|
||||
|
||||
const md_info_t sha256_info = {
|
||||
POLARSSL_MD_SHA256,
|
||||
"SHA256",
|
||||
32,
|
||||
sha256_starts_wrap,
|
||||
sha256_update_wrap,
|
||||
sha256_finish_wrap,
|
||||
sha256_wrap,
|
||||
sha256_file_wrap,
|
||||
sha256_hmac_starts_wrap,
|
||||
sha256_hmac_update_wrap,
|
||||
sha256_hmac_finish_wrap,
|
||||
sha256_hmac_reset_wrap,
|
||||
sha256_hmac_wrap,
|
||||
sha256_ctx_alloc,
|
||||
sha256_ctx_free,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_SHA4_C)
|
||||
|
||||
void sha384_starts_wrap( void *ctx )
|
||||
{
|
||||
sha4_starts( (sha4_context *) ctx, 1 );
|
||||
}
|
||||
|
||||
void sha384_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
sha4_update( (sha4_context *) ctx, input, ilen );
|
||||
}
|
||||
|
||||
void sha384_finish_wrap( void *ctx, unsigned char *output )
|
||||
{
|
||||
sha4_finish( (sha4_context *) ctx, output );
|
||||
}
|
||||
|
||||
void sha384_wrap( const unsigned char *input, size_t ilen,
|
||||
unsigned char *output )
|
||||
{
|
||||
sha4( input, ilen, output, 1 );
|
||||
}
|
||||
|
||||
int sha384_file_wrap( const char *path, unsigned char *output )
|
||||
{
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
return sha4_file( path, output, 1 );
|
||||
#else
|
||||
((void) path);
|
||||
((void) output);
|
||||
return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
void sha384_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
|
||||
{
|
||||
sha4_hmac_starts( (sha4_context *) ctx, key, keylen, 1 );
|
||||
}
|
||||
|
||||
void sha384_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
sha4_hmac_update( (sha4_context *) ctx, input, ilen );
|
||||
}
|
||||
|
||||
void sha384_hmac_finish_wrap( void *ctx, unsigned char *output )
|
||||
{
|
||||
sha4_hmac_finish( (sha4_context *) ctx, output );
|
||||
}
|
||||
|
||||
void sha384_hmac_reset_wrap( void *ctx )
|
||||
{
|
||||
sha4_hmac_reset( (sha4_context *) ctx );
|
||||
}
|
||||
|
||||
void sha384_hmac_wrap( const unsigned char *key, size_t keylen,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output )
|
||||
{
|
||||
sha4_hmac( key, keylen, input, ilen, output, 1 );
|
||||
}
|
||||
|
||||
void * sha384_ctx_alloc( void )
|
||||
{
|
||||
return malloc( sizeof( sha4_context ) );
|
||||
}
|
||||
|
||||
void sha384_ctx_free( void *ctx )
|
||||
{
|
||||
free( ctx );
|
||||
}
|
||||
|
||||
const md_info_t sha384_info = {
|
||||
POLARSSL_MD_SHA384,
|
||||
"SHA384",
|
||||
48,
|
||||
sha384_starts_wrap,
|
||||
sha384_update_wrap,
|
||||
sha384_finish_wrap,
|
||||
sha384_wrap,
|
||||
sha384_file_wrap,
|
||||
sha384_hmac_starts_wrap,
|
||||
sha384_hmac_update_wrap,
|
||||
sha384_hmac_finish_wrap,
|
||||
sha384_hmac_reset_wrap,
|
||||
sha384_hmac_wrap,
|
||||
sha384_ctx_alloc,
|
||||
sha384_ctx_free,
|
||||
};
|
||||
|
||||
void sha512_starts_wrap( void *ctx )
|
||||
{
|
||||
sha4_starts( (sha4_context *) ctx, 0 );
|
||||
}
|
||||
|
||||
void sha512_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
sha4_update( (sha4_context *) ctx, input, ilen );
|
||||
}
|
||||
|
||||
void sha512_finish_wrap( void *ctx, unsigned char *output )
|
||||
{
|
||||
sha4_finish( (sha4_context *) ctx, output );
|
||||
}
|
||||
|
||||
void sha512_wrap( const unsigned char *input, size_t ilen,
|
||||
unsigned char *output )
|
||||
{
|
||||
sha4( input, ilen, output, 0 );
|
||||
}
|
||||
|
||||
int sha512_file_wrap( const char *path, unsigned char *output )
|
||||
{
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
return sha4_file( path, output, 0 );
|
||||
#else
|
||||
((void) path);
|
||||
((void) output);
|
||||
return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
void sha512_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
|
||||
{
|
||||
sha4_hmac_starts( (sha4_context *) ctx, key, keylen, 0 );
|
||||
}
|
||||
|
||||
void sha512_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
sha4_hmac_update( (sha4_context *) ctx, input, ilen );
|
||||
}
|
||||
|
||||
void sha512_hmac_finish_wrap( void *ctx, unsigned char *output )
|
||||
{
|
||||
sha4_hmac_finish( (sha4_context *) ctx, output );
|
||||
}
|
||||
|
||||
void sha512_hmac_reset_wrap( void *ctx )
|
||||
{
|
||||
sha4_hmac_reset( (sha4_context *) ctx );
|
||||
}
|
||||
|
||||
void sha512_hmac_wrap( const unsigned char *key, size_t keylen,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output )
|
||||
{
|
||||
sha4_hmac( key, keylen, input, ilen, output, 0 );
|
||||
}
|
||||
|
||||
void * sha512_ctx_alloc( void )
|
||||
{
|
||||
return malloc( sizeof( sha4_context ) );
|
||||
}
|
||||
|
||||
void sha512_ctx_free( void *ctx )
|
||||
{
|
||||
free( ctx );
|
||||
}
|
||||
|
||||
const md_info_t sha512_info = {
|
||||
POLARSSL_MD_SHA512,
|
||||
"SHA512",
|
||||
64,
|
||||
sha512_starts_wrap,
|
||||
sha512_update_wrap,
|
||||
sha512_finish_wrap,
|
||||
sha512_wrap,
|
||||
sha512_file_wrap,
|
||||
sha512_hmac_starts_wrap,
|
||||
sha512_hmac_update_wrap,
|
||||
sha512_hmac_finish_wrap,
|
||||
sha512_hmac_reset_wrap,
|
||||
sha512_hmac_wrap,
|
||||
sha512_ctx_alloc,
|
||||
sha512_ctx_free,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* \file md_wrap.h
|
||||
*
|
||||
* \brief Message digest wrappers.
|
||||
*
|
||||
* \author Adriaan de Jong <dejong@fox-it.com>
|
||||
*
|
||||
* Copyright (C) 2006-2011, 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_MD_WRAP_H
|
||||
#define POLARSSL_MD_WRAP_H
|
||||
|
||||
#include "polarssl/config.h"
|
||||
#include "polarssl/md.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_MD2_C)
|
||||
extern const md_info_t md2_info;
|
||||
#endif
|
||||
#if defined(POLARSSL_MD4_C)
|
||||
extern const md_info_t md4_info;
|
||||
#endif
|
||||
#if defined(POLARSSL_MD5_C)
|
||||
extern const md_info_t md5_info;
|
||||
#endif
|
||||
#if defined(POLARSSL_SHA1_C)
|
||||
extern const md_info_t sha1_info;
|
||||
#endif
|
||||
#if defined(POLARSSL_SHA2_C)
|
||||
extern const md_info_t sha224_info;
|
||||
extern const md_info_t sha256_info;
|
||||
#endif
|
||||
#if defined(POLARSSL_SHA4_C)
|
||||
extern const md_info_t sha384_info;
|
||||
extern const md_info_t sha512_info;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* POLARSSL_MD_WRAP_H */
|
||||
+374
@@ -0,0 +1,374 @@
|
||||
/*
|
||||
* TCP networking functions
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_NET_C)
|
||||
|
||||
#include "polarssl/net.h"
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN32_WCE)
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
|
||||
#if defined(_WIN32_WCE)
|
||||
#pragma comment( lib, "ws2.lib" )
|
||||
#else
|
||||
#pragma comment( lib, "ws2_32.lib" )
|
||||
#endif
|
||||
|
||||
#define read(fd,buf,len) recv(fd,(char*)buf,(int) len,0)
|
||||
#define write(fd,buf,len) send(fd,(char*)buf,(int) len,0)
|
||||
#define close(fd) closesocket(fd)
|
||||
|
||||
static int wsa_init_done = 0;
|
||||
|
||||
#else
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \
|
||||
defined(__DragonflyBSD__)
|
||||
#include <sys/endian.h>
|
||||
#elif defined(__APPLE__)
|
||||
#include <machine/endian.h>
|
||||
#elif defined(sun)
|
||||
#include <sys/isa_defs.h>
|
||||
#else
|
||||
#include <endian.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <basetsd.h>
|
||||
typedef UINT32 uint32_t;
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* htons() is not always available.
|
||||
* By default go for LITTLE_ENDIAN variant. Otherwise hope for _BYTE_ORDER and __BIG_ENDIAN
|
||||
* to help determine endianess.
|
||||
*/
|
||||
#if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define POLARSSL_HTONS(n) (n)
|
||||
#define POLARSSL_HTONL(n) (n)
|
||||
#else
|
||||
#define POLARSSL_HTONS(n) ((((unsigned short)(n) & 0xFF ) << 8 ) | \
|
||||
(((unsigned short)(n) & 0xFF00 ) >> 8 ))
|
||||
#define POLARSSL_HTONL(n) ((((unsigned long )(n) & 0xFF ) << 24) | \
|
||||
(((unsigned long )(n) & 0xFF00 ) << 8 ) | \
|
||||
(((unsigned long )(n) & 0xFF0000 ) >> 8 ) | \
|
||||
(((unsigned long )(n) & 0xFF000000) >> 24))
|
||||
#endif
|
||||
|
||||
unsigned short net_htons(unsigned short n);
|
||||
unsigned long net_htonl(unsigned long n);
|
||||
#define net_htons(n) POLARSSL_HTONS(n)
|
||||
#define net_htonl(n) POLARSSL_HTONL(n)
|
||||
|
||||
/*
|
||||
* Initiate a TCP connection with host:port
|
||||
*/
|
||||
int net_connect( int *fd, const char *host, int port )
|
||||
{
|
||||
struct sockaddr_in server_addr;
|
||||
struct hostent *server_host;
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN32_WCE)
|
||||
WSADATA wsaData;
|
||||
|
||||
if( wsa_init_done == 0 )
|
||||
{
|
||||
if( WSAStartup( MAKEWORD(2,0), &wsaData ) == SOCKET_ERROR )
|
||||
return( POLARSSL_ERR_NET_SOCKET_FAILED );
|
||||
|
||||
wsa_init_done = 1;
|
||||
}
|
||||
#else
|
||||
signal( SIGPIPE, SIG_IGN );
|
||||
#endif
|
||||
|
||||
if( ( server_host = gethostbyname( host ) ) == NULL )
|
||||
return( POLARSSL_ERR_NET_UNKNOWN_HOST );
|
||||
|
||||
if( ( *fd = socket( AF_INET, SOCK_STREAM, IPPROTO_IP ) ) < 0 )
|
||||
return( POLARSSL_ERR_NET_SOCKET_FAILED );
|
||||
|
||||
memcpy( (void *) &server_addr.sin_addr,
|
||||
(void *) server_host->h_addr,
|
||||
server_host->h_length );
|
||||
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_port = net_htons( port );
|
||||
|
||||
if( connect( *fd, (struct sockaddr *) &server_addr,
|
||||
sizeof( server_addr ) ) < 0 )
|
||||
{
|
||||
close( *fd );
|
||||
return( POLARSSL_ERR_NET_CONNECT_FAILED );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a listening socket on bind_ip:port
|
||||
*/
|
||||
int net_bind( int *fd, const char *bind_ip, int port )
|
||||
{
|
||||
int n, c[4];
|
||||
struct sockaddr_in server_addr;
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN32_WCE)
|
||||
WSADATA wsaData;
|
||||
|
||||
if( wsa_init_done == 0 )
|
||||
{
|
||||
if( WSAStartup( MAKEWORD(2,0), &wsaData ) == SOCKET_ERROR )
|
||||
return( POLARSSL_ERR_NET_SOCKET_FAILED );
|
||||
|
||||
wsa_init_done = 1;
|
||||
}
|
||||
#else
|
||||
signal( SIGPIPE, SIG_IGN );
|
||||
#endif
|
||||
|
||||
if( ( *fd = socket( AF_INET, SOCK_STREAM, IPPROTO_IP ) ) < 0 )
|
||||
return( POLARSSL_ERR_NET_SOCKET_FAILED );
|
||||
|
||||
n = 1;
|
||||
setsockopt( *fd, SOL_SOCKET, SO_REUSEADDR,
|
||||
(const char *) &n, sizeof( n ) );
|
||||
|
||||
server_addr.sin_addr.s_addr = net_htonl( INADDR_ANY );
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_port = net_htons( port );
|
||||
|
||||
if( bind_ip != NULL )
|
||||
{
|
||||
memset( c, 0, sizeof( c ) );
|
||||
sscanf( bind_ip, "%d.%d.%d.%d", &c[0], &c[1], &c[2], &c[3] );
|
||||
|
||||
for( n = 0; n < 4; n++ )
|
||||
if( c[n] < 0 || c[n] > 255 )
|
||||
break;
|
||||
|
||||
if( n == 4 )
|
||||
server_addr.sin_addr.s_addr = net_htonl(
|
||||
( (uint32_t) c[0] << 24 ) |
|
||||
( (uint32_t) c[1] << 16 ) |
|
||||
( (uint32_t) c[2] << 8 ) |
|
||||
( (uint32_t) c[3] ) );
|
||||
}
|
||||
|
||||
if( bind( *fd, (struct sockaddr *) &server_addr,
|
||||
sizeof( server_addr ) ) < 0 )
|
||||
{
|
||||
close( *fd );
|
||||
return( POLARSSL_ERR_NET_BIND_FAILED );
|
||||
}
|
||||
|
||||
if( listen( *fd, POLARSSL_NET_LISTEN_BACKLOG ) != 0 )
|
||||
{
|
||||
close( *fd );
|
||||
return( POLARSSL_ERR_NET_LISTEN_FAILED );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the current operation is blocking
|
||||
*/
|
||||
static int net_is_blocking( void )
|
||||
{
|
||||
#if defined(_WIN32) || defined(_WIN32_WCE)
|
||||
return( WSAGetLastError() == WSAEWOULDBLOCK );
|
||||
#else
|
||||
switch( errno )
|
||||
{
|
||||
#if defined EAGAIN
|
||||
case EAGAIN:
|
||||
#endif
|
||||
#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN
|
||||
case EWOULDBLOCK:
|
||||
#endif
|
||||
return( 1 );
|
||||
}
|
||||
return( 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Accept a connection from a remote client
|
||||
*/
|
||||
int net_accept( int bind_fd, int *client_fd, void *client_ip )
|
||||
{
|
||||
struct sockaddr_in client_addr;
|
||||
|
||||
#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \
|
||||
defined(_SOCKLEN_T_DECLARED)
|
||||
socklen_t n = (socklen_t) sizeof( client_addr );
|
||||
#else
|
||||
int n = (int) sizeof( client_addr );
|
||||
#endif
|
||||
|
||||
*client_fd = accept( bind_fd, (struct sockaddr *)
|
||||
&client_addr, &n );
|
||||
|
||||
if( *client_fd < 0 )
|
||||
{
|
||||
if( net_is_blocking() != 0 )
|
||||
return( POLARSSL_ERR_NET_WANT_READ );
|
||||
|
||||
return( POLARSSL_ERR_NET_ACCEPT_FAILED );
|
||||
}
|
||||
|
||||
if( client_ip != NULL )
|
||||
memcpy( client_ip, &client_addr.sin_addr.s_addr,
|
||||
sizeof( client_addr.sin_addr.s_addr ) );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the socket blocking or non-blocking
|
||||
*/
|
||||
int net_set_block( int fd )
|
||||
{
|
||||
#if defined(_WIN32) || defined(_WIN32_WCE)
|
||||
u_long n = 0;
|
||||
return( ioctlsocket( fd, FIONBIO, &n ) );
|
||||
#else
|
||||
return( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) & ~O_NONBLOCK ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
int net_set_nonblock( int fd )
|
||||
{
|
||||
#if defined(_WIN32) || defined(_WIN32_WCE)
|
||||
u_long n = 1;
|
||||
return( ioctlsocket( fd, FIONBIO, &n ) );
|
||||
#else
|
||||
return( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) | O_NONBLOCK ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Portable usleep helper
|
||||
*/
|
||||
void net_usleep( unsigned long usec )
|
||||
{
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = usec;
|
||||
select( 0, NULL, NULL, NULL, &tv );
|
||||
}
|
||||
|
||||
/*
|
||||
* Read at most 'len' characters
|
||||
*/
|
||||
int net_recv( void *ctx, unsigned char *buf, size_t len )
|
||||
{
|
||||
int ret = read( *((int *) ctx), buf, len );
|
||||
|
||||
if( ret < 0 )
|
||||
{
|
||||
if( net_is_blocking() != 0 )
|
||||
return( POLARSSL_ERR_NET_WANT_READ );
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN32_WCE)
|
||||
if( WSAGetLastError() == WSAECONNRESET )
|
||||
return( POLARSSL_ERR_NET_CONN_RESET );
|
||||
#else
|
||||
if( errno == EPIPE || errno == ECONNRESET )
|
||||
return( POLARSSL_ERR_NET_CONN_RESET );
|
||||
|
||||
if( errno == EINTR )
|
||||
return( POLARSSL_ERR_NET_WANT_READ );
|
||||
#endif
|
||||
|
||||
return( POLARSSL_ERR_NET_RECV_FAILED );
|
||||
}
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Write at most 'len' characters
|
||||
*/
|
||||
int net_send( void *ctx, const unsigned char *buf, size_t len )
|
||||
{
|
||||
int ret = write( *((int *) ctx), buf, len );
|
||||
|
||||
if( ret < 0 )
|
||||
{
|
||||
if( net_is_blocking() != 0 )
|
||||
return( POLARSSL_ERR_NET_WANT_WRITE );
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN32_WCE)
|
||||
if( WSAGetLastError() == WSAECONNRESET )
|
||||
return( POLARSSL_ERR_NET_CONN_RESET );
|
||||
#else
|
||||
if( errno == EPIPE || errno == ECONNRESET )
|
||||
return( POLARSSL_ERR_NET_CONN_RESET );
|
||||
|
||||
if( errno == EINTR )
|
||||
return( POLARSSL_ERR_NET_WANT_WRITE );
|
||||
#endif
|
||||
|
||||
return( POLARSSL_ERR_NET_SEND_FAILED );
|
||||
}
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Gracefully close the connection
|
||||
*/
|
||||
void net_close( int fd )
|
||||
{
|
||||
shutdown( fd, 2 );
|
||||
close( fd );
|
||||
}
|
||||
|
||||
#endif
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
/**
|
||||
* \file net.h
|
||||
*
|
||||
* \brief Network communication functions
|
||||
*
|
||||
* Copyright (C) 2006-2011, 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_NET_H
|
||||
#define POLARSSL_NET_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define POLARSSL_ERR_NET_UNKNOWN_HOST -0x0056 /**< Failed to get an IP address for the given hostname. */
|
||||
#define POLARSSL_ERR_NET_SOCKET_FAILED -0x0042 /**< Failed to open a socket. */
|
||||
#define POLARSSL_ERR_NET_CONNECT_FAILED -0x0044 /**< The connection to the given server / port failed. */
|
||||
#define POLARSSL_ERR_NET_BIND_FAILED -0x0046 /**< Binding of the socket failed. */
|
||||
#define POLARSSL_ERR_NET_LISTEN_FAILED -0x0048 /**< Could not listen on the socket. */
|
||||
#define POLARSSL_ERR_NET_ACCEPT_FAILED -0x004A /**< Could not accept the incoming connection. */
|
||||
#define POLARSSL_ERR_NET_RECV_FAILED -0x004C /**< Reading information from the socket failed. */
|
||||
#define POLARSSL_ERR_NET_SEND_FAILED -0x004E /**< Sending information through the socket failed. */
|
||||
#define POLARSSL_ERR_NET_CONN_RESET -0x0050 /**< Connection was reset by peer. */
|
||||
#define POLARSSL_ERR_NET_WANT_READ -0x0052 /**< Connection requires a read call. */
|
||||
#define POLARSSL_ERR_NET_WANT_WRITE -0x0054 /**< Connection requires a write call. */
|
||||
|
||||
#define POLARSSL_NET_LISTEN_BACKLOG 10 /**< The backlog that listen() should use. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Initiate a TCP connection with host:port
|
||||
*
|
||||
* \param fd Socket to use
|
||||
* \param host Host to connect to
|
||||
* \param port Port to connect to
|
||||
*
|
||||
* \return 0 if successful, or one of:
|
||||
* POLARSSL_ERR_NET_SOCKET_FAILED,
|
||||
* POLARSSL_ERR_NET_UNKNOWN_HOST,
|
||||
* POLARSSL_ERR_NET_CONNECT_FAILED
|
||||
*/
|
||||
int net_connect( int *fd, const char *host, int port );
|
||||
|
||||
/**
|
||||
* \brief Create a listening socket on bind_ip:port.
|
||||
* If bind_ip == NULL, all interfaces are binded.
|
||||
*
|
||||
* \param fd Socket to use
|
||||
* \param bind_ip IP to bind to, can be NULL
|
||||
* \param port Port number to use
|
||||
*
|
||||
* \return 0 if successful, or one of:
|
||||
* POLARSSL_ERR_NET_SOCKET_FAILED,
|
||||
* POLARSSL_ERR_NET_BIND_FAILED,
|
||||
* POLARSSL_ERR_NET_LISTEN_FAILED
|
||||
*/
|
||||
int net_bind( int *fd, const char *bind_ip, int port );
|
||||
|
||||
/**
|
||||
* \brief Accept a connection from a remote client
|
||||
*
|
||||
* \param bind_fd Relevant socket
|
||||
* \param client_fd Will contain the connected client socket
|
||||
* \param client_ip Will contain the client IP address
|
||||
*
|
||||
* \return 0 if successful, POLARSSL_ERR_NET_ACCEPT_FAILED, or
|
||||
* POLARSSL_ERR_NET_WOULD_BLOCK is bind_fd was set to
|
||||
* non-blocking and accept() is blocking.
|
||||
*/
|
||||
int net_accept( int bind_fd, int *client_fd, void *client_ip );
|
||||
|
||||
/**
|
||||
* \brief Set the socket blocking
|
||||
*
|
||||
* \param fd Socket to set
|
||||
*
|
||||
* \return 0 if successful, or a non-zero error code
|
||||
*/
|
||||
int net_set_block( int fd );
|
||||
|
||||
/**
|
||||
* \brief Set the socket non-blocking
|
||||
*
|
||||
* \param fd Socket to set
|
||||
*
|
||||
* \return 0 if successful, or a non-zero error code
|
||||
*/
|
||||
int net_set_nonblock( int fd );
|
||||
|
||||
/**
|
||||
* \brief Portable usleep helper
|
||||
*
|
||||
* \param usec Amount of microseconds to sleep
|
||||
*
|
||||
* \note Real amount of time slept will not be less than
|
||||
* select()'s timeout granularity (typically, 10ms).
|
||||
*/
|
||||
void net_usleep( unsigned long usec );
|
||||
|
||||
/**
|
||||
* \brief Read at most 'len' characters. If no error occurs,
|
||||
* the actual amount read is returned.
|
||||
*
|
||||
* \param ctx Socket
|
||||
* \param buf The buffer to write to
|
||||
* \param len Maximum length of the buffer
|
||||
*
|
||||
* \return This function returns the number of bytes received,
|
||||
* or a non-zero error code; POLARSSL_ERR_NET_WANT_READ
|
||||
* indicates read() is blocking.
|
||||
*/
|
||||
int net_recv( void *ctx, unsigned char *buf, size_t len );
|
||||
|
||||
/**
|
||||
* \brief Write at most 'len' characters. If no error occurs,
|
||||
* the actual amount read is returned.
|
||||
*
|
||||
* \param ctx Socket
|
||||
* \param buf The buffer to read from
|
||||
* \param len The length of the buffer
|
||||
*
|
||||
* \return This function returns the number of bytes sent,
|
||||
* or a non-zero error code; POLARSSL_ERR_NET_WANT_WRITE
|
||||
* indicates write() is blocking.
|
||||
*/
|
||||
int net_send( void *ctx, const unsigned char *buf, size_t len );
|
||||
|
||||
/**
|
||||
* \brief Gracefully shutdown the connection
|
||||
*
|
||||
* \param fd The socket to close
|
||||
*/
|
||||
void net_close( int fd );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* net.h */
|
||||
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
* \file openssl.h
|
||||
*
|
||||
* \brief OpenSSL wrapper (definitions, inline functions).
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* OpenSSL wrapper contributed by David Barett
|
||||
*/
|
||||
#ifndef POLARSSL_OPENSSL_H
|
||||
#define POLARSSL_OPENSSL_H
|
||||
|
||||
#include "polarssl/aes.h"
|
||||
#include "polarssl/md5.h"
|
||||
#include "polarssl/rsa.h"
|
||||
#include "polarssl/sha1.h"
|
||||
|
||||
#define AES_SIZE 16
|
||||
#define AES_BLOCK_SIZE 16
|
||||
#define AES_KEY aes_context
|
||||
#define MD5_CTX md5_context
|
||||
#define SHA_CTX sha1_context
|
||||
|
||||
#define SHA1_Init( CTX ) \
|
||||
sha1_starts( (CTX) )
|
||||
#define SHA1_Update( CTX, BUF, LEN ) \
|
||||
sha1_update( (CTX), (unsigned char *)(BUF), (LEN) )
|
||||
#define SHA1_Final( OUT, CTX ) \
|
||||
sha1_finish( (CTX), (OUT) )
|
||||
|
||||
#define MD5_Init( CTX ) \
|
||||
md5_starts( (CTX) )
|
||||
#define MD5_Update( CTX, BUF, LEN ) \
|
||||
md5_update( (CTX), (unsigned char *)(BUF), (LEN) )
|
||||
#define MD5_Final( OUT, CTX ) \
|
||||
md5_finish( (CTX), (OUT) )
|
||||
|
||||
#define AES_set_encrypt_key( KEY, KEYSIZE, CTX ) \
|
||||
aes_setkey_enc( (CTX), (KEY), (KEYSIZE) )
|
||||
#define AES_set_decrypt_key( KEY, KEYSIZE, CTX ) \
|
||||
aes_setkey_dec( (CTX), (KEY), (KEYSIZE) )
|
||||
#define AES_cbc_encrypt( INPUT, OUTPUT, LEN, CTX, IV, MODE ) \
|
||||
aes_crypt_cbc( (CTX), (MODE), (LEN), (IV), (INPUT), (OUTPUT) )
|
||||
|
||||
/*
|
||||
* RSA stuff follows. TODO: needs cleanup
|
||||
*/
|
||||
inline int __RSA_Passthrough( void *output, void *input, int size )
|
||||
{
|
||||
memcpy( output, input, size );
|
||||
return size;
|
||||
}
|
||||
|
||||
inline rsa_context* d2i_RSA_PUBKEY( void *ignore, unsigned char **bufptr,
|
||||
int len )
|
||||
{
|
||||
unsigned char *buffer = *(unsigned char **) bufptr;
|
||||
rsa_context *rsa;
|
||||
|
||||
/*
|
||||
* Not a general-purpose parser: only parses public key from *exactly*
|
||||
* openssl genrsa -out privkey.pem 512 (or 1024)
|
||||
* openssl rsa -in privkey.pem -out privatekey.der -outform der
|
||||
* openssl rsa -in privkey.pem -out pubkey.der -outform der -pubout
|
||||
*
|
||||
* TODO: make a general-purpose parse
|
||||
*/
|
||||
if( ignore != 0 || ( len != 94 && len != 162 ) )
|
||||
return( 0 );
|
||||
|
||||
rsa = (rsa_context *) malloc( sizeof( rsa_rsa ) );
|
||||
if( rsa == NULL )
|
||||
return( 0 );
|
||||
|
||||
memset( rsa, 0, sizeof( rsa_context ) );
|
||||
|
||||
if( ( len == 94 &&
|
||||
mpi_read_binary( &rsa->N, &buffer[ 25], 64 ) == 0 &&
|
||||
mpi_read_binary( &rsa->E, &buffer[ 91], 3 ) == 0 ) ||
|
||||
( len == 162 &&
|
||||
mpi_read_binary( &rsa->N, &buffer[ 29], 128 ) == 0 ) &&
|
||||
mpi_read_binary( &rsa->E, &buffer[159], 3 ) == 0 )
|
||||
{
|
||||
/*
|
||||
* key read successfully
|
||||
*/
|
||||
rsa->len = ( mpi_msb( &rsa->N ) + 7 ) >> 3;
|
||||
return( rsa );
|
||||
}
|
||||
else
|
||||
{
|
||||
memset( rsa, 0, sizeof( rsa_context ) );
|
||||
free( rsa );
|
||||
return( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
#define RSA rsa_context
|
||||
#define RSA_PKCS1_PADDING 1 /* ignored; always encrypt with this */
|
||||
#define RSA_size( CTX ) (CTX)->len
|
||||
#define RSA_free( CTX ) rsa_free( CTX )
|
||||
#define ERR_get_error( ) "ERR_get_error() not supported"
|
||||
#define RSA_blinding_off( IGNORE )
|
||||
|
||||
#define d2i_RSAPrivateKey( a, b, c ) new rsa_context /* TODO: C++ bleh */
|
||||
|
||||
inline int RSA_public_decrypt ( int size, unsigned char* input, unsigned char* output, RSA* key, int ignore ) { int outsize=size; if( !rsa_pkcs1_decrypt( key, RSA_PUBLIC, &outsize, input, output ) ) return outsize; else return -1; }
|
||||
inline int RSA_private_decrypt( int size, unsigned char* input, unsigned char* output, RSA* key, int ignore ) { int outsize=size; if( !rsa_pkcs1_decrypt( key, RSA_PRIVATE, &outsize, input, output ) ) return outsize; else return -1; }
|
||||
inline int RSA_public_encrypt ( int size, unsigned char* input, unsigned char* output, RSA* key, int ignore ) { if( !rsa_pkcs1_encrypt( key, RSA_PUBLIC, size, input, output ) ) return RSA_size(key); else return -1; }
|
||||
inline int RSA_private_encrypt( int size, unsigned char* input, unsigned char* output, RSA* key, int ignore ) { if( !rsa_pkcs1_encrypt( key, RSA_PRIVATE, size, input, output ) ) return RSA_size(key); else return -1; }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* openssl.h */
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* VIA PadLock support functions
|
||||
*
|
||||
* 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 implementation is based on the VIA PadLock Programming Guide:
|
||||
*
|
||||
* http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/
|
||||
* programming_guide.pdf
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_PADLOCK_C)
|
||||
|
||||
#include "polarssl/padlock.h"
|
||||
|
||||
#if defined(POLARSSL_HAVE_X86)
|
||||
|
||||
/*
|
||||
* PadLock detection routine
|
||||
*/
|
||||
int padlock_supports( int feature )
|
||||
{
|
||||
static int flags = -1;
|
||||
int ebx, edx;
|
||||
|
||||
if( flags == -1 )
|
||||
{
|
||||
__asm__( "movl %%ebx, %0 \n" \
|
||||
"movl $0xC0000000, %%eax \n" \
|
||||
"cpuid \n" \
|
||||
"cmpl $0xC0000001, %%eax \n" \
|
||||
"movl $0, %%edx \n" \
|
||||
"jb unsupported \n" \
|
||||
"movl $0xC0000001, %%eax \n" \
|
||||
"cpuid \n" \
|
||||
"unsupported: \n" \
|
||||
"movl %%edx, %1 \n" \
|
||||
"movl %2, %%ebx \n"
|
||||
: "=m" (ebx), "=m" (edx)
|
||||
: "m" (ebx)
|
||||
: "eax", "ecx", "edx" );
|
||||
|
||||
flags = edx;
|
||||
}
|
||||
|
||||
return( flags & feature );
|
||||
}
|
||||
|
||||
/*
|
||||
* PadLock AES-ECB block en(de)cryption
|
||||
*/
|
||||
int padlock_xcryptecb( aes_context *ctx,
|
||||
int mode,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] )
|
||||
{
|
||||
int ebx;
|
||||
uint32_t *rk;
|
||||
uint32_t *blk;
|
||||
uint32_t *ctrl;
|
||||
unsigned char buf[256];
|
||||
|
||||
rk = ctx->rk;
|
||||
blk = PADLOCK_ALIGN16( buf );
|
||||
memcpy( blk, input, 16 );
|
||||
|
||||
ctrl = blk + 4;
|
||||
*ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode^1 ) - 10 ) << 9 );
|
||||
|
||||
__asm__( "pushfl; popfl \n" \
|
||||
"movl %%ebx, %0 \n" \
|
||||
"movl $1, %%ecx \n" \
|
||||
"movl %2, %%edx \n" \
|
||||
"movl %3, %%ebx \n" \
|
||||
"movl %4, %%esi \n" \
|
||||
"movl %4, %%edi \n" \
|
||||
".byte 0xf3,0x0f,0xa7,0xc8\n" \
|
||||
"movl %1, %%ebx \n"
|
||||
: "=m" (ebx)
|
||||
: "m" (ebx), "m" (ctrl), "m" (rk), "m" (blk)
|
||||
: "ecx", "edx", "esi", "edi" );
|
||||
|
||||
memcpy( output, blk, 16 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* PadLock AES-CBC buffer en(de)cryption
|
||||
*/
|
||||
int padlock_xcryptcbc( aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
int ebx;
|
||||
size_t count;
|
||||
uint32_t *rk;
|
||||
uint32_t *iw;
|
||||
uint32_t *ctrl;
|
||||
unsigned char buf[256];
|
||||
|
||||
if( ( (long) input & 15 ) != 0 ||
|
||||
( (long) output & 15 ) != 0 )
|
||||
return( POLARSSL_ERR_PADLOCK_DATA_MISALIGNED );
|
||||
|
||||
rk = ctx->rk;
|
||||
iw = PADLOCK_ALIGN16( buf );
|
||||
memcpy( iw, iv, 16 );
|
||||
|
||||
ctrl = iw + 4;
|
||||
*ctrl = 0x80 | ctx->nr | ( ( ctx->nr + (mode^1) - 10 ) << 9 );
|
||||
|
||||
count = (length + 15) >> 4;
|
||||
|
||||
__asm__( "pushfl; popfl \n" \
|
||||
"movl %%ebx, %0 \n" \
|
||||
"movl %2, %%ecx \n" \
|
||||
"movl %3, %%edx \n" \
|
||||
"movl %4, %%ebx \n" \
|
||||
"movl %5, %%esi \n" \
|
||||
"movl %6, %%edi \n" \
|
||||
"movl %7, %%eax \n" \
|
||||
".byte 0xf3,0x0f,0xa7,0xd0\n" \
|
||||
"movl %1, %%ebx \n"
|
||||
: "=m" (ebx)
|
||||
: "m" (ebx), "m" (count), "m" (ctrl),
|
||||
"m" (rk), "m" (input), "m" (output), "m" (iw)
|
||||
: "eax", "ecx", "edx", "esi", "edi" );
|
||||
|
||||
memcpy( iv, iw, 16 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* \file padlock.h
|
||||
*
|
||||
* \brief VIA PadLock ACE for HW encryption/decryption supported by some processors
|
||||
*
|
||||
* 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 "polarssl/aes.h"
|
||||
|
||||
#define POLARSSL_ERR_PADLOCK_DATA_MISALIGNED -0x0030 /**< Input data should be aligned. */
|
||||
|
||||
#if defined(POLARSSL_HAVE_ASM) && defined(__GNUC__) && defined(__i386__)
|
||||
|
||||
#ifndef POLARSSL_HAVE_X86
|
||||
#define POLARSSL_HAVE_X86
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <basetsd.h>
|
||||
typedef INT32 int32_t;
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define PADLOCK_RNG 0x000C
|
||||
#define PADLOCK_ACE 0x00C0
|
||||
#define PADLOCK_PHE 0x0C00
|
||||
#define PADLOCK_PMM 0x3000
|
||||
|
||||
#define PADLOCK_ALIGN16(x) (uint32_t *) (16 + ((int32_t) x & ~15))
|
||||
|
||||
#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,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_X86 */
|
||||
|
||||
#endif /* padlock.h */
|
||||
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* \file pbkdf2.c
|
||||
*
|
||||
* \brief Password-Based Key Derivation Function 2 (from PKCS#5)
|
||||
* DEPRECATED: Use pkcs5.c instead
|
||||
*
|
||||
* \author Mathias Olsson <mathias@kompetensum.com>
|
||||
*
|
||||
* Copyright (C) 2006-2012, 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.
|
||||
*/
|
||||
/*
|
||||
* PBKDF2 is part of PKCS#5
|
||||
*
|
||||
* http://tools.ietf.org/html/rfc2898 (Specification)
|
||||
* http://tools.ietf.org/html/rfc6070 (Test vectors)
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_PBKDF2_C)
|
||||
|
||||
#include "polarssl/pbkdf2.h"
|
||||
#include "polarssl/pkcs5.h"
|
||||
|
||||
int pbkdf2_hmac( md_context_t *ctx, const unsigned char *password, size_t plen,
|
||||
const unsigned char *salt, size_t slen,
|
||||
unsigned int iteration_count,
|
||||
uint32_t key_length, unsigned char *output )
|
||||
{
|
||||
return pkcs5_pbkdf2_hmac( ctx, password, plen, salt, slen, iteration_count,
|
||||
key_length, output );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_SELF_TEST)
|
||||
int pbkdf2_self_test( int verbose )
|
||||
{
|
||||
return pkcs5_self_test( verbose );
|
||||
}
|
||||
#endif /* POLARSSL_SELF_TEST */
|
||||
|
||||
#endif /* POLARSSL_PBKDF2_C */
|
||||
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* \file pbkdf2.h
|
||||
*
|
||||
* \brief Password-Based Key Derivation Function 2 (from PKCS#5)
|
||||
* DEPRECATED: use pkcs5.h instead.
|
||||
*
|
||||
* \author Mathias Olsson <mathias@kompetensum.com>
|
||||
*
|
||||
* Copyright (C) 2006-2012, 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_PBKDF2_H
|
||||
#define POLARSSL_PBKDF2_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "polarssl/md.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <basetsd.h>
|
||||
typedef UINT32 uint32_t;
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#define POLARSSL_ERR_PBKDF2_BAD_INPUT_DATA -0x007C /**< Bad input parameters to function. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief PKCS#5 PBKDF2 using HMAC
|
||||
* DEPRECATED: Use pkcs5_pbkdf2_hmac() instead!
|
||||
*
|
||||
* \param ctx Generic HMAC context
|
||||
* \param password Password to use when generating key
|
||||
* \param plen Length of password
|
||||
* \param salt Salt to use when generating key
|
||||
* \param slen Length of salt
|
||||
* \param iteration_count Iteration count
|
||||
* \param key_length Length of generated key
|
||||
* \param output Generated key. Must be at least as big as key_length
|
||||
*
|
||||
* \returns 0 on success, or a PolarSSL error code if verification fails.
|
||||
*/
|
||||
int pbkdf2_hmac( md_context_t *ctx, const unsigned char *password,
|
||||
size_t plen, const unsigned char *salt, size_t slen,
|
||||
unsigned int iteration_count,
|
||||
uint32_t key_length, unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
* DEPRECATED: Use pkcs5_self_test() instead!
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int pbkdf2_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* pbkdf2.h */
|
||||
+355
@@ -0,0 +1,355 @@
|
||||
/*
|
||||
* Privacy Enhanced Mail (PEM) decoding
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_PEM_C)
|
||||
|
||||
#include "polarssl/pem.h"
|
||||
#include "polarssl/base64.h"
|
||||
#include "polarssl/des.h"
|
||||
#include "polarssl/aes.h"
|
||||
#include "polarssl/md5.h"
|
||||
#include "polarssl/cipher.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void pem_init( pem_context *ctx )
|
||||
{
|
||||
memset( ctx, 0, sizeof( pem_context ) );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_MD5_C) && (defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C))
|
||||
/*
|
||||
* Read a 16-byte hex string and convert it to binary
|
||||
*/
|
||||
static int pem_get_iv( const unsigned char *s, unsigned char *iv, size_t iv_len )
|
||||
{
|
||||
size_t i, j, k;
|
||||
|
||||
memset( iv, 0, iv_len );
|
||||
|
||||
for( i = 0; i < iv_len * 2; i++, s++ )
|
||||
{
|
||||
if( *s >= '0' && *s <= '9' ) j = *s - '0'; else
|
||||
if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else
|
||||
if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else
|
||||
return( POLARSSL_ERR_PEM_INVALID_ENC_IV );
|
||||
|
||||
k = ( ( i & 1 ) != 0 ) ? j : j << 4;
|
||||
|
||||
iv[i >> 1] = (unsigned char)( iv[i >> 1] | k );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static void pem_pbkdf1( unsigned char *key, size_t keylen,
|
||||
unsigned char *iv,
|
||||
const unsigned char *pwd, size_t pwdlen )
|
||||
{
|
||||
md5_context md5_ctx;
|
||||
unsigned char md5sum[16];
|
||||
size_t use_len;
|
||||
|
||||
/*
|
||||
* key[ 0..15] = MD5(pwd || IV)
|
||||
*/
|
||||
md5_starts( &md5_ctx );
|
||||
md5_update( &md5_ctx, pwd, pwdlen );
|
||||
md5_update( &md5_ctx, iv, 8 );
|
||||
md5_finish( &md5_ctx, md5sum );
|
||||
|
||||
if( keylen <= 16 )
|
||||
{
|
||||
memcpy( key, md5sum, keylen );
|
||||
|
||||
memset( &md5_ctx, 0, sizeof( md5_ctx ) );
|
||||
memset( md5sum, 0, 16 );
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy( key, md5sum, 16 );
|
||||
|
||||
/*
|
||||
* key[16..23] = MD5(key[ 0..15] || pwd || IV])
|
||||
*/
|
||||
md5_starts( &md5_ctx );
|
||||
md5_update( &md5_ctx, md5sum, 16 );
|
||||
md5_update( &md5_ctx, pwd, pwdlen );
|
||||
md5_update( &md5_ctx, iv, 8 );
|
||||
md5_finish( &md5_ctx, md5sum );
|
||||
|
||||
use_len = 16;
|
||||
if( keylen < 32 )
|
||||
use_len = keylen - 16;
|
||||
|
||||
memcpy( key + 16, md5sum, use_len );
|
||||
|
||||
memset( &md5_ctx, 0, sizeof( md5_ctx ) );
|
||||
memset( md5sum, 0, 16 );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_DES_C)
|
||||
/*
|
||||
* Decrypt with DES-CBC, using PBKDF1 for key derivation
|
||||
*/
|
||||
static void pem_des_decrypt( unsigned char des_iv[8],
|
||||
unsigned char *buf, size_t buflen,
|
||||
const unsigned char *pwd, size_t pwdlen )
|
||||
{
|
||||
des_context des_ctx;
|
||||
unsigned char des_key[8];
|
||||
|
||||
pem_pbkdf1( des_key, 8, des_iv, pwd, pwdlen );
|
||||
|
||||
des_setkey_dec( &des_ctx, des_key );
|
||||
des_crypt_cbc( &des_ctx, DES_DECRYPT, buflen,
|
||||
des_iv, buf, buf );
|
||||
|
||||
memset( &des_ctx, 0, sizeof( des_ctx ) );
|
||||
memset( des_key, 0, 8 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Decrypt with 3DES-CBC, using PBKDF1 for key derivation
|
||||
*/
|
||||
static void pem_des3_decrypt( unsigned char des3_iv[8],
|
||||
unsigned char *buf, size_t buflen,
|
||||
const unsigned char *pwd, size_t pwdlen )
|
||||
{
|
||||
des3_context des3_ctx;
|
||||
unsigned char des3_key[24];
|
||||
|
||||
pem_pbkdf1( des3_key, 24, des3_iv, pwd, pwdlen );
|
||||
|
||||
des3_set3key_dec( &des3_ctx, des3_key );
|
||||
des3_crypt_cbc( &des3_ctx, DES_DECRYPT, buflen,
|
||||
des3_iv, buf, buf );
|
||||
|
||||
memset( &des3_ctx, 0, sizeof( des3_ctx ) );
|
||||
memset( des3_key, 0, 24 );
|
||||
}
|
||||
#endif /* POLARSSL_DES_C */
|
||||
|
||||
#if defined(POLARSSL_AES_C)
|
||||
/*
|
||||
* Decrypt with AES-XXX-CBC, using PBKDF1 for key derivation
|
||||
*/
|
||||
static void pem_aes_decrypt( unsigned char aes_iv[16], unsigned int keylen,
|
||||
unsigned char *buf, size_t buflen,
|
||||
const unsigned char *pwd, size_t pwdlen )
|
||||
{
|
||||
aes_context aes_ctx;
|
||||
unsigned char aes_key[32];
|
||||
|
||||
pem_pbkdf1( aes_key, keylen, aes_iv, pwd, pwdlen );
|
||||
|
||||
aes_setkey_dec( &aes_ctx, aes_key, keylen * 8 );
|
||||
aes_crypt_cbc( &aes_ctx, AES_DECRYPT, buflen,
|
||||
aes_iv, buf, buf );
|
||||
|
||||
memset( &aes_ctx, 0, sizeof( aes_ctx ) );
|
||||
memset( aes_key, 0, keylen );
|
||||
}
|
||||
#endif /* POLARSSL_AES_C */
|
||||
|
||||
#endif /* POLARSSL_MD5_C && (POLARSSL_AES_C || POLARSSL_DES_C) */
|
||||
|
||||
int pem_read_buffer( pem_context *ctx, char *header, char *footer, const unsigned char *data, const unsigned char *pwd, size_t pwdlen, size_t *use_len )
|
||||
{
|
||||
int ret, enc;
|
||||
size_t len;
|
||||
unsigned char *buf;
|
||||
const unsigned char *s1, *s2, *end;
|
||||
#if defined(POLARSSL_MD5_C) && (defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C))
|
||||
unsigned char pem_iv[16];
|
||||
cipher_type_t enc_alg = POLARSSL_CIPHER_NONE;
|
||||
#else
|
||||
((void) pwd);
|
||||
((void) pwdlen);
|
||||
#endif /* POLARSSL_MD5_C && (POLARSSL_AES_C || POLARSSL_DES_C) */
|
||||
|
||||
if( ctx == NULL )
|
||||
return( POLARSSL_ERR_PEM_BAD_INPUT_DATA );
|
||||
|
||||
s1 = (unsigned char *) strstr( (const char *) data, header );
|
||||
|
||||
if( s1 == NULL )
|
||||
return( POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT );
|
||||
|
||||
s2 = (unsigned char *) strstr( (const char *) data, footer );
|
||||
|
||||
if( s2 == NULL || s2 <= s1 )
|
||||
return( POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT );
|
||||
|
||||
s1 += strlen( header );
|
||||
if( *s1 == '\r' ) s1++;
|
||||
if( *s1 == '\n' ) s1++;
|
||||
else return( POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT );
|
||||
|
||||
end = s2;
|
||||
end += strlen( footer );
|
||||
if( *end == '\r' ) end++;
|
||||
if( *end == '\n' ) end++;
|
||||
*use_len = end - data;
|
||||
|
||||
enc = 0;
|
||||
|
||||
if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
|
||||
{
|
||||
#if defined(POLARSSL_MD5_C) && (defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C))
|
||||
enc++;
|
||||
|
||||
s1 += 22;
|
||||
if( *s1 == '\r' ) s1++;
|
||||
if( *s1 == '\n' ) s1++;
|
||||
else return( POLARSSL_ERR_PEM_INVALID_DATA );
|
||||
|
||||
|
||||
#if defined(POLARSSL_DES_C)
|
||||
if( memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) == 0 )
|
||||
{
|
||||
enc_alg = POLARSSL_CIPHER_DES_EDE3_CBC;
|
||||
|
||||
s1 += 23;
|
||||
if( pem_get_iv( s1, pem_iv, 8 ) != 0 )
|
||||
return( POLARSSL_ERR_PEM_INVALID_ENC_IV );
|
||||
|
||||
s1 += 16;
|
||||
}
|
||||
else if( memcmp( s1, "DEK-Info: DES-CBC,", 18 ) == 0 )
|
||||
{
|
||||
enc_alg = POLARSSL_CIPHER_DES_CBC;
|
||||
|
||||
s1 += 18;
|
||||
if( pem_get_iv( s1, pem_iv, 8) != 0 )
|
||||
return( POLARSSL_ERR_PEM_INVALID_ENC_IV );
|
||||
|
||||
s1 += 16;
|
||||
}
|
||||
#endif /* POLARSSL_DES_C */
|
||||
|
||||
#if defined(POLARSSL_AES_C)
|
||||
if( memcmp( s1, "DEK-Info: AES-", 14 ) == 0 )
|
||||
{
|
||||
if( memcmp( s1, "DEK-Info: AES-128-CBC,", 22 ) == 0 )
|
||||
enc_alg = POLARSSL_CIPHER_AES_128_CBC;
|
||||
else if( memcmp( s1, "DEK-Info: AES-192-CBC,", 22 ) == 0 )
|
||||
enc_alg = POLARSSL_CIPHER_AES_192_CBC;
|
||||
else if( memcmp( s1, "DEK-Info: AES-256-CBC,", 22 ) == 0 )
|
||||
enc_alg = POLARSSL_CIPHER_AES_256_CBC;
|
||||
else
|
||||
return( POLARSSL_ERR_PEM_UNKNOWN_ENC_ALG );
|
||||
|
||||
s1 += 22;
|
||||
if( pem_get_iv( s1, pem_iv, 16 ) != 0 )
|
||||
return( POLARSSL_ERR_PEM_INVALID_ENC_IV );
|
||||
|
||||
s1 += 32;
|
||||
}
|
||||
#endif /* POLARSSL_AES_C */
|
||||
|
||||
if( enc_alg == POLARSSL_CIPHER_NONE )
|
||||
return( POLARSSL_ERR_PEM_UNKNOWN_ENC_ALG );
|
||||
|
||||
if( *s1 == '\r' ) s1++;
|
||||
if( *s1 == '\n' ) s1++;
|
||||
else return( POLARSSL_ERR_PEM_INVALID_DATA );
|
||||
#else
|
||||
return( POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE );
|
||||
#endif /* POLARSSL_MD5_C && (POLARSSL_AES_C || POLARSSL_DES_C) */
|
||||
}
|
||||
|
||||
len = 0;
|
||||
ret = base64_decode( NULL, &len, s1, s2 - s1 );
|
||||
|
||||
if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
|
||||
return( POLARSSL_ERR_PEM_INVALID_DATA + ret );
|
||||
|
||||
if( ( buf = (unsigned char *) malloc( len ) ) == NULL )
|
||||
return( POLARSSL_ERR_PEM_MALLOC_FAILED );
|
||||
|
||||
if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
|
||||
{
|
||||
free( buf );
|
||||
return( POLARSSL_ERR_PEM_INVALID_DATA + ret );
|
||||
}
|
||||
|
||||
if( enc != 0 )
|
||||
{
|
||||
#if defined(POLARSSL_MD5_C) && (defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C))
|
||||
if( pwd == NULL )
|
||||
{
|
||||
free( buf );
|
||||
return( POLARSSL_ERR_PEM_PASSWORD_REQUIRED );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_DES_C)
|
||||
if( enc_alg == POLARSSL_CIPHER_DES_EDE3_CBC )
|
||||
pem_des3_decrypt( pem_iv, buf, len, pwd, pwdlen );
|
||||
else if( enc_alg == POLARSSL_CIPHER_DES_CBC )
|
||||
pem_des_decrypt( pem_iv, buf, len, pwd, pwdlen );
|
||||
#endif /* POLARSSL_DES_C */
|
||||
|
||||
#if defined(POLARSSL_AES_C)
|
||||
if( enc_alg == POLARSSL_CIPHER_AES_128_CBC )
|
||||
pem_aes_decrypt( pem_iv, 16, buf, len, pwd, pwdlen );
|
||||
else if( enc_alg == POLARSSL_CIPHER_AES_192_CBC )
|
||||
pem_aes_decrypt( pem_iv, 24, buf, len, pwd, pwdlen );
|
||||
else if( enc_alg == POLARSSL_CIPHER_AES_256_CBC )
|
||||
pem_aes_decrypt( pem_iv, 32, buf, len, pwd, pwdlen );
|
||||
#endif /* POLARSSL_AES_C */
|
||||
|
||||
if( buf[0] != 0x30 || buf[1] != 0x82 ||
|
||||
buf[4] != 0x02 || buf[5] != 0x01 )
|
||||
{
|
||||
free( buf );
|
||||
return( POLARSSL_ERR_PEM_PASSWORD_MISMATCH );
|
||||
}
|
||||
#else
|
||||
free( buf );
|
||||
return( POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE );
|
||||
#endif
|
||||
}
|
||||
|
||||
ctx->buf = buf;
|
||||
ctx->buflen = len;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
void pem_free( pem_context *ctx )
|
||||
{
|
||||
if( ctx->buf )
|
||||
free( ctx->buf );
|
||||
|
||||
if( ctx->info )
|
||||
free( ctx->info );
|
||||
|
||||
memset( ctx, 0, sizeof( pem_context ) );
|
||||
}
|
||||
|
||||
#endif
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
* \file pem.h
|
||||
*
|
||||
* \brief Privacy Enhanced Mail (PEM) decoding
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef POLARSSL_PEM_H
|
||||
#define POLARSSL_PEM_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* \name PEM Error codes
|
||||
* These error codes are returned in case of errors reading the
|
||||
* PEM data.
|
||||
* \{
|
||||
*/
|
||||
#define POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT -0x1080 /**< No PEM header or footer found. */
|
||||
#define POLARSSL_ERR_PEM_INVALID_DATA -0x1100 /**< PEM string is not as expected. */
|
||||
#define POLARSSL_ERR_PEM_MALLOC_FAILED -0x1180 /**< Failed to allocate memory. */
|
||||
#define POLARSSL_ERR_PEM_INVALID_ENC_IV -0x1200 /**< RSA IV is not in hex-format. */
|
||||
#define POLARSSL_ERR_PEM_UNKNOWN_ENC_ALG -0x1280 /**< Unsupported key encryption algorithm. */
|
||||
#define POLARSSL_ERR_PEM_PASSWORD_REQUIRED -0x1300 /**< Private key password can't be empty. */
|
||||
#define POLARSSL_ERR_PEM_PASSWORD_MISMATCH -0x1380 /**< Given private key password does not allow for correct decryption. */
|
||||
#define POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE -0x1400 /**< Unavailable feature, e.g. hashing/encryption combination. */
|
||||
#define POLARSSL_ERR_PEM_BAD_INPUT_DATA -0x1480 /**< Bad input parameters to function. */
|
||||
/* \} name */
|
||||
|
||||
/**
|
||||
* \brief PEM context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned char *buf; /*!< buffer for decoded data */
|
||||
size_t buflen; /*!< length of the buffer */
|
||||
unsigned char *info; /*!< buffer for extra header information */
|
||||
}
|
||||
pem_context;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief PEM context setup
|
||||
*
|
||||
* \param ctx context to be initialized
|
||||
*/
|
||||
void pem_init( pem_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Read a buffer for PEM information and store the resulting
|
||||
* data into the specified context buffers.
|
||||
*
|
||||
* \param ctx context to use
|
||||
* \param header header string to seek and expect
|
||||
* \param footer footer string to seek and expect
|
||||
* \param data source data to look in
|
||||
* \param pwd password for decryption (can be NULL)
|
||||
* \param pwdlen length of password
|
||||
* \param use_len destination for total length used (set after header is
|
||||
* correctly read, so unless you get
|
||||
* POLARSSL_ERR_PEM_BAD_INPUT_DATA or
|
||||
* POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT, use_len is
|
||||
* the length to skip)
|
||||
*
|
||||
* \return 0 on success, ior a specific PEM error code
|
||||
*/
|
||||
int pem_read_buffer( pem_context *ctx, char *header, char *footer,
|
||||
const unsigned char *data,
|
||||
const unsigned char *pwd,
|
||||
size_t pwdlen, size_t *use_len );
|
||||
|
||||
/**
|
||||
* \brief PEM context memory freeing
|
||||
*
|
||||
* \param ctx context to be freed
|
||||
*/
|
||||
void pem_free( pem_context *ctx );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* pem.h */
|
||||
@@ -0,0 +1,238 @@
|
||||
/**
|
||||
* \file pkcs11.c
|
||||
*
|
||||
* \brief Wrapper for PKCS#11 library libpkcs11-helper
|
||||
*
|
||||
* \author Adriaan de Jong <dejong@fox-it.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "polarssl/pkcs11.h"
|
||||
|
||||
#if defined(POLARSSL_PKCS11_C)
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
int pkcs11_x509_cert_init( x509_cert *cert, pkcs11h_certificate_t pkcs11_cert )
|
||||
{
|
||||
int ret = 1;
|
||||
unsigned char *cert_blob = NULL;
|
||||
size_t cert_blob_size = 0;
|
||||
|
||||
if( cert == NULL )
|
||||
{
|
||||
ret = 2;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, NULL, &cert_blob_size ) != CKR_OK )
|
||||
{
|
||||
ret = 3;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cert_blob = malloc( cert_blob_size );
|
||||
if( NULL == cert_blob )
|
||||
{
|
||||
ret = 4;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, cert_blob, &cert_blob_size ) != CKR_OK )
|
||||
{
|
||||
ret = 5;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if( 0 != x509parse_crt(cert, cert_blob, cert_blob_size ) )
|
||||
{
|
||||
ret = 6;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
if( NULL != cert_blob )
|
||||
free( cert_blob );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int pkcs11_priv_key_init( pkcs11_context *priv_key,
|
||||
pkcs11h_certificate_t pkcs11_cert )
|
||||
{
|
||||
int ret = 1;
|
||||
x509_cert cert;
|
||||
|
||||
memset( &cert, 0, sizeof( cert ) );
|
||||
|
||||
if( priv_key == NULL )
|
||||
goto cleanup;
|
||||
|
||||
if( 0 != pkcs11_x509_cert_init( &cert, pkcs11_cert ) )
|
||||
goto cleanup;
|
||||
|
||||
priv_key->len = cert.rsa.len;
|
||||
priv_key->pkcs11h_cert = pkcs11_cert;
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
x509_free( &cert );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void pkcs11_priv_key_free( pkcs11_context *priv_key )
|
||||
{
|
||||
if( NULL != priv_key )
|
||||
pkcs11h_certificate_freeCertificate( priv_key->pkcs11h_cert );
|
||||
}
|
||||
|
||||
int pkcs11_decrypt( pkcs11_context *ctx,
|
||||
int mode, size_t *olen,
|
||||
const unsigned char *input,
|
||||
unsigned char *output,
|
||||
size_t output_max_len )
|
||||
{
|
||||
size_t input_len, output_len;
|
||||
|
||||
if( NULL == ctx )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
if( RSA_PUBLIC == mode )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
output_len = input_len = ctx->len;
|
||||
|
||||
if( input_len < 16 || input_len > output_max_len )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
/* Determine size of output buffer */
|
||||
if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input,
|
||||
input_len, NULL, &output_len ) != CKR_OK )
|
||||
{
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
if( output_len > output_max_len )
|
||||
return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );
|
||||
|
||||
if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input,
|
||||
input_len, output, &output_len ) != CKR_OK )
|
||||
{
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
}
|
||||
*olen = output_len;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int pkcs11_sign( pkcs11_context *ctx,
|
||||
int mode,
|
||||
int hash_id,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
unsigned char *sig )
|
||||
{
|
||||
size_t olen, asn_len;
|
||||
unsigned char *p = sig;
|
||||
|
||||
if( NULL == ctx )
|
||||
return POLARSSL_ERR_RSA_BAD_INPUT_DATA;
|
||||
|
||||
if( RSA_PUBLIC == mode )
|
||||
return POLARSSL_ERR_RSA_BAD_INPUT_DATA;
|
||||
|
||||
olen = ctx->len;
|
||||
|
||||
switch( hash_id )
|
||||
{
|
||||
case SIG_RSA_RAW:
|
||||
asn_len = 0;
|
||||
memcpy( p, hash, hashlen );
|
||||
break;
|
||||
|
||||
case SIG_RSA_MD2:
|
||||
asn_len = OID_SIZE(ASN1_HASH_MDX);
|
||||
memcpy( p, ASN1_HASH_MDX, asn_len );
|
||||
memcpy( p + asn_len, hash, hashlen );
|
||||
p[13] = 2; break;
|
||||
|
||||
case SIG_RSA_MD4:
|
||||
asn_len = OID_SIZE(ASN1_HASH_MDX);
|
||||
memcpy( p, ASN1_HASH_MDX, asn_len );
|
||||
memcpy( p + asn_len, hash, hashlen );
|
||||
p[13] = 4; break;
|
||||
|
||||
case SIG_RSA_MD5:
|
||||
asn_len = OID_SIZE(ASN1_HASH_MDX);
|
||||
memcpy( p, ASN1_HASH_MDX, asn_len );
|
||||
memcpy( p + asn_len, hash, hashlen );
|
||||
p[13] = 5; break;
|
||||
|
||||
case SIG_RSA_SHA1:
|
||||
asn_len = OID_SIZE(ASN1_HASH_SHA1);
|
||||
memcpy( p, ASN1_HASH_SHA1, asn_len );
|
||||
memcpy( p + 15, hash, hashlen );
|
||||
break;
|
||||
|
||||
case SIG_RSA_SHA224:
|
||||
asn_len = OID_SIZE(ASN1_HASH_SHA2X);
|
||||
memcpy( p, ASN1_HASH_SHA2X, asn_len );
|
||||
memcpy( p + asn_len, hash, hashlen );
|
||||
p[1] += hashlen; p[14] = 4; p[18] += hashlen; break;
|
||||
|
||||
case SIG_RSA_SHA256:
|
||||
asn_len = OID_SIZE(ASN1_HASH_SHA2X);
|
||||
memcpy( p, ASN1_HASH_SHA2X, asn_len );
|
||||
memcpy( p + asn_len, hash, hashlen );
|
||||
p[1] += hashlen; p[14] = 1; p[18] += hashlen; break;
|
||||
|
||||
case SIG_RSA_SHA384:
|
||||
asn_len = OID_SIZE(ASN1_HASH_SHA2X);
|
||||
memcpy( p, ASN1_HASH_SHA2X, asn_len );
|
||||
memcpy( p + asn_len, hash, hashlen );
|
||||
p[1] += hashlen; p[14] = 2; p[18] += hashlen; break;
|
||||
|
||||
case SIG_RSA_SHA512:
|
||||
asn_len = OID_SIZE(ASN1_HASH_SHA2X);
|
||||
memcpy( p, ASN1_HASH_SHA2X, asn_len );
|
||||
memcpy( p + asn_len, hash, hashlen );
|
||||
p[1] += hashlen; p[14] = 3; p[18] += hashlen; break;
|
||||
|
||||
default:
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
if( pkcs11h_certificate_signAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, sig,
|
||||
asn_len + hashlen, sig, &olen ) != CKR_OK )
|
||||
{
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif /* defined(POLARSSL_PKCS11_C) */
|
||||
@@ -0,0 +1,161 @@
|
||||
/**
|
||||
* \file pkcs11.h
|
||||
*
|
||||
* \brief Wrapper for PKCS#11 library libpkcs11-helper
|
||||
*
|
||||
* \author Adriaan de Jong <dejong@fox-it.com>
|
||||
*
|
||||
* Copyright (C) 2006-2011, 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_PKCS11_H
|
||||
#define POLARSSL_PKCS11_H
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_PKCS11_C)
|
||||
|
||||
#include "polarssl/x509.h"
|
||||
|
||||
#include <pkcs11-helper-1.0/pkcs11h-certificate.h>
|
||||
|
||||
#if defined(_MSC_VER) && !defined(inline)
|
||||
#define inline _inline
|
||||
#else
|
||||
#if defined(__ARMCC_VERSION) && !defined(inline)
|
||||
#define inline __inline
|
||||
#endif /* __ARMCC_VERSION */
|
||||
#endif /*_MSC_VER */
|
||||
|
||||
/**
|
||||
* Context for PKCS #11 private keys.
|
||||
*/
|
||||
typedef struct {
|
||||
pkcs11h_certificate_t pkcs11h_cert;
|
||||
int len;
|
||||
} pkcs11_context;
|
||||
|
||||
/**
|
||||
* Fill in a PolarSSL certificate, based on the given PKCS11 helper certificate.
|
||||
*
|
||||
* \param cert X.509 certificate to fill
|
||||
* \param pkcs11h_cert PKCS #11 helper certificate
|
||||
*
|
||||
* \return 0 on success.
|
||||
*/
|
||||
int pkcs11_x509_cert_init( x509_cert *cert, pkcs11h_certificate_t pkcs11h_cert );
|
||||
|
||||
/**
|
||||
* Initialise a pkcs11_context, storing the given certificate. Note that the
|
||||
* pkcs11_context will take over control of the certificate, freeing it when
|
||||
* done.
|
||||
*
|
||||
* \param priv_key Private key structure to fill.
|
||||
* \param pkcs11_cert PKCS #11 helper certificate
|
||||
*
|
||||
* \return 0 on success
|
||||
*/
|
||||
int pkcs11_priv_key_init( pkcs11_context *priv_key,
|
||||
pkcs11h_certificate_t pkcs11_cert );
|
||||
|
||||
/**
|
||||
* Free the contents of the given private key context. Note that the structure
|
||||
* itself is not freed.
|
||||
*
|
||||
* \param priv_key Private key structure to cleanup
|
||||
*/
|
||||
void pkcs11_priv_key_free( pkcs11_context *priv_key );
|
||||
|
||||
/**
|
||||
* \brief Do an RSA private key decrypt, then remove the message padding
|
||||
*
|
||||
* \param ctx PKCS #11 context
|
||||
* \param mode must be RSA_PRIVATE, for compatibility with rsa.c's signature
|
||||
* \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 pkcs11_decrypt( pkcs11_context *ctx,
|
||||
int mode, size_t *olen,
|
||||
const unsigned char *input,
|
||||
unsigned char *output,
|
||||
size_t output_max_len );
|
||||
|
||||
/**
|
||||
* \brief Do a private RSA to sign a message digest
|
||||
*
|
||||
* \param ctx PKCS #11 context
|
||||
* \param mode must be RSA_PRIVATE, for compatibility with rsa.c's signature
|
||||
* \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 pkcs11_sign( pkcs11_context *ctx,
|
||||
int mode,
|
||||
int hash_id,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
unsigned char *sig );
|
||||
|
||||
/**
|
||||
* SSL/TLS wrappers for PKCS#11 functions
|
||||
*/
|
||||
static inline int ssl_pkcs11_decrypt( void *ctx, int mode, size_t *olen,
|
||||
const unsigned char *input, unsigned char *output,
|
||||
size_t output_max_len )
|
||||
{
|
||||
return pkcs11_decrypt( (pkcs11_context *) ctx, mode, olen, input, output,
|
||||
output_max_len );
|
||||
}
|
||||
|
||||
static inline int ssl_pkcs11_sign( void *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
|
||||
int mode, int hash_id, unsigned int hashlen,
|
||||
const unsigned char *hash, unsigned char *sig )
|
||||
{
|
||||
((void) f_rng);
|
||||
((void) p_rng);
|
||||
return pkcs11_sign( (pkcs11_context *) ctx, mode, hash_id,
|
||||
hashlen, hash, sig );
|
||||
}
|
||||
|
||||
static inline size_t ssl_pkcs11_key_len( void *ctx )
|
||||
{
|
||||
return ( (pkcs11_context *) ctx )->len;
|
||||
}
|
||||
|
||||
#endif /* POLARSSL_PKCS11_C */
|
||||
|
||||
#endif /* POLARSSL_PKCS11_H */
|
||||
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
* PKCS#12 Personal Information Exchange Syntax
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
* The PKCS #12 Personal Information Exchange Syntax Standard v1.1
|
||||
*
|
||||
* http://www.rsa.com/rsalabs/pkcs/files/h11301-wp-pkcs-12v1-1-personal-information-exchange-syntax.pdf
|
||||
* ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1-1.asn
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_PKCS12_C)
|
||||
|
||||
#include "polarssl/pkcs12.h"
|
||||
#include "polarssl/asn1.h"
|
||||
#include "polarssl/cipher.h"
|
||||
|
||||
#if defined(POLARSSL_ARC4_C)
|
||||
#include "polarssl/arc4.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_DES_C)
|
||||
#include "polarssl/des.h"
|
||||
#endif
|
||||
|
||||
static int pkcs12_parse_pbe_params( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
asn1_buf *salt, int *iterations )
|
||||
{
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
|
||||
/*
|
||||
* pkcs-12PbeParams ::= SEQUENCE {
|
||||
* salt OCTET STRING,
|
||||
* iterations INTEGER
|
||||
* }
|
||||
*
|
||||
*/
|
||||
if( ( ret = asn1_get_tag( p, end, &len,
|
||||
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
|
||||
{
|
||||
return( POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT + ret );
|
||||
}
|
||||
|
||||
end = *p + len;
|
||||
|
||||
if( ( ret = asn1_get_tag( p, end, &salt->len, ASN1_OCTET_STRING ) ) != 0 )
|
||||
return( POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT + ret );
|
||||
|
||||
salt->p = *p;
|
||||
*p += salt->len;
|
||||
|
||||
if( ( ret = asn1_get_int( p, end, iterations ) ) != 0 )
|
||||
return( POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT + ret );
|
||||
|
||||
if( *p != end )
|
||||
return( POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT +
|
||||
POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int pkcs12_pbe_derive_key_iv( asn1_buf *pbe_params, md_type_t md_type,
|
||||
const unsigned char *pwd, size_t pwdlen,
|
||||
unsigned char *key, size_t keylen,
|
||||
unsigned char *iv, size_t ivlen )
|
||||
{
|
||||
int ret, iterations;
|
||||
asn1_buf salt;
|
||||
size_t i;
|
||||
unsigned char *p, *end;
|
||||
unsigned char unipwd[258];
|
||||
|
||||
memset(&salt, 0, sizeof(asn1_buf));
|
||||
memset(&unipwd, 0, sizeof(unipwd));
|
||||
|
||||
p = pbe_params->p;
|
||||
end = p + pbe_params->len;
|
||||
|
||||
if( ( ret = pkcs12_parse_pbe_params( &p, end, &salt, &iterations ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
for(i = 0; i < pwdlen; i++)
|
||||
unipwd[i * 2 + 1] = pwd[i];
|
||||
|
||||
if( ( ret = pkcs12_derivation( key, keylen, unipwd, pwdlen * 2 + 2,
|
||||
salt.p, salt.len, md_type,
|
||||
PKCS12_DERIVE_KEY, iterations ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( iv == NULL || ivlen == 0 )
|
||||
return( 0 );
|
||||
|
||||
if( ( ret = pkcs12_derivation( iv, ivlen, unipwd, pwdlen * 2 + 2,
|
||||
salt.p, salt.len, md_type,
|
||||
PKCS12_DERIVE_IV, iterations ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int pkcs12_pbe_sha1_rc4_128( asn1_buf *pbe_params, int mode,
|
||||
const unsigned char *pwd, size_t pwdlen,
|
||||
const unsigned char *data, size_t len,
|
||||
unsigned char *output )
|
||||
{
|
||||
#if !defined(POLARSSL_ARC4_C)
|
||||
((void) pbe_params);
|
||||
((void) mode);
|
||||
((void) pwd);
|
||||
((void) pwdlen);
|
||||
((void) data);
|
||||
((void) len);
|
||||
((void) output);
|
||||
return( POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE );
|
||||
#else
|
||||
int ret;
|
||||
unsigned char key[16];
|
||||
arc4_context ctx;
|
||||
((void) mode);
|
||||
|
||||
if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, POLARSSL_MD_SHA1,
|
||||
pwd, pwdlen,
|
||||
key, 16, NULL, 0 ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
arc4_setup( &ctx, key, 16 );
|
||||
if( ( ret = arc4_crypt( &ctx, len, data, output ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
return( 0 );
|
||||
#endif /* POLARSSL_ARC4_C */
|
||||
}
|
||||
|
||||
int pkcs12_pbe( asn1_buf *pbe_params, int mode,
|
||||
cipher_type_t cipher_type, md_type_t md_type,
|
||||
const unsigned char *pwd, size_t pwdlen,
|
||||
const unsigned char *data, size_t len,
|
||||
unsigned char *output )
|
||||
{
|
||||
int ret, keylen = 0;
|
||||
unsigned char key[32];
|
||||
unsigned char iv[16];
|
||||
const cipher_info_t *cipher_info;
|
||||
cipher_context_t cipher_ctx;
|
||||
size_t olen = 0;
|
||||
|
||||
cipher_info = cipher_info_from_type( cipher_type );
|
||||
if( cipher_info == NULL )
|
||||
return( POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE );
|
||||
|
||||
keylen = cipher_info->key_length / 8;
|
||||
|
||||
if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, md_type, pwd, pwdlen,
|
||||
key, keylen,
|
||||
iv, cipher_info->iv_size ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( ( ret = cipher_init_ctx( &cipher_ctx, cipher_info ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = cipher_setkey( &cipher_ctx, key, keylen, mode ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = cipher_reset( &cipher_ctx, iv ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = cipher_update( &cipher_ctx, data, len,
|
||||
output, &olen ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( ( ret = cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 )
|
||||
return( POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static void pkcs12_fill_buffer( unsigned char *data, size_t data_len,
|
||||
const unsigned char *filler, size_t fill_len )
|
||||
{
|
||||
unsigned char *p = data;
|
||||
size_t use_len;
|
||||
|
||||
while( data_len > 0 )
|
||||
{
|
||||
use_len = ( data_len > fill_len ) ? fill_len : data_len;
|
||||
memcpy( p, filler, use_len );
|
||||
p += use_len;
|
||||
data_len -= use_len;
|
||||
}
|
||||
}
|
||||
|
||||
int pkcs12_derivation( unsigned char *data, size_t datalen,
|
||||
const unsigned char *pwd, size_t pwdlen,
|
||||
const unsigned char *salt, size_t saltlen,
|
||||
md_type_t md_type, int id, int iterations )
|
||||
{
|
||||
int ret, i;
|
||||
unsigned int j;
|
||||
|
||||
unsigned char diversifier[128];
|
||||
unsigned char salt_block[128], pwd_block[128], hash_block[128];
|
||||
unsigned char hash_output[POLARSSL_MD_MAX_SIZE];
|
||||
unsigned char *p;
|
||||
unsigned char c;
|
||||
|
||||
size_t hlen, use_len, v;
|
||||
|
||||
const md_info_t *md_info;
|
||||
md_context_t md_ctx;
|
||||
|
||||
// This version only allows max of 64 bytes of password or salt
|
||||
if( datalen > 128 || pwdlen > 64 || saltlen > 64 )
|
||||
return( POLARSSL_ERR_PKCS12_BAD_INPUT_DATA );
|
||||
|
||||
md_info = md_info_from_type( md_type );
|
||||
if( md_info == NULL )
|
||||
return( POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE );
|
||||
|
||||
if ( ( ret = md_init_ctx( &md_ctx, md_info ) ) != 0 )
|
||||
return( ret );
|
||||
hlen = md_get_size( md_info );
|
||||
|
||||
if( hlen <= 32 )
|
||||
v = 64;
|
||||
else
|
||||
v = 128;
|
||||
|
||||
memset( diversifier, (unsigned char) id, v );
|
||||
|
||||
pkcs12_fill_buffer( salt_block, v, salt, saltlen );
|
||||
pkcs12_fill_buffer( pwd_block, v, pwd, pwdlen );
|
||||
|
||||
p = data;
|
||||
while( datalen > 0 )
|
||||
{
|
||||
// Calculate hash( diversifier || salt_block || pwd_block )
|
||||
if( ( ret = md_starts( &md_ctx ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = md_update( &md_ctx, diversifier, v ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = md_update( &md_ctx, salt_block, v ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = md_update( &md_ctx, pwd_block, v ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = md_finish( &md_ctx, hash_output ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
// Perform remaining ( iterations - 1 ) recursive hash calculations
|
||||
for( i = 1; i < iterations; i++ )
|
||||
{
|
||||
if( ( ret = md( md_info, hash_output, hlen, hash_output ) ) != 0 )
|
||||
return( ret );
|
||||
}
|
||||
|
||||
use_len = ( datalen > hlen ) ? hlen : datalen;
|
||||
memcpy( p, hash_output, use_len );
|
||||
datalen -= use_len;
|
||||
p += use_len;
|
||||
|
||||
if( datalen == 0 )
|
||||
break;
|
||||
|
||||
// Concatenating copies of hash_output into hash_block (B)
|
||||
pkcs12_fill_buffer( hash_block, v, hash_output, hlen );
|
||||
|
||||
// B += 1
|
||||
for( i = v; i > 0; i-- )
|
||||
if( ++hash_block[i - 1] != 0 )
|
||||
break;
|
||||
|
||||
// salt_block += B
|
||||
c = 0;
|
||||
for( i = v; i > 0; i-- )
|
||||
{
|
||||
j = salt_block[i - 1] + hash_block[i - 1] + c;
|
||||
c = (unsigned char) (j >> 8);
|
||||
salt_block[i - 1] = j & 0xFF;
|
||||
}
|
||||
|
||||
// pwd_block += B
|
||||
c = 0;
|
||||
for( i = v; i > 0; i-- )
|
||||
{
|
||||
j = pwd_block[i - 1] + hash_block[i - 1] + c;
|
||||
c = (unsigned char) (j >> 8);
|
||||
pwd_block[i - 1] = j & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif /* POLARSSL_PKCS12_C */
|
||||
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* \file pkcs12.h
|
||||
*
|
||||
* \brief PKCS#12 Personal Information Exchange Syntax
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef POLARSSL_PKCS12_H
|
||||
#define POLARSSL_PKCS12_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "polarssl/md.h"
|
||||
#include "polarssl/cipher.h"
|
||||
#include "polarssl/asn1.h"
|
||||
|
||||
#define POLARSSL_ERR_PKCS12_BAD_INPUT_DATA -0x1F80 /**< Bad input parameters to function. */
|
||||
#define POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE -0x1F00 /**< Feature not available, e.g. unsupported encryption scheme. */
|
||||
#define POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT -0x1E80 /**< PBE ASN.1 data not as expected. */
|
||||
#define POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH -0x1E00 /**< Given private key password does not allow for correct decryption. */
|
||||
|
||||
#define PKCS12_DERIVE_KEY 1 /*< encryption/decryption key */
|
||||
#define PKCS12_DERIVE_IV 2 /*< initialization vector */
|
||||
#define PKCS12_DERIVE_MAC_KEY 3 /*< integrity / MAC key */
|
||||
|
||||
#define PKCS12_PBE_DECRYPT 0
|
||||
#define PKCS12_PBE_ENCRYPT 1
|
||||
|
||||
/*
|
||||
* PKCS#12 PBE types
|
||||
*/
|
||||
#define OID_PKCS12 "\x2a\x86\x48\x86\xf7\x0d\x01\x0c"
|
||||
#define OID_PKCS12_PBE_SHA1_RC4_128 OID_PKCS12 "\x01\x01"
|
||||
#define OID_PKCS12_PBE_SHA1_DES3_EDE_CBC OID_PKCS12 "\x01\x03"
|
||||
#define OID_PKCS12_PBE_SHA1_DES2_EDE_CBC OID_PKCS12 "\x01\x04"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief PKCS12 Password Based function (encryption / decryption)
|
||||
* for pbeWithSHAAnd128BitRC4
|
||||
*
|
||||
* \param pbe_params an ASN1 buffer containing the pkcs-12PbeParams structure
|
||||
* \param mode either PKCS12_PBE_ENCRYPT or PKCS12_PBE_DECRYPT
|
||||
* \param pwd the password used (may be NULL if no password is used)
|
||||
* \param pwdlen length of the password (may be 0)
|
||||
* \param input the input data
|
||||
* \param len data length
|
||||
* \param output the output buffer
|
||||
*
|
||||
* \return 0 if successful, or a PolarSSL error code
|
||||
*/
|
||||
int pkcs12_pbe_sha1_rc4_128( asn1_buf *pbe_params, int mode,
|
||||
const unsigned char *pwd, size_t pwdlen,
|
||||
const unsigned char *input, size_t len,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief PKCS12 Password Based function (encryption / decryption)
|
||||
* for cipher-based and md-based PBE's
|
||||
*
|
||||
* \param pbe_params an ASN1 buffer containing the pkcs-12PbeParams structure
|
||||
* \param mode either PKCS12_PBE_ENCRYPT or PKCS12_PBE_DECRYPT
|
||||
* \param cipher_type the cipher used
|
||||
* \param md_type the md used
|
||||
* \param pwd the password used (may be NULL if no password is used)
|
||||
* \param pwdlen length of the password (may be 0)
|
||||
* \param input the input data
|
||||
* \param len data length
|
||||
* \param output the output buffer
|
||||
*
|
||||
* \return 0 if successful, or a PolarSSL error code
|
||||
*/
|
||||
int pkcs12_pbe( asn1_buf *pbe_params, int mode,
|
||||
cipher_type_t cipher_type, md_type_t md_type,
|
||||
const unsigned char *pwd, size_t pwdlen,
|
||||
const unsigned char *input, size_t len,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief The PKCS#12 derivation function uses a password and a salt
|
||||
* to produce pseudo-random bits for a particular "purpose".
|
||||
*
|
||||
* Depending on the given id, this function can produce an
|
||||
* encryption/decryption key, an nitialization vector or an
|
||||
* integrity key.
|
||||
*
|
||||
* \param data buffer to store the derived data in
|
||||
* \param datalen length to fill
|
||||
* \param pwd password to use (may be NULL if no password is used)
|
||||
* \param pwdlen length of the password (may be 0)
|
||||
* \param salt salt buffer to use
|
||||
* \param saltlen length of the salt
|
||||
* \param md md type to use during the derivation
|
||||
* \param id id that describes the purpose (can be PKCS12_DERIVE_KEY,
|
||||
* PKCS12_DERIVE_IV or PKCS12_DERIVE_MAC_KEY)
|
||||
* \param iterations number of iterations
|
||||
*
|
||||
* \return 0 if successful, or a MD, BIGNUM type error.
|
||||
*/
|
||||
int pkcs12_derivation( unsigned char *data, size_t datalen,
|
||||
const unsigned char *pwd, size_t pwdlen,
|
||||
const unsigned char *salt, size_t saltlen,
|
||||
md_type_t md, int id, int iterations );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* pkcs12.h */
|
||||
@@ -0,0 +1,415 @@
|
||||
/**
|
||||
* \file pkcs5.c
|
||||
*
|
||||
* \brief PKCS#5 functions
|
||||
*
|
||||
* \author Mathias Olsson <mathias@kompetensum.com>
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
* PKCS#5 includes PBKDF2 and more
|
||||
*
|
||||
* http://tools.ietf.org/html/rfc2898 (Specification)
|
||||
* http://tools.ietf.org/html/rfc6070 (Test vectors)
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_PKCS5_C)
|
||||
|
||||
#include "polarssl/pkcs5.h"
|
||||
#include "polarssl/asn1.h"
|
||||
#include "polarssl/cipher.h"
|
||||
|
||||
#define OID_CMP(oid_str, oid_buf) \
|
||||
( ( OID_SIZE(oid_str) == (oid_buf)->len ) && \
|
||||
memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0)
|
||||
|
||||
static int pkcs5_parse_pbkdf2_params( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
asn1_buf *salt, int *iterations,
|
||||
int *keylen, md_type_t *md_type )
|
||||
{
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
asn1_buf prf_alg_oid;
|
||||
|
||||
/*
|
||||
* PBKDF2-params ::= SEQUENCE {
|
||||
* salt OCTET STRING,
|
||||
* iterationCount INTEGER,
|
||||
* keyLength INTEGER OPTIONAL
|
||||
* prf AlgorithmIdentifier DEFAULT algid-hmacWithSHA1
|
||||
* }
|
||||
*
|
||||
*/
|
||||
if( ( ret = asn1_get_tag( p, end, &len,
|
||||
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
|
||||
{
|
||||
return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
|
||||
}
|
||||
|
||||
end = *p + len;
|
||||
|
||||
if( ( ret = asn1_get_tag( p, end, &salt->len, ASN1_OCTET_STRING ) ) != 0 )
|
||||
return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
|
||||
|
||||
salt->p = *p;
|
||||
*p += salt->len;
|
||||
|
||||
if( ( ret = asn1_get_int( p, end, iterations ) ) != 0 )
|
||||
return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
|
||||
|
||||
if( *p == end )
|
||||
return( 0 );
|
||||
|
||||
if( ( ret = asn1_get_int( p, end, keylen ) ) != 0 )
|
||||
{
|
||||
if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
|
||||
return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
|
||||
}
|
||||
|
||||
if( *p == end )
|
||||
return( 0 );
|
||||
|
||||
if( ( ret = asn1_get_tag( p, end, &prf_alg_oid.len, ASN1_OID ) ) != 0 )
|
||||
return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
|
||||
|
||||
if( !OID_CMP( OID_HMAC_SHA1, &prf_alg_oid ) )
|
||||
return( POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE );
|
||||
|
||||
*md_type = POLARSSL_MD_SHA1;
|
||||
|
||||
if( *p != end )
|
||||
return( POLARSSL_ERR_PKCS5_INVALID_FORMAT +
|
||||
POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int pkcs5_pbes2( asn1_buf *pbe_params, int mode,
|
||||
const unsigned char *pwd, size_t pwdlen,
|
||||
const unsigned char *data, size_t datalen,
|
||||
unsigned char *output )
|
||||
{
|
||||
int ret, iterations = 0, keylen = 0;
|
||||
unsigned char *p, *end, *end2;
|
||||
asn1_buf kdf_alg_oid, enc_scheme_oid, salt;
|
||||
md_type_t md_type = POLARSSL_MD_SHA1;
|
||||
unsigned char key[32], iv[32];
|
||||
size_t len = 0, olen = 0;
|
||||
const md_info_t *md_info;
|
||||
const cipher_info_t *cipher_info;
|
||||
md_context_t md_ctx;
|
||||
cipher_context_t cipher_ctx;
|
||||
|
||||
p = pbe_params->p;
|
||||
end = p + pbe_params->len;
|
||||
|
||||
/*
|
||||
* PBES2-params ::= SEQUENCE {
|
||||
* keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
|
||||
* encryptionScheme AlgorithmIdentifier {{PBES2-Encs}}
|
||||
* }
|
||||
*/
|
||||
if( ( ret = asn1_get_tag( &p, end, &len,
|
||||
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
|
||||
{
|
||||
return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
|
||||
}
|
||||
|
||||
if( ( ret = asn1_get_tag( &p, end, &len,
|
||||
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
|
||||
{
|
||||
return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
|
||||
}
|
||||
|
||||
end2 = p + len;
|
||||
|
||||
if( ( ret = asn1_get_tag( &p, end2, &kdf_alg_oid.len, ASN1_OID ) ) != 0 )
|
||||
return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
|
||||
|
||||
kdf_alg_oid.p = p;
|
||||
p += kdf_alg_oid.len;
|
||||
|
||||
// Only PBKDF2 supported at the moment
|
||||
//
|
||||
if( !OID_CMP( OID_PKCS5_PBKDF2, &kdf_alg_oid ) )
|
||||
return( POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE );
|
||||
|
||||
if( ( ret = pkcs5_parse_pbkdf2_params( &p, end2,
|
||||
&salt, &iterations, &keylen,
|
||||
&md_type ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
md_info = md_info_from_type( md_type );
|
||||
if( md_info == NULL )
|
||||
return( POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE );
|
||||
|
||||
if( ( ret = asn1_get_tag( &p, end, &len,
|
||||
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
|
||||
{
|
||||
return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
|
||||
}
|
||||
|
||||
end2 = p + len;
|
||||
|
||||
if( ( ret = asn1_get_tag( &p, end2, &enc_scheme_oid.len, ASN1_OID ) ) != 0 )
|
||||
return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
|
||||
|
||||
enc_scheme_oid.p = p;
|
||||
p += enc_scheme_oid.len;
|
||||
|
||||
#if defined(POLARSSL_DES_C)
|
||||
// Only DES-CBC and DES-EDE3-CBC supported at the moment
|
||||
//
|
||||
if( OID_CMP( OID_DES_EDE3_CBC, &enc_scheme_oid ) )
|
||||
{
|
||||
cipher_info = cipher_info_from_type( POLARSSL_CIPHER_DES_EDE3_CBC );
|
||||
}
|
||||
else if( OID_CMP( OID_DES_CBC, &enc_scheme_oid ) )
|
||||
{
|
||||
cipher_info = cipher_info_from_type( POLARSSL_CIPHER_DES_CBC );
|
||||
}
|
||||
else
|
||||
#endif /* POLARSSL_DES_C */
|
||||
return( POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE );
|
||||
|
||||
if( cipher_info == NULL )
|
||||
return( POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE );
|
||||
|
||||
keylen = cipher_info->key_length / 8;
|
||||
|
||||
if( ( ret = asn1_get_tag( &p, end2, &len, ASN1_OCTET_STRING ) ) != 0 )
|
||||
return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
|
||||
|
||||
if( len != cipher_info->iv_size )
|
||||
return( POLARSSL_ERR_PKCS5_INVALID_FORMAT );
|
||||
|
||||
memcpy( iv, p, len );
|
||||
|
||||
if( ( ret = md_init_ctx( &md_ctx, md_info ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = cipher_init_ctx( &cipher_ctx, cipher_info ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if ( ( ret = pkcs5_pbkdf2_hmac( &md_ctx, pwd, pwdlen, salt.p, salt.len,
|
||||
iterations, keylen, key ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( ( ret = cipher_setkey( &cipher_ctx, key, keylen, mode ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = cipher_reset( &cipher_ctx, iv ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = cipher_update( &cipher_ctx, data, datalen,
|
||||
output, &olen ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( ( ret = cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 )
|
||||
return( POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int pkcs5_pbkdf2_hmac( md_context_t *ctx, const unsigned char *password,
|
||||
size_t plen, const unsigned char *salt, size_t slen,
|
||||
unsigned int iteration_count,
|
||||
uint32_t key_length, unsigned char *output )
|
||||
{
|
||||
int ret, j;
|
||||
unsigned int i;
|
||||
unsigned char md1[POLARSSL_MD_MAX_SIZE];
|
||||
unsigned char work[POLARSSL_MD_MAX_SIZE];
|
||||
unsigned char md_size = md_get_size( ctx->md_info );
|
||||
size_t use_len;
|
||||
unsigned char *out_p = output;
|
||||
unsigned char counter[4];
|
||||
|
||||
memset( counter, 0, 4 );
|
||||
counter[3] = 1;
|
||||
|
||||
if( iteration_count > 0xFFFFFFFF )
|
||||
return( POLARSSL_ERR_PKCS5_BAD_INPUT_DATA );
|
||||
|
||||
while( key_length )
|
||||
{
|
||||
// U1 ends up in work
|
||||
//
|
||||
if( ( ret = md_hmac_starts( ctx, password, plen ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = md_hmac_update( ctx, salt, slen ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = md_hmac_update( ctx, counter, 4 ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = md_hmac_finish( ctx, work ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
memcpy( md1, work, md_size );
|
||||
|
||||
for ( i = 1; i < iteration_count; i++ )
|
||||
{
|
||||
// U2 ends up in md1
|
||||
//
|
||||
if( ( ret = md_hmac_starts( ctx, password, plen ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = md_hmac_update( ctx, md1, md_size ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = md_hmac_finish( ctx, md1 ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
// U1 xor U2
|
||||
//
|
||||
for( j = 0; j < md_size; j++ )
|
||||
work[j] ^= md1[j];
|
||||
}
|
||||
|
||||
use_len = ( key_length < md_size ) ? key_length : md_size;
|
||||
memcpy( out_p, work, use_len );
|
||||
|
||||
key_length -= use_len;
|
||||
out_p += use_len;
|
||||
|
||||
for( i = 4; i > 0; i-- )
|
||||
if( ++counter[i - 1] != 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_SELF_TEST)
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define MAX_TESTS 6
|
||||
|
||||
size_t plen[MAX_TESTS] =
|
||||
{ 8, 8, 8, 8, 24, 9 };
|
||||
|
||||
unsigned char password[MAX_TESTS][32] =
|
||||
{
|
||||
"password",
|
||||
"password",
|
||||
"password",
|
||||
"password",
|
||||
"passwordPASSWORDpassword",
|
||||
"pass\0word",
|
||||
};
|
||||
|
||||
size_t slen[MAX_TESTS] =
|
||||
{ 4, 4, 4, 4, 36, 5 };
|
||||
|
||||
unsigned char salt[MAX_TESTS][40] =
|
||||
{
|
||||
"salt",
|
||||
"salt",
|
||||
"salt",
|
||||
"salt",
|
||||
"saltSALTsaltSALTsaltSALTsaltSALTsalt",
|
||||
"sa\0lt",
|
||||
};
|
||||
|
||||
uint32_t it_cnt[MAX_TESTS] =
|
||||
{ 1, 2, 4096, 16777216, 4096, 4096 };
|
||||
|
||||
uint32_t key_len[MAX_TESTS] =
|
||||
{ 20, 20, 20, 20, 25, 16 };
|
||||
|
||||
|
||||
unsigned char result_key[MAX_TESTS][32] =
|
||||
{
|
||||
{ 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71,
|
||||
0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06,
|
||||
0x2f, 0xe0, 0x37, 0xa6 },
|
||||
{ 0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c,
|
||||
0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0,
|
||||
0xd8, 0xde, 0x89, 0x57 },
|
||||
{ 0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a,
|
||||
0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0,
|
||||
0x65, 0xa4, 0x29, 0xc1 },
|
||||
{ 0xee, 0xfe, 0x3d, 0x61, 0xcd, 0x4d, 0xa4, 0xe4,
|
||||
0xe9, 0x94, 0x5b, 0x3d, 0x6b, 0xa2, 0x15, 0x8c,
|
||||
0x26, 0x34, 0xe9, 0x84 },
|
||||
{ 0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b,
|
||||
0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a,
|
||||
0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70,
|
||||
0x38 },
|
||||
{ 0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d,
|
||||
0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3 },
|
||||
};
|
||||
|
||||
int pkcs5_self_test( int verbose )
|
||||
{
|
||||
md_context_t sha1_ctx;
|
||||
const md_info_t *info_sha1;
|
||||
int ret, i;
|
||||
unsigned char key[64];
|
||||
|
||||
info_sha1 = md_info_from_type( POLARSSL_MD_SHA1 );
|
||||
if( info_sha1 == NULL )
|
||||
return( 1 );
|
||||
|
||||
if( ( ret = md_init_ctx( &sha1_ctx, info_sha1 ) ) != 0 )
|
||||
return( 1 );
|
||||
|
||||
for( i = 0; i < MAX_TESTS; i++ )
|
||||
{
|
||||
printf( " PBKDF2 (SHA1) #%d: ", i );
|
||||
|
||||
ret = pkcs5_pbkdf2_hmac( &sha1_ctx, password[i], plen[i], salt[i],
|
||||
slen[i], it_cnt[i], key_len[i], key );
|
||||
if( ret != 0 ||
|
||||
memcmp( result_key[i], key, key_len[i] ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "passed\n" );
|
||||
}
|
||||
|
||||
printf( "\n" );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif /* POLARSSL_SELF_TEST */
|
||||
|
||||
#endif /* POLARSSL_PKCS5_C */
|
||||
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
* \file pkcs#5.h
|
||||
*
|
||||
* \brief PKCS#5 functions
|
||||
*
|
||||
* \author Mathias Olsson <mathias@kompetensum.com>
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef POLARSSL_PKCS5_H
|
||||
#define POLARSSL_PKCS5_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "polarssl/asn1.h"
|
||||
#include "polarssl/md.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <basetsd.h>
|
||||
typedef UINT32 uint32_t;
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#define POLARSSL_ERR_PKCS5_BAD_INPUT_DATA -0x3f80 /**< Bad input parameters to function. */
|
||||
#define POLARSSL_ERR_PKCS5_INVALID_FORMAT -0x3f00 /**< Unexpected ASN.1 data. */
|
||||
#define POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE -0x3e80 /**< Requested encryption or digest alg not available. */
|
||||
#define POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH -0x3e00 /**< Given private key password does not allow for correct decryption. */
|
||||
|
||||
#define PKCS5_DECRYPT 0
|
||||
#define PKCS5_ENCRYPT 1
|
||||
|
||||
/*
|
||||
* PKCS#5 OIDs
|
||||
*/
|
||||
#define OID_PKCS5 "\x2a\x86\x48\x86\xf7\x0d\x01\x05"
|
||||
#define OID_PKCS5_PBES2 OID_PKCS5 "\x0d"
|
||||
#define OID_PKCS5_PBKDF2 OID_PKCS5 "\x0c"
|
||||
|
||||
/*
|
||||
* Encryption Algorithm OIDs
|
||||
*/
|
||||
#define OID_DES_CBC "\x2b\x0e\x03\x02\x07"
|
||||
#define OID_DES_EDE3_CBC "\x2a\x86\x48\x86\xf7\x0d\x03\x07"
|
||||
|
||||
/*
|
||||
* Digest Algorithm OIDs
|
||||
*/
|
||||
#define OID_HMAC_SHA1 "\x2a\x86\x48\x86\xf7\x0d\x02\x07"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief PKCS#5 PBES2 function
|
||||
*
|
||||
* \param pbe_params the ASN.1 algorithm parameters
|
||||
* \param mode either PKCS5_DECRYPT or PKCS5_ENCRYPT
|
||||
* \param pwd password to use when generating key
|
||||
* \param plen length of password
|
||||
* \param data data to process
|
||||
* \param datalen length of data
|
||||
* \param output output buffer
|
||||
*
|
||||
* \returns 0 on success, or a PolarSSL error code if verification fails.
|
||||
*/
|
||||
int pkcs5_pbes2( asn1_buf *pbe_params, int mode,
|
||||
const unsigned char *pwd, size_t pwdlen,
|
||||
const unsigned char *data, size_t datalen,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief PKCS#5 PBKDF2 using HMAC
|
||||
*
|
||||
* \param ctx Generic HMAC context
|
||||
* \param password Password to use when generating key
|
||||
* \param plen Length of password
|
||||
* \param salt Salt to use when generating key
|
||||
* \param slen Length of salt
|
||||
* \param iteration_count Iteration count
|
||||
* \param key_length Length of generated key
|
||||
* \param output Generated key. Must be at least as big as key_length
|
||||
*
|
||||
* \returns 0 on success, or a PolarSSL error code if verification fails.
|
||||
*/
|
||||
int pkcs5_pbkdf2_hmac( md_context_t *ctx, const unsigned char *password,
|
||||
size_t plen, const unsigned char *salt, size_t slen,
|
||||
unsigned int iteration_count,
|
||||
uint32_t key_length, unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int pkcs5_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* pkcs5.h */
|
||||
+1466
File diff suppressed because it is too large
Load Diff
+597
@@ -0,0 +1,597 @@
|
||||
/**
|
||||
* \file rsa.h
|
||||
*
|
||||
* \brief The RSA public-key cryptosystem
|
||||
*
|
||||
* Copyright (C) 2006-2010, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef POLARSSL_RSA_H
|
||||
#define POLARSSL_RSA_H
|
||||
|
||||
#include "polarssl/bignum.h"
|
||||
|
||||
/*
|
||||
* RSA Error codes
|
||||
*/
|
||||
#define POLARSSL_ERR_RSA_BAD_INPUT_DATA -0x4080 /**< Bad input parameters to function. */
|
||||
#define POLARSSL_ERR_RSA_INVALID_PADDING -0x4100 /**< Input data contains invalid padding and is rejected. */
|
||||
#define POLARSSL_ERR_RSA_KEY_GEN_FAILED -0x4180 /**< Something failed during generation of a key. */
|
||||
#define POLARSSL_ERR_RSA_KEY_CHECK_FAILED -0x4200 /**< Key failed to pass the libraries validity check. */
|
||||
#define POLARSSL_ERR_RSA_PUBLIC_FAILED -0x4280 /**< The public key operation failed. */
|
||||
#define POLARSSL_ERR_RSA_PRIVATE_FAILED -0x4300 /**< The private key operation failed. */
|
||||
#define POLARSSL_ERR_RSA_VERIFY_FAILED -0x4380 /**< The PKCS#1 verification failed. */
|
||||
#define POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE -0x4400 /**< The output buffer for decryption is not large enough. */
|
||||
#define POLARSSL_ERR_RSA_RNG_FAILED -0x4480 /**< The random generator failed to generate non-zeros. */
|
||||
|
||||
/*
|
||||
* PKCS#1 constants
|
||||
*/
|
||||
#define SIG_RSA_RAW 0
|
||||
#define SIG_RSA_MD2 2
|
||||
#define SIG_RSA_MD4 3
|
||||
#define SIG_RSA_MD5 4
|
||||
#define SIG_RSA_SHA1 5
|
||||
#define SIG_RSA_SHA224 14
|
||||
#define SIG_RSA_SHA256 11
|
||||
#define SIG_RSA_SHA384 12
|
||||
#define SIG_RSA_SHA512 13
|
||||
|
||||
#define RSA_PUBLIC 0
|
||||
#define RSA_PRIVATE 1
|
||||
|
||||
#define RSA_PKCS_V15 0
|
||||
#define RSA_PKCS_V21 1
|
||||
|
||||
#define RSA_SIGN 1
|
||||
#define RSA_CRYPT 2
|
||||
|
||||
#define ASN1_STR_CONSTRUCTED_SEQUENCE "\x30"
|
||||
#define ASN1_STR_NULL "\x05"
|
||||
#define ASN1_STR_OID "\x06"
|
||||
#define ASN1_STR_OCTET_STRING "\x04"
|
||||
|
||||
#define OID_DIGEST_ALG_MDX "\x2A\x86\x48\x86\xF7\x0D\x02\x00"
|
||||
#define OID_HASH_ALG_SHA1 "\x2b\x0e\x03\x02\x1a"
|
||||
#define OID_HASH_ALG_SHA2X "\x60\x86\x48\x01\x65\x03\x04\x02\x00"
|
||||
|
||||
#define OID_ISO_MEMBER_BODIES "\x2a"
|
||||
#define OID_ISO_IDENTIFIED_ORG "\x2b"
|
||||
|
||||
/*
|
||||
* ISO Member bodies OID parts
|
||||
*/
|
||||
#define OID_COUNTRY_US "\x86\x48"
|
||||
#define OID_RSA_DATA_SECURITY "\x86\xf7\x0d"
|
||||
|
||||
/*
|
||||
* ISO Identified organization OID parts
|
||||
*/
|
||||
#define OID_OIW_SECSIG_SHA1 "\x0e\x03\x02\x1a"
|
||||
|
||||
/*
|
||||
* DigestInfo ::= SEQUENCE {
|
||||
* digestAlgorithm DigestAlgorithmIdentifier,
|
||||
* digest Digest }
|
||||
*
|
||||
* DigestAlgorithmIdentifier ::= AlgorithmIdentifier
|
||||
*
|
||||
* Digest ::= OCTET STRING
|
||||
*/
|
||||
#define ASN1_HASH_MDX \
|
||||
( \
|
||||
ASN1_STR_CONSTRUCTED_SEQUENCE "\x20" \
|
||||
ASN1_STR_CONSTRUCTED_SEQUENCE "\x0C" \
|
||||
ASN1_STR_OID "\x08" \
|
||||
OID_DIGEST_ALG_MDX \
|
||||
ASN1_STR_NULL "\x00" \
|
||||
ASN1_STR_OCTET_STRING "\x10" \
|
||||
)
|
||||
|
||||
#define ASN1_HASH_SHA1 \
|
||||
ASN1_STR_CONSTRUCTED_SEQUENCE "\x21" \
|
||||
ASN1_STR_CONSTRUCTED_SEQUENCE "\x09" \
|
||||
ASN1_STR_OID "\x05" \
|
||||
OID_HASH_ALG_SHA1 \
|
||||
ASN1_STR_NULL "\x00" \
|
||||
ASN1_STR_OCTET_STRING "\x14"
|
||||
|
||||
#define ASN1_HASH_SHA1_ALT \
|
||||
ASN1_STR_CONSTRUCTED_SEQUENCE "\x1F" \
|
||||
ASN1_STR_CONSTRUCTED_SEQUENCE "\x07" \
|
||||
ASN1_STR_OID "\x05" \
|
||||
OID_HASH_ALG_SHA1 \
|
||||
ASN1_STR_OCTET_STRING "\x14"
|
||||
|
||||
#define ASN1_HASH_SHA2X \
|
||||
ASN1_STR_CONSTRUCTED_SEQUENCE "\x11" \
|
||||
ASN1_STR_CONSTRUCTED_SEQUENCE "\x0d" \
|
||||
ASN1_STR_OID "\x09" \
|
||||
OID_HASH_ALG_SHA2X \
|
||||
ASN1_STR_NULL "\x00" \
|
||||
ASN1_STR_OCTET_STRING "\x00"
|
||||
|
||||
/**
|
||||
* \brief RSA context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int ver; /*!< always 0 */
|
||||
size_t len; /*!< size(N) in chars */
|
||||
|
||||
mpi N; /*!< public modulus */
|
||||
mpi E; /*!< public exponent */
|
||||
|
||||
mpi D; /*!< private exponent */
|
||||
mpi P; /*!< 1st prime factor */
|
||||
mpi Q; /*!< 2nd prime factor */
|
||||
mpi DP; /*!< D % (P - 1) */
|
||||
mpi DQ; /*!< D % (Q - 1) */
|
||||
mpi QP; /*!< 1 / (Q % P) */
|
||||
|
||||
mpi RN; /*!< cached R^2 mod N */
|
||||
mpi RP; /*!< cached R^2 mod P */
|
||||
mpi RQ; /*!< cached R^2 mod Q */
|
||||
|
||||
int padding; /*!< RSA_PKCS_V15 for 1.5 padding and
|
||||
RSA_PKCS_v21 for OAEP/PSS */
|
||||
int hash_id; /*!< Hash identifier of md_type_t as
|
||||
specified in the md.h header file
|
||||
for the EME-OAEP and EMSA-PSS
|
||||
encoding */
|
||||
}
|
||||
rsa_context;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Initialize an RSA context
|
||||
*
|
||||
* Note: Set padding to RSA_PKCS_V21 for the RSAES-OAEP
|
||||
* encryption scheme and the RSASSA-PSS signature scheme.
|
||||
*
|
||||
* \param ctx RSA context to be initialized
|
||||
* \param padding RSA_PKCS_V15 or RSA_PKCS_V21
|
||||
* \param hash_id RSA_PKCS_V21 hash identifier
|
||||
*
|
||||
* \note The hash_id parameter is actually ignored
|
||||
* when using RSA_PKCS_V15 padding.
|
||||
*/
|
||||
void rsa_init( rsa_context *ctx,
|
||||
int padding,
|
||||
int hash_id);
|
||||
|
||||
/**
|
||||
* \brief Generate an RSA keypair
|
||||
*
|
||||
* \param ctx RSA context that will hold the key
|
||||
* \param f_rng RNG function
|
||||
* \param p_rng RNG parameter
|
||||
* \param nbits size of the public key in bits
|
||||
* \param exponent public exponent (e.g., 65537)
|
||||
*
|
||||
* \note rsa_init() must be called beforehand to setup
|
||||
* the RSA context.
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||
*/
|
||||
int rsa_gen_key( rsa_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
unsigned int nbits, int exponent );
|
||||
|
||||
/**
|
||||
* \brief Check a public RSA key
|
||||
*
|
||||
* \param ctx RSA context to be checked
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||
*/
|
||||
int rsa_check_pubkey( const rsa_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Check a private RSA key
|
||||
*
|
||||
* \param ctx RSA context to be checked
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||
*/
|
||||
int rsa_check_privkey( const rsa_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Do an RSA public key operation
|
||||
*
|
||||
* \param ctx RSA context
|
||||
* \param input input buffer
|
||||
* \param output output buffer
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note This function does NOT take care of message
|
||||
* padding. Also, be sure to set input[0] = 0 or assure that
|
||||
* input is smaller than N.
|
||||
*
|
||||
* \note The input and output buffers must be large
|
||||
* enough (eg. 128 bytes if RSA-1024 is used).
|
||||
*/
|
||||
int rsa_public( rsa_context *ctx,
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief Do an RSA private key operation
|
||||
*
|
||||
* \param ctx RSA context
|
||||
* \param input input buffer
|
||||
* \param output output buffer
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note The input and output buffers must be large
|
||||
* enough (eg. 128 bytes if RSA-1024 is used).
|
||||
*/
|
||||
int rsa_private( rsa_context *ctx,
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief Generic wrapper to perform a PKCS#1 encryption using the
|
||||
* mode from the context. Add the message padding, then do an
|
||||
* RSA operation.
|
||||
*
|
||||
* \param ctx RSA context
|
||||
* \param f_rng RNG function (Needed for padding and PKCS#1 v2.1 encoding)
|
||||
* \param p_rng RNG parameter
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
* \param ilen contains the plaintext length
|
||||
* \param input buffer holding the data to be encrypted
|
||||
* \param output buffer that will hold the ciphertext
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note The output buffer must be as large as the size
|
||||
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
|
||||
*/
|
||||
int rsa_pkcs1_encrypt( rsa_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
int mode, size_t ilen,
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief Perform a PKCS#1 v1.5 encryption (RSAES-PKCS1-v1_5-ENCRYPT)
|
||||
*
|
||||
* \param ctx RSA context
|
||||
* \param f_rng RNG function (Needed for padding)
|
||||
* \param p_rng RNG parameter
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
* \param ilen contains the plaintext length
|
||||
* \param input buffer holding the data to be encrypted
|
||||
* \param output buffer that will hold the ciphertext
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note The output buffer must be as large as the size
|
||||
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
|
||||
*/
|
||||
int rsa_rsaes_pkcs1_v15_encrypt( rsa_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
int mode, size_t ilen,
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief Perform a PKCS#1 v2.1 OAEP encryption (RSAES-OAEP-ENCRYPT)
|
||||
*
|
||||
* \param ctx RSA context
|
||||
* \param f_rng RNG function (Needed for padding and PKCS#1 v2.1 encoding)
|
||||
* \param p_rng RNG parameter
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
* \param label buffer holding the custom label to use
|
||||
* \param label_len contains the label length
|
||||
* \param ilen contains the plaintext length
|
||||
* \param input buffer holding the data to be encrypted
|
||||
* \param output buffer that will hold the ciphertext
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note The output buffer must be as large as the size
|
||||
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
|
||||
*/
|
||||
int rsa_rsaes_oaep_encrypt( rsa_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
int mode,
|
||||
const unsigned char *label, size_t label_len,
|
||||
size_t ilen,
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief Generic wrapper to perform a PKCS#1 decryption using the
|
||||
* mode from the context. Do an RSA operation, then remove
|
||||
* the message padding
|
||||
*
|
||||
* \param ctx RSA context
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
* \param olen will contain the plaintext length
|
||||
* \param input buffer holding the encrypted data
|
||||
* \param output buffer that will hold the plaintext
|
||||
* \param output_max_len maximum length of the output buffer
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note The output buffer must be as large as the size
|
||||
* of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
|
||||
* an error is thrown.
|
||||
*/
|
||||
int rsa_pkcs1_decrypt( rsa_context *ctx,
|
||||
int mode, size_t *olen,
|
||||
const unsigned char *input,
|
||||
unsigned char *output,
|
||||
size_t output_max_len );
|
||||
|
||||
/**
|
||||
* \brief Perform a PKCS#1 v1.5 decryption (RSAES-PKCS1-v1_5-DECRYPT)
|
||||
*
|
||||
* \param ctx RSA context
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
* \param olen will contain the plaintext length
|
||||
* \param input buffer holding the encrypted data
|
||||
* \param output buffer that will hold the plaintext
|
||||
* \param output_max_len maximum length of the output buffer
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note The output buffer must be as large as the size
|
||||
* of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
|
||||
* an error is thrown.
|
||||
*/
|
||||
int rsa_rsaes_pkcs1_v15_decrypt( rsa_context *ctx,
|
||||
int mode, size_t *olen,
|
||||
const unsigned char *input,
|
||||
unsigned char *output,
|
||||
size_t output_max_len );
|
||||
|
||||
/**
|
||||
* \brief Perform a PKCS#1 v2.1 OAEP decryption (RSAES-OAEP-DECRYPT)
|
||||
*
|
||||
* \param ctx RSA context
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
* \param label buffer holding the custom label to use
|
||||
* \param label_len contains the label length
|
||||
* \param olen will contain the plaintext length
|
||||
* \param input buffer holding the encrypted data
|
||||
* \param output buffer that will hold the plaintext
|
||||
* \param output_max_len maximum length of the output buffer
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note The output buffer must be as large as the size
|
||||
* of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
|
||||
* an error is thrown.
|
||||
*/
|
||||
int rsa_rsaes_oaep_decrypt( rsa_context *ctx,
|
||||
int mode,
|
||||
const unsigned char *label, size_t label_len,
|
||||
size_t *olen,
|
||||
const unsigned char *input,
|
||||
unsigned char *output,
|
||||
size_t output_max_len );
|
||||
|
||||
/**
|
||||
* \brief Generic wrapper to perform a PKCS#1 signature using the
|
||||
* mode from the context. Do a private RSA operation to sign
|
||||
* a message digest
|
||||
*
|
||||
* \param ctx RSA context
|
||||
* \param f_rng RNG function (Needed for PKCS#1 v2.1 encoding)
|
||||
* \param p_rng RNG parameter
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
* \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
|
||||
* \param hashlen message digest length (for SIG_RSA_RAW only)
|
||||
* \param hash buffer holding the message digest
|
||||
* \param sig buffer that will hold the ciphertext
|
||||
*
|
||||
* \return 0 if the signing operation was successful,
|
||||
* or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note The "sig" buffer must be as large as the size
|
||||
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
|
||||
*
|
||||
* \note In case of PKCS#1 v2.1 encoding keep in mind that
|
||||
* the hash_id in the RSA context is the one used for the
|
||||
* encoding. hash_id in the function call is the type of hash
|
||||
* that is encoded. According to RFC 3447 it is advised to
|
||||
* keep both hashes the same.
|
||||
*/
|
||||
int rsa_pkcs1_sign( rsa_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
int mode,
|
||||
int hash_id,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
unsigned char *sig );
|
||||
|
||||
/**
|
||||
* \brief Perform a PKCS#1 v1.5 signature (RSASSA-PKCS1-v1_5-SIGN)
|
||||
*
|
||||
* \param ctx RSA context
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
* \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
|
||||
* \param hashlen message digest length (for SIG_RSA_RAW only)
|
||||
* \param hash buffer holding the message digest
|
||||
* \param sig buffer that will hold the ciphertext
|
||||
*
|
||||
* \return 0 if the signing operation was successful,
|
||||
* or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note The "sig" buffer must be as large as the size
|
||||
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
|
||||
*/
|
||||
int rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx,
|
||||
int mode,
|
||||
int hash_id,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
unsigned char *sig );
|
||||
|
||||
/**
|
||||
* \brief Perform a PKCS#1 v2.1 PSS signature (RSASSA-PSS-SIGN)
|
||||
*
|
||||
* \param ctx RSA context
|
||||
* \param f_rng RNG function (Needed for PKCS#1 v2.1 encoding)
|
||||
* \param p_rng RNG parameter
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
* \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
|
||||
* \param hashlen message digest length (for SIG_RSA_RAW only)
|
||||
* \param hash buffer holding the message digest
|
||||
* \param sig buffer that will hold the ciphertext
|
||||
*
|
||||
* \return 0 if the signing operation was successful,
|
||||
* or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note The "sig" buffer must be as large as the size
|
||||
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
|
||||
*
|
||||
* \note In case of PKCS#1 v2.1 encoding keep in mind that
|
||||
* the hash_id in the RSA context is the one used for the
|
||||
* encoding. hash_id in the function call is the type of hash
|
||||
* that is encoded. According to RFC 3447 it is advised to
|
||||
* keep both hashes the same.
|
||||
*/
|
||||
int rsa_rsassa_pss_sign( rsa_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
int mode,
|
||||
int hash_id,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
unsigned char *sig );
|
||||
|
||||
/**
|
||||
* \brief Generic wrapper to perform a PKCS#1 verification using the
|
||||
* mode from the context. Do a public RSA operation and check
|
||||
* the message digest
|
||||
*
|
||||
* \param ctx points to an RSA public key
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
* \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
|
||||
* \param hashlen message digest length (for SIG_RSA_RAW only)
|
||||
* \param hash buffer holding the message digest
|
||||
* \param sig buffer holding the ciphertext
|
||||
*
|
||||
* \return 0 if the verify operation was successful,
|
||||
* or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note The "sig" buffer must be as large as the size
|
||||
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
|
||||
*
|
||||
* \note In case of PKCS#1 v2.1 encoding keep in mind that
|
||||
* the hash_id in the RSA context is the one used for the
|
||||
* verification. hash_id in the function call is the type of hash
|
||||
* that is verified. According to RFC 3447 it is advised to
|
||||
* keep both hashes the same.
|
||||
*/
|
||||
int rsa_pkcs1_verify( rsa_context *ctx,
|
||||
int mode,
|
||||
int hash_id,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
unsigned char *sig );
|
||||
|
||||
/**
|
||||
* \brief Perform a PKCS#1 v1.5 verification (RSASSA-PKCS1-v1_5-VERIFY)
|
||||
*
|
||||
* \param ctx points to an RSA public key
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
* \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
|
||||
* \param hashlen message digest length (for SIG_RSA_RAW only)
|
||||
* \param hash buffer holding the message digest
|
||||
* \param sig buffer holding the ciphertext
|
||||
*
|
||||
* \return 0 if the verify operation was successful,
|
||||
* or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note The "sig" buffer must be as large as the size
|
||||
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
|
||||
*/
|
||||
int rsa_rsassa_pkcs1_v15_verify( rsa_context *ctx,
|
||||
int mode,
|
||||
int hash_id,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
unsigned char *sig );
|
||||
|
||||
/**
|
||||
* \brief Perform a PKCS#1 v2.1 PSS verification (RSASSA-PSS-VERIFY)
|
||||
* \brief Do a public RSA and check the message digest
|
||||
*
|
||||
* \param ctx points to an RSA public key
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
* \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
|
||||
* \param hashlen message digest length (for SIG_RSA_RAW only)
|
||||
* \param hash buffer holding the message digest
|
||||
* \param sig buffer holding the ciphertext
|
||||
*
|
||||
* \return 0 if the verify operation was successful,
|
||||
* or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note The "sig" buffer must be as large as the size
|
||||
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
|
||||
*
|
||||
* \note In case of PKCS#1 v2.1 encoding keep in mind that
|
||||
* the hash_id in the RSA context is the one used for the
|
||||
* verification. hash_id in the function call is the type of hash
|
||||
* that is verified. According to RFC 3447 it is advised to
|
||||
* keep both hashes the same.
|
||||
*/
|
||||
int rsa_rsassa_pss_verify( rsa_context *ctx,
|
||||
int mode,
|
||||
int hash_id,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
unsigned char *sig );
|
||||
|
||||
/**
|
||||
* \brief Free the components of an RSA key
|
||||
*
|
||||
* \param ctx RSA Context to free
|
||||
*/
|
||||
void rsa_free( rsa_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int rsa_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* rsa.h */
|
||||
+624
@@ -0,0 +1,624 @@
|
||||
/*
|
||||
* FIPS-180-1 compliant SHA-1 implementation
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
* The SHA-1 standard was published by NIST in 1993.
|
||||
*
|
||||
* http://www.itl.nist.gov/fipspubs/fip180-1.htm
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_SHA1_C)
|
||||
|
||||
#include "polarssl/sha1.h"
|
||||
|
||||
#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if !defined(POLARSSL_SHA1_ALT)
|
||||
|
||||
/*
|
||||
* 32-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
#ifndef GET_UINT32_BE
|
||||
#define GET_UINT32_BE(n,b,i) \
|
||||
{ \
|
||||
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
|
||||
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
|
||||
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
|
||||
| ( (uint32_t) (b)[(i) + 3] ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PUT_UINT32_BE
|
||||
#define PUT_UINT32_BE(n,b,i) \
|
||||
{ \
|
||||
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SHA-1 context setup
|
||||
*/
|
||||
void sha1_starts( sha1_context *ctx )
|
||||
{
|
||||
ctx->total[0] = 0;
|
||||
ctx->total[1] = 0;
|
||||
|
||||
ctx->state[0] = 0x67452301;
|
||||
ctx->state[1] = 0xEFCDAB89;
|
||||
ctx->state[2] = 0x98BADCFE;
|
||||
ctx->state[3] = 0x10325476;
|
||||
ctx->state[4] = 0xC3D2E1F0;
|
||||
}
|
||||
|
||||
void sha1_process( sha1_context *ctx, const unsigned char data[64] )
|
||||
{
|
||||
uint32_t temp, W[16], A, B, C, D, E;
|
||||
|
||||
GET_UINT32_BE( W[ 0], data, 0 );
|
||||
GET_UINT32_BE( W[ 1], data, 4 );
|
||||
GET_UINT32_BE( W[ 2], data, 8 );
|
||||
GET_UINT32_BE( W[ 3], data, 12 );
|
||||
GET_UINT32_BE( W[ 4], data, 16 );
|
||||
GET_UINT32_BE( W[ 5], data, 20 );
|
||||
GET_UINT32_BE( W[ 6], data, 24 );
|
||||
GET_UINT32_BE( W[ 7], data, 28 );
|
||||
GET_UINT32_BE( W[ 8], data, 32 );
|
||||
GET_UINT32_BE( W[ 9], data, 36 );
|
||||
GET_UINT32_BE( W[10], data, 40 );
|
||||
GET_UINT32_BE( W[11], data, 44 );
|
||||
GET_UINT32_BE( W[12], data, 48 );
|
||||
GET_UINT32_BE( W[13], data, 52 );
|
||||
GET_UINT32_BE( W[14], data, 56 );
|
||||
GET_UINT32_BE( W[15], data, 60 );
|
||||
|
||||
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
|
||||
|
||||
#define R(t) \
|
||||
( \
|
||||
temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
|
||||
W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \
|
||||
( W[t & 0x0F] = S(temp,1) ) \
|
||||
)
|
||||
|
||||
#define P(a,b,c,d,e,x) \
|
||||
{ \
|
||||
e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
|
||||
}
|
||||
|
||||
A = ctx->state[0];
|
||||
B = ctx->state[1];
|
||||
C = ctx->state[2];
|
||||
D = ctx->state[3];
|
||||
E = ctx->state[4];
|
||||
|
||||
#define F(x,y,z) (z ^ (x & (y ^ z)))
|
||||
#define K 0x5A827999
|
||||
|
||||
P( A, B, C, D, E, W[0] );
|
||||
P( E, A, B, C, D, W[1] );
|
||||
P( D, E, A, B, C, W[2] );
|
||||
P( C, D, E, A, B, W[3] );
|
||||
P( B, C, D, E, A, W[4] );
|
||||
P( A, B, C, D, E, W[5] );
|
||||
P( E, A, B, C, D, W[6] );
|
||||
P( D, E, A, B, C, W[7] );
|
||||
P( C, D, E, A, B, W[8] );
|
||||
P( B, C, D, E, A, W[9] );
|
||||
P( A, B, C, D, E, W[10] );
|
||||
P( E, A, B, C, D, W[11] );
|
||||
P( D, E, A, B, C, W[12] );
|
||||
P( C, D, E, A, B, W[13] );
|
||||
P( B, C, D, E, A, W[14] );
|
||||
P( A, B, C, D, E, W[15] );
|
||||
P( E, A, B, C, D, R(16) );
|
||||
P( D, E, A, B, C, R(17) );
|
||||
P( C, D, E, A, B, R(18) );
|
||||
P( B, C, D, E, A, R(19) );
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) (x ^ y ^ z)
|
||||
#define K 0x6ED9EBA1
|
||||
|
||||
P( A, B, C, D, E, R(20) );
|
||||
P( E, A, B, C, D, R(21) );
|
||||
P( D, E, A, B, C, R(22) );
|
||||
P( C, D, E, A, B, R(23) );
|
||||
P( B, C, D, E, A, R(24) );
|
||||
P( A, B, C, D, E, R(25) );
|
||||
P( E, A, B, C, D, R(26) );
|
||||
P( D, E, A, B, C, R(27) );
|
||||
P( C, D, E, A, B, R(28) );
|
||||
P( B, C, D, E, A, R(29) );
|
||||
P( A, B, C, D, E, R(30) );
|
||||
P( E, A, B, C, D, R(31) );
|
||||
P( D, E, A, B, C, R(32) );
|
||||
P( C, D, E, A, B, R(33) );
|
||||
P( B, C, D, E, A, R(34) );
|
||||
P( A, B, C, D, E, R(35) );
|
||||
P( E, A, B, C, D, R(36) );
|
||||
P( D, E, A, B, C, R(37) );
|
||||
P( C, D, E, A, B, R(38) );
|
||||
P( B, C, D, E, A, R(39) );
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) ((x & y) | (z & (x | y)))
|
||||
#define K 0x8F1BBCDC
|
||||
|
||||
P( A, B, C, D, E, R(40) );
|
||||
P( E, A, B, C, D, R(41) );
|
||||
P( D, E, A, B, C, R(42) );
|
||||
P( C, D, E, A, B, R(43) );
|
||||
P( B, C, D, E, A, R(44) );
|
||||
P( A, B, C, D, E, R(45) );
|
||||
P( E, A, B, C, D, R(46) );
|
||||
P( D, E, A, B, C, R(47) );
|
||||
P( C, D, E, A, B, R(48) );
|
||||
P( B, C, D, E, A, R(49) );
|
||||
P( A, B, C, D, E, R(50) );
|
||||
P( E, A, B, C, D, R(51) );
|
||||
P( D, E, A, B, C, R(52) );
|
||||
P( C, D, E, A, B, R(53) );
|
||||
P( B, C, D, E, A, R(54) );
|
||||
P( A, B, C, D, E, R(55) );
|
||||
P( E, A, B, C, D, R(56) );
|
||||
P( D, E, A, B, C, R(57) );
|
||||
P( C, D, E, A, B, R(58) );
|
||||
P( B, C, D, E, A, R(59) );
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) (x ^ y ^ z)
|
||||
#define K 0xCA62C1D6
|
||||
|
||||
P( A, B, C, D, E, R(60) );
|
||||
P( E, A, B, C, D, R(61) );
|
||||
P( D, E, A, B, C, R(62) );
|
||||
P( C, D, E, A, B, R(63) );
|
||||
P( B, C, D, E, A, R(64) );
|
||||
P( A, B, C, D, E, R(65) );
|
||||
P( E, A, B, C, D, R(66) );
|
||||
P( D, E, A, B, C, R(67) );
|
||||
P( C, D, E, A, B, R(68) );
|
||||
P( B, C, D, E, A, R(69) );
|
||||
P( A, B, C, D, E, R(70) );
|
||||
P( E, A, B, C, D, R(71) );
|
||||
P( D, E, A, B, C, R(72) );
|
||||
P( C, D, E, A, B, R(73) );
|
||||
P( B, C, D, E, A, R(74) );
|
||||
P( A, B, C, D, E, R(75) );
|
||||
P( E, A, B, C, D, R(76) );
|
||||
P( D, E, A, B, C, R(77) );
|
||||
P( C, D, E, A, B, R(78) );
|
||||
P( B, C, D, E, A, R(79) );
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
ctx->state[0] += A;
|
||||
ctx->state[1] += B;
|
||||
ctx->state[2] += C;
|
||||
ctx->state[3] += D;
|
||||
ctx->state[4] += E;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-1 process buffer
|
||||
*/
|
||||
void sha1_update( sha1_context *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
size_t fill;
|
||||
uint32_t left;
|
||||
|
||||
if( ilen <= 0 )
|
||||
return;
|
||||
|
||||
left = ctx->total[0] & 0x3F;
|
||||
fill = 64 - left;
|
||||
|
||||
ctx->total[0] += (uint32_t) ilen;
|
||||
ctx->total[0] &= 0xFFFFFFFF;
|
||||
|
||||
if( ctx->total[0] < (uint32_t) ilen )
|
||||
ctx->total[1]++;
|
||||
|
||||
if( left && ilen >= fill )
|
||||
{
|
||||
memcpy( (void *) (ctx->buffer + left), input, fill );
|
||||
sha1_process( ctx, ctx->buffer );
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while( ilen >= 64 )
|
||||
{
|
||||
sha1_process( ctx, input );
|
||||
input += 64;
|
||||
ilen -= 64;
|
||||
}
|
||||
|
||||
if( ilen > 0 )
|
||||
memcpy( (void *) (ctx->buffer + left), input, ilen );
|
||||
}
|
||||
|
||||
static const unsigned char sha1_padding[64] =
|
||||
{
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* SHA-1 final digest
|
||||
*/
|
||||
void sha1_finish( sha1_context *ctx, unsigned char output[20] )
|
||||
{
|
||||
uint32_t last, padn;
|
||||
uint32_t high, low;
|
||||
unsigned char msglen[8];
|
||||
|
||||
high = ( ctx->total[0] >> 29 )
|
||||
| ( ctx->total[1] << 3 );
|
||||
low = ( ctx->total[0] << 3 );
|
||||
|
||||
PUT_UINT32_BE( high, msglen, 0 );
|
||||
PUT_UINT32_BE( low, msglen, 4 );
|
||||
|
||||
last = ctx->total[0] & 0x3F;
|
||||
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
|
||||
|
||||
sha1_update( ctx, sha1_padding, padn );
|
||||
sha1_update( ctx, msglen, 8 );
|
||||
|
||||
PUT_UINT32_BE( ctx->state[0], output, 0 );
|
||||
PUT_UINT32_BE( ctx->state[1], output, 4 );
|
||||
PUT_UINT32_BE( ctx->state[2], output, 8 );
|
||||
PUT_UINT32_BE( ctx->state[3], output, 12 );
|
||||
PUT_UINT32_BE( ctx->state[4], output, 16 );
|
||||
}
|
||||
|
||||
#endif /* !POLARSSL_SHA1_ALT */
|
||||
|
||||
/*
|
||||
* output = SHA-1( input buffer )
|
||||
*/
|
||||
void sha1( const unsigned char *input, size_t ilen, unsigned char output[20] )
|
||||
{
|
||||
sha1_context ctx;
|
||||
|
||||
sha1_starts( &ctx );
|
||||
sha1_update( &ctx, input, ilen );
|
||||
sha1_finish( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( sha1_context ) );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
/*
|
||||
* output = SHA-1( file contents )
|
||||
*/
|
||||
int sha1_file( const char *path, unsigned char output[20] )
|
||||
{
|
||||
FILE *f;
|
||||
size_t n;
|
||||
sha1_context ctx;
|
||||
unsigned char buf[1024];
|
||||
|
||||
if( ( f = fopen( path, "rb" ) ) == NULL )
|
||||
return( POLARSSL_ERR_SHA1_FILE_IO_ERROR );
|
||||
|
||||
sha1_starts( &ctx );
|
||||
|
||||
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
|
||||
sha1_update( &ctx, buf, n );
|
||||
|
||||
sha1_finish( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( sha1_context ) );
|
||||
|
||||
if( ferror( f ) != 0 )
|
||||
{
|
||||
fclose( f );
|
||||
return( POLARSSL_ERR_SHA1_FILE_IO_ERROR );
|
||||
}
|
||||
|
||||
fclose( f );
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* POLARSSL_FS_IO */
|
||||
|
||||
/*
|
||||
* SHA-1 HMAC context setup
|
||||
*/
|
||||
void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key, size_t keylen )
|
||||
{
|
||||
size_t i;
|
||||
unsigned char sum[20];
|
||||
|
||||
if( keylen > 64 )
|
||||
{
|
||||
sha1( key, keylen, sum );
|
||||
keylen = 20;
|
||||
key = sum;
|
||||
}
|
||||
|
||||
memset( ctx->ipad, 0x36, 64 );
|
||||
memset( ctx->opad, 0x5C, 64 );
|
||||
|
||||
for( i = 0; i < keylen; i++ )
|
||||
{
|
||||
ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
|
||||
ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
|
||||
}
|
||||
|
||||
sha1_starts( ctx );
|
||||
sha1_update( ctx, ctx->ipad, 64 );
|
||||
|
||||
memset( sum, 0, sizeof( sum ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-1 HMAC process buffer
|
||||
*/
|
||||
void sha1_hmac_update( sha1_context *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
sha1_update( ctx, input, ilen );
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-1 HMAC final digest
|
||||
*/
|
||||
void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] )
|
||||
{
|
||||
unsigned char tmpbuf[20];
|
||||
|
||||
sha1_finish( ctx, tmpbuf );
|
||||
sha1_starts( ctx );
|
||||
sha1_update( ctx, ctx->opad, 64 );
|
||||
sha1_update( ctx, tmpbuf, 20 );
|
||||
sha1_finish( ctx, output );
|
||||
|
||||
memset( tmpbuf, 0, sizeof( tmpbuf ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA1 HMAC context reset
|
||||
*/
|
||||
void sha1_hmac_reset( sha1_context *ctx )
|
||||
{
|
||||
sha1_starts( ctx );
|
||||
sha1_update( ctx, ctx->ipad, 64 );
|
||||
}
|
||||
|
||||
/*
|
||||
* output = HMAC-SHA-1( hmac key, input buffer )
|
||||
*/
|
||||
void sha1_hmac( const unsigned char *key, size_t keylen,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char output[20] )
|
||||
{
|
||||
sha1_context ctx;
|
||||
|
||||
sha1_hmac_starts( &ctx, key, keylen );
|
||||
sha1_hmac_update( &ctx, input, ilen );
|
||||
sha1_hmac_finish( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( sha1_context ) );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_SELF_TEST)
|
||||
/*
|
||||
* FIPS-180-1 test vectors
|
||||
*/
|
||||
static unsigned char sha1_test_buf[3][57] =
|
||||
{
|
||||
{ "abc" },
|
||||
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
|
||||
{ "" }
|
||||
};
|
||||
|
||||
static const int sha1_test_buflen[3] =
|
||||
{
|
||||
3, 56, 1000
|
||||
};
|
||||
|
||||
static const unsigned char sha1_test_sum[3][20] =
|
||||
{
|
||||
{ 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
|
||||
0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D },
|
||||
{ 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
|
||||
0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 },
|
||||
{ 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
|
||||
0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F }
|
||||
};
|
||||
|
||||
/*
|
||||
* RFC 2202 test vectors
|
||||
*/
|
||||
static unsigned char sha1_hmac_test_key[7][26] =
|
||||
{
|
||||
{ "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
|
||||
"\x0B\x0B\x0B\x0B" },
|
||||
{ "Jefe" },
|
||||
{ "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
|
||||
"\xAA\xAA\xAA\xAA" },
|
||||
{ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
|
||||
"\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
|
||||
{ "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
|
||||
"\x0C\x0C\x0C\x0C" },
|
||||
{ "" }, /* 0xAA 80 times */
|
||||
{ "" }
|
||||
};
|
||||
|
||||
static const int sha1_hmac_test_keylen[7] =
|
||||
{
|
||||
20, 4, 20, 25, 20, 80, 80
|
||||
};
|
||||
|
||||
static unsigned char sha1_hmac_test_buf[7][74] =
|
||||
{
|
||||
{ "Hi There" },
|
||||
{ "what do ya want for nothing?" },
|
||||
{ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
|
||||
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
|
||||
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
|
||||
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
|
||||
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
|
||||
{ "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
|
||||
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
|
||||
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
|
||||
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
|
||||
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
|
||||
{ "Test With Truncation" },
|
||||
{ "Test Using Larger Than Block-Size Key - Hash Key First" },
|
||||
{ "Test Using Larger Than Block-Size Key and Larger"
|
||||
" Than One Block-Size Data" }
|
||||
};
|
||||
|
||||
static const int sha1_hmac_test_buflen[7] =
|
||||
{
|
||||
8, 28, 50, 50, 20, 54, 73
|
||||
};
|
||||
|
||||
static const unsigned char sha1_hmac_test_sum[7][20] =
|
||||
{
|
||||
{ 0xB6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xE2, 0x8B,
|
||||
0xC0, 0xB6, 0xFB, 0x37, 0x8C, 0x8E, 0xF1, 0x46, 0xBE, 0x00 },
|
||||
{ 0xEF, 0xFC, 0xDF, 0x6A, 0xE5, 0xEB, 0x2F, 0xA2, 0xD2, 0x74,
|
||||
0x16, 0xD5, 0xF1, 0x84, 0xDF, 0x9C, 0x25, 0x9A, 0x7C, 0x79 },
|
||||
{ 0x12, 0x5D, 0x73, 0x42, 0xB9, 0xAC, 0x11, 0xCD, 0x91, 0xA3,
|
||||
0x9A, 0xF4, 0x8A, 0xA1, 0x7B, 0x4F, 0x63, 0xF1, 0x75, 0xD3 },
|
||||
{ 0x4C, 0x90, 0x07, 0xF4, 0x02, 0x62, 0x50, 0xC6, 0xBC, 0x84,
|
||||
0x14, 0xF9, 0xBF, 0x50, 0xC8, 0x6C, 0x2D, 0x72, 0x35, 0xDA },
|
||||
{ 0x4C, 0x1A, 0x03, 0x42, 0x4B, 0x55, 0xE0, 0x7F, 0xE7, 0xF2,
|
||||
0x7B, 0xE1 },
|
||||
{ 0xAA, 0x4A, 0xE5, 0xE1, 0x52, 0x72, 0xD0, 0x0E, 0x95, 0x70,
|
||||
0x56, 0x37, 0xCE, 0x8A, 0x3B, 0x55, 0xED, 0x40, 0x21, 0x12 },
|
||||
{ 0xE8, 0xE9, 0x9D, 0x0F, 0x45, 0x23, 0x7D, 0x78, 0x6D, 0x6B,
|
||||
0xBA, 0xA7, 0x96, 0x5C, 0x78, 0x08, 0xBB, 0xFF, 0x1A, 0x91 }
|
||||
};
|
||||
|
||||
/*
|
||||
* Checkup routine
|
||||
*/
|
||||
int sha1_self_test( int verbose )
|
||||
{
|
||||
int i, j, buflen;
|
||||
unsigned char buf[1024];
|
||||
unsigned char sha1sum[20];
|
||||
sha1_context ctx;
|
||||
|
||||
/*
|
||||
* SHA-1
|
||||
*/
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( " SHA-1 test #%d: ", i + 1 );
|
||||
|
||||
sha1_starts( &ctx );
|
||||
|
||||
if( i == 2 )
|
||||
{
|
||||
memset( buf, 'a', buflen = 1000 );
|
||||
|
||||
for( j = 0; j < 1000; j++ )
|
||||
sha1_update( &ctx, buf, buflen );
|
||||
}
|
||||
else
|
||||
sha1_update( &ctx, sha1_test_buf[i],
|
||||
sha1_test_buflen[i] );
|
||||
|
||||
sha1_finish( &ctx, sha1sum );
|
||||
|
||||
if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "passed\n" );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "\n" );
|
||||
|
||||
for( i = 0; i < 7; i++ )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( " HMAC-SHA-1 test #%d: ", i + 1 );
|
||||
|
||||
if( i == 5 || i == 6 )
|
||||
{
|
||||
memset( buf, '\xAA', buflen = 80 );
|
||||
sha1_hmac_starts( &ctx, buf, buflen );
|
||||
}
|
||||
else
|
||||
sha1_hmac_starts( &ctx, sha1_hmac_test_key[i],
|
||||
sha1_hmac_test_keylen[i] );
|
||||
|
||||
sha1_hmac_update( &ctx, sha1_hmac_test_buf[i],
|
||||
sha1_hmac_test_buflen[i] );
|
||||
|
||||
sha1_hmac_finish( &ctx, sha1sum );
|
||||
|
||||
buflen = ( i == 4 ) ? 12 : 20;
|
||||
|
||||
if( memcmp( sha1sum, sha1_hmac_test_sum[i], buflen ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "passed\n" );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "\n" );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
/**
|
||||
* \file sha1.h
|
||||
*
|
||||
* \brief SHA-1 cryptographic hash function
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef POLARSSL_SHA1_H
|
||||
#define POLARSSL_SHA1_H
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <basetsd.h>
|
||||
typedef UINT32 uint32_t;
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#define POLARSSL_ERR_SHA1_FILE_IO_ERROR -0x0076 /**< Read/write error in file. */
|
||||
|
||||
#if !defined(POLARSSL_SHA1_ALT)
|
||||
// Regular implementation
|
||||
//
|
||||
|
||||
/**
|
||||
* \brief SHA-1 context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t total[2]; /*!< number of bytes processed */
|
||||
uint32_t state[5]; /*!< intermediate digest state */
|
||||
unsigned char buffer[64]; /*!< data block being processed */
|
||||
|
||||
unsigned char ipad[64]; /*!< HMAC: inner padding */
|
||||
unsigned char opad[64]; /*!< HMAC: outer padding */
|
||||
}
|
||||
sha1_context;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief SHA-1 context setup
|
||||
*
|
||||
* \param ctx context to be initialized
|
||||
*/
|
||||
void sha1_starts( sha1_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief SHA-1 process buffer
|
||||
*
|
||||
* \param ctx SHA-1 context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void sha1_update( sha1_context *ctx, const unsigned char *input, size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief SHA-1 final digest
|
||||
*
|
||||
* \param ctx SHA-1 context
|
||||
* \param output SHA-1 checksum result
|
||||
*/
|
||||
void sha1_finish( sha1_context *ctx, unsigned char output[20] );
|
||||
|
||||
/* Internal use */
|
||||
void sha1_process( sha1_context *ctx, const unsigned char data[64] );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* POLARSSL_SHA1_ALT */
|
||||
#include "polarssl/sha1_alt.h"
|
||||
#endif /* POLARSSL_SHA1_ALT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Output = SHA-1( input buffer )
|
||||
*
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
* \param output SHA-1 checksum result
|
||||
*/
|
||||
void sha1( const unsigned char *input, size_t ilen, unsigned char output[20] );
|
||||
|
||||
/**
|
||||
* \brief Output = SHA-1( file contents )
|
||||
*
|
||||
* \param path input file name
|
||||
* \param output SHA-1 checksum result
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_SHA1_FILE_IO_ERROR
|
||||
*/
|
||||
int sha1_file( const char *path, unsigned char output[20] );
|
||||
|
||||
/**
|
||||
* \brief SHA-1 HMAC context setup
|
||||
*
|
||||
* \param ctx HMAC context to be initialized
|
||||
* \param key HMAC secret key
|
||||
* \param keylen length of the HMAC key
|
||||
*/
|
||||
void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key, size_t keylen );
|
||||
|
||||
/**
|
||||
* \brief SHA-1 HMAC process buffer
|
||||
*
|
||||
* \param ctx HMAC context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void sha1_hmac_update( sha1_context *ctx, const unsigned char *input, size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief SHA-1 HMAC final digest
|
||||
*
|
||||
* \param ctx HMAC context
|
||||
* \param output SHA-1 HMAC checksum result
|
||||
*/
|
||||
void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] );
|
||||
|
||||
/**
|
||||
* \brief SHA-1 HMAC context reset
|
||||
*
|
||||
* \param ctx HMAC context to be reset
|
||||
*/
|
||||
void sha1_hmac_reset( sha1_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Output = HMAC-SHA-1( hmac key, input buffer )
|
||||
*
|
||||
* \param key HMAC secret key
|
||||
* \param keylen length of the HMAC key
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
* \param output HMAC-SHA-1 result
|
||||
*/
|
||||
void sha1_hmac( const unsigned char *key, size_t keylen,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char output[20] );
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int sha1_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* sha1.h */
|
||||
+705
@@ -0,0 +1,705 @@
|
||||
/*
|
||||
* FIPS-180-2 compliant SHA-256 implementation
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
* The SHA-256 Secure Hash Standard was published by NIST in 2002.
|
||||
*
|
||||
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_SHA2_C)
|
||||
|
||||
#include "polarssl/sha2.h"
|
||||
|
||||
#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if !defined(POLARSSL_SHA2_ALT)
|
||||
|
||||
/*
|
||||
* 32-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
#ifndef GET_UINT32_BE
|
||||
#define GET_UINT32_BE(n,b,i) \
|
||||
{ \
|
||||
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
|
||||
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
|
||||
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
|
||||
| ( (uint32_t) (b)[(i) + 3] ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PUT_UINT32_BE
|
||||
#define PUT_UINT32_BE(n,b,i) \
|
||||
{ \
|
||||
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
void sha2_process( sha2_context *ctx, const unsigned char data[64] )
|
||||
{
|
||||
uint32_t temp1, temp2, W[64];
|
||||
uint32_t A, B, C, D, E, F, G, H;
|
||||
|
||||
GET_UINT32_BE( W[ 0], data, 0 );
|
||||
GET_UINT32_BE( W[ 1], data, 4 );
|
||||
GET_UINT32_BE( W[ 2], data, 8 );
|
||||
GET_UINT32_BE( W[ 3], data, 12 );
|
||||
GET_UINT32_BE( W[ 4], data, 16 );
|
||||
GET_UINT32_BE( W[ 5], data, 20 );
|
||||
GET_UINT32_BE( W[ 6], data, 24 );
|
||||
GET_UINT32_BE( W[ 7], data, 28 );
|
||||
GET_UINT32_BE( W[ 8], data, 32 );
|
||||
GET_UINT32_BE( W[ 9], data, 36 );
|
||||
GET_UINT32_BE( W[10], data, 40 );
|
||||
GET_UINT32_BE( W[11], data, 44 );
|
||||
GET_UINT32_BE( W[12], data, 48 );
|
||||
GET_UINT32_BE( W[13], data, 52 );
|
||||
GET_UINT32_BE( W[14], data, 56 );
|
||||
GET_UINT32_BE( W[15], data, 60 );
|
||||
|
||||
#define 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, size_t ilen )
|
||||
{
|
||||
size_t fill;
|
||||
uint32_t left;
|
||||
|
||||
if( ilen <= 0 )
|
||||
return;
|
||||
|
||||
left = ctx->total[0] & 0x3F;
|
||||
fill = 64 - left;
|
||||
|
||||
ctx->total[0] += (uint32_t) ilen;
|
||||
ctx->total[0] &= 0xFFFFFFFF;
|
||||
|
||||
if( ctx->total[0] < (uint32_t) ilen )
|
||||
ctx->total[1]++;
|
||||
|
||||
if( left && ilen >= fill )
|
||||
{
|
||||
memcpy( (void *) (ctx->buffer + left), input, fill );
|
||||
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), 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] )
|
||||
{
|
||||
uint32_t last, padn;
|
||||
uint32_t high, low;
|
||||
unsigned char msglen[8];
|
||||
|
||||
high = ( ctx->total[0] >> 29 )
|
||||
| ( ctx->total[1] << 3 );
|
||||
low = ( ctx->total[0] << 3 );
|
||||
|
||||
PUT_UINT32_BE( high, msglen, 0 );
|
||||
PUT_UINT32_BE( low, msglen, 4 );
|
||||
|
||||
last = ctx->total[0] & 0x3F;
|
||||
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
|
||||
|
||||
sha2_update( ctx, sha2_padding, padn );
|
||||
sha2_update( ctx, msglen, 8 );
|
||||
|
||||
PUT_UINT32_BE( ctx->state[0], output, 0 );
|
||||
PUT_UINT32_BE( ctx->state[1], output, 4 );
|
||||
PUT_UINT32_BE( ctx->state[2], output, 8 );
|
||||
PUT_UINT32_BE( ctx->state[3], output, 12 );
|
||||
PUT_UINT32_BE( ctx->state[4], output, 16 );
|
||||
PUT_UINT32_BE( ctx->state[5], output, 20 );
|
||||
PUT_UINT32_BE( ctx->state[6], output, 24 );
|
||||
|
||||
if( ctx->is224 == 0 )
|
||||
PUT_UINT32_BE( ctx->state[7], output, 28 );
|
||||
}
|
||||
|
||||
#endif /* !POLARSSL_SHA2_ALT */
|
||||
|
||||
/*
|
||||
* output = SHA-256( input buffer )
|
||||
*/
|
||||
void sha2( const unsigned char *input, size_t 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 ) );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
/*
|
||||
* 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( POLARSSL_ERR_SHA2_FILE_IO_ERROR );
|
||||
|
||||
sha2_starts( &ctx, is224 );
|
||||
|
||||
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
|
||||
sha2_update( &ctx, buf, n );
|
||||
|
||||
sha2_finish( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( sha2_context ) );
|
||||
|
||||
if( ferror( f ) != 0 )
|
||||
{
|
||||
fclose( f );
|
||||
return( POLARSSL_ERR_SHA2_FILE_IO_ERROR );
|
||||
}
|
||||
|
||||
fclose( f );
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* POLARSSL_FS_IO */
|
||||
|
||||
/*
|
||||
* SHA-256 HMAC context setup
|
||||
*/
|
||||
void sha2_hmac_starts( sha2_context *ctx, const unsigned char *key, size_t keylen,
|
||||
int is224 )
|
||||
{
|
||||
size_t 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, size_t 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, size_t keylen,
|
||||
const unsigned char *input, size_t 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
|
||||
+188
@@ -0,0 +1,188 @@
|
||||
/**
|
||||
* \file sha2.h
|
||||
*
|
||||
* \brief SHA-224 and SHA-256 cryptographic hash function
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef POLARSSL_SHA2_H
|
||||
#define POLARSSL_SHA2_H
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <basetsd.h>
|
||||
typedef UINT32 uint32_t;
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#define POLARSSL_ERR_SHA2_FILE_IO_ERROR -0x0078 /**< Read/write error in file. */
|
||||
|
||||
#if !defined(POLARSSL_SHA2_ALT)
|
||||
// Regular implementation
|
||||
//
|
||||
|
||||
/**
|
||||
* \brief SHA-256 context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t total[2]; /*!< number of bytes processed */
|
||||
uint32_t state[8]; /*!< intermediate digest state */
|
||||
unsigned char buffer[64]; /*!< data block being processed */
|
||||
|
||||
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, size_t 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] );
|
||||
|
||||
/* Internal use */
|
||||
void sha2_process( sha2_context *ctx, const unsigned char data[64] );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* POLARSSL_SHA2_ALT */
|
||||
#include "polarssl/sha2_alt.h"
|
||||
#endif /* POLARSSL_SHA2_ALT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Output = SHA-256( input buffer )
|
||||
*
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
* \param output SHA-224/256 checksum result
|
||||
* \param is224 0 = use SHA256, 1 = use SHA224
|
||||
*/
|
||||
void sha2( const unsigned char *input, size_t 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, or POLARSSL_ERR_SHA2_FILE_IO_ERROR
|
||||
*/
|
||||
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, size_t 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, size_t 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, size_t keylen,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char output[32], int is224 );
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int sha2_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* sha2.h */
|
||||
+760
@@ -0,0 +1,760 @@
|
||||
/*
|
||||
* FIPS-180-2 compliant SHA-384/512 implementation
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
* The SHA-512 Secure Hash Standard was published by NIST in 2002.
|
||||
*
|
||||
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_SHA4_C)
|
||||
|
||||
#include "polarssl/sha4.h"
|
||||
|
||||
#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if !defined(POLARSSL_SHA4_ALT)
|
||||
|
||||
/*
|
||||
* 64-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
#ifndef GET_UINT64_BE
|
||||
#define GET_UINT64_BE(n,b,i) \
|
||||
{ \
|
||||
(n) = ( (uint64_t) (b)[(i) ] << 56 ) \
|
||||
| ( (uint64_t) (b)[(i) + 1] << 48 ) \
|
||||
| ( (uint64_t) (b)[(i) + 2] << 40 ) \
|
||||
| ( (uint64_t) (b)[(i) + 3] << 32 ) \
|
||||
| ( (uint64_t) (b)[(i) + 4] << 24 ) \
|
||||
| ( (uint64_t) (b)[(i) + 5] << 16 ) \
|
||||
| ( (uint64_t) (b)[(i) + 6] << 8 ) \
|
||||
| ( (uint64_t) (b)[(i) + 7] ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PUT_UINT64_BE
|
||||
#define PUT_UINT64_BE(n,b,i) \
|
||||
{ \
|
||||
(b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
|
||||
(b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 7] = (unsigned char) ( (n) ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Round constants
|
||||
*/
|
||||
static const uint64_t K[80] =
|
||||
{
|
||||
UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
|
||||
UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
|
||||
UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
|
||||
UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
|
||||
UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
|
||||
UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
|
||||
UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
|
||||
UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
|
||||
UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
|
||||
UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
|
||||
UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
|
||||
UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
|
||||
UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
|
||||
UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
|
||||
UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
|
||||
UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
|
||||
UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
|
||||
UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
|
||||
UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
|
||||
UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
|
||||
UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
|
||||
UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
|
||||
UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
|
||||
UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
|
||||
UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
|
||||
UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
|
||||
UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
|
||||
UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
|
||||
UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
|
||||
UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
|
||||
UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
|
||||
UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
|
||||
UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
|
||||
UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
|
||||
UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
|
||||
UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
|
||||
UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
|
||||
UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
|
||||
UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
|
||||
UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
|
||||
};
|
||||
|
||||
/*
|
||||
* SHA-512 context setup
|
||||
*/
|
||||
void sha4_starts( sha4_context *ctx, int is384 )
|
||||
{
|
||||
ctx->total[0] = 0;
|
||||
ctx->total[1] = 0;
|
||||
|
||||
if( is384 == 0 )
|
||||
{
|
||||
/* SHA-512 */
|
||||
ctx->state[0] = UL64(0x6A09E667F3BCC908);
|
||||
ctx->state[1] = UL64(0xBB67AE8584CAA73B);
|
||||
ctx->state[2] = UL64(0x3C6EF372FE94F82B);
|
||||
ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
|
||||
ctx->state[4] = UL64(0x510E527FADE682D1);
|
||||
ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
|
||||
ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
|
||||
ctx->state[7] = UL64(0x5BE0CD19137E2179);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* SHA-384 */
|
||||
ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
|
||||
ctx->state[1] = UL64(0x629A292A367CD507);
|
||||
ctx->state[2] = UL64(0x9159015A3070DD17);
|
||||
ctx->state[3] = UL64(0x152FECD8F70E5939);
|
||||
ctx->state[4] = UL64(0x67332667FFC00B31);
|
||||
ctx->state[5] = UL64(0x8EB44A8768581511);
|
||||
ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
|
||||
ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
|
||||
}
|
||||
|
||||
ctx->is384 = is384;
|
||||
}
|
||||
|
||||
static void sha4_process( sha4_context *ctx, const unsigned char data[128] )
|
||||
{
|
||||
int i;
|
||||
uint64_t temp1, temp2, W[80];
|
||||
uint64_t A, B, C, D, E, F, G, H;
|
||||
|
||||
#define SHR(x,n) (x >> n)
|
||||
#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
|
||||
|
||||
#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
|
||||
#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
|
||||
|
||||
#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
|
||||
#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
|
||||
|
||||
#define F0(x,y,z) ((x & y) | (z & (x | y)))
|
||||
#define F1(x,y,z) (z ^ (x & (y ^ z)))
|
||||
|
||||
#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; \
|
||||
}
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
GET_UINT64_BE( W[i], data, i << 3 );
|
||||
}
|
||||
|
||||
for( ; i < 80; i++ )
|
||||
{
|
||||
W[i] = S1(W[i - 2]) + W[i - 7] +
|
||||
S0(W[i - 15]) + W[i - 16];
|
||||
}
|
||||
|
||||
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];
|
||||
i = 0;
|
||||
|
||||
do
|
||||
{
|
||||
P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
|
||||
P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
|
||||
P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
|
||||
P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
|
||||
P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
|
||||
P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
|
||||
P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
|
||||
P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
|
||||
}
|
||||
while( i < 80 );
|
||||
|
||||
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-512 process buffer
|
||||
*/
|
||||
void sha4_update( sha4_context *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
size_t fill;
|
||||
unsigned int left;
|
||||
|
||||
if( ilen <= 0 )
|
||||
return;
|
||||
|
||||
left = (unsigned int) (ctx->total[0] & 0x7F);
|
||||
fill = 128 - left;
|
||||
|
||||
ctx->total[0] += (uint64_t) ilen;
|
||||
|
||||
if( ctx->total[0] < (uint64_t) ilen )
|
||||
ctx->total[1]++;
|
||||
|
||||
if( left && ilen >= fill )
|
||||
{
|
||||
memcpy( (void *) (ctx->buffer + left), input, fill );
|
||||
sha4_process( ctx, ctx->buffer );
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while( ilen >= 128 )
|
||||
{
|
||||
sha4_process( ctx, input );
|
||||
input += 128;
|
||||
ilen -= 128;
|
||||
}
|
||||
|
||||
if( ilen > 0 )
|
||||
memcpy( (void *) (ctx->buffer + left), input, ilen );
|
||||
}
|
||||
|
||||
static const unsigned char sha4_padding[128] =
|
||||
{
|
||||
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,
|
||||
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, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* SHA-512 final digest
|
||||
*/
|
||||
void sha4_finish( sha4_context *ctx, unsigned char output[64] )
|
||||
{
|
||||
size_t last, padn;
|
||||
uint64_t high, low;
|
||||
unsigned char msglen[16];
|
||||
|
||||
high = ( ctx->total[0] >> 61 )
|
||||
| ( ctx->total[1] << 3 );
|
||||
low = ( ctx->total[0] << 3 );
|
||||
|
||||
PUT_UINT64_BE( high, msglen, 0 );
|
||||
PUT_UINT64_BE( low, msglen, 8 );
|
||||
|
||||
last = (size_t)( ctx->total[0] & 0x7F );
|
||||
padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
|
||||
|
||||
sha4_update( ctx, sha4_padding, padn );
|
||||
sha4_update( ctx, msglen, 16 );
|
||||
|
||||
PUT_UINT64_BE( ctx->state[0], output, 0 );
|
||||
PUT_UINT64_BE( ctx->state[1], output, 8 );
|
||||
PUT_UINT64_BE( ctx->state[2], output, 16 );
|
||||
PUT_UINT64_BE( ctx->state[3], output, 24 );
|
||||
PUT_UINT64_BE( ctx->state[4], output, 32 );
|
||||
PUT_UINT64_BE( ctx->state[5], output, 40 );
|
||||
|
||||
if( ctx->is384 == 0 )
|
||||
{
|
||||
PUT_UINT64_BE( ctx->state[6], output, 48 );
|
||||
PUT_UINT64_BE( ctx->state[7], output, 56 );
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !POLARSSL_SHA4_ALT */
|
||||
|
||||
/*
|
||||
* output = SHA-512( input buffer )
|
||||
*/
|
||||
void sha4( const unsigned char *input, size_t ilen,
|
||||
unsigned char output[64], int is384 )
|
||||
{
|
||||
sha4_context ctx;
|
||||
|
||||
sha4_starts( &ctx, is384 );
|
||||
sha4_update( &ctx, input, ilen );
|
||||
sha4_finish( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( sha4_context ) );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
/*
|
||||
* output = SHA-512( file contents )
|
||||
*/
|
||||
int sha4_file( const char *path, unsigned char output[64], int is384 )
|
||||
{
|
||||
FILE *f;
|
||||
size_t n;
|
||||
sha4_context ctx;
|
||||
unsigned char buf[1024];
|
||||
|
||||
if( ( f = fopen( path, "rb" ) ) == NULL )
|
||||
return( POLARSSL_ERR_SHA4_FILE_IO_ERROR );
|
||||
|
||||
sha4_starts( &ctx, is384 );
|
||||
|
||||
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
|
||||
sha4_update( &ctx, buf, n );
|
||||
|
||||
sha4_finish( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( sha4_context ) );
|
||||
|
||||
if( ferror( f ) != 0 )
|
||||
{
|
||||
fclose( f );
|
||||
return( POLARSSL_ERR_SHA4_FILE_IO_ERROR );
|
||||
}
|
||||
|
||||
fclose( f );
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* POLARSSL_FS_IO */
|
||||
|
||||
/*
|
||||
* SHA-512 HMAC context setup
|
||||
*/
|
||||
void sha4_hmac_starts( sha4_context *ctx, const unsigned char *key, size_t keylen,
|
||||
int is384 )
|
||||
{
|
||||
size_t i;
|
||||
unsigned char sum[64];
|
||||
|
||||
if( keylen > 128 )
|
||||
{
|
||||
sha4( key, keylen, sum, is384 );
|
||||
keylen = ( is384 ) ? 48 : 64;
|
||||
key = sum;
|
||||
}
|
||||
|
||||
memset( ctx->ipad, 0x36, 128 );
|
||||
memset( ctx->opad, 0x5C, 128 );
|
||||
|
||||
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] );
|
||||
}
|
||||
|
||||
sha4_starts( ctx, is384 );
|
||||
sha4_update( ctx, ctx->ipad, 128 );
|
||||
|
||||
memset( sum, 0, sizeof( sum ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-512 HMAC process buffer
|
||||
*/
|
||||
void sha4_hmac_update( sha4_context *ctx,
|
||||
const unsigned char *input, size_t ilen )
|
||||
{
|
||||
sha4_update( ctx, input, ilen );
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-512 HMAC final digest
|
||||
*/
|
||||
void sha4_hmac_finish( sha4_context *ctx, unsigned char output[64] )
|
||||
{
|
||||
int is384, hlen;
|
||||
unsigned char tmpbuf[64];
|
||||
|
||||
is384 = ctx->is384;
|
||||
hlen = ( is384 == 0 ) ? 64 : 48;
|
||||
|
||||
sha4_finish( ctx, tmpbuf );
|
||||
sha4_starts( ctx, is384 );
|
||||
sha4_update( ctx, ctx->opad, 128 );
|
||||
sha4_update( ctx, tmpbuf, hlen );
|
||||
sha4_finish( ctx, output );
|
||||
|
||||
memset( tmpbuf, 0, sizeof( tmpbuf ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-512 HMAC context reset
|
||||
*/
|
||||
void sha4_hmac_reset( sha4_context *ctx )
|
||||
{
|
||||
sha4_starts( ctx, ctx->is384 );
|
||||
sha4_update( ctx, ctx->ipad, 128 );
|
||||
}
|
||||
|
||||
/*
|
||||
* output = HMAC-SHA-512( hmac key, input buffer )
|
||||
*/
|
||||
void sha4_hmac( const unsigned char *key, size_t keylen,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char output[64], int is384 )
|
||||
{
|
||||
sha4_context ctx;
|
||||
|
||||
sha4_hmac_starts( &ctx, key, keylen, is384 );
|
||||
sha4_hmac_update( &ctx, input, ilen );
|
||||
sha4_hmac_finish( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( sha4_context ) );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_SELF_TEST)
|
||||
|
||||
/*
|
||||
* FIPS-180-2 test vectors
|
||||
*/
|
||||
static unsigned char sha4_test_buf[3][113] =
|
||||
{
|
||||
{ "abc" },
|
||||
{ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
|
||||
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
|
||||
{ "" }
|
||||
};
|
||||
|
||||
static const int sha4_test_buflen[3] =
|
||||
{
|
||||
3, 112, 1000
|
||||
};
|
||||
|
||||
static const unsigned char sha4_test_sum[6][64] =
|
||||
{
|
||||
/*
|
||||
* SHA-384 test vectors
|
||||
*/
|
||||
{ 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
|
||||
0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
|
||||
0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
|
||||
0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
|
||||
0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
|
||||
0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
|
||||
{ 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
|
||||
0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
|
||||
0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
|
||||
0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
|
||||
0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
|
||||
0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
|
||||
{ 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
|
||||
0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
|
||||
0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
|
||||
0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
|
||||
0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
|
||||
0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
|
||||
|
||||
/*
|
||||
* SHA-512 test vectors
|
||||
*/
|
||||
{ 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
|
||||
0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
|
||||
0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
|
||||
0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
|
||||
0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
|
||||
0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
|
||||
0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
|
||||
0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
|
||||
{ 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
|
||||
0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
|
||||
0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
|
||||
0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
|
||||
0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
|
||||
0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
|
||||
0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
|
||||
0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
|
||||
{ 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
|
||||
0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
|
||||
0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
|
||||
0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
|
||||
0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
|
||||
0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
|
||||
0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
|
||||
0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
|
||||
};
|
||||
|
||||
/*
|
||||
* RFC 4231 test vectors
|
||||
*/
|
||||
static unsigned char sha4_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 sha4_hmac_test_keylen[7] =
|
||||
{
|
||||
20, 4, 20, 25, 20, 131, 131
|
||||
};
|
||||
|
||||
static unsigned char sha4_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 sha4_hmac_test_buflen[7] =
|
||||
{
|
||||
8, 28, 50, 50, 20, 54, 152
|
||||
};
|
||||
|
||||
static const unsigned char sha4_hmac_test_sum[14][64] =
|
||||
{
|
||||
/*
|
||||
* HMAC-SHA-384 test vectors
|
||||
*/
|
||||
{ 0xAF, 0xD0, 0x39, 0x44, 0xD8, 0x48, 0x95, 0x62,
|
||||
0x6B, 0x08, 0x25, 0xF4, 0xAB, 0x46, 0x90, 0x7F,
|
||||
0x15, 0xF9, 0xDA, 0xDB, 0xE4, 0x10, 0x1E, 0xC6,
|
||||
0x82, 0xAA, 0x03, 0x4C, 0x7C, 0xEB, 0xC5, 0x9C,
|
||||
0xFA, 0xEA, 0x9E, 0xA9, 0x07, 0x6E, 0xDE, 0x7F,
|
||||
0x4A, 0xF1, 0x52, 0xE8, 0xB2, 0xFA, 0x9C, 0xB6 },
|
||||
{ 0xAF, 0x45, 0xD2, 0xE3, 0x76, 0x48, 0x40, 0x31,
|
||||
0x61, 0x7F, 0x78, 0xD2, 0xB5, 0x8A, 0x6B, 0x1B,
|
||||
0x9C, 0x7E, 0xF4, 0x64, 0xF5, 0xA0, 0x1B, 0x47,
|
||||
0xE4, 0x2E, 0xC3, 0x73, 0x63, 0x22, 0x44, 0x5E,
|
||||
0x8E, 0x22, 0x40, 0xCA, 0x5E, 0x69, 0xE2, 0xC7,
|
||||
0x8B, 0x32, 0x39, 0xEC, 0xFA, 0xB2, 0x16, 0x49 },
|
||||
{ 0x88, 0x06, 0x26, 0x08, 0xD3, 0xE6, 0xAD, 0x8A,
|
||||
0x0A, 0xA2, 0xAC, 0xE0, 0x14, 0xC8, 0xA8, 0x6F,
|
||||
0x0A, 0xA6, 0x35, 0xD9, 0x47, 0xAC, 0x9F, 0xEB,
|
||||
0xE8, 0x3E, 0xF4, 0xE5, 0x59, 0x66, 0x14, 0x4B,
|
||||
0x2A, 0x5A, 0xB3, 0x9D, 0xC1, 0x38, 0x14, 0xB9,
|
||||
0x4E, 0x3A, 0xB6, 0xE1, 0x01, 0xA3, 0x4F, 0x27 },
|
||||
{ 0x3E, 0x8A, 0x69, 0xB7, 0x78, 0x3C, 0x25, 0x85,
|
||||
0x19, 0x33, 0xAB, 0x62, 0x90, 0xAF, 0x6C, 0xA7,
|
||||
0x7A, 0x99, 0x81, 0x48, 0x08, 0x50, 0x00, 0x9C,
|
||||
0xC5, 0x57, 0x7C, 0x6E, 0x1F, 0x57, 0x3B, 0x4E,
|
||||
0x68, 0x01, 0xDD, 0x23, 0xC4, 0xA7, 0xD6, 0x79,
|
||||
0xCC, 0xF8, 0xA3, 0x86, 0xC6, 0x74, 0xCF, 0xFB },
|
||||
{ 0x3A, 0xBF, 0x34, 0xC3, 0x50, 0x3B, 0x2A, 0x23,
|
||||
0xA4, 0x6E, 0xFC, 0x61, 0x9B, 0xAE, 0xF8, 0x97 },
|
||||
{ 0x4E, 0xCE, 0x08, 0x44, 0x85, 0x81, 0x3E, 0x90,
|
||||
0x88, 0xD2, 0xC6, 0x3A, 0x04, 0x1B, 0xC5, 0xB4,
|
||||
0x4F, 0x9E, 0xF1, 0x01, 0x2A, 0x2B, 0x58, 0x8F,
|
||||
0x3C, 0xD1, 0x1F, 0x05, 0x03, 0x3A, 0xC4, 0xC6,
|
||||
0x0C, 0x2E, 0xF6, 0xAB, 0x40, 0x30, 0xFE, 0x82,
|
||||
0x96, 0x24, 0x8D, 0xF1, 0x63, 0xF4, 0x49, 0x52 },
|
||||
{ 0x66, 0x17, 0x17, 0x8E, 0x94, 0x1F, 0x02, 0x0D,
|
||||
0x35, 0x1E, 0x2F, 0x25, 0x4E, 0x8F, 0xD3, 0x2C,
|
||||
0x60, 0x24, 0x20, 0xFE, 0xB0, 0xB8, 0xFB, 0x9A,
|
||||
0xDC, 0xCE, 0xBB, 0x82, 0x46, 0x1E, 0x99, 0xC5,
|
||||
0xA6, 0x78, 0xCC, 0x31, 0xE7, 0x99, 0x17, 0x6D,
|
||||
0x38, 0x60, 0xE6, 0x11, 0x0C, 0x46, 0x52, 0x3E },
|
||||
|
||||
/*
|
||||
* HMAC-SHA-512 test vectors
|
||||
*/
|
||||
{ 0x87, 0xAA, 0x7C, 0xDE, 0xA5, 0xEF, 0x61, 0x9D,
|
||||
0x4F, 0xF0, 0xB4, 0x24, 0x1A, 0x1D, 0x6C, 0xB0,
|
||||
0x23, 0x79, 0xF4, 0xE2, 0xCE, 0x4E, 0xC2, 0x78,
|
||||
0x7A, 0xD0, 0xB3, 0x05, 0x45, 0xE1, 0x7C, 0xDE,
|
||||
0xDA, 0xA8, 0x33, 0xB7, 0xD6, 0xB8, 0xA7, 0x02,
|
||||
0x03, 0x8B, 0x27, 0x4E, 0xAE, 0xA3, 0xF4, 0xE4,
|
||||
0xBE, 0x9D, 0x91, 0x4E, 0xEB, 0x61, 0xF1, 0x70,
|
||||
0x2E, 0x69, 0x6C, 0x20, 0x3A, 0x12, 0x68, 0x54 },
|
||||
{ 0x16, 0x4B, 0x7A, 0x7B, 0xFC, 0xF8, 0x19, 0xE2,
|
||||
0xE3, 0x95, 0xFB, 0xE7, 0x3B, 0x56, 0xE0, 0xA3,
|
||||
0x87, 0xBD, 0x64, 0x22, 0x2E, 0x83, 0x1F, 0xD6,
|
||||
0x10, 0x27, 0x0C, 0xD7, 0xEA, 0x25, 0x05, 0x54,
|
||||
0x97, 0x58, 0xBF, 0x75, 0xC0, 0x5A, 0x99, 0x4A,
|
||||
0x6D, 0x03, 0x4F, 0x65, 0xF8, 0xF0, 0xE6, 0xFD,
|
||||
0xCA, 0xEA, 0xB1, 0xA3, 0x4D, 0x4A, 0x6B, 0x4B,
|
||||
0x63, 0x6E, 0x07, 0x0A, 0x38, 0xBC, 0xE7, 0x37 },
|
||||
{ 0xFA, 0x73, 0xB0, 0x08, 0x9D, 0x56, 0xA2, 0x84,
|
||||
0xEF, 0xB0, 0xF0, 0x75, 0x6C, 0x89, 0x0B, 0xE9,
|
||||
0xB1, 0xB5, 0xDB, 0xDD, 0x8E, 0xE8, 0x1A, 0x36,
|
||||
0x55, 0xF8, 0x3E, 0x33, 0xB2, 0x27, 0x9D, 0x39,
|
||||
0xBF, 0x3E, 0x84, 0x82, 0x79, 0xA7, 0x22, 0xC8,
|
||||
0x06, 0xB4, 0x85, 0xA4, 0x7E, 0x67, 0xC8, 0x07,
|
||||
0xB9, 0x46, 0xA3, 0x37, 0xBE, 0xE8, 0x94, 0x26,
|
||||
0x74, 0x27, 0x88, 0x59, 0xE1, 0x32, 0x92, 0xFB },
|
||||
{ 0xB0, 0xBA, 0x46, 0x56, 0x37, 0x45, 0x8C, 0x69,
|
||||
0x90, 0xE5, 0xA8, 0xC5, 0xF6, 0x1D, 0x4A, 0xF7,
|
||||
0xE5, 0x76, 0xD9, 0x7F, 0xF9, 0x4B, 0x87, 0x2D,
|
||||
0xE7, 0x6F, 0x80, 0x50, 0x36, 0x1E, 0xE3, 0xDB,
|
||||
0xA9, 0x1C, 0xA5, 0xC1, 0x1A, 0xA2, 0x5E, 0xB4,
|
||||
0xD6, 0x79, 0x27, 0x5C, 0xC5, 0x78, 0x80, 0x63,
|
||||
0xA5, 0xF1, 0x97, 0x41, 0x12, 0x0C, 0x4F, 0x2D,
|
||||
0xE2, 0xAD, 0xEB, 0xEB, 0x10, 0xA2, 0x98, 0xDD },
|
||||
{ 0x41, 0x5F, 0xAD, 0x62, 0x71, 0x58, 0x0A, 0x53,
|
||||
0x1D, 0x41, 0x79, 0xBC, 0x89, 0x1D, 0x87, 0xA6 },
|
||||
{ 0x80, 0xB2, 0x42, 0x63, 0xC7, 0xC1, 0xA3, 0xEB,
|
||||
0xB7, 0x14, 0x93, 0xC1, 0xDD, 0x7B, 0xE8, 0xB4,
|
||||
0x9B, 0x46, 0xD1, 0xF4, 0x1B, 0x4A, 0xEE, 0xC1,
|
||||
0x12, 0x1B, 0x01, 0x37, 0x83, 0xF8, 0xF3, 0x52,
|
||||
0x6B, 0x56, 0xD0, 0x37, 0xE0, 0x5F, 0x25, 0x98,
|
||||
0xBD, 0x0F, 0xD2, 0x21, 0x5D, 0x6A, 0x1E, 0x52,
|
||||
0x95, 0xE6, 0x4F, 0x73, 0xF6, 0x3F, 0x0A, 0xEC,
|
||||
0x8B, 0x91, 0x5A, 0x98, 0x5D, 0x78, 0x65, 0x98 },
|
||||
{ 0xE3, 0x7B, 0x6A, 0x77, 0x5D, 0xC8, 0x7D, 0xBA,
|
||||
0xA4, 0xDF, 0xA9, 0xF9, 0x6E, 0x5E, 0x3F, 0xFD,
|
||||
0xDE, 0xBD, 0x71, 0xF8, 0x86, 0x72, 0x89, 0x86,
|
||||
0x5D, 0xF5, 0xA3, 0x2D, 0x20, 0xCD, 0xC9, 0x44,
|
||||
0xB6, 0x02, 0x2C, 0xAC, 0x3C, 0x49, 0x82, 0xB1,
|
||||
0x0D, 0x5E, 0xEB, 0x55, 0xC3, 0xE4, 0xDE, 0x15,
|
||||
0x13, 0x46, 0x76, 0xFB, 0x6D, 0xE0, 0x44, 0x60,
|
||||
0x65, 0xC9, 0x74, 0x40, 0xFA, 0x8C, 0x6A, 0x58 }
|
||||
};
|
||||
|
||||
/*
|
||||
* Checkup routine
|
||||
*/
|
||||
int sha4_self_test( int verbose )
|
||||
{
|
||||
int i, j, k, buflen;
|
||||
unsigned char buf[1024];
|
||||
unsigned char sha4sum[64];
|
||||
sha4_context ctx;
|
||||
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
j = i % 3;
|
||||
k = i < 3;
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
|
||||
|
||||
sha4_starts( &ctx, k );
|
||||
|
||||
if( j == 2 )
|
||||
{
|
||||
memset( buf, 'a', buflen = 1000 );
|
||||
|
||||
for( j = 0; j < 1000; j++ )
|
||||
sha4_update( &ctx, buf, buflen );
|
||||
}
|
||||
else
|
||||
sha4_update( &ctx, sha4_test_buf[j],
|
||||
sha4_test_buflen[j] );
|
||||
|
||||
sha4_finish( &ctx, sha4sum );
|
||||
|
||||
if( memcmp( sha4sum, sha4_test_sum[i], 64 - k * 16 ) != 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: ", 512 - k * 128, j + 1 );
|
||||
|
||||
if( j == 5 || j == 6 )
|
||||
{
|
||||
memset( buf, '\xAA', buflen = 131 );
|
||||
sha4_hmac_starts( &ctx, buf, buflen, k );
|
||||
}
|
||||
else
|
||||
sha4_hmac_starts( &ctx, sha4_hmac_test_key[j],
|
||||
sha4_hmac_test_keylen[j], k );
|
||||
|
||||
sha4_hmac_update( &ctx, sha4_hmac_test_buf[j],
|
||||
sha4_hmac_test_buflen[j] );
|
||||
|
||||
sha4_hmac_finish( &ctx, sha4sum );
|
||||
|
||||
buflen = ( j == 4 ) ? 16 : 64 - k * 16;
|
||||
|
||||
if( memcmp( sha4sum, sha4_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
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
/**
|
||||
* \file sha4.h
|
||||
*
|
||||
* \brief SHA-384 and SHA-512 cryptographic hash function
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef POLARSSL_SHA4_H
|
||||
#define POLARSSL_SHA4_H
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_MSC_VER) || defined(__WATCOMC__)
|
||||
#define UL64(x) x##ui64
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#define UL64(x) x##ULL
|
||||
#endif
|
||||
|
||||
#define POLARSSL_ERR_SHA4_FILE_IO_ERROR -0x007A /**< Read/write error in file. */
|
||||
|
||||
#if !defined(POLARSSL_SHA1_ALT)
|
||||
// Regular implementation
|
||||
//
|
||||
|
||||
/**
|
||||
* \brief SHA-512 context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint64_t total[2]; /*!< number of bytes processed */
|
||||
uint64_t state[8]; /*!< intermediate digest state */
|
||||
unsigned char buffer[128]; /*!< data block being processed */
|
||||
|
||||
unsigned char ipad[128]; /*!< HMAC: inner padding */
|
||||
unsigned char opad[128]; /*!< HMAC: outer padding */
|
||||
int is384; /*!< 0 => SHA-512, else SHA-384 */
|
||||
}
|
||||
sha4_context;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief SHA-512 context setup
|
||||
*
|
||||
* \param ctx context to be initialized
|
||||
* \param is384 0 = use SHA512, 1 = use SHA384
|
||||
*/
|
||||
void sha4_starts( sha4_context *ctx, int is384 );
|
||||
|
||||
/**
|
||||
* \brief SHA-512 process buffer
|
||||
*
|
||||
* \param ctx SHA-512 context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void sha4_update( sha4_context *ctx, const unsigned char *input, size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief SHA-512 final digest
|
||||
*
|
||||
* \param ctx SHA-512 context
|
||||
* \param output SHA-384/512 checksum result
|
||||
*/
|
||||
void sha4_finish( sha4_context *ctx, unsigned char output[64] );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* POLARSSL_SHA4_ALT */
|
||||
#include "polarssl/sha4_alt.h"
|
||||
#endif /* POLARSSL_SHA4_ALT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Output = SHA-512( input buffer )
|
||||
*
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
* \param output SHA-384/512 checksum result
|
||||
* \param is384 0 = use SHA512, 1 = use SHA384
|
||||
*/
|
||||
void sha4( const unsigned char *input, size_t ilen,
|
||||
unsigned char output[64], int is384 );
|
||||
|
||||
/**
|
||||
* \brief Output = SHA-512( file contents )
|
||||
*
|
||||
* \param path input file name
|
||||
* \param output SHA-384/512 checksum result
|
||||
* \param is384 0 = use SHA512, 1 = use SHA384
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_SHA4_FILE_IO_ERROR
|
||||
*/
|
||||
int sha4_file( const char *path, unsigned char output[64], int is384 );
|
||||
|
||||
/**
|
||||
* \brief SHA-512 HMAC context setup
|
||||
*
|
||||
* \param ctx HMAC context to be initialized
|
||||
* \param is384 0 = use SHA512, 1 = use SHA384
|
||||
* \param key HMAC secret key
|
||||
* \param keylen length of the HMAC key
|
||||
*/
|
||||
void sha4_hmac_starts( sha4_context *ctx, const unsigned char *key, size_t keylen,
|
||||
int is384 );
|
||||
|
||||
/**
|
||||
* \brief SHA-512 HMAC process buffer
|
||||
*
|
||||
* \param ctx HMAC context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void sha4_hmac_update( sha4_context *ctx, const unsigned char *input, size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief SHA-512 HMAC final digest
|
||||
*
|
||||
* \param ctx HMAC context
|
||||
* \param output SHA-384/512 HMAC checksum result
|
||||
*/
|
||||
void sha4_hmac_finish( sha4_context *ctx, unsigned char output[64] );
|
||||
|
||||
/**
|
||||
* \brief SHA-512 HMAC context reset
|
||||
*
|
||||
* \param ctx HMAC context to be reset
|
||||
*/
|
||||
void sha4_hmac_reset( sha4_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Output = HMAC-SHA-512( 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-384/512 result
|
||||
* \param is384 0 = use SHA512, 1 = use SHA384
|
||||
*/
|
||||
void sha4_hmac( const unsigned char *key, size_t keylen,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char output[64], int is384 );
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int sha4_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* sha4.h */
|
||||
+1140
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* SSL session cache implementation
|
||||
*
|
||||
* Copyright (C) 2006-2012, 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.
|
||||
*/
|
||||
/*
|
||||
* These session callbacks use a simple chained list
|
||||
* to store and retrieve the session information.
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_SSL_CACHE_C)
|
||||
|
||||
#include "polarssl/ssl_cache.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void ssl_cache_init( ssl_cache_context *cache )
|
||||
{
|
||||
memset( cache, 0, sizeof( ssl_cache_context ) );
|
||||
|
||||
cache->timeout = SSL_CACHE_DEFAULT_TIMEOUT;
|
||||
cache->max_entries = SSL_CACHE_DEFAULT_MAX_ENTRIES;
|
||||
}
|
||||
|
||||
int ssl_cache_get( void *data, ssl_session *session )
|
||||
{
|
||||
time_t t = time( NULL );
|
||||
ssl_cache_context *cache = (ssl_cache_context *) data;
|
||||
ssl_cache_entry *cur, *entry;
|
||||
|
||||
cur = cache->chain;
|
||||
entry = NULL;
|
||||
|
||||
while( cur != NULL )
|
||||
{
|
||||
entry = cur;
|
||||
cur = cur->next;
|
||||
|
||||
if( cache->timeout != 0 &&
|
||||
(int) ( t - entry->timestamp ) > cache->timeout )
|
||||
continue;
|
||||
|
||||
if( session->ciphersuite != entry->session.ciphersuite ||
|
||||
session->compression != entry->session.compression ||
|
||||
session->length != entry->session.length )
|
||||
continue;
|
||||
|
||||
if( memcmp( session->id, entry->session.id,
|
||||
entry->session.length ) != 0 )
|
||||
continue;
|
||||
|
||||
memcpy( session->master, entry->session.master, 48 );
|
||||
|
||||
/*
|
||||
* Restore peer certificate (without rest of the original chain)
|
||||
*/
|
||||
if( entry->peer_cert.p != NULL )
|
||||
{
|
||||
session->peer_cert = (x509_cert *) malloc( sizeof(x509_cert) );
|
||||
if( session->peer_cert == NULL )
|
||||
return( 1 );
|
||||
|
||||
memset( session->peer_cert, 0, sizeof(x509_cert) );
|
||||
if( x509parse_crt( session->peer_cert, entry->peer_cert.p,
|
||||
entry->peer_cert.len ) != 0 )
|
||||
{
|
||||
free( session->peer_cert );
|
||||
session->peer_cert = NULL;
|
||||
return( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
int ssl_cache_set( void *data, const ssl_session *session )
|
||||
{
|
||||
time_t t = time( NULL ), oldest = 0;
|
||||
ssl_cache_context *cache = (ssl_cache_context *) data;
|
||||
ssl_cache_entry *cur, *prv, *old = NULL;
|
||||
int count = 0;
|
||||
|
||||
cur = cache->chain;
|
||||
prv = NULL;
|
||||
|
||||
while( cur != NULL )
|
||||
{
|
||||
count++;
|
||||
|
||||
if( cache->timeout != 0 &&
|
||||
(int) ( t - cur->timestamp ) > cache->timeout )
|
||||
{
|
||||
cur->timestamp = t;
|
||||
break; /* expired, reuse this slot, update timestamp */
|
||||
}
|
||||
|
||||
if( memcmp( session->id, cur->session.id, cur->session.length ) == 0 )
|
||||
break; /* client reconnected, keep timestamp for session id */
|
||||
|
||||
if( oldest == 0 || cur->timestamp < oldest )
|
||||
{
|
||||
oldest = cur->timestamp;
|
||||
old = cur;
|
||||
}
|
||||
|
||||
prv = cur;
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
if( cur == NULL )
|
||||
{
|
||||
/*
|
||||
* Reuse oldest entry if max_entries reached
|
||||
*/
|
||||
if( old != NULL && count >= cache->max_entries )
|
||||
{
|
||||
cur = old;
|
||||
memset( &cur->session, 0, sizeof(ssl_session) );
|
||||
if( cur->peer_cert.p != NULL )
|
||||
{
|
||||
free( cur->peer_cert.p );
|
||||
memset( &cur->peer_cert, 0, sizeof(x509_buf) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cur = (ssl_cache_entry *) malloc( sizeof(ssl_cache_entry) );
|
||||
if( cur == NULL )
|
||||
return( 1 );
|
||||
|
||||
memset( cur, 0, sizeof(ssl_cache_entry) );
|
||||
|
||||
if( prv == NULL )
|
||||
cache->chain = cur;
|
||||
else
|
||||
prv->next = cur;
|
||||
}
|
||||
|
||||
cur->timestamp = t;
|
||||
}
|
||||
|
||||
memcpy( &cur->session, session, sizeof( ssl_session ) );
|
||||
|
||||
/*
|
||||
* Store peer certificate
|
||||
*/
|
||||
if( session->peer_cert != NULL )
|
||||
{
|
||||
cur->peer_cert.p = (unsigned char *) malloc( session->peer_cert->raw.len );
|
||||
if( cur->peer_cert.p == NULL )
|
||||
return( 1 );
|
||||
|
||||
memcpy( cur->peer_cert.p, session->peer_cert->raw.p,
|
||||
session->peer_cert->raw.len );
|
||||
cur->peer_cert.len = session->peer_cert->raw.len;
|
||||
|
||||
cur->session.peer_cert = NULL;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
void ssl_cache_set_timeout( ssl_cache_context *cache, int timeout )
|
||||
{
|
||||
if( timeout < 0 ) timeout = 0;
|
||||
|
||||
cache->timeout = timeout;
|
||||
}
|
||||
|
||||
void ssl_cache_set_max_entries( ssl_cache_context *cache, int max )
|
||||
{
|
||||
if( max < 0 ) max = 0;
|
||||
|
||||
cache->max_entries = max;
|
||||
}
|
||||
|
||||
void ssl_cache_free( ssl_cache_context *cache )
|
||||
{
|
||||
ssl_cache_entry *cur, *prv;
|
||||
|
||||
cur = cache->chain;
|
||||
|
||||
while( cur != NULL )
|
||||
{
|
||||
prv = cur;
|
||||
cur = cur->next;
|
||||
|
||||
ssl_session_free( &prv->session );
|
||||
|
||||
if( prv->peer_cert.p != NULL )
|
||||
free( prv->peer_cert.p );
|
||||
|
||||
free( prv );
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* POLARSSL_SSL_CACHE_C */
|
||||
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* \file ssl_cache.h
|
||||
*
|
||||
* \brief SSL session cache implementation
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef POLARSSL_SSL_CACHE_H
|
||||
#define POLARSSL_SSL_CACHE_H
|
||||
|
||||
#include "polarssl/ssl.h"
|
||||
|
||||
#if !defined(POLARSSL_CONFIG_OPTIONS)
|
||||
#define SSL_CACHE_DEFAULT_TIMEOUT 86400 /*!< 1 day */
|
||||
#define SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /*!< Maximum entries in cache */
|
||||
#endif /* !POLARSSL_CONFIG_OPTIONS */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct _ssl_cache_context ssl_cache_context;
|
||||
typedef struct _ssl_cache_entry ssl_cache_entry;
|
||||
|
||||
/**
|
||||
* \brief This structure is used for storing cache entries
|
||||
*/
|
||||
struct _ssl_cache_entry
|
||||
{
|
||||
time_t timestamp; /*!< entry timestamp */
|
||||
ssl_session session; /*!< entry session */
|
||||
x509_buf peer_cert; /*!< entry peer_cert */
|
||||
ssl_cache_entry *next; /*!< chain pointer */
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Cache context
|
||||
*/
|
||||
struct _ssl_cache_context
|
||||
{
|
||||
ssl_cache_entry *chain; /*!< start of the chain */
|
||||
int timeout; /*!< cache entry timeout */
|
||||
int max_entries; /*!< maximum entries */
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Initialize an SSL cache context
|
||||
*
|
||||
* \param cache SSL cache context
|
||||
*/
|
||||
void ssl_cache_init( ssl_cache_context *cache );
|
||||
|
||||
/**
|
||||
* \brief Cache get callback implementation
|
||||
*
|
||||
* \param data SSL cache context
|
||||
* \param session session to retrieve entry for
|
||||
*/
|
||||
int ssl_cache_get( void *data, ssl_session *session );
|
||||
|
||||
/**
|
||||
* \brief Cache set callback implementation
|
||||
*
|
||||
* \param data SSL cache context
|
||||
* \param session session to store entry for
|
||||
*/
|
||||
int ssl_cache_set( void *data, const ssl_session *session );
|
||||
|
||||
/**
|
||||
* \brief Set the cache timeout
|
||||
* (Default: SSL_CACHE_DEFAULT_TIMEOUT (1 day))
|
||||
*
|
||||
* A timeout of 0 indicates no timeout.
|
||||
*
|
||||
* \param cache SSL cache context
|
||||
* \param timeout cache entry timeout
|
||||
*/
|
||||
void ssl_cache_set_timeout( ssl_cache_context *cache, int timeout );
|
||||
|
||||
/**
|
||||
* \brief Set the cache timeout
|
||||
* (Default: SSL_CACHE_DEFAULT_MAX_ENTRIES (50))
|
||||
*
|
||||
* \param cache SSL cache context
|
||||
* \param max cache entry maximum
|
||||
*/
|
||||
void ssl_cache_set_max_entries( ssl_cache_context *cache, int max );
|
||||
|
||||
/**
|
||||
* \brief Free referenced items in a cache context and clear memory
|
||||
*
|
||||
* \param cache SSL cache context
|
||||
*/
|
||||
void ssl_cache_free( ssl_cache_context *cache );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ssl_cache.h */
|
||||
+1386
File diff suppressed because it is too large
Load Diff
+1623
File diff suppressed because it is too large
Load Diff
+3991
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
* Portable interface to the CPU cycle counter
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_TIMING_C)
|
||||
|
||||
#include "polarssl/timing.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#include <windows.h>
|
||||
#include <winbase.h>
|
||||
|
||||
struct _hr_time
|
||||
{
|
||||
LARGE_INTEGER start;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
|
||||
struct _hr_time
|
||||
{
|
||||
struct timeval start;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \
|
||||
(defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
|
||||
|
||||
#define POLARSSL_HAVE_HARDCLOCK
|
||||
|
||||
unsigned long hardclock( void )
|
||||
{
|
||||
unsigned long tsc;
|
||||
__asm rdtsc
|
||||
__asm mov [tsc], eax
|
||||
return( tsc );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \
|
||||
defined(__GNUC__) && defined(__i386__)
|
||||
|
||||
#define POLARSSL_HAVE_HARDCLOCK
|
||||
|
||||
unsigned long hardclock( void )
|
||||
{
|
||||
unsigned long lo, hi;
|
||||
asm( "rdtsc" : "=a" (lo), "=d" (hi) );
|
||||
return( lo );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \
|
||||
defined(__GNUC__) && (defined(__amd64__) || defined(__x86_64__))
|
||||
|
||||
#define POLARSSL_HAVE_HARDCLOCK
|
||||
|
||||
unsigned long hardclock( void )
|
||||
{
|
||||
unsigned long lo, hi;
|
||||
asm( "rdtsc" : "=a" (lo), "=d" (hi) );
|
||||
return( lo | (hi << 32) );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \
|
||||
defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
|
||||
|
||||
#define POLARSSL_HAVE_HARDCLOCK
|
||||
|
||||
unsigned long hardclock( void )
|
||||
{
|
||||
unsigned long tbl, tbu0, tbu1;
|
||||
|
||||
do
|
||||
{
|
||||
asm( "mftbu %0" : "=r" (tbu0) );
|
||||
asm( "mftb %0" : "=r" (tbl ) );
|
||||
asm( "mftbu %0" : "=r" (tbu1) );
|
||||
}
|
||||
while( tbu0 != tbu1 );
|
||||
|
||||
return( tbl );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \
|
||||
defined(__GNUC__) && defined(__sparc64__)
|
||||
|
||||
#if defined(__OpenBSD__)
|
||||
#warning OpenBSD does not allow access to tick register using software version instead
|
||||
#else
|
||||
#define POLARSSL_HAVE_HARDCLOCK
|
||||
|
||||
unsigned long hardclock( void )
|
||||
{
|
||||
unsigned long tick;
|
||||
asm( "rdpr %%tick, %0;" : "=&r" (tick) );
|
||||
return( tick );
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \
|
||||
defined(__GNUC__) && defined(__sparc__) && !defined(__sparc64__)
|
||||
|
||||
#define POLARSSL_HAVE_HARDCLOCK
|
||||
|
||||
unsigned long hardclock( void )
|
||||
{
|
||||
unsigned long tick;
|
||||
asm( ".byte 0x83, 0x41, 0x00, 0x00" );
|
||||
asm( "mov %%g1, %0" : "=r" (tick) );
|
||||
return( tick );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \
|
||||
defined(__GNUC__) && defined(__alpha__)
|
||||
|
||||
#define POLARSSL_HAVE_HARDCLOCK
|
||||
|
||||
unsigned long hardclock( void )
|
||||
{
|
||||
unsigned long cc;
|
||||
asm( "rpcc %0" : "=r" (cc) );
|
||||
return( cc & 0xFFFFFFFF );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \
|
||||
defined(__GNUC__) && defined(__ia64__)
|
||||
|
||||
#define POLARSSL_HAVE_HARDCLOCK
|
||||
|
||||
unsigned long hardclock( void )
|
||||
{
|
||||
unsigned long itc;
|
||||
asm( "mov %0 = ar.itc" : "=r" (itc) );
|
||||
return( itc );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(_MSC_VER)
|
||||
|
||||
#define POLARSSL_HAVE_HARDCLOCK
|
||||
|
||||
unsigned long hardclock( void )
|
||||
{
|
||||
LARGE_INTEGER offset;
|
||||
|
||||
QueryPerformanceCounter( &offset );
|
||||
|
||||
return (unsigned long)( offset.QuadPart );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(POLARSSL_HAVE_HARDCLOCK)
|
||||
|
||||
#define POLARSSL_HAVE_HARDCLOCK
|
||||
|
||||
static int hardclock_init = 0;
|
||||
static struct timeval tv_init;
|
||||
|
||||
unsigned long hardclock( void )
|
||||
{
|
||||
struct timeval tv_cur;
|
||||
|
||||
if( hardclock_init == 0 )
|
||||
{
|
||||
gettimeofday( &tv_init, NULL );
|
||||
hardclock_init = 1;
|
||||
}
|
||||
|
||||
gettimeofday( &tv_cur, NULL );
|
||||
return( ( tv_cur.tv_sec - tv_init.tv_sec ) * 1000000
|
||||
+ ( tv_cur.tv_usec - tv_init.tv_usec ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
volatile int alarmed = 0;
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
unsigned long get_timer( struct hr_time *val, int reset )
|
||||
{
|
||||
unsigned long delta;
|
||||
LARGE_INTEGER offset, hfreq;
|
||||
struct _hr_time *t = (struct _hr_time *) val;
|
||||
|
||||
QueryPerformanceCounter( &offset );
|
||||
QueryPerformanceFrequency( &hfreq );
|
||||
|
||||
delta = (unsigned long)( ( 1000 *
|
||||
( offset.QuadPart - t->start.QuadPart ) ) /
|
||||
hfreq.QuadPart );
|
||||
|
||||
if( reset )
|
||||
QueryPerformanceCounter( &t->start );
|
||||
|
||||
return( delta );
|
||||
}
|
||||
|
||||
DWORD WINAPI TimerProc( LPVOID uElapse )
|
||||
{
|
||||
Sleep( (DWORD) uElapse );
|
||||
alarmed = 1;
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
void set_alarm( int seconds )
|
||||
{
|
||||
DWORD ThreadId;
|
||||
|
||||
alarmed = 0;
|
||||
CloseHandle( CreateThread( NULL, 0, TimerProc,
|
||||
(LPVOID) ( seconds * 1000 ), 0, &ThreadId ) );
|
||||
}
|
||||
|
||||
void m_sleep( int milliseconds )
|
||||
{
|
||||
Sleep( milliseconds );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
unsigned long get_timer( struct hr_time *val, int reset )
|
||||
{
|
||||
unsigned long delta;
|
||||
struct timeval offset;
|
||||
struct _hr_time *t = (struct _hr_time *) val;
|
||||
|
||||
gettimeofday( &offset, NULL );
|
||||
|
||||
delta = ( offset.tv_sec - t->start.tv_sec ) * 1000
|
||||
+ ( offset.tv_usec - t->start.tv_usec ) / 1000;
|
||||
|
||||
if( reset )
|
||||
{
|
||||
t->start.tv_sec = offset.tv_sec;
|
||||
t->start.tv_usec = offset.tv_usec;
|
||||
}
|
||||
|
||||
return( delta );
|
||||
}
|
||||
|
||||
#if defined(INTEGRITY)
|
||||
void m_sleep( int milliseconds )
|
||||
{
|
||||
usleep( milliseconds * 1000 );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void sighandler( int signum )
|
||||
{
|
||||
alarmed = 1;
|
||||
signal( signum, sighandler );
|
||||
}
|
||||
|
||||
void set_alarm( int seconds )
|
||||
{
|
||||
alarmed = 0;
|
||||
signal( SIGALRM, sighandler );
|
||||
alarm( seconds );
|
||||
}
|
||||
|
||||
void m_sleep( int milliseconds )
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
tv.tv_sec = milliseconds / 1000;
|
||||
tv.tv_usec = milliseconds * 1000;
|
||||
|
||||
select( 0, NULL, NULL, NULL, &tv );
|
||||
}
|
||||
#endif /* INTEGRITY */
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* \file timing.h
|
||||
*
|
||||
* \brief Portable interface to the CPU cycle counter
|
||||
*
|
||||
* 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_TIMING_H
|
||||
#define POLARSSL_TIMING_H
|
||||
|
||||
/**
|
||||
* \brief timer structure
|
||||
*/
|
||||
struct hr_time
|
||||
{
|
||||
unsigned char opaque[32];
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern volatile int alarmed;
|
||||
|
||||
/**
|
||||
* \brief Return the CPU cycle counter value
|
||||
*/
|
||||
unsigned long hardclock( void );
|
||||
|
||||
/**
|
||||
* \brief Return the elapsed time in milliseconds
|
||||
*
|
||||
* \param val points to a timer structure
|
||||
* \param reset if set to 1, the timer is restarted
|
||||
*/
|
||||
unsigned long get_timer( struct hr_time *val, int reset );
|
||||
|
||||
/**
|
||||
* \brief Setup an alarm clock
|
||||
*
|
||||
* \param seconds delay before the "alarmed" flag is set
|
||||
*/
|
||||
void set_alarm( int seconds );
|
||||
|
||||
/**
|
||||
* \brief Sleep for a certain amount of time
|
||||
*
|
||||
* \param milliseconds delay in milliseconds
|
||||
*/
|
||||
void m_sleep( int milliseconds );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* timing.h */
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Version information
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_VERSION_C)
|
||||
|
||||
#include "polarssl/version.h"
|
||||
#include <string.h>
|
||||
|
||||
const char version[] = POLARSSL_VERSION_STRING;
|
||||
|
||||
unsigned int version_get_number()
|
||||
{
|
||||
return POLARSSL_VERSION_NUMBER;
|
||||
}
|
||||
|
||||
void version_get_string( char *string )
|
||||
{
|
||||
memcpy( string, POLARSSL_VERSION_STRING, sizeof( POLARSSL_VERSION_STRING ) );
|
||||
}
|
||||
|
||||
void version_get_string_full( char *string )
|
||||
{
|
||||
memcpy( string, POLARSSL_VERSION_STRING_FULL, sizeof( POLARSSL_VERSION_STRING_FULL ) );
|
||||
}
|
||||
|
||||
#endif /* POLARSSL_VERSION_C */
|
||||
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* \file version.h
|
||||
*
|
||||
* \brief Run-time version information
|
||||
*
|
||||
* Copyright (C) 2006-2012, 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 defines and run-time variables can be used to
|
||||
* determine the version number of the PolarSSL library used.
|
||||
*/
|
||||
#ifndef POLARSSL_VERSION_H
|
||||
#define POLARSSL_VERSION_H
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
/**
|
||||
* The version number x.y.z is split into three parts.
|
||||
* Major, Minor, Patchlevel
|
||||
*/
|
||||
#define POLARSSL_VERSION_MAJOR 1
|
||||
#define POLARSSL_VERSION_MINOR 2
|
||||
#define POLARSSL_VERSION_PATCH 8
|
||||
|
||||
/**
|
||||
* The single version number has the following structure:
|
||||
* MMNNPP00
|
||||
* Major version | Minor version | Patch version
|
||||
*/
|
||||
#define POLARSSL_VERSION_NUMBER 0x01020800
|
||||
#define POLARSSL_VERSION_STRING "1.2.8"
|
||||
#define POLARSSL_VERSION_STRING_FULL "PolarSSL 1.2.8"
|
||||
|
||||
#if defined(POLARSSL_VERSION_C)
|
||||
|
||||
/**
|
||||
* Get the version number.
|
||||
*
|
||||
* \return The constructed version number in the format
|
||||
* MMNNPP00 (Major, Minor, Patch).
|
||||
*/
|
||||
unsigned int version_get_number( void );
|
||||
|
||||
/**
|
||||
* Get the version string ("x.y.z").
|
||||
*
|
||||
* \param string The string that will receive the value.
|
||||
* (Should be at least 9 bytes in size)
|
||||
*/
|
||||
void version_get_string( char *string );
|
||||
|
||||
/**
|
||||
* Get the full version string ("PolarSSL x.y.z").
|
||||
*
|
||||
* \param string The string that will receive the value.
|
||||
* (Should be at least 18 bytes in size)
|
||||
*/
|
||||
void version_get_string_full( char *string );
|
||||
|
||||
#endif /* POLARSSL_VERSION_C */
|
||||
|
||||
#endif /* version.h */
|
||||
+778
@@ -0,0 +1,778 @@
|
||||
/**
|
||||
* \file x509.h
|
||||
*
|
||||
* \brief X.509 certificate and private key decoding
|
||||
*
|
||||
* Copyright (C) 2006-2011, 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_X509_H
|
||||
#define POLARSSL_X509_H
|
||||
|
||||
#include "polarssl/asn1.h"
|
||||
#include "polarssl/rsa.h"
|
||||
#include "polarssl/dhm.h"
|
||||
|
||||
/**
|
||||
* \addtogroup x509_module
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \name X509 Error codes
|
||||
* \{
|
||||
*/
|
||||
#define POLARSSL_ERR_X509_FEATURE_UNAVAILABLE -0x2080 /**< Unavailable feature, e.g. RSA hashing/encryption combination. */
|
||||
#define POLARSSL_ERR_X509_CERT_INVALID_PEM -0x2100 /**< The PEM-encoded certificate contains invalid elements, e.g. invalid character. */
|
||||
#define POLARSSL_ERR_X509_CERT_INVALID_FORMAT -0x2180 /**< The certificate format is invalid, e.g. different type expected. */
|
||||
#define POLARSSL_ERR_X509_CERT_INVALID_VERSION -0x2200 /**< The certificate version element is invalid. */
|
||||
#define POLARSSL_ERR_X509_CERT_INVALID_SERIAL -0x2280 /**< The serial tag or value is invalid. */
|
||||
#define POLARSSL_ERR_X509_CERT_INVALID_ALG -0x2300 /**< The algorithm tag or value is invalid. */
|
||||
#define POLARSSL_ERR_X509_CERT_INVALID_NAME -0x2380 /**< The name tag or value is invalid. */
|
||||
#define POLARSSL_ERR_X509_CERT_INVALID_DATE -0x2400 /**< The date tag or value is invalid. */
|
||||
#define POLARSSL_ERR_X509_CERT_INVALID_PUBKEY -0x2480 /**< The pubkey tag or value is invalid (only RSA is supported). */
|
||||
#define POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE -0x2500 /**< The signature tag or value invalid. */
|
||||
#define POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS -0x2580 /**< The extension tag or value is invalid. */
|
||||
#define POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION -0x2600 /**< Certificate or CRL has an unsupported version number. */
|
||||
#define POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG -0x2680 /**< Signature algorithm (oid) is unsupported. */
|
||||
#define POLARSSL_ERR_X509_UNKNOWN_PK_ALG -0x2700 /**< Key algorithm is unsupported (only RSA is supported). */
|
||||
#define POLARSSL_ERR_X509_CERT_SIG_MISMATCH -0x2780 /**< Certificate signature algorithms do not match. (see \c ::x509_cert sig_oid) */
|
||||
#define POLARSSL_ERR_X509_CERT_VERIFY_FAILED -0x2800 /**< Certificate verification failed, e.g. CRL, CA or signature check failed. */
|
||||
#define POLARSSL_ERR_X509_KEY_INVALID_VERSION -0x2880 /**< Unsupported RSA key version */
|
||||
#define POLARSSL_ERR_X509_KEY_INVALID_FORMAT -0x2900 /**< Invalid RSA key tag or value. */
|
||||
#define POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT -0x2980 /**< Format not recognized as DER or PEM. */
|
||||
#define POLARSSL_ERR_X509_INVALID_INPUT -0x2A00 /**< Input invalid. */
|
||||
#define POLARSSL_ERR_X509_MALLOC_FAILED -0x2A80 /**< Allocation of memory failed. */
|
||||
#define POLARSSL_ERR_X509_FILE_IO_ERROR -0x2B00 /**< Read/write of file failed. */
|
||||
#define POLARSSL_ERR_X509_PASSWORD_REQUIRED -0x2B80 /**< Private key password can't be empty. */
|
||||
#define POLARSSL_ERR_X509_PASSWORD_MISMATCH -0x2C00 /**< Given private key password does not allow for correct decryption. */
|
||||
/* \} name */
|
||||
|
||||
|
||||
/**
|
||||
* \name X509 Verify codes
|
||||
* \{
|
||||
*/
|
||||
#define BADCERT_EXPIRED 0x01 /**< The certificate validity has expired. */
|
||||
#define BADCERT_REVOKED 0x02 /**< The certificate has been revoked (is on a CRL). */
|
||||
#define BADCERT_CN_MISMATCH 0x04 /**< The certificate Common Name (CN) does not match with the expected CN. */
|
||||
#define BADCERT_NOT_TRUSTED 0x08 /**< The certificate is not correctly signed by the trusted CA. */
|
||||
#define BADCRL_NOT_TRUSTED 0x10 /**< CRL is not correctly signed by the trusted CA. */
|
||||
#define BADCRL_EXPIRED 0x20 /**< CRL is expired. */
|
||||
#define BADCERT_MISSING 0x40 /**< Certificate was missing. */
|
||||
#define BADCERT_SKIP_VERIFY 0x80 /**< Certificate verification was skipped. */
|
||||
#define BADCERT_OTHER 0x0100 /**< Other reason (can be used by verify callback) */
|
||||
/* \} name */
|
||||
/* \} addtogroup x509_module */
|
||||
|
||||
/*
|
||||
* various object identifiers
|
||||
*/
|
||||
#define X520_COMMON_NAME 3
|
||||
#define X520_COUNTRY 6
|
||||
#define X520_LOCALITY 7
|
||||
#define X520_STATE 8
|
||||
#define X520_ORGANIZATION 10
|
||||
#define X520_ORG_UNIT 11
|
||||
#define PKCS9_EMAIL 1
|
||||
|
||||
#define X509_OUTPUT_DER 0x01
|
||||
#define X509_OUTPUT_PEM 0x02
|
||||
#define PEM_LINE_LENGTH 72
|
||||
#define X509_ISSUER 0x01
|
||||
#define X509_SUBJECT 0x02
|
||||
|
||||
#define OID_X520 "\x55\x04"
|
||||
#define OID_CN OID_X520 "\x03"
|
||||
#define OID_COUNTRY OID_X520 "\x06"
|
||||
#define OID_LOCALITY OID_X520 "\x07"
|
||||
#define OID_STATE OID_X520 "\x08"
|
||||
#define OID_ORGANIZATION OID_X520 "\x0A"
|
||||
#define OID_ORG_UNIT OID_X520 "\x0B"
|
||||
|
||||
#define OID_PKCS1 "\x2A\x86\x48\x86\xF7\x0D\x01\x01"
|
||||
#define OID_PKCS1_RSA OID_PKCS1 "\x01"
|
||||
#define OID_PKCS1_SHA1 OID_PKCS1 "\x05"
|
||||
|
||||
#define OID_RSA_SHA_OBS "\x2B\x0E\x03\x02\x1D"
|
||||
|
||||
#define OID_PKCS9 "\x2A\x86\x48\x86\xF7\x0D\x01\x09"
|
||||
#define OID_PKCS9_EMAIL OID_PKCS9 "\x01"
|
||||
|
||||
/** ISO arc for standard certificate and CRL extensions */
|
||||
#define OID_ID_CE "\x55\x1D" /**< id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29} */
|
||||
|
||||
/**
|
||||
* Private Internet Extensions
|
||||
* { iso(1) identified-organization(3) dod(6) internet(1)
|
||||
* security(5) mechanisms(5) pkix(7) }
|
||||
*/
|
||||
#define OID_PKIX "\x2B\x06\x01\x05\x05\x07"
|
||||
|
||||
/*
|
||||
* OIDs for standard certificate extensions
|
||||
*/
|
||||
#define OID_AUTHORITY_KEY_IDENTIFIER OID_ID_CE "\x23" /**< id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 } */
|
||||
#define OID_SUBJECT_KEY_IDENTIFIER OID_ID_CE "\x0E" /**< id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 } */
|
||||
#define OID_KEY_USAGE OID_ID_CE "\x0F" /**< id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 } */
|
||||
#define OID_CERTIFICATE_POLICIES OID_ID_CE "\x20" /**< id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 } */
|
||||
#define OID_POLICY_MAPPINGS OID_ID_CE "\x21" /**< id-ce-policyMappings OBJECT IDENTIFIER ::= { id-ce 33 } */
|
||||
#define OID_SUBJECT_ALT_NAME OID_ID_CE "\x11" /**< id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 } */
|
||||
#define OID_ISSUER_ALT_NAME OID_ID_CE "\x12" /**< id-ce-issuerAltName OBJECT IDENTIFIER ::= { id-ce 18 } */
|
||||
#define OID_SUBJECT_DIRECTORY_ATTRS OID_ID_CE "\x09" /**< id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 } */
|
||||
#define OID_BASIC_CONSTRAINTS OID_ID_CE "\x13" /**< id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 } */
|
||||
#define OID_NAME_CONSTRAINTS OID_ID_CE "\x1E" /**< id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 } */
|
||||
#define OID_POLICY_CONSTRAINTS OID_ID_CE "\x24" /**< id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 } */
|
||||
#define OID_EXTENDED_KEY_USAGE OID_ID_CE "\x25" /**< id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 } */
|
||||
#define OID_CRL_DISTRIBUTION_POINTS OID_ID_CE "\x1F" /**< id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= { id-ce 31 } */
|
||||
#define OID_INIHIBIT_ANYPOLICY OID_ID_CE "\x36" /**< id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 } */
|
||||
#define OID_FRESHEST_CRL OID_ID_CE "\x2E" /**< id-ce-freshestCRL OBJECT IDENTIFIER ::= { id-ce 46 } */
|
||||
|
||||
/*
|
||||
* X.509 v3 Key Usage Extension flags
|
||||
*/
|
||||
#define KU_DIGITAL_SIGNATURE (0x80) /* bit 0 */
|
||||
#define KU_NON_REPUDIATION (0x40) /* bit 1 */
|
||||
#define KU_KEY_ENCIPHERMENT (0x20) /* bit 2 */
|
||||
#define KU_DATA_ENCIPHERMENT (0x10) /* bit 3 */
|
||||
#define KU_KEY_AGREEMENT (0x08) /* bit 4 */
|
||||
#define KU_KEY_CERT_SIGN (0x04) /* bit 5 */
|
||||
#define KU_CRL_SIGN (0x02) /* bit 6 */
|
||||
|
||||
/*
|
||||
* X.509 v3 Extended key usage OIDs
|
||||
*/
|
||||
#define OID_ANY_EXTENDED_KEY_USAGE OID_EXTENDED_KEY_USAGE "\x00" /**< anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 } */
|
||||
|
||||
#define OID_KP OID_PKIX "\x03" /**< id-kp OBJECT IDENTIFIER ::= { id-pkix 3 } */
|
||||
#define OID_SERVER_AUTH OID_KP "\x01" /**< id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 } */
|
||||
#define OID_CLIENT_AUTH OID_KP "\x02" /**< id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 } */
|
||||
#define OID_CODE_SIGNING OID_KP "\x03" /**< id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 } */
|
||||
#define OID_EMAIL_PROTECTION OID_KP "\x04" /**< id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 } */
|
||||
#define OID_TIME_STAMPING OID_KP "\x08" /**< id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 } */
|
||||
#define OID_OCSP_SIGNING OID_KP "\x09" /**< id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 } */
|
||||
|
||||
#define STRING_SERVER_AUTH "TLS Web Server Authentication"
|
||||
#define STRING_CLIENT_AUTH "TLS Web Client Authentication"
|
||||
#define STRING_CODE_SIGNING "Code Signing"
|
||||
#define STRING_EMAIL_PROTECTION "E-mail Protection"
|
||||
#define STRING_TIME_STAMPING "Time Stamping"
|
||||
#define STRING_OCSP_SIGNING "OCSP Signing"
|
||||
|
||||
/*
|
||||
* OIDs for CRL extensions
|
||||
*/
|
||||
#define OID_PRIVATE_KEY_USAGE_PERIOD OID_ID_CE "\x10"
|
||||
#define OID_CRL_NUMBER OID_ID_CE "\x14" /**< id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 } */
|
||||
|
||||
/*
|
||||
* Netscape certificate extensions
|
||||
*/
|
||||
#define OID_NETSCAPE "\x60\x86\x48\x01\x86\xF8\x42" /**< Netscape OID */
|
||||
#define OID_NS_CERT OID_NETSCAPE "\x01"
|
||||
#define OID_NS_CERT_TYPE OID_NS_CERT "\x01"
|
||||
#define OID_NS_BASE_URL OID_NS_CERT "\x02"
|
||||
#define OID_NS_REVOCATION_URL OID_NS_CERT "\x03"
|
||||
#define OID_NS_CA_REVOCATION_URL OID_NS_CERT "\x04"
|
||||
#define OID_NS_RENEWAL_URL OID_NS_CERT "\x07"
|
||||
#define OID_NS_CA_POLICY_URL OID_NS_CERT "\x08"
|
||||
#define OID_NS_SSL_SERVER_NAME OID_NS_CERT "\x0C"
|
||||
#define OID_NS_COMMENT OID_NS_CERT "\x0D"
|
||||
#define OID_NS_DATA_TYPE OID_NETSCAPE "\x02"
|
||||
#define OID_NS_CERT_SEQUENCE OID_NS_DATA_TYPE "\x05"
|
||||
|
||||
/*
|
||||
* Netscape certificate types
|
||||
* (http://www.mozilla.org/projects/security/pki/nss/tech-notes/tn3.html)
|
||||
*/
|
||||
|
||||
#define NS_CERT_TYPE_SSL_CLIENT (0x80) /* bit 0 */
|
||||
#define NS_CERT_TYPE_SSL_SERVER (0x40) /* bit 1 */
|
||||
#define NS_CERT_TYPE_EMAIL (0x20) /* bit 2 */
|
||||
#define NS_CERT_TYPE_OBJECT_SIGNING (0x10) /* bit 3 */
|
||||
#define NS_CERT_TYPE_RESERVED (0x08) /* bit 4 */
|
||||
#define NS_CERT_TYPE_SSL_CA (0x04) /* bit 5 */
|
||||
#define NS_CERT_TYPE_EMAIL_CA (0x02) /* bit 6 */
|
||||
#define NS_CERT_TYPE_OBJECT_SIGNING_CA (0x01) /* bit 7 */
|
||||
|
||||
#define EXT_AUTHORITY_KEY_IDENTIFIER (1 << 0)
|
||||
#define EXT_SUBJECT_KEY_IDENTIFIER (1 << 1)
|
||||
#define EXT_KEY_USAGE (1 << 2)
|
||||
#define EXT_CERTIFICATE_POLICIES (1 << 3)
|
||||
#define EXT_POLICY_MAPPINGS (1 << 4)
|
||||
#define EXT_SUBJECT_ALT_NAME (1 << 5)
|
||||
#define EXT_ISSUER_ALT_NAME (1 << 6)
|
||||
#define EXT_SUBJECT_DIRECTORY_ATTRS (1 << 7)
|
||||
#define EXT_BASIC_CONSTRAINTS (1 << 8)
|
||||
#define EXT_NAME_CONSTRAINTS (1 << 9)
|
||||
#define EXT_POLICY_CONSTRAINTS (1 << 10)
|
||||
#define EXT_EXTENDED_KEY_USAGE (1 << 11)
|
||||
#define EXT_CRL_DISTRIBUTION_POINTS (1 << 12)
|
||||
#define EXT_INIHIBIT_ANYPOLICY (1 << 13)
|
||||
#define EXT_FRESHEST_CRL (1 << 14)
|
||||
|
||||
#define EXT_NS_CERT_TYPE (1 << 16)
|
||||
|
||||
/*
|
||||
* Storage format identifiers
|
||||
* Recognized formats: PEM and DER
|
||||
*/
|
||||
#define X509_FORMAT_DER 1
|
||||
#define X509_FORMAT_PEM 2
|
||||
|
||||
/**
|
||||
* \addtogroup x509_module
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* \name Structures for parsing X.509 certificates and CRLs
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Type-length-value structure that allows for ASN1 using DER.
|
||||
*/
|
||||
typedef asn1_buf x509_buf;
|
||||
|
||||
/**
|
||||
* Container for ASN1 bit strings.
|
||||
*/
|
||||
typedef asn1_bitstring x509_bitstring;
|
||||
|
||||
/**
|
||||
* Container for ASN1 named information objects.
|
||||
* It allows for Relative Distinguished Names (e.g. cn=polarssl,ou=code,etc.).
|
||||
*/
|
||||
typedef struct _x509_name
|
||||
{
|
||||
x509_buf oid; /**< The object identifier. */
|
||||
x509_buf val; /**< The named value. */
|
||||
struct _x509_name *next; /**< The next named information object. */
|
||||
}
|
||||
x509_name;
|
||||
|
||||
/**
|
||||
* Container for a sequence of ASN.1 items
|
||||
*/
|
||||
typedef asn1_sequence x509_sequence;
|
||||
|
||||
/** Container for date and time (precision in seconds). */
|
||||
typedef struct _x509_time
|
||||
{
|
||||
int year, mon, day; /**< Date. */
|
||||
int hour, min, sec; /**< Time. */
|
||||
}
|
||||
x509_time;
|
||||
|
||||
/**
|
||||
* Container for an X.509 certificate. The certificate may be chained.
|
||||
*/
|
||||
typedef struct _x509_cert
|
||||
{
|
||||
x509_buf raw; /**< The raw certificate data (DER). */
|
||||
x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */
|
||||
|
||||
int version; /**< The X.509 version. (0=v1, 1=v2, 2=v3) */
|
||||
x509_buf serial; /**< Unique id for certificate issued by a specific CA. */
|
||||
x509_buf sig_oid1; /**< Signature algorithm, e.g. sha1RSA */
|
||||
|
||||
x509_buf issuer_raw; /**< The raw issuer data (DER). Used for quick comparison. */
|
||||
x509_buf subject_raw; /**< The raw subject data (DER). Used for quick comparison. */
|
||||
|
||||
x509_name issuer; /**< The parsed issuer data (named information object). */
|
||||
x509_name subject; /**< The parsed subject data (named information object). */
|
||||
|
||||
x509_time valid_from; /**< Start time of certificate validity. */
|
||||
x509_time valid_to; /**< End time of certificate validity. */
|
||||
|
||||
x509_buf pk_oid; /**< Subject public key info. Includes the public key algorithm and the key itself. */
|
||||
rsa_context rsa; /**< Container for the RSA context. Only RSA is supported for public keys at this time. */
|
||||
|
||||
x509_buf issuer_id; /**< Optional X.509 v2/v3 issuer unique identifier. */
|
||||
x509_buf subject_id; /**< Optional X.509 v2/v3 subject unique identifier. */
|
||||
x509_buf v3_ext; /**< Optional X.509 v3 extensions. Only Basic Contraints are supported at this time. */
|
||||
x509_sequence subject_alt_names; /**< Optional list of Subject Alternative Names (Only dNSName supported). */
|
||||
|
||||
int ext_types; /**< Bit string containing detected and parsed extensions */
|
||||
int ca_istrue; /**< Optional Basic Constraint extension value: 1 if this certificate belongs to a CA, 0 otherwise. */
|
||||
int max_pathlen; /**< Optional Basic Constraint extension value: The maximum path length to the root certificate. Path length is 1 higher than RFC 5280 'meaning', so 1+ */
|
||||
|
||||
unsigned char key_usage; /**< Optional key usage extension value: See the values below */
|
||||
|
||||
x509_sequence ext_key_usage; /**< Optional list of extended key usage OIDs. */
|
||||
|
||||
unsigned char ns_cert_type; /**< Optional Netscape certificate type extension value: See the values below */
|
||||
|
||||
x509_buf sig_oid2; /**< Signature algorithm. Must match sig_oid1. */
|
||||
x509_buf sig; /**< Signature: hash of the tbs part signed with the private key. */
|
||||
int sig_alg; /**< Internal representation of the signature algorithm, e.g. SIG_RSA_MD2 */
|
||||
|
||||
struct _x509_cert *next; /**< Next certificate in the CA-chain. */
|
||||
}
|
||||
x509_cert;
|
||||
|
||||
/**
|
||||
* Certificate revocation list entry.
|
||||
* Contains the CA-specific serial numbers and revocation dates.
|
||||
*/
|
||||
typedef struct _x509_crl_entry
|
||||
{
|
||||
x509_buf raw;
|
||||
|
||||
x509_buf serial;
|
||||
|
||||
x509_time revocation_date;
|
||||
|
||||
x509_buf entry_ext;
|
||||
|
||||
struct _x509_crl_entry *next;
|
||||
}
|
||||
x509_crl_entry;
|
||||
|
||||
/**
|
||||
* Certificate revocation list structure.
|
||||
* Every CRL may have multiple entries.
|
||||
*/
|
||||
typedef struct _x509_crl
|
||||
{
|
||||
x509_buf raw; /**< The raw certificate data (DER). */
|
||||
x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */
|
||||
|
||||
int version;
|
||||
x509_buf sig_oid1;
|
||||
|
||||
x509_buf issuer_raw; /**< The raw issuer data (DER). */
|
||||
|
||||
x509_name issuer; /**< The parsed issuer data (named information object). */
|
||||
|
||||
x509_time this_update;
|
||||
x509_time next_update;
|
||||
|
||||
x509_crl_entry entry; /**< The CRL entries containing the certificate revocation times for this CA. */
|
||||
|
||||
x509_buf crl_ext;
|
||||
|
||||
x509_buf sig_oid2;
|
||||
x509_buf sig;
|
||||
int sig_alg;
|
||||
|
||||
struct _x509_crl *next;
|
||||
}
|
||||
x509_crl;
|
||||
/** \} name Structures for parsing X.509 certificates and CRLs */
|
||||
/** \} addtogroup x509_module */
|
||||
|
||||
/**
|
||||
* \name Structures for writing X.509 certificates.
|
||||
* XvP: commented out as they are not used.
|
||||
* - <tt>typedef struct _x509_node x509_node;</tt>
|
||||
* - <tt>typedef struct _x509_raw x509_raw;</tt>
|
||||
*/
|
||||
/*
|
||||
typedef struct _x509_node
|
||||
{
|
||||
unsigned char *data;
|
||||
unsigned char *p;
|
||||
unsigned char *end;
|
||||
|
||||
size_t len;
|
||||
}
|
||||
x509_node;
|
||||
|
||||
typedef struct _x509_raw
|
||||
{
|
||||
x509_node raw;
|
||||
x509_node tbs;
|
||||
|
||||
x509_node version;
|
||||
x509_node serial;
|
||||
x509_node tbs_signalg;
|
||||
x509_node issuer;
|
||||
x509_node validity;
|
||||
x509_node subject;
|
||||
x509_node subpubkey;
|
||||
|
||||
x509_node signalg;
|
||||
x509_node sign;
|
||||
}
|
||||
x509_raw;
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \name Functions to read in DHM parameters, a certificate, CRL or private RSA key
|
||||
* \{
|
||||
*/
|
||||
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
* \brief Parse a single DER formatted certificate and add it
|
||||
* to the chained list.
|
||||
*
|
||||
* \param chain points to the start of the chain
|
||||
* \param buf buffer holding the certificate DER data
|
||||
* \param buflen size of the buffer
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_crt_der( x509_cert *chain, const unsigned char *buf, size_t buflen );
|
||||
|
||||
/**
|
||||
* \brief Parse one or more certificates and add them
|
||||
* to the chained list. Parses permissively. If some
|
||||
* certificates can be parsed, the result is the number
|
||||
* of failed certificates it encountered. If none complete
|
||||
* correctly, the first error is returned.
|
||||
*
|
||||
* \param chain points to the start of the chain
|
||||
* \param buf buffer holding the certificate data
|
||||
* \param buflen size of the buffer
|
||||
*
|
||||
* \return 0 if all certificates parsed successfully, a positive number
|
||||
* if partly successful or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen );
|
||||
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
* \brief Load one or more certificates and add them
|
||||
* to the chained list. Parses permissively. If some
|
||||
* certificates can be parsed, the result is the number
|
||||
* of failed certificates it encountered. If none complete
|
||||
* correctly, the first error is returned.
|
||||
*
|
||||
* \param chain points to the start of the chain
|
||||
* \param path filename to read the certificates from
|
||||
*
|
||||
* \return 0 if all certificates parsed successfully, a positive number
|
||||
* if partly successful or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_crtfile( x509_cert *chain, const char *path );
|
||||
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
* \brief Load one or more certificate files from a path and add them
|
||||
* to the chained list. Parses permissively. If some
|
||||
* certificates can be parsed, the result is the number
|
||||
* of failed certificates it encountered. If none complete
|
||||
* correctly, the first error is returned.
|
||||
*
|
||||
* \param chain points to the start of the chain
|
||||
* \param path directory / folder to read the certificate files from
|
||||
*
|
||||
* \return 0 if all certificates parsed successfully, a positive number
|
||||
* if partly successful or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_crtpath( x509_cert *chain, const char *path );
|
||||
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
* \brief Parse one or more CRLs and add them
|
||||
* to the chained list
|
||||
*
|
||||
* \param chain points to the start of the chain
|
||||
* \param buf buffer holding the CRL data
|
||||
* \param buflen size of the buffer
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen );
|
||||
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
* \brief Load one or more CRLs and add them
|
||||
* to the chained list
|
||||
*
|
||||
* \param chain points to the start of the chain
|
||||
* \param path filename to read the CRLs from
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_crlfile( x509_crl *chain, const char *path );
|
||||
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
* \brief Parse a private RSA key
|
||||
*
|
||||
* \param rsa RSA context to be initialized
|
||||
* \param key input buffer
|
||||
* \param keylen size of the buffer
|
||||
* \param pwd password for decryption (optional)
|
||||
* \param pwdlen size of the password
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_key( rsa_context *rsa,
|
||||
const unsigned char *key, size_t keylen,
|
||||
const unsigned char *pwd, size_t pwdlen );
|
||||
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
* \brief Load and parse a private RSA key
|
||||
*
|
||||
* \param rsa RSA context to be initialized
|
||||
* \param path filename to read the private key from
|
||||
* \param password password to decrypt the file (can be NULL)
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_keyfile( rsa_context *rsa, const char *path,
|
||||
const char *password );
|
||||
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
* \brief Parse a public RSA key
|
||||
*
|
||||
* \param rsa RSA context to be initialized
|
||||
* \param key input buffer
|
||||
* \param keylen size of the buffer
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_public_key( rsa_context *rsa,
|
||||
const unsigned char *key, size_t keylen );
|
||||
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
* \brief Load and parse a public RSA key
|
||||
*
|
||||
* \param rsa RSA context to be initialized
|
||||
* \param path filename to read the private key from
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_public_keyfile( rsa_context *rsa, const char *path );
|
||||
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
* \brief Parse DHM parameters
|
||||
*
|
||||
* \param dhm DHM context to be initialized
|
||||
* \param dhmin input buffer
|
||||
* \param dhminlen size of the buffer
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen );
|
||||
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
* \brief Load and parse DHM parameters
|
||||
*
|
||||
* \param dhm DHM context to be initialized
|
||||
* \param path filename to read the DHM Parameters from
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_dhmfile( dhm_context *dhm, const char *path );
|
||||
|
||||
/** \} name Functions to read in DHM parameters, a certificate, CRL or private RSA key */
|
||||
|
||||
/**
|
||||
* \brief Store the certificate DN in printable form into buf;
|
||||
* no more than size characters will be written.
|
||||
*
|
||||
* \param buf Buffer to write to
|
||||
* \param size Maximum size of buffer
|
||||
* \param dn The X509 name to represent
|
||||
*
|
||||
* \return The amount of data written to the buffer, or -1 in
|
||||
* case of an error.
|
||||
*/
|
||||
int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn );
|
||||
|
||||
/**
|
||||
* \brief Store the certificate serial in printable form into buf;
|
||||
* no more than size characters will be written.
|
||||
*
|
||||
* \param buf Buffer to write to
|
||||
* \param size Maximum size of buffer
|
||||
* \param serial The X509 serial to represent
|
||||
*
|
||||
* \return The amount of data written to the buffer, or -1 in
|
||||
* case of an error.
|
||||
*/
|
||||
int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial );
|
||||
|
||||
/**
|
||||
* \brief Returns an informational string about the
|
||||
* certificate.
|
||||
*
|
||||
* \param buf Buffer to write to
|
||||
* \param size Maximum size of buffer
|
||||
* \param prefix A line prefix
|
||||
* \param crt The X509 certificate to represent
|
||||
*
|
||||
* \return The amount of data written to the buffer, or -1 in
|
||||
* case of an error.
|
||||
*/
|
||||
int x509parse_cert_info( char *buf, size_t size, const char *prefix,
|
||||
const x509_cert *crt );
|
||||
|
||||
/**
|
||||
* \brief Returns an informational string about the
|
||||
* CRL.
|
||||
*
|
||||
* \param buf Buffer to write to
|
||||
* \param size Maximum size of buffer
|
||||
* \param prefix A line prefix
|
||||
* \param crl The X509 CRL to represent
|
||||
*
|
||||
* \return The amount of data written to the buffer, or -1 in
|
||||
* case of an error.
|
||||
*/
|
||||
int x509parse_crl_info( char *buf, size_t size, const char *prefix,
|
||||
const x509_crl *crl );
|
||||
|
||||
/**
|
||||
* \brief Give an known OID, return its descriptive string.
|
||||
*
|
||||
* \param oid buffer containing the oid
|
||||
*
|
||||
* \return Return a string if the OID is known,
|
||||
* or NULL otherwise.
|
||||
*/
|
||||
const char *x509_oid_get_description( x509_buf *oid );
|
||||
|
||||
/**
|
||||
* \brief Give an OID, return a string version of its OID number.
|
||||
*
|
||||
* \param buf Buffer to write to
|
||||
* \param size Maximum size of buffer
|
||||
* \param oid Buffer containing the OID
|
||||
*
|
||||
* \return The amount of data written to the buffer, or -1 in
|
||||
* case of an error.
|
||||
*/
|
||||
int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid );
|
||||
|
||||
/**
|
||||
* \brief Check a given x509_time against the system time and check
|
||||
* if it is valid.
|
||||
*
|
||||
* \param time x509_time to check
|
||||
*
|
||||
* \return Return 0 if the x509_time is still valid,
|
||||
* or 1 otherwise.
|
||||
*/
|
||||
int x509parse_time_expired( const x509_time *time );
|
||||
|
||||
/**
|
||||
* \name Functions to verify a certificate
|
||||
* \{
|
||||
*/
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
* \brief Verify the certificate signature
|
||||
*
|
||||
* The verify callback is a user-supplied callback that
|
||||
* can clear / modify / add flags for a certificate. If set,
|
||||
* the verification callback is called for each
|
||||
* certificate in the chain (from the trust-ca down to the
|
||||
* presented crt). The parameters for the callback are:
|
||||
* (void *parameter, x509_cert *crt, int certificate_depth,
|
||||
* int *flags). With the flags representing current flags for
|
||||
* that specific certificate and the certificate depth from
|
||||
* the bottom (Peer cert depth = 0).
|
||||
*
|
||||
* All flags left after returning from the callback
|
||||
* are also returned to the application. The function should
|
||||
* return 0 for anything but a fatal error.
|
||||
*
|
||||
* \param crt a certificate to be verified
|
||||
* \param trust_ca the trusted CA chain
|
||||
* \param ca_crl the CRL chain for trusted CA's
|
||||
* \param cn expected Common Name (can be set to
|
||||
* NULL if the CN must not be verified)
|
||||
* \param flags result of the verification
|
||||
* \param f_vrfy verification function
|
||||
* \param p_vrfy verification parameter
|
||||
*
|
||||
* \return 0 if successful or POLARSSL_ERR_X509_SIG_VERIFY_FAILED,
|
||||
* in which case *flags will have one or more of
|
||||
* the following values set:
|
||||
* BADCERT_EXPIRED --
|
||||
* BADCERT_REVOKED --
|
||||
* BADCERT_CN_MISMATCH --
|
||||
* BADCERT_NOT_TRUSTED
|
||||
* or another error in case of a fatal error encountered
|
||||
* during the verification process.
|
||||
*/
|
||||
int x509parse_verify( x509_cert *crt,
|
||||
x509_cert *trust_ca,
|
||||
x509_crl *ca_crl,
|
||||
const char *cn, int *flags,
|
||||
int (*f_vrfy)(void *, x509_cert *, int, int *),
|
||||
void *p_vrfy );
|
||||
|
||||
/**
|
||||
* \brief Verify the certificate signature
|
||||
*
|
||||
* \param crt a certificate to be verified
|
||||
* \param crl the CRL to verify against
|
||||
*
|
||||
* \return 1 if the certificate is revoked, 0 otherwise
|
||||
*
|
||||
*/
|
||||
int x509parse_revoked( const x509_cert *crt, const x509_crl *crl );
|
||||
|
||||
/** \} name Functions to verify a certificate */
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* \name Functions to clear a certificate, CRL or private RSA key
|
||||
* \{
|
||||
*/
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
* \brief Unallocate all certificate data
|
||||
*
|
||||
* \param crt Certificate chain to free
|
||||
*/
|
||||
void x509_free( x509_cert *crt );
|
||||
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
* \brief Unallocate all CRL data
|
||||
*
|
||||
* \param crl CRL chain to free
|
||||
*/
|
||||
void x509_crl_free( x509_crl *crl );
|
||||
|
||||
/** \} name Functions to clear a certificate, CRL or private RSA key */
|
||||
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int x509_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* x509.h */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,285 @@
|
||||
/*
|
||||
* X509 buffer writing functionality
|
||||
*
|
||||
* Copyright (C) 2006-2012, 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.
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_X509_WRITE_C)
|
||||
|
||||
#include "polarssl/asn1write.h"
|
||||
#include "polarssl/x509write.h"
|
||||
#include "polarssl/x509.h"
|
||||
#include "polarssl/sha1.h"
|
||||
#include "polarssl/sha2.h"
|
||||
#include "polarssl/sha4.h"
|
||||
#include "polarssl/md4.h"
|
||||
#include "polarssl/md5.h"
|
||||
|
||||
int x509_write_pubkey_der( unsigned char *buf, size_t size, rsa_context *rsa )
|
||||
{
|
||||
int ret;
|
||||
unsigned char *c;
|
||||
size_t len = 0;
|
||||
|
||||
c = buf + size - 1;
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->E ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->N ) );
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
if( c - buf < 1 )
|
||||
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
|
||||
|
||||
*--c = 0;
|
||||
len += 1;
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) );
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, buf, OID_PKCS1_RSA ) );
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
int x509_write_key_der( unsigned char *buf, size_t size, rsa_context *rsa )
|
||||
{
|
||||
int ret;
|
||||
unsigned char *c;
|
||||
size_t len = 0;
|
||||
|
||||
c = buf + size - 1;
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->QP ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DQ ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DP ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->Q ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->P ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->D ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->E ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->N ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 0 ) );
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
// TODO: Make NON RSA Specific variant later on
|
||||
/* *--c = 0;
|
||||
len += 1;
|
||||
|
||||
len += asn1_write_len( &c, len);
|
||||
len += asn1_write_tag( &c, ASN1_BIT_STRING );
|
||||
|
||||
len += asn1_write_oid( &c, OID_PKCS1_RSA );
|
||||
|
||||
len += asn1_write_int( &c, 0 );
|
||||
|
||||
len += asn1_write_len( &c, len);
|
||||
len += asn1_write_tag( &c, ASN1_CONSTRUCTED | ASN1_SEQUENCE );*/
|
||||
|
||||
/* for(i = 0; i < len; ++i)
|
||||
{
|
||||
if (i % 16 == 0 ) printf("\n");
|
||||
printf("%02x ", c[i]);
|
||||
}
|
||||
printf("\n");*/
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
int x509_write_name( unsigned char **p, unsigned char *start, char *oid,
|
||||
char *name )
|
||||
{
|
||||
int ret;
|
||||
size_t string_len = 0;
|
||||
size_t oid_len = 0;
|
||||
size_t len = 0;
|
||||
|
||||
// Write PrintableString for all except OID_PKCS9_EMAIL
|
||||
//
|
||||
if( OID_SIZE( OID_PKCS9_EMAIL ) == strlen( oid ) &&
|
||||
memcmp( oid, OID_PKCS9_EMAIL, strlen( oid ) ) == 0 )
|
||||
{
|
||||
ASN1_CHK_ADD( string_len, asn1_write_ia5_string( p, start, name ) );
|
||||
}
|
||||
else
|
||||
ASN1_CHK_ADD( string_len, asn1_write_printable_string( p, start, name ) );
|
||||
|
||||
// Write OID
|
||||
//
|
||||
ASN1_CHK_ADD( oid_len, asn1_write_oid( p, start, oid ) );
|
||||
|
||||
len = oid_len + string_len;
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, oid_len + string_len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SET ) );
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper for x509 hashes.
|
||||
*/
|
||||
static void x509_hash( const unsigned char *in, size_t len, int alg,
|
||||
unsigned char *out )
|
||||
{
|
||||
switch( alg )
|
||||
{
|
||||
#if defined(POLARSSL_MD2_C)
|
||||
case SIG_RSA_MD2 : md2( in, len, out ); break;
|
||||
#endif
|
||||
#if defined(POLARSSL_MD4_C)
|
||||
case SIG_RSA_MD4 : md4( in, len, out ); break;
|
||||
#endif
|
||||
#if defined(POLARSSL_MD5_C)
|
||||
case SIG_RSA_MD5 : md5( in, len, out ); break;
|
||||
#endif
|
||||
#if defined(POLARSSL_SHA1_C)
|
||||
case SIG_RSA_SHA1 : sha1( in, len, out ); break;
|
||||
#endif
|
||||
#if defined(POLARSSL_SHA2_C)
|
||||
case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
|
||||
case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
|
||||
#endif
|
||||
#if defined(POLARSSL_SHA4_C)
|
||||
case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
|
||||
case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
|
||||
#endif
|
||||
default:
|
||||
memset( out, '\xFF', 64 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int x509_write_sig( unsigned char **p, unsigned char *start, char *oid,
|
||||
unsigned char *sig, size_t size )
|
||||
{
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
|
||||
if( *p - start < (int) size + 1 )
|
||||
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
|
||||
|
||||
len = size;
|
||||
(*p) -= len;
|
||||
memcpy( *p, sig, len );
|
||||
|
||||
*--(*p) = 0;
|
||||
len += 1;
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_BIT_STRING ) );
|
||||
|
||||
// Write OID
|
||||
//
|
||||
ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( p, start, oid ) );
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
int x509_write_cert_req( unsigned char *buf, size_t size, rsa_context *rsa,
|
||||
x509_req_name *req_name, int hash_id )
|
||||
{
|
||||
int ret;
|
||||
char sig_oid[10];
|
||||
unsigned char *c, *c2;
|
||||
unsigned char hash[64];
|
||||
unsigned char sig[POLARSSL_MPI_MAX_SIZE];
|
||||
unsigned char tmp_buf[2048];
|
||||
size_t sub_len = 0, pub_len = 0, sig_len = 0;
|
||||
size_t len = 0;
|
||||
x509_req_name *cur = req_name;
|
||||
|
||||
c = tmp_buf + 2048 - 1;
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, 0 ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC ) );
|
||||
|
||||
ASN1_CHK_ADD( pub_len, asn1_write_mpi( &c, tmp_buf, &rsa->E ) );
|
||||
ASN1_CHK_ADD( pub_len, asn1_write_mpi( &c, tmp_buf, &rsa->N ) );
|
||||
|
||||
ASN1_CHK_ADD( pub_len, asn1_write_len( &c, tmp_buf, pub_len ) );
|
||||
ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
if( c - tmp_buf < 1 )
|
||||
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
|
||||
|
||||
*--c = 0;
|
||||
pub_len += 1;
|
||||
|
||||
ASN1_CHK_ADD( pub_len, asn1_write_len( &c, tmp_buf, pub_len ) );
|
||||
ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, tmp_buf, ASN1_BIT_STRING ) );
|
||||
|
||||
ASN1_CHK_ADD( pub_len, asn1_write_algorithm_identifier( &c, tmp_buf, OID_PKCS1_RSA ) );
|
||||
|
||||
len += pub_len;
|
||||
ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, pub_len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
while( cur != NULL )
|
||||
{
|
||||
ASN1_CHK_ADD( sub_len, x509_write_name( &c, tmp_buf, cur->oid, cur->name ) );
|
||||
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
len += sub_len;
|
||||
ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, sub_len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_int( &c, tmp_buf, 0 ) );
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
x509_hash( c, len, hash_id, hash );
|
||||
|
||||
rsa_pkcs1_sign( rsa, NULL, NULL, RSA_PRIVATE, hash_id, 0, hash, sig );
|
||||
|
||||
// Generate correct OID
|
||||
//
|
||||
memcpy( sig_oid, OID_PKCS1, 8 );
|
||||
sig_oid[8] = hash_id;
|
||||
sig_oid[9] = '\0';
|
||||
|
||||
c2 = buf + size - 1;
|
||||
ASN1_CHK_ADD( sig_len, x509_write_sig( &c2, buf, sig_oid, sig, rsa->len ) );
|
||||
|
||||
c2 -= len;
|
||||
memcpy( c2, c, len );
|
||||
|
||||
len += sig_len;
|
||||
ASN1_CHK_ADD( len, asn1_write_len( &c2, buf, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( &c2, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* \file x509write.h
|
||||
*
|
||||
* \brief X509 buffer writing functionality
|
||||
*
|
||||
* Copyright (C) 2006-2012, 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_X509_WRITE_H
|
||||
#define POLARSSL_X509_WRITE_H
|
||||
|
||||
#include "polarssl/rsa.h"
|
||||
|
||||
typedef struct _x509_req_name
|
||||
{
|
||||
char oid[128];
|
||||
char name[128];
|
||||
|
||||
struct _x509_req_name *next;
|
||||
}
|
||||
x509_req_name;
|
||||
|
||||
int x509_write_pubkey_der( unsigned char *buf, size_t size, rsa_context *rsa );
|
||||
int x509_write_key_der( unsigned char *buf, size_t size, rsa_context *rsa );
|
||||
int x509_write_cert_req( unsigned char *buf, size_t size, rsa_context *rsa,
|
||||
x509_req_name *req_name, int hash_id );
|
||||
|
||||
#endif /* POLARSSL_X509_WRITE_H */
|
||||
+251
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* An 32-bit implementation of the XTEA algorithm
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_XTEA_C)
|
||||
|
||||
#include "polarssl/xtea.h"
|
||||
|
||||
#if !defined(POLARSSL_XTEA_ALT)
|
||||
|
||||
/*
|
||||
* 32-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
#ifndef GET_UINT32_BE
|
||||
#define GET_UINT32_BE(n,b,i) \
|
||||
{ \
|
||||
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
|
||||
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
|
||||
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
|
||||
| ( (uint32_t) (b)[(i) + 3] ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PUT_UINT32_BE
|
||||
#define PUT_UINT32_BE(n,b,i) \
|
||||
{ \
|
||||
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* XTEA key schedule
|
||||
*/
|
||||
void xtea_setup( xtea_context *ctx, unsigned char key[16] )
|
||||
{
|
||||
int i;
|
||||
|
||||
memset(ctx, 0, sizeof(xtea_context));
|
||||
|
||||
for( i = 0; i < 4; i++ )
|
||||
{
|
||||
GET_UINT32_BE( ctx->k[i], key, i << 2 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* XTEA encrypt function
|
||||
*/
|
||||
int xtea_crypt_ecb( xtea_context *ctx, int mode, unsigned char input[8],
|
||||
unsigned char output[8])
|
||||
{
|
||||
uint32_t *k, v0, v1, i;
|
||||
|
||||
k = ctx->k;
|
||||
|
||||
GET_UINT32_BE( v0, input, 0 );
|
||||
GET_UINT32_BE( v1, input, 4 );
|
||||
|
||||
if( mode == XTEA_ENCRYPT )
|
||||
{
|
||||
uint32_t sum = 0, delta = 0x9E3779B9;
|
||||
|
||||
for( i = 0; i < 32; i++ )
|
||||
{
|
||||
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
|
||||
sum += delta;
|
||||
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
|
||||
}
|
||||
}
|
||||
else /* XTEA_DECRYPT */
|
||||
{
|
||||
uint32_t delta = 0x9E3779B9, sum = delta * 32;
|
||||
|
||||
for( i = 0; i < 32; i++ )
|
||||
{
|
||||
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
|
||||
sum -= delta;
|
||||
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
|
||||
}
|
||||
}
|
||||
|
||||
PUT_UINT32_BE( v0, output, 0 );
|
||||
PUT_UINT32_BE( v1, output, 4 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* XTEA-CBC buffer encryption/decryption
|
||||
*/
|
||||
int xtea_crypt_cbc( xtea_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[8],
|
||||
unsigned char *input,
|
||||
unsigned char *output)
|
||||
{
|
||||
int i;
|
||||
unsigned char temp[8];
|
||||
|
||||
if(length % 8)
|
||||
return( POLARSSL_ERR_XTEA_INVALID_INPUT_LENGTH );
|
||||
|
||||
if( mode == XTEA_DECRYPT )
|
||||
{
|
||||
while( length > 0 )
|
||||
{
|
||||
memcpy( temp, input, 8 );
|
||||
xtea_crypt_ecb( ctx, mode, input, output );
|
||||
|
||||
for(i = 0; i < 8; i++)
|
||||
output[i] = (unsigned char)( output[i] ^ iv[i] );
|
||||
|
||||
memcpy( iv, temp, 8 );
|
||||
|
||||
input += 8;
|
||||
output += 8;
|
||||
length -= 8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while( length > 0 )
|
||||
{
|
||||
for( i = 0; i < 8; i++ )
|
||||
output[i] = (unsigned char)( input[i] ^ iv[i] );
|
||||
|
||||
xtea_crypt_ecb( ctx, mode, output, output );
|
||||
memcpy( iv, output, 8 );
|
||||
|
||||
input += 8;
|
||||
output += 8;
|
||||
length -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* !POLARSSL_XTEA_ALT */
|
||||
|
||||
#if defined(POLARSSL_SELF_TEST)
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* XTEA tests vectors (non-official)
|
||||
*/
|
||||
|
||||
static const unsigned char xtea_test_key[6][16] =
|
||||
{
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
|
||||
0x0c, 0x0d, 0x0e, 0x0f },
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
|
||||
0x0c, 0x0d, 0x0e, 0x0f },
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
|
||||
0x0c, 0x0d, 0x0e, 0x0f },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00 }
|
||||
};
|
||||
|
||||
static const unsigned char xtea_test_pt[6][8] =
|
||||
{
|
||||
{ 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
|
||||
{ 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
|
||||
{ 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f },
|
||||
{ 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
|
||||
{ 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
|
||||
{ 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 }
|
||||
};
|
||||
|
||||
static const unsigned char xtea_test_ct[6][8] =
|
||||
{
|
||||
{ 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 },
|
||||
{ 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 },
|
||||
{ 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
|
||||
{ 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 },
|
||||
{ 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d },
|
||||
{ 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }
|
||||
};
|
||||
|
||||
/*
|
||||
* Checkup routine
|
||||
*/
|
||||
int xtea_self_test( int verbose )
|
||||
{
|
||||
int i;
|
||||
unsigned char buf[8];
|
||||
xtea_context ctx;
|
||||
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( " XTEA test #%d: ", i + 1 );
|
||||
|
||||
memcpy( buf, xtea_test_pt[i], 8 );
|
||||
|
||||
xtea_setup( &ctx, (unsigned char *) xtea_test_key[i] );
|
||||
xtea_crypt_ecb( &ctx, XTEA_ENCRYPT, buf, buf );
|
||||
|
||||
if( memcmp( buf, xtea_test_ct[i], 8 ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "passed\n" );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "\n" );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
/**
|
||||
* \file xtea.h
|
||||
*
|
||||
* \brief XTEA block cipher (32-bit)
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef POLARSSL_XTEA_H
|
||||
#define POLARSSL_XTEA_H
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <basetsd.h>
|
||||
typedef UINT32 uint32_t;
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#define XTEA_ENCRYPT 1
|
||||
#define XTEA_DECRYPT 0
|
||||
|
||||
#define POLARSSL_ERR_XTEA_INVALID_INPUT_LENGTH -0x0028 /**< The data input has an invalid length. */
|
||||
|
||||
#if !defined(POLARSSL_XTEA_ALT)
|
||||
// Regular implementation
|
||||
//
|
||||
|
||||
/**
|
||||
* \brief XTEA context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t k[4]; /*!< key */
|
||||
}
|
||||
xtea_context;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief XTEA key schedule
|
||||
*
|
||||
* \param ctx XTEA context to be initialized
|
||||
* \param key the secret key
|
||||
*/
|
||||
void xtea_setup( xtea_context *ctx, unsigned char key[16] );
|
||||
|
||||
/**
|
||||
* \brief XTEA cipher function
|
||||
*
|
||||
* \param ctx XTEA context
|
||||
* \param mode XTEA_ENCRYPT or XTEA_DECRYPT
|
||||
* \param input 8-byte input block
|
||||
* \param output 8-byte output block
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int xtea_crypt_ecb( xtea_context *ctx,
|
||||
int mode,
|
||||
unsigned char input[8],
|
||||
unsigned char output[8] );
|
||||
|
||||
/**
|
||||
* \brief XTEA CBC cipher function
|
||||
*
|
||||
* \param ctx XTEA context
|
||||
* \param mode XTEA_ENCRYPT or XTEA_DECRYPT
|
||||
* \param length the length of input, multiple of 8
|
||||
* \param iv initialization vector for CBC mode
|
||||
* \param input input block
|
||||
* \param output output block
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_XTEA_INVALID_INPUT_LENGTH if the length % 8 != 0
|
||||
*/
|
||||
int xtea_crypt_cbc( xtea_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[8],
|
||||
unsigned char *input,
|
||||
unsigned char *output);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* POLARSSL_XTEA_ALT */
|
||||
#include "polarssl/xtea_alt.h"
|
||||
#endif /* POLARSSL_XTEA_ALT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int xtea_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* xtea.h */
|
||||
Reference in New Issue
Block a user