mirror of https://github.com/hak5/openwrt-owl.git
parent
169642253f
commit
2cf4946597
|
@ -0,0 +1,39 @@
|
|||
#
|
||||
# Copyright (C) 2010 Jo-Philipp Wich <xm@subsignal.org>
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=px5g
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/px5g
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=Standalone X.509 certificate generator
|
||||
endef
|
||||
|
||||
define Package/px5g/description
|
||||
Px5g is a tiny standalone X.509 certificate generator.
|
||||
It suitable to create key files and certificates in DER
|
||||
and PEM format for use with stunnel, uhttpd and others.
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
mkdir -p $(PKG_BUILD_DIR)
|
||||
$(CP) ./src/* $(PKG_BUILD_DIR)/
|
||||
endef
|
||||
|
||||
define Package/px5g/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/px5g $(1)/usr/sbin/px5g
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,px5g))
|
|
@ -0,0 +1,14 @@
|
|||
CFLAGS?=-O2
|
||||
CFLAGS+=
|
||||
SFLAGS:=--std=gnu99
|
||||
WFLAGS:=-Wall -Werror -pedantic
|
||||
LDFLAGS?=
|
||||
BINARY:=px5g
|
||||
|
||||
all: $(BINARY)
|
||||
|
||||
$(BINARY): *.c library/*.c
|
||||
$(CC) -I. $(CFLAGS) $(SFLAGS) $(WFLAGS) $(LDFLAGS) -o $@ $+
|
||||
|
||||
clean:
|
||||
rm -f $(BINARY)
|
|
@ -0,0 +1,264 @@
|
|||
/*
|
||||
* RFC 1521 base64 encoding/decoding
|
||||
*
|
||||
* Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
|
||||
*
|
||||
* Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the names of PolarSSL or XySSL nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_BASE64_C)
|
||||
|
||||
#include "polarssl/base64.h"
|
||||
|
||||
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, int *dlen,
|
||||
unsigned char *src, int slen )
|
||||
{
|
||||
int 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, int *dlen,
|
||||
unsigned char *src, int slen )
|
||||
{
|
||||
int i, j, n;
|
||||
unsigned long 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 )
|
||||
return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
|
||||
|
||||
if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
|
||||
return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
|
||||
|
||||
if( base64_dec_map[src[i]] < 64 && j != 0 )
|
||||
return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
|
||||
|
||||
n++;
|
||||
}
|
||||
|
||||
if( n == 0 )
|
||||
return( 0 );
|
||||
|
||||
n = ((n * 6) + 7) >> 3;
|
||||
|
||||
if( *dlen < 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 )
|
||||
{
|
||||
int len;
|
||||
unsigned char *src, buffer[128];
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( " Base64 encoding test: " );
|
||||
|
||||
len = sizeof( buffer );
|
||||
src = (unsigned char *) 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 = (unsigned char *) 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
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,276 @@
|
|||
/*
|
||||
* HAVEGE: HArdware Volatile Entropy Gathering and Expansion
|
||||
*
|
||||
* Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
|
||||
*
|
||||
* Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the names of PolarSSL or XySSL nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* 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 <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_HAVEGE_C)
|
||||
|
||||
#include "polarssl/havege.h"
|
||||
#include "polarssl/timing.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_rand( void *p_rng )
|
||||
{
|
||||
int ret;
|
||||
havege_state *hs = (havege_state *) p_rng;
|
||||
|
||||
if( hs->offset[1] >= COLLECT_SIZE )
|
||||
havege_fill( hs );
|
||||
|
||||
ret = hs->pool[hs->offset[0]++];
|
||||
ret ^= hs->pool[hs->offset[1]++];
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_RAND_TEST)
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
FILE *f;
|
||||
time_t t;
|
||||
int i, j, k;
|
||||
havege_state hs;
|
||||
unsigned char buf[1024];
|
||||
|
||||
if( argc < 2 )
|
||||
{
|
||||
fprintf( stderr, "usage: %s <output filename>\n", argv[0] );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( ( f = fopen( argv[1], "wb+" ) ) == NULL )
|
||||
{
|
||||
printf( "failed to open '%s' for writing.\n", argv[0] );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
havege_init( &hs );
|
||||
|
||||
t = time( NULL );
|
||||
|
||||
for( i = 0, k = 32768; i < k; i++ )
|
||||
{
|
||||
for( j = 0; j < sizeof( buf ); j++ )
|
||||
buf[j] = havege_rand( &hs );
|
||||
|
||||
fwrite( buf, sizeof( buf ), 1, f );
|
||||
|
||||
printf( "Generating 32Mb of data in file '%s'... %04.1f" \
|
||||
"%% done\r", argv[1], (100 * (float) (i + 1)) / k );
|
||||
fflush( stdout );
|
||||
}
|
||||
|
||||
if( t == time( NULL ) )
|
||||
t--;
|
||||
|
||||
fclose( f );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,750 @@
|
|||
/*
|
||||
* The RSA public-key cryptosystem
|
||||
*
|
||||
* Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
|
||||
*
|
||||
* Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the names of PolarSSL or XySSL nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* RSA was designed by Ron Rivest, Adi Shamir and Len Adleman.
|
||||
*
|
||||
* http://theory.lcs.mit.edu/~rivest/rsapaper.pdf
|
||||
* http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_RSA_C)
|
||||
|
||||
#include "polarssl/rsa.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* Initialize an RSA context
|
||||
*/
|
||||
void rsa_init( rsa_context *ctx,
|
||||
int padding,
|
||||
int hash_id,
|
||||
int (*f_rng)(void *),
|
||||
void *p_rng )
|
||||
{
|
||||
memset( ctx, 0, sizeof( rsa_context ) );
|
||||
|
||||
ctx->padding = padding;
|
||||
ctx->hash_id = hash_id;
|
||||
|
||||
ctx->f_rng = f_rng;
|
||||
ctx->p_rng = p_rng;
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_GENPRIME)
|
||||
|
||||
/*
|
||||
* Generate an RSA keypair
|
||||
*/
|
||||
int rsa_gen_key( rsa_context *ctx, int nbits, int exponent )
|
||||
{
|
||||
int ret;
|
||||
mpi P1, Q1, H, G;
|
||||
|
||||
if( ctx->f_rng == NULL || nbits < 128 || exponent < 3 )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
mpi_init( &P1, &Q1, &H, &G, NULL );
|
||||
|
||||
/*
|
||||
* find primes P and Q with Q < P so that:
|
||||
* GCD( E, (P-1)*(Q-1) ) == 1
|
||||
*/
|
||||
MPI_CHK( mpi_lset( &ctx->E, exponent ) );
|
||||
|
||||
do
|
||||
{
|
||||
MPI_CHK( mpi_gen_prime( &ctx->P, ( nbits + 1 ) >> 1, 0,
|
||||
ctx->f_rng, ctx->p_rng ) );
|
||||
|
||||
MPI_CHK( mpi_gen_prime( &ctx->Q, ( nbits + 1 ) >> 1, 0,
|
||||
ctx->f_rng, ctx->p_rng ) );
|
||||
|
||||
if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
|
||||
mpi_swap( &ctx->P, &ctx->Q );
|
||||
|
||||
if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
|
||||
continue;
|
||||
|
||||
MPI_CHK( mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
|
||||
if( mpi_msb( &ctx->N ) != nbits )
|
||||
continue;
|
||||
|
||||
MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
|
||||
MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
|
||||
MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
|
||||
MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) );
|
||||
}
|
||||
while( mpi_cmp_int( &G, 1 ) != 0 );
|
||||
|
||||
/*
|
||||
* D = E^-1 mod ((P-1)*(Q-1))
|
||||
* DP = D mod (P - 1)
|
||||
* DQ = D mod (Q - 1)
|
||||
* QP = Q^-1 mod P
|
||||
*/
|
||||
MPI_CHK( mpi_inv_mod( &ctx->D , &ctx->E, &H ) );
|
||||
MPI_CHK( mpi_mod_mpi( &ctx->DP, &ctx->D, &P1 ) );
|
||||
MPI_CHK( mpi_mod_mpi( &ctx->DQ, &ctx->D, &Q1 ) );
|
||||
MPI_CHK( mpi_inv_mod( &ctx->QP, &ctx->Q, &ctx->P ) );
|
||||
|
||||
ctx->len = ( mpi_msb( &ctx->N ) + 7 ) >> 3;
|
||||
|
||||
cleanup:
|
||||
|
||||
mpi_free( &G, &H, &Q1, &P1, NULL );
|
||||
|
||||
if( ret != 0 )
|
||||
{
|
||||
rsa_free( ctx );
|
||||
return( POLARSSL_ERR_RSA_KEY_GEN_FAILED | ret );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check a public RSA key
|
||||
*/
|
||||
int rsa_check_pubkey( rsa_context *ctx )
|
||||
{
|
||||
if( ( ctx->N.p[0] & 1 ) == 0 ||
|
||||
( ctx->E.p[0] & 1 ) == 0 )
|
||||
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
|
||||
|
||||
if( mpi_msb( &ctx->N ) < 128 ||
|
||||
mpi_msb( &ctx->N ) > 4096 )
|
||||
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
|
||||
|
||||
if( mpi_msb( &ctx->E ) < 2 ||
|
||||
mpi_msb( &ctx->E ) > 64 )
|
||||
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Check a private RSA key
|
||||
*/
|
||||
int rsa_check_privkey( rsa_context *ctx )
|
||||
{
|
||||
int ret;
|
||||
mpi PQ, DE, P1, Q1, H, I, G;
|
||||
|
||||
if( ( ret = rsa_check_pubkey( ctx ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
mpi_init( &PQ, &DE, &P1, &Q1, &H, &I, &G, NULL );
|
||||
|
||||
MPI_CHK( mpi_mul_mpi( &PQ, &ctx->P, &ctx->Q ) );
|
||||
MPI_CHK( mpi_mul_mpi( &DE, &ctx->D, &ctx->E ) );
|
||||
MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
|
||||
MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
|
||||
MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
|
||||
MPI_CHK( mpi_mod_mpi( &I, &DE, &H ) );
|
||||
MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) );
|
||||
|
||||
if( mpi_cmp_mpi( &PQ, &ctx->N ) == 0 &&
|
||||
mpi_cmp_int( &I, 1 ) == 0 &&
|
||||
mpi_cmp_int( &G, 1 ) == 0 )
|
||||
{
|
||||
mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, NULL );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, NULL );
|
||||
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED | ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Do an RSA public key operation
|
||||
*/
|
||||
int rsa_public( rsa_context *ctx,
|
||||
unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
int ret, olen;
|
||||
mpi T;
|
||||
|
||||
mpi_init( &T, NULL );
|
||||
|
||||
MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
|
||||
|
||||
if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
|
||||
{
|
||||
mpi_free( &T, NULL );
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
olen = ctx->len;
|
||||
MPI_CHK( mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
|
||||
MPI_CHK( mpi_write_binary( &T, output, olen ) );
|
||||
|
||||
cleanup:
|
||||
|
||||
mpi_free( &T, NULL );
|
||||
|
||||
if( ret != 0 )
|
||||
return( POLARSSL_ERR_RSA_PUBLIC_FAILED | ret );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Do an RSA private key operation
|
||||
*/
|
||||
int rsa_private( rsa_context *ctx,
|
||||
unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
int ret, olen;
|
||||
mpi T, T1, T2;
|
||||
|
||||
mpi_init( &T, &T1, &T2, NULL );
|
||||
|
||||
MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
|
||||
|
||||
if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
|
||||
{
|
||||
mpi_free( &T, NULL );
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
#if 0
|
||||
MPI_CHK( mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) );
|
||||
#else
|
||||
/*
|
||||
* faster decryption using the CRT
|
||||
*
|
||||
* T1 = input ^ dP mod P
|
||||
* T2 = input ^ dQ mod Q
|
||||
*/
|
||||
MPI_CHK( mpi_exp_mod( &T1, &T, &ctx->DP, &ctx->P, &ctx->RP ) );
|
||||
MPI_CHK( mpi_exp_mod( &T2, &T, &ctx->DQ, &ctx->Q, &ctx->RQ ) );
|
||||
|
||||
/*
|
||||
* T = (T1 - T2) * (Q^-1 mod P) mod P
|
||||
*/
|
||||
MPI_CHK( mpi_sub_mpi( &T, &T1, &T2 ) );
|
||||
MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->QP ) );
|
||||
MPI_CHK( mpi_mod_mpi( &T, &T1, &ctx->P ) );
|
||||
|
||||
/*
|
||||
* output = T2 + T * Q
|
||||
*/
|
||||
MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->Q ) );
|
||||
MPI_CHK( mpi_add_mpi( &T, &T2, &T1 ) );
|
||||
#endif
|
||||
|
||||
olen = ctx->len;
|
||||
MPI_CHK( mpi_write_binary( &T, output, olen ) );
|
||||
|
||||
cleanup:
|
||||
|
||||
mpi_free( &T, &T1, &T2, NULL );
|
||||
|
||||
if( ret != 0 )
|
||||
return( POLARSSL_ERR_RSA_PRIVATE_FAILED | ret );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the message padding, then do an RSA operation
|
||||
*/
|
||||
int rsa_pkcs1_encrypt( rsa_context *ctx,
|
||||
int mode, int ilen,
|
||||
unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
int nb_pad, olen;
|
||||
unsigned char *p = output;
|
||||
|
||||
olen = ctx->len;
|
||||
|
||||
switch( ctx->padding )
|
||||
{
|
||||
case RSA_PKCS_V15:
|
||||
|
||||
if( ilen < 0 || olen < ilen + 11 )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
nb_pad = olen - 3 - ilen;
|
||||
|
||||
*p++ = 0;
|
||||
*p++ = RSA_CRYPT;
|
||||
|
||||
while( nb_pad-- > 0 )
|
||||
{
|
||||
do {
|
||||
*p = (unsigned char) rand();
|
||||
} while( *p == 0 );
|
||||
p++;
|
||||
}
|
||||
*p++ = 0;
|
||||
memcpy( p, input, ilen );
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
}
|
||||
|
||||
return( ( mode == RSA_PUBLIC )
|
||||
? rsa_public( ctx, output, output )
|
||||
: rsa_private( ctx, output, output ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Do an RSA operation, then remove the message padding
|
||||
*/
|
||||
int rsa_pkcs1_decrypt( rsa_context *ctx,
|
||||
int mode, int *olen,
|
||||
unsigned char *input,
|
||||
unsigned char *output,
|
||||
int output_max_len)
|
||||
{
|
||||
int ret, ilen;
|
||||
unsigned char *p;
|
||||
unsigned char buf[512];
|
||||
|
||||
ilen = ctx->len;
|
||||
|
||||
if( ilen < 16 || ilen > (int) sizeof( buf ) )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
ret = ( mode == RSA_PUBLIC )
|
||||
? rsa_public( ctx, input, buf )
|
||||
: rsa_private( ctx, input, buf );
|
||||
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
p = buf;
|
||||
|
||||
switch( ctx->padding )
|
||||
{
|
||||
case RSA_PKCS_V15:
|
||||
|
||||
if( *p++ != 0 || *p++ != RSA_CRYPT )
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
|
||||
while( *p != 0 )
|
||||
{
|
||||
if( p >= buf + ilen - 1 )
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
p++;
|
||||
}
|
||||
p++;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
}
|
||||
|
||||
if (ilen - (int)(p - buf) > output_max_len)
|
||||
return( POLARSSL_ERR_RSA_OUTPUT_TO_LARGE );
|
||||
|
||||
*olen = ilen - (int)(p - buf);
|
||||
memcpy( output, p, *olen );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Do an RSA operation to sign the message digest
|
||||
*/
|
||||
int rsa_pkcs1_sign( rsa_context *ctx,
|
||||
int mode,
|
||||
int hash_id,
|
||||
int hashlen,
|
||||
unsigned char *hash,
|
||||
unsigned char *sig )
|
||||
{
|
||||
int nb_pad, olen;
|
||||
unsigned char *p = sig;
|
||||
|
||||
olen = ctx->len;
|
||||
|
||||
switch( ctx->padding )
|
||||
{
|
||||
case RSA_PKCS_V15:
|
||||
|
||||
switch( hash_id )
|
||||
{
|
||||
case RSA_RAW:
|
||||
nb_pad = olen - 3 - hashlen;
|
||||
break;
|
||||
|
||||
case RSA_MD2:
|
||||
case RSA_MD4:
|
||||
case RSA_MD5:
|
||||
nb_pad = olen - 3 - 34;
|
||||
break;
|
||||
|
||||
case RSA_SHA1:
|
||||
nb_pad = olen - 3 - 35;
|
||||
break;
|
||||
|
||||
default:
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
if( nb_pad < 8 )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
*p++ = 0;
|
||||
*p++ = RSA_SIGN;
|
||||
memset( p, 0xFF, nb_pad );
|
||||
p += nb_pad;
|
||||
*p++ = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
}
|
||||
|
||||
switch( hash_id )
|
||||
{
|
||||
case RSA_RAW:
|
||||
memcpy( p, hash, hashlen );
|
||||
break;
|
||||
|
||||
case RSA_MD2:
|
||||
memcpy( p, ASN1_HASH_MDX, 18 );
|
||||
memcpy( p + 18, hash, 16 );
|
||||
p[13] = 2; break;
|
||||
|
||||
case RSA_MD4:
|
||||
memcpy( p, ASN1_HASH_MDX, 18 );
|
||||
memcpy( p + 18, hash, 16 );
|
||||
p[13] = 4; break;
|
||||
|
||||
case RSA_MD5:
|
||||
memcpy( p, ASN1_HASH_MDX, 18 );
|
||||
memcpy( p + 18, hash, 16 );
|
||||
p[13] = 5; break;
|
||||
|
||||
case RSA_SHA1:
|
||||
memcpy( p, ASN1_HASH_SHA1, 15 );
|
||||
memcpy( p + 15, hash, 20 );
|
||||
break;
|
||||
|
||||
default:
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
return( ( mode == RSA_PUBLIC )
|
||||
? rsa_public( ctx, sig, sig )
|
||||
: rsa_private( ctx, sig, sig ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Do an RSA operation and check the message digest
|
||||
*/
|
||||
int rsa_pkcs1_verify( rsa_context *ctx,
|
||||
int mode,
|
||||
int hash_id,
|
||||
int hashlen,
|
||||
unsigned char *hash,
|
||||
unsigned char *sig )
|
||||
{
|
||||
int ret, len, siglen;
|
||||
unsigned char *p, c;
|
||||
unsigned char buf[512];
|
||||
|
||||
siglen = ctx->len;
|
||||
|
||||
if( siglen < 16 || siglen > (int) sizeof( buf ) )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
ret = ( mode == RSA_PUBLIC )
|
||||
? rsa_public( ctx, sig, buf )
|
||||
: rsa_private( ctx, sig, buf );
|
||||
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
p = buf;
|
||||
|
||||
switch( ctx->padding )
|
||||
{
|
||||
case RSA_PKCS_V15:
|
||||
|
||||
if( *p++ != 0 || *p++ != RSA_SIGN )
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
|
||||
while( *p != 0 )
|
||||
{
|
||||
if( p >= buf + siglen - 1 || *p != 0xFF )
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
p++;
|
||||
}
|
||||
p++;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
}
|
||||
|
||||
len = siglen - (int)( p - buf );
|
||||
|
||||
if( len == 34 )
|
||||
{
|
||||
c = p[13];
|
||||
p[13] = 0;
|
||||
|
||||
if( memcmp( p, ASN1_HASH_MDX, 18 ) != 0 )
|
||||
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||
|
||||
if( ( c == 2 && hash_id == RSA_MD2 ) ||
|
||||
( c == 4 && hash_id == RSA_MD4 ) ||
|
||||
( c == 5 && hash_id == RSA_MD5 ) )
|
||||
{
|
||||
if( memcmp( p + 18, hash, 16 ) == 0 )
|
||||
return( 0 );
|
||||
else
|
||||
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||
}
|
||||
}
|
||||
|
||||
if( len == 35 && hash_id == RSA_SHA1 )
|
||||
{
|
||||
if( memcmp( p, ASN1_HASH_SHA1, 15 ) == 0 &&
|
||||
memcmp( p + 15, hash, 20 ) == 0 )
|
||||
return( 0 );
|
||||
else
|
||||
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||
}
|
||||
|
||||
if( len == hashlen && hash_id == RSA_RAW )
|
||||
{
|
||||
if( memcmp( p, hash, hashlen ) == 0 )
|
||||
return( 0 );
|
||||
else
|
||||
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||
}
|
||||
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the components of an RSA key
|
||||
*/
|
||||
void rsa_free( rsa_context *ctx )
|
||||
{
|
||||
mpi_free( &ctx->RQ, &ctx->RP, &ctx->RN,
|
||||
&ctx->QP, &ctx->DQ, &ctx->DP,
|
||||
&ctx->Q, &ctx->P, &ctx->D,
|
||||
&ctx->E, &ctx->N, NULL );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_SELF_TEST)
|
||||
|
||||
#include "polarssl/sha1.h"
|
||||
|
||||
/*
|
||||
* Example RSA-1024 keypair, for test purposes
|
||||
*/
|
||||
#define KEY_LEN 128
|
||||
|
||||
#define RSA_N "9292758453063D803DD603D5E777D788" \
|
||||
"8ED1D5BF35786190FA2F23EBC0848AEA" \
|
||||
"DDA92CA6C3D80B32C4D109BE0F36D6AE" \
|
||||
"7130B9CED7ACDF54CFC7555AC14EEBAB" \
|
||||
"93A89813FBF3C4F8066D2D800F7C38A8" \
|
||||
"1AE31942917403FF4946B0A83D3D3E05" \
|
||||
"EE57C6F5F5606FB5D4BC6CD34EE0801A" \
|
||||
"5E94BB77B07507233A0BC7BAC8F90F79"
|
||||
|
||||
#define RSA_E "10001"
|
||||
|
||||
#define RSA_D "24BF6185468786FDD303083D25E64EFC" \
|
||||
"66CA472BC44D253102F8B4A9D3BFA750" \
|
||||
"91386C0077937FE33FA3252D28855837" \
|
||||
"AE1B484A8A9A45F7EE8C0C634F99E8CD" \
|
||||
"DF79C5CE07EE72C7F123142198164234" \
|
||||
"CABB724CF78B8173B9F880FC86322407" \
|
||||
"AF1FEDFDDE2BEB674CA15F3E81A1521E" \
|
||||
"071513A1E85B5DFA031F21ECAE91A34D"
|
||||
|
||||
#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
|
||||
"2C01CAD19EA484A87EA4377637E75500" \
|
||||
"FCB2005C5C7DD6EC4AC023CDA285D796" \
|
||||
"C3D9E75E1EFC42488BB4F1D13AC30A57"
|
||||
|
||||
#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
|
||||
"E211C2B9E5DB1ED0BF61D0D9899620F4" \
|
||||
"910E4168387E3C30AA1E00C339A79508" \
|
||||
"8452DD96A9A5EA5D9DCA68DA636032AF"
|
||||
|
||||
#define RSA_DP "C1ACF567564274FB07A0BBAD5D26E298" \
|
||||
"3C94D22288ACD763FD8E5600ED4A702D" \
|
||||
"F84198A5F06C2E72236AE490C93F07F8" \
|
||||
"3CC559CD27BC2D1CA488811730BB5725"
|
||||
|
||||
#define RSA_DQ "4959CBF6F8FEF750AEE6977C155579C7" \
|
||||
"D8AAEA56749EA28623272E4F7D0592AF" \
|
||||
"7C1F1313CAC9471B5C523BFE592F517B" \
|
||||
"407A1BD76C164B93DA2D32A383E58357"
|
||||
|
||||
#define RSA_QP "9AE7FBC99546432DF71896FC239EADAE" \
|
||||
"F38D18D2B2F0E2DD275AA977E2BF4411" \
|
||||
"F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \
|
||||
"A74206CEC169D74BF5A8C50D6F48EA08"
|
||||
|
||||
#define PT_LEN 24
|
||||
#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
|
||||
"\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
|
||||
|
||||
/*
|
||||
* Checkup routine
|
||||
*/
|
||||
int rsa_self_test( int verbose )
|
||||
{
|
||||
int len;
|
||||
rsa_context rsa;
|
||||
unsigned char sha1sum[20];
|
||||
unsigned char rsa_plaintext[PT_LEN];
|
||||
unsigned char rsa_decrypted[PT_LEN];
|
||||
unsigned char rsa_ciphertext[KEY_LEN];
|
||||
|
||||
memset( &rsa, 0, sizeof( rsa_context ) );
|
||||
|
||||
rsa.len = KEY_LEN;
|
||||
mpi_read_string( &rsa.N , 16, RSA_N );
|
||||
mpi_read_string( &rsa.E , 16, RSA_E );
|
||||
mpi_read_string( &rsa.D , 16, RSA_D );
|
||||
mpi_read_string( &rsa.P , 16, RSA_P );
|
||||
mpi_read_string( &rsa.Q , 16, RSA_Q );
|
||||
mpi_read_string( &rsa.DP, 16, RSA_DP );
|
||||
mpi_read_string( &rsa.DQ, 16, RSA_DQ );
|
||||
mpi_read_string( &rsa.QP, 16, RSA_QP );
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( " RSA key validation: " );
|
||||
|
||||
if( rsa_check_pubkey( &rsa ) != 0 ||
|
||||
rsa_check_privkey( &rsa ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "passed\n PKCS#1 encryption : " );
|
||||
|
||||
memcpy( rsa_plaintext, RSA_PT, PT_LEN );
|
||||
|
||||
if( rsa_pkcs1_encrypt( &rsa, RSA_PUBLIC, PT_LEN,
|
||||
rsa_plaintext, rsa_ciphertext ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "passed\n PKCS#1 decryption : " );
|
||||
|
||||
if( rsa_pkcs1_decrypt( &rsa, RSA_PRIVATE, &len,
|
||||
rsa_ciphertext, rsa_decrypted,
|
||||
sizeof(rsa_decrypted) ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "passed\n PKCS#1 data sign : " );
|
||||
|
||||
sha1( rsa_plaintext, PT_LEN, sha1sum );
|
||||
|
||||
if( rsa_pkcs1_sign( &rsa, RSA_PRIVATE, RSA_SHA1, 20,
|
||||
sha1sum, rsa_ciphertext ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "passed\n PKCS#1 sig. verify: " );
|
||||
|
||||
if( rsa_pkcs1_verify( &rsa, RSA_PUBLIC, RSA_SHA1, 20,
|
||||
sha1sum, rsa_ciphertext ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
printf( "passed\n\n" );
|
||||
|
||||
rsa_free( &rsa );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,622 @@
|
|||
/*
|
||||
* FIPS-180-1 compliant SHA-1 implementation
|
||||
*
|
||||
* Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
|
||||
*
|
||||
* Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the names of PolarSSL or XySSL nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* 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"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* 32-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
#ifndef GET_ULONG_BE
|
||||
#define GET_ULONG_BE(n,b,i) \
|
||||
{ \
|
||||
(n) = ( (unsigned long) (b)[(i) ] << 24 ) \
|
||||
| ( (unsigned long) (b)[(i) + 1] << 16 ) \
|
||||
| ( (unsigned long) (b)[(i) + 2] << 8 ) \
|
||||
| ( (unsigned long) (b)[(i) + 3] ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PUT_ULONG_BE
|
||||
#define PUT_ULONG_BE(n,b,i) \
|
||||
{ \
|
||||
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SHA-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;
|
||||
}
|
||||
|
||||
static void sha1_process( sha1_context *ctx, unsigned char data[64] )
|
||||
{
|
||||
unsigned long temp, W[16], A, B, C, D, E;
|
||||
|
||||
GET_ULONG_BE( W[ 0], data, 0 );
|
||||
GET_ULONG_BE( W[ 1], data, 4 );
|
||||
GET_ULONG_BE( W[ 2], data, 8 );
|
||||
GET_ULONG_BE( W[ 3], data, 12 );
|
||||
GET_ULONG_BE( W[ 4], data, 16 );
|
||||
GET_ULONG_BE( W[ 5], data, 20 );
|
||||
GET_ULONG_BE( W[ 6], data, 24 );
|
||||
GET_ULONG_BE( W[ 7], data, 28 );
|
||||
GET_ULONG_BE( W[ 8], data, 32 );
|
||||
GET_ULONG_BE( W[ 9], data, 36 );
|
||||
GET_ULONG_BE( W[10], data, 40 );
|
||||
GET_ULONG_BE( W[11], data, 44 );
|
||||
GET_ULONG_BE( W[12], data, 48 );
|
||||
GET_ULONG_BE( W[13], data, 52 );
|
||||
GET_ULONG_BE( W[14], data, 56 );
|
||||
GET_ULONG_BE( W[15], data, 60 );
|
||||
|
||||
#define 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, unsigned char *input, int ilen )
|
||||
{
|
||||
int fill;
|
||||
unsigned long left;
|
||||
|
||||
if( ilen <= 0 )
|
||||
return;
|
||||
|
||||
left = ctx->total[0] & 0x3F;
|
||||
fill = 64 - left;
|
||||
|
||||
ctx->total[0] += ilen;
|
||||
ctx->total[0] &= 0xFFFFFFFF;
|
||||
|
||||
if( ctx->total[0] < (unsigned long) ilen )
|
||||
ctx->total[1]++;
|
||||
|
||||
if( left && ilen >= fill )
|
||||
{
|
||||
memcpy( (void *) (ctx->buffer + left),
|
||||
(void *) input, fill );
|
||||
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),
|
||||
(void *) 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] )
|
||||
{
|
||||
unsigned long last, padn;
|
||||
unsigned long high, low;
|
||||
unsigned char msglen[8];
|
||||
|
||||
high = ( ctx->total[0] >> 29 )
|
||||
| ( ctx->total[1] << 3 );
|
||||
low = ( ctx->total[0] << 3 );
|
||||
|
||||
PUT_ULONG_BE( high, msglen, 0 );
|
||||
PUT_ULONG_BE( low, msglen, 4 );
|
||||
|
||||
last = ctx->total[0] & 0x3F;
|
||||
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
|
||||
|
||||
sha1_update( ctx, (unsigned char *) sha1_padding, padn );
|
||||
sha1_update( ctx, msglen, 8 );
|
||||
|
||||
PUT_ULONG_BE( ctx->state[0], output, 0 );
|
||||
PUT_ULONG_BE( ctx->state[1], output, 4 );
|
||||
PUT_ULONG_BE( ctx->state[2], output, 8 );
|
||||
PUT_ULONG_BE( ctx->state[3], output, 12 );
|
||||
PUT_ULONG_BE( ctx->state[4], output, 16 );
|
||||
}
|
||||
|
||||
/*
|
||||
* output = SHA-1( input buffer )
|
||||
*/
|
||||
void sha1( unsigned char *input, int 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 ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* output = SHA-1( file contents )
|
||||
*/
|
||||
int sha1_file( 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( 1 );
|
||||
|
||||
sha1_starts( &ctx );
|
||||
|
||||
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
|
||||
sha1_update( &ctx, buf, (int) n );
|
||||
|
||||
sha1_finish( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( sha1_context ) );
|
||||
|
||||
if( ferror( f ) != 0 )
|
||||
{
|
||||
fclose( f );
|
||||
return( 2 );
|
||||
}
|
||||
|
||||
fclose( f );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-1 HMAC context setup
|
||||
*/
|
||||
void sha1_hmac_starts( sha1_context *ctx, unsigned char *key, int keylen )
|
||||
{
|
||||
int 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, unsigned char *input, int 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 ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* output = HMAC-SHA-1( hmac key, input buffer )
|
||||
*/
|
||||
void sha1_hmac( unsigned char *key, int keylen,
|
||||
unsigned char *input, int 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
|
|
@ -0,0 +1,265 @@
|
|||
/*
|
||||
* Portable interface to the CPU cycle counter
|
||||
*
|
||||
* Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
|
||||
*
|
||||
* Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the names of PolarSSL or XySSL nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#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(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
|
||||
|
||||
unsigned long hardclock( void )
|
||||
{
|
||||
unsigned long tsc;
|
||||
__asm rdtsc
|
||||
__asm mov [tsc], eax
|
||||
return( tsc );
|
||||
}
|
||||
|
||||
#else
|
||||
#if defined(__GNUC__) && defined(__i386__)
|
||||
|
||||
unsigned long hardclock( void )
|
||||
{
|
||||
unsigned long tsc;
|
||||
asm( "rdtsc" : "=a" (tsc) );
|
||||
return( tsc );
|
||||
}
|
||||
|
||||
#else
|
||||
#if defined(__GNUC__) && (defined(__amd64__) || defined(__x86_64__))
|
||||
|
||||
unsigned long hardclock( void )
|
||||
{
|
||||
unsigned long lo, hi;
|
||||
asm( "rdtsc" : "=a" (lo), "=d" (hi) );
|
||||
return( lo | (hi << 32) );
|
||||
}
|
||||
|
||||
#else
|
||||
#if defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
#else
|
||||
#if defined(__GNUC__) && defined(__sparc__)
|
||||
|
||||
unsigned long hardclock( void )
|
||||
{
|
||||
unsigned long tick;
|
||||
asm( ".byte 0x83, 0x41, 0x00, 0x00" );
|
||||
asm( "mov %%g1, %0" : "=r" (tick) );
|
||||
return( tick );
|
||||
}
|
||||
|
||||
#else
|
||||
#if defined(__GNUC__) && defined(__alpha__)
|
||||
|
||||
unsigned long hardclock( void )
|
||||
{
|
||||
unsigned long cc;
|
||||
asm( "rpcc %0" : "=r" (cc) );
|
||||
return( cc & 0xFFFFFFFF );
|
||||
}
|
||||
|
||||
#else
|
||||
#if defined(__GNUC__) && defined(__ia64__)
|
||||
|
||||
unsigned long hardclock( void )
|
||||
{
|
||||
unsigned long itc;
|
||||
asm( "mov %0 = ar.itc" : "=r" (itc) );
|
||||
return( itc );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
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 /* generic */
|
||||
#endif /* IA-64 */
|
||||
#endif /* Alpha */
|
||||
#endif /* SPARC8 */
|
||||
#endif /* PowerPC */
|
||||
#endif /* AMD64 */
|
||||
#endif /* i586+ */
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,93 @@
|
|||
/**
|
||||
* \file base64.h
|
||||
*
|
||||
* Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
|
||||
*
|
||||
* Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the names of PolarSSL or XySSL nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef POLARSSL_BASE64_H
|
||||
#define POLARSSL_BASE64_H
|
||||
|
||||
#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL -0x0010
|
||||
#define POLARSSL_ERR_BASE64_INVALID_CHARACTER -0x0012
|
||||
|
||||
#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, int *dlen,
|
||||
unsigned char *src, int 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_DATA 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, int *dlen,
|
||||
unsigned char *src, int 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 */
|
|
@ -0,0 +1,437 @@
|
|||
/**
|
||||
* \file bignum.h
|
||||
*
|
||||
* Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
|
||||
*
|
||||
* Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the names of PolarSSL or XySSL nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef POLARSSL_BIGNUM_H
|
||||
#define POLARSSL_BIGNUM_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define POLARSSL_ERR_MPI_FILE_IO_ERROR -0x0002
|
||||
#define POLARSSL_ERR_MPI_BAD_INPUT_DATA -0x0004
|
||||
#define POLARSSL_ERR_MPI_INVALID_CHARACTER -0x0006
|
||||
#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL -0x0008
|
||||
#define POLARSSL_ERR_MPI_NEGATIVE_VALUE -0x000A
|
||||
#define POLARSSL_ERR_MPI_DIVISION_BY_ZERO -0x000C
|
||||
#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE -0x000E
|
||||
|
||||
#define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup
|
||||
|
||||
/*
|
||||
* Define the base integer type, architecture-wise
|
||||
*/
|
||||
#if defined(POLARSSL_HAVE_INT8)
|
||||
typedef unsigned char t_int;
|
||||
typedef unsigned short t_dbl;
|
||||
#else
|
||||
#if defined(POLARSSL_HAVE_INT16)
|
||||
typedef unsigned short t_int;
|
||||
typedef unsigned long t_dbl;
|
||||
#else
|
||||
typedef unsigned long t_int;
|
||||
#if defined(_MSC_VER) && defined(_M_IX86)
|
||||
typedef unsigned __int64 t_dbl;
|
||||
#else
|
||||
#if defined(__amd64__) || defined(__x86_64__) || \
|
||||
defined(__ppc64__) || defined(__powerpc64__) || \
|
||||
defined(__ia64__) || defined(__alpha__)
|
||||
typedef unsigned int t_dbl __attribute__((mode(TI)));
|
||||
#else
|
||||
typedef unsigned long long t_dbl;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief MPI structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int s; /*!< integer sign */
|
||||
int n; /*!< total # of limbs */
|
||||
t_int *p; /*!< pointer to limbs */
|
||||
}
|
||||
mpi;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Initialize one or more mpi
|
||||
*/
|
||||
void mpi_init( mpi *X, ... );
|
||||
|
||||
/**
|
||||
* \brief Unallocate one or more mpi
|
||||
*/
|
||||
void mpi_free( mpi *X, ... );
|
||||
|
||||
/**
|
||||
* \brief Enlarge to the specified number of limbs
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* 1 if memory allocation failed
|
||||
*/
|
||||
int mpi_grow( mpi *X, int nblimbs );
|
||||
|
||||
/**
|
||||
* \brief Copy the contents of Y into X
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* 1 if memory allocation failed
|
||||
*/
|
||||
int mpi_copy( mpi *X, mpi *Y );
|
||||
|
||||
/**
|
||||
* \brief Swap the contents of X and Y
|
||||
*/
|
||||
void mpi_swap( mpi *X, mpi *Y );
|
||||
|
||||
/**
|
||||
* \brief Set value from integer
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* 1 if memory allocation failed
|
||||
*/
|
||||
int mpi_lset( mpi *X, int z );
|
||||
|
||||
/**
|
||||
* \brief Return the number of least significant bits
|
||||
*/
|
||||
int mpi_lsb( mpi *X );
|
||||
|
||||
/**
|
||||
* \brief Return the number of most significant bits
|
||||
*/
|
||||
int mpi_msb( mpi *X );
|
||||
|
||||
/**
|
||||
* \brief Return the total size in bytes
|
||||
*/
|
||||
int mpi_size( mpi *X );
|
||||
|
||||
/**
|
||||
* \brief Import from an ASCII string
|
||||
*
|
||||
* \param X destination mpi
|
||||
* \param radix input numeric base
|
||||
* \param s null-terminated string buffer
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
|
||||
*/
|
||||
int mpi_read_string( mpi *X, int radix, char *s );
|
||||
|
||||
/**
|
||||
* \brief Export into an ASCII string
|
||||
*
|
||||
* \param X source mpi
|
||||
* \param radix output numeric base
|
||||
* \param s string buffer
|
||||
* \param slen string buffer size
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
|
||||
*
|
||||
* \note Call this function with *slen = 0 to obtain the
|
||||
* minimum required buffer size in *slen.
|
||||
*/
|
||||
int mpi_write_string( mpi *X, int radix, char *s, int *slen );
|
||||
|
||||
/**
|
||||
* \brief Read X from an opened file
|
||||
*
|
||||
* \param X destination mpi
|
||||
* \param radix input numeric base
|
||||
* \param fin input file handle
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
|
||||
*/
|
||||
int mpi_read_file( mpi *X, int radix, FILE *fin );
|
||||
|
||||
/**
|
||||
* \brief Write X into an opened file, or stdout
|
||||
*
|
||||
* \param p prefix, can be NULL
|
||||
* \param X source mpi
|
||||
* \param radix output numeric base
|
||||
* \param fout output file handle
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
|
||||
*
|
||||
* \note Set fout == NULL to print X on the console.
|
||||
*/
|
||||
int mpi_write_file( char *p, mpi *X, int radix, FILE *fout );
|
||||
|
||||
/**
|
||||
* \brief Import X from unsigned binary data, big endian
|
||||
*
|
||||
* \param X destination mpi
|
||||
* \param buf input buffer
|
||||
* \param buflen input buffer size
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* 1 if memory allocation failed
|
||||
*/
|
||||
int mpi_read_binary( mpi *X, unsigned char *buf, int buflen );
|
||||
|
||||
/**
|
||||
* \brief Export X into unsigned binary data, big endian
|
||||
*
|
||||
* \param X source mpi
|
||||
* \param buf output buffer
|
||||
* \param buflen output buffer size
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough
|
||||
*
|
||||
* \note Call this function with *buflen = 0 to obtain the
|
||||
* minimum required buffer size in *buflen.
|
||||
*/
|
||||
int mpi_write_binary( mpi *X, unsigned char *buf, int buflen );
|
||||
|
||||
/**
|
||||
* \brief Left-shift: X <<= count
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* 1 if memory allocation failed
|
||||
*/
|
||||
int mpi_shift_l( mpi *X, int count );
|
||||
|
||||
/**
|
||||
* \brief Right-shift: X >>= count
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* 1 if memory allocation failed
|
||||
*/
|
||||
int mpi_shift_r( mpi *X, int count );
|
||||
|
||||
/**
|
||||
* \brief Compare unsigned values
|
||||
*
|
||||
* \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( mpi *X, mpi *Y );
|
||||
|
||||
/**
|
||||
* \brief Compare signed values
|
||||
*
|
||||
* \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( mpi *X, mpi *Y );
|
||||
|
||||
/**
|
||||
* \brief Compare signed values
|
||||
*
|
||||
* \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( mpi *X, int z );
|
||||
|
||||
/**
|
||||
* \brief Unsigned addition: X = |A| + |B|
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* 1 if memory allocation failed
|
||||
*/
|
||||
int mpi_add_abs( mpi *X, mpi *A, mpi *B );
|
||||
|
||||
/**
|
||||
* \brief Unsigned substraction: X = |A| - |B|
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* POLARSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A
|
||||
*/
|
||||
int mpi_sub_abs( mpi *X, mpi *A, mpi *B );
|
||||
|
||||
/**
|
||||
* \brief Signed addition: X = A + B
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* 1 if memory allocation failed
|
||||
*/
|
||||
int mpi_add_mpi( mpi *X, mpi *A, mpi *B );
|
||||
|
||||
/**
|
||||
* \brief Signed substraction: X = A - B
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* 1 if memory allocation failed
|
||||
*/
|
||||
int mpi_sub_mpi( mpi *X, mpi *A, mpi *B );
|
||||
|
||||
/**
|
||||
* \brief Signed addition: X = A + b
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* 1 if memory allocation failed
|
||||
*/
|
||||
int mpi_add_int( mpi *X, mpi *A, int b );
|
||||
|
||||
/**
|
||||
* \brief Signed substraction: X = A - b
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* 1 if memory allocation failed
|
||||
*/
|
||||
int mpi_sub_int( mpi *X, mpi *A, int b );
|
||||
|
||||
/**
|
||||
* \brief Baseline multiplication: X = A * B
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* 1 if memory allocation failed
|
||||
*/
|
||||
int mpi_mul_mpi( mpi *X, mpi *A, mpi *B );
|
||||
|
||||
/**
|
||||
* \brief Baseline multiplication: X = A * b
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* 1 if memory allocation failed
|
||||
*/
|
||||
int mpi_mul_int( mpi *X, mpi *A, t_int b );
|
||||
|
||||
/**
|
||||
* \brief Division by mpi: A = Q * B + R
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* 1 if memory allocation failed,
|
||||
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0
|
||||
*
|
||||
* \note Either Q or R can be NULL.
|
||||
*/
|
||||
int mpi_div_mpi( mpi *Q, mpi *R, mpi *A, mpi *B );
|
||||
|
||||
/**
|
||||
* \brief Division by int: A = Q * b + R
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* 1 if memory allocation failed,
|
||||
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
|
||||
*
|
||||
* \note Either Q or R can be NULL.
|
||||
*/
|
||||
int mpi_div_int( mpi *Q, mpi *R, mpi *A, int b );
|
||||
|
||||
/**
|
||||
* \brief Modulo: R = A mod B
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* 1 if memory allocation failed,
|
||||
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0
|
||||
*/
|
||||
int mpi_mod_mpi( mpi *R, mpi *A, mpi *B );
|
||||
|
||||
/**
|
||||
* \brief Modulo: r = A mod b
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* 1 if memory allocation failed,
|
||||
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
|
||||
*/
|
||||
int mpi_mod_int( t_int *r, mpi *A, int b );
|
||||
|
||||
/**
|
||||
* \brief Sliding-window exponentiation: X = A^E mod N
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* 1 if memory allocation failed,
|
||||
* POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even
|
||||
*
|
||||
* \note _RR is used to avoid re-computing R*R mod N across
|
||||
* multiple calls, which speeds up things a bit. It can
|
||||
* be set to NULL if the extra performance is unneeded.
|
||||
*/
|
||||
int mpi_exp_mod( mpi *X, mpi *A, mpi *E, mpi *N, mpi *_RR );
|
||||
|
||||
/**
|
||||
* \brief Greatest common divisor: G = gcd(A, B)
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* 1 if memory allocation failed
|
||||
*/
|
||||
int mpi_gcd( mpi *G, mpi *A, mpi *B );
|
||||
|
||||
/**
|
||||
* \brief Modular inverse: X = A^-1 mod N
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* 1 if memory allocation failed,
|
||||
* POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil
|
||||
* POLARSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N
|
||||
*/
|
||||
int mpi_inv_mod( mpi *X, mpi *A, mpi *N );
|
||||
|
||||
/**
|
||||
* \brief Miller-Rabin primality test
|
||||
*
|
||||
* \return 0 if successful (probably prime),
|
||||
* 1 if memory allocation failed,
|
||||
* POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime
|
||||
*/
|
||||
int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng );
|
||||
|
||||
/**
|
||||
* \brief Prime number generation
|
||||
*
|
||||
* \param X destination mpi
|
||||
* \param nbits required size of X in bits
|
||||
* \param dh_flag if 1, then (X-1)/2 will be prime too
|
||||
* \param f_rng RNG function
|
||||
* \param p_rng RNG parameter
|
||||
*
|
||||
* \return 0 if successful (probably prime),
|
||||
* 1 if memory allocation failed,
|
||||
* POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
|
||||
*/
|
||||
int mpi_gen_prime( mpi *X, int nbits, int dh_flag,
|
||||
int (*f_rng)(void *), void *p_rng );
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int mpi_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* bignum.h */
|
|
@ -0,0 +1,731 @@
|
|||
/**
|
||||
* \file bn_mul.h
|
||||
*
|
||||
* Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
|
||||
*
|
||||
* Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the names of PolarSSL or XySSL nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* 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/config.h"
|
||||
|
||||
#if defined(POLARSSL_HAVE_ASM)
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#if defined(__i386__)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
asm( "movl %%ebx, %0 " : "=m" (t)); \
|
||||
asm( "movl %0, %%esi " :: "m" (s)); \
|
||||
asm( "movl %0, %%edi " :: "m" (d)); \
|
||||
asm( "movl %0, %%ecx " :: "m" (c)); \
|
||||
asm( "movl %0, %%ebx " :: "m" (b));
|
||||
|
||||
#define MULADDC_CORE \
|
||||
asm( "lodsl " ); \
|
||||
asm( "mull %ebx " ); \
|
||||
asm( "addl %ecx, %eax " ); \
|
||||
asm( "adcl $0, %edx " ); \
|
||||
asm( "addl (%edi), %eax " ); \
|
||||
asm( "adcl $0, %edx " ); \
|
||||
asm( "movl %edx, %ecx " ); \
|
||||
asm( "stosl " );
|
||||
|
||||
#if defined(POLARSSL_HAVE_SSE2)
|
||||
|
||||
#define MULADDC_HUIT \
|
||||
asm( "movd %ecx, %mm1 " ); \
|
||||
asm( "movd %ebx, %mm0 " ); \
|
||||
asm( "movd (%edi), %mm3 " ); \
|
||||
asm( "paddq %mm3, %mm1 " ); \
|
||||
asm( "movd (%esi), %mm2 " ); \
|
||||
asm( "pmuludq %mm0, %mm2 " ); \
|
||||
asm( "movd 4(%esi), %mm4 " ); \
|
||||
asm( "pmuludq %mm0, %mm4 " ); \
|
||||
asm( "movd 8(%esi), %mm6 " ); \
|
||||
asm( "pmuludq %mm0, %mm6 " ); \
|
||||
asm( "movd 12(%esi), %mm7 " ); \
|
||||
asm( "pmuludq %mm0, %mm7 " ); \
|
||||
asm( "paddq %mm2, %mm1 " ); \
|
||||
asm( "movd 4(%edi), %mm3 " ); \
|
||||
asm( "paddq %mm4, %mm3 " ); \
|
||||
asm( "movd 8(%edi), %mm5 " ); \
|
||||
asm( "paddq %mm6, %mm5 " ); \
|
||||
asm( "movd 12(%edi), %mm4 " ); \
|
||||
asm( "paddq %mm4, %mm7 " ); \
|
||||
asm( "movd %mm1, (%edi) " ); \
|
||||
asm( "movd 16(%esi), %mm2 " ); \
|
||||
asm( "pmuludq %mm0, %mm2 " ); \
|
||||
asm( "psrlq $32, %mm1 " ); \
|
||||
asm( "movd 20(%esi), %mm4 " ); \
|
||||
asm( "pmuludq %mm0, %mm4 " ); \
|
||||
asm( "paddq %mm3, %mm1 " ); \
|
||||
asm( "movd 24(%esi), %mm6 " ); \
|
||||
asm( "pmuludq %mm0, %mm6 " ); \
|
||||
asm( "movd %mm1, 4(%edi) " ); \
|
||||
asm( "psrlq $32, %mm1 " ); \
|
||||
asm( "movd 28(%esi), %mm3 " ); \
|
||||
asm( "pmuludq %mm0, %mm3 " ); \
|
||||
asm( "paddq %mm5, %mm1 " ); \
|
||||
asm( "movd 16(%edi), %mm5 " ); \
|
||||
asm( "paddq %mm5, %mm2 " ); \
|
||||
asm( "movd %mm1, 8(%edi) " ); \
|
||||
asm( "psrlq $32, %mm1 " ); \
|
||||
asm( "paddq %mm7, %mm1 " ); \
|
||||
asm( "movd 20(%edi), %mm5 " ); \
|
||||
asm( "paddq %mm5, %mm4 " ); \
|
||||
asm( "movd %mm1, 12(%edi) " ); \
|
||||
asm( "psrlq $32, %mm1 " ); \
|
||||
asm( "paddq %mm2, %mm1 " ); \
|
||||
asm( "movd 24(%edi), %mm5 " ); \
|
||||
asm( "paddq %mm5, %mm6 " ); \
|
||||
asm( "movd %mm1, 16(%edi) " ); \
|
||||
asm( "psrlq $32, %mm1 " ); \
|
||||
asm( "paddq %mm4, %mm1 " ); \
|
||||
asm( "movd 28(%edi), %mm5 " ); \
|
||||
asm( "paddq %mm5, %mm3 " ); \
|
||||
asm( "movd %mm1, 20(%edi) " ); \
|
||||
asm( "psrlq $32, %mm1 " ); \
|
||||
asm( "paddq %mm6, %mm1 " ); \
|
||||
asm( "movd %mm1, 24(%edi) " ); \
|
||||
asm( "psrlq $32, %mm1 " ); \
|
||||
asm( "paddq %mm3, %mm1 " ); \
|
||||
asm( "movd %mm1, 28(%edi) " ); \
|
||||
asm( "addl $32, %edi " ); \
|
||||
asm( "addl $32, %esi " ); \
|
||||
asm( "psrlq $32, %mm1 " ); \
|
||||
asm( "movd %mm1, %ecx " );
|
||||
|
||||
#define MULADDC_STOP \
|
||||
asm( "emms " ); \
|
||||
asm( "movl %0, %%ebx " :: "m" (t)); \
|
||||
asm( "movl %%ecx, %0 " : "=m" (c)); \
|
||||
asm( "movl %%edi, %0 " : "=m" (d)); \
|
||||
asm( "movl %%esi, %0 " : "=m" (s) :: \
|
||||
"eax", "ecx", "edx", "esi", "edi" );
|
||||
|
||||
#else
|
||||
|
||||
#define MULADDC_STOP \
|
||||
asm( "movl %0, %%ebx " :: "m" (t)); \
|
||||
asm( "movl %%ecx, %0 " : "=m" (c)); \
|
||||
asm( "movl %%edi, %0 " : "=m" (d)); \
|
||||
asm( "movl %%esi, %0 " : "=m" (s) :: \
|
||||
"eax", "ecx", "edx", "esi", "edi" );
|
||||
|
||||
#endif /* SSE2 */
|
||||
#endif /* i386 */
|
||||
|
||||
#if defined(__amd64__) || defined (__x86_64__)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
asm( "movq %0, %%rsi " :: "m" (s)); \
|
||||
asm( "movq %0, %%rdi " :: "m" (d)); \
|
||||
asm( "movq %0, %%rcx " :: "m" (c)); \
|
||||
asm( "movq %0, %%rbx " :: "m" (b)); \
|
||||
asm( "xorq %r8, %r8 " );
|
||||
|
||||
#define MULADDC_CORE \
|
||||
asm( "movq (%rsi),%rax " ); \
|
||||
asm( "mulq %rbx " ); \
|
||||
asm( "addq $8, %rsi " ); \
|
||||
asm( "addq %rcx, %rax " ); \
|
||||
asm( "movq %r8, %rcx " ); \
|
||||
asm( "adcq $0, %rdx " ); \
|
||||
asm( "nop " ); \
|
||||
asm( "addq %rax, (%rdi) " ); \
|
||||
asm( "adcq %rdx, %rcx " ); \
|
||||
asm( "addq $8, %rdi " );
|
||||
|
||||
#define MULADDC_STOP \
|
||||
asm( "movq %%rcx, %0 " : "=m" (c)); \
|
||||
asm( "movq %%rdi, %0 " : "=m" (d)); \
|
||||
asm( "movq %%rsi, %0 " : "=m" (s) :: \
|
||||
"rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" );
|
||||
|
||||
#endif /* AMD64 */
|
||||
|
||||
#if defined(__mc68020__) || defined(__mcpu32__)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
asm( "movl %0, %%a2 " :: "m" (s)); \
|
||||
asm( "movl %0, %%a3 " :: "m" (d)); \
|
||||
asm( "movl %0, %%d3 " :: "m" (c)); \
|
||||
asm( "movl %0, %%d2 " :: "m" (b)); \
|
||||
asm( "moveq #0, %d0 " );
|
||||
|
||||
#define MULADDC_CORE \
|
||||
asm( "movel %a2@+, %d1 " ); \
|
||||
asm( "mulul %d2, %d4:%d1 " ); \
|
||||
asm( "addl %d3, %d1 " ); \
|
||||
asm( "addxl %d0, %d4 " ); \
|
||||
asm( "moveq #0, %d3 " ); \
|
||||
asm( "addl %d1, %a3@+ " ); \
|
||||
asm( "addxl %d4, %d3 " );
|
||||
|
||||
#define MULADDC_STOP \
|
||||
asm( "movl %%d3, %0 " : "=m" (c)); \
|
||||
asm( "movl %%a3, %0 " : "=m" (d)); \
|
||||
asm( "movl %%a2, %0 " : "=m" (s) :: \
|
||||
"d0", "d1", "d2", "d3", "d4", "a2", "a3" );
|
||||
|
||||
#define MULADDC_HUIT \
|
||||
asm( "movel %a2@+, %d1 " ); \
|
||||
asm( "mulul %d2, %d4:%d1 " ); \
|
||||
asm( "addxl %d3, %d1 " ); \
|
||||
asm( "addxl %d0, %d4 " ); \
|
||||
asm( "addl %d1, %a3@+ " ); \
|
||||
asm( "movel %a2@+, %d1 " ); \
|
||||
asm( "mulul %d2, %d3:%d1 " ); \
|
||||
asm( "addxl %d4, %d1 " ); \
|
||||
asm( "addxl %d0, %d3 " ); \
|
||||
asm( "addl %d1, %a3@+ " ); \
|
||||
asm( "movel %a2@+, %d1 " ); \
|
||||
asm( "mulul %d2, %d4:%d1 " ); \
|
||||
asm( "addxl %d3, %d1 " ); \
|
||||
asm( "addxl %d0, %d4 " ); \
|
||||
asm( "addl %d1, %a3@+ " ); \
|
||||
asm( "movel %a2@+, %d1 " ); \
|
||||
asm( "mulul %d2, %d3:%d1 " ); \
|
||||
asm( "addxl %d4, %d1 " ); \
|
||||
asm( "addxl %d0, %d3 " ); \
|
||||
asm( "addl %d1, %a3@+ " ); \
|
||||
asm( "movel %a2@+, %d1 " ); \
|
||||
asm( "mulul %d2, %d4:%d1 " ); \
|
||||
asm( "addxl %d3, %d1 " ); \
|
||||
asm( "addxl %d0, %d4 " ); \
|
||||
asm( "addl %d1, %a3@+ " ); \
|
||||
asm( "movel %a2@+, %d1 " ); \
|
||||
asm( "mulul %d2, %d3:%d1 " ); \
|
||||
asm( "addxl %d4, %d1 " ); \
|
||||
asm( "addxl %d0, %d3 " ); \
|
||||
asm( "addl %d1, %a3@+ " ); \
|
||||
asm( "movel %a2@+, %d1 " ); \
|
||||
asm( "mulul %d2, %d4:%d1 " ); \
|
||||
asm( "addxl %d3, %d1 " ); \
|
||||
asm( "addxl %d0, %d4 " ); \
|
||||
asm( "addl %d1, %a3@+ " ); \
|
||||
asm( "movel %a2@+, %d1 " ); \
|
||||
asm( "mulul %d2, %d3:%d1 " ); \
|
||||
asm( "addxl %d4, %d1 " ); \
|
||||
asm( "addxl %d0, %d3 " ); \
|
||||
asm( "addl %d1, %a3@+ " ); \
|
||||
asm( "addxl %d0, %d3 " );
|
||||
|
||||
#endif /* MC68000 */
|
||||
|
||||
#if defined(__powerpc__) || defined(__ppc__)
|
||||
#if defined(__powerpc64__) || defined(__ppc64__)
|
||||
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
asm( "ld r3, %0 " :: "m" (s)); \
|
||||
asm( "ld r4, %0 " :: "m" (d)); \
|
||||
asm( "ld r5, %0 " :: "m" (c)); \
|
||||
asm( "ld r6, %0 " :: "m" (b)); \
|
||||
asm( "addi r3, r3, -8 " ); \
|
||||
asm( "addi r4, r4, -8 " ); \
|
||||
asm( "addic r5, r5, 0 " );
|
||||
|
||||
#define MULADDC_CORE \
|
||||
asm( "ldu r7, 8(r3) " ); \
|
||||
asm( "mulld r8, r7, r6 " ); \
|
||||
asm( "mulhdu r9, r7, r6 " ); \
|
||||
asm( "adde r8, r8, r5 " ); \
|
||||
asm( "ld r7, 8(r4) " ); \
|
||||
asm( "addze r5, r9 " ); \
|
||||
asm( "addc r8, r8, r7 " ); \
|
||||
asm( "stdu r8, 8(r4) " );
|
||||
|
||||
#define MULADDC_STOP \
|
||||
asm( "addze r5, r5 " ); \
|
||||
asm( "addi r4, r4, 8 " ); \
|
||||
asm( "addi r3, r3, 8 " ); \
|
||||
asm( "std r5, %0 " : "=m" (c)); \
|
||||
asm( "std r4, %0 " : "=m" (d)); \
|
||||
asm( "std r3, %0 " : "=m" (s) :: \
|
||||
"r3", "r4", "r5", "r6", "r7", "r8", "r9" );
|
||||
|
||||
#else
|
||||
|
||||
#define MULADDC_INIT \
|
||||
asm( "ld %%r3, %0 " :: "m" (s)); \
|
||||
asm( "ld %%r4, %0 " :: "m" (d)); \
|
||||
asm( "ld %%r5, %0 " :: "m" (c)); \
|
||||
asm( "ld %%r6, %0 " :: "m" (b)); \
|
||||
asm( "addi %r3, %r3, -8 " ); \
|
||||
asm( "addi %r4, %r4, -8 " ); \
|
||||
asm( "addic %r5, %r5, 0 " );
|
||||
|
||||
#define MULADDC_CORE \
|
||||
asm( "ldu %r7, 8(%r3) " ); \
|
||||
asm( "mulld %r8, %r7, %r6 " ); \
|
||||
asm( "mulhdu %r9, %r7, %r6 " ); \
|
||||
asm( "adde %r8, %r8, %r5 " ); \
|
||||
asm( "ld %r7, 8(%r4) " ); \
|
||||
asm( "addze %r5, %r9 " ); \
|
||||
asm( "addc %r8, %r8, %r7 " ); \
|
||||
asm( "stdu %r8, 8(%r4) " );
|
||||
|
||||
#define MULADDC_STOP \
|
||||
asm( "addze %r5, %r5 " ); \
|
||||
asm( "addi %r4, %r4, 8 " ); \
|
||||
asm( "addi %r3, %r3, 8 " ); \
|
||||
asm( "std %%r5, %0 " : "=m" (c)); \
|
||||
asm( "std %%r4, %0 " : "=m" (d)); \
|
||||
asm( "std %%r3, %0 " : "=m" (s) :: \
|
||||
"r3", "r4", "r5", "r6", "r7", "r8", "r9" );
|
||||
|
||||
#endif
|
||||
|
||||
#else /* PPC32 */
|
||||
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
asm( "lwz r3, %0 " :: "m" (s)); \
|
||||
asm( "lwz r4, %0 " :: "m" (d)); \
|
||||
asm( "lwz r5, %0 " :: "m" (c)); \
|
||||
asm( "lwz r6, %0 " :: "m" (b)); \
|
||||
asm( "addi r3, r3, -4 " ); \
|
||||
asm( "addi r4, r4, -4 " ); \
|
||||
asm( "addic r5, r5, 0 " );
|
||||
|
||||
#define MULADDC_CORE \
|
||||
asm( "lwzu r7, 4(r3) " ); \
|
||||
asm( "mullw r8, r7, r6 " ); \
|
||||
asm( "mulhwu r9, r7, r6 " ); \
|
||||
asm( "adde r8, r8, r5 " ); \
|
||||
asm( "lwz r7, 4(r4) " ); \
|
||||
asm( "addze r5, r9 " ); \
|
||||
asm( "addc r8, r8, r7 " ); \
|
||||
asm( "stwu r8, 4(r4) " );
|
||||
|
||||
#define MULADDC_STOP \
|
||||
asm( "addze r5, r5 " ); \
|
||||
asm( "addi r4, r4, 4 " ); \
|
||||
asm( "addi r3, r3, 4 " ); \
|
||||
asm( "stw r5, %0 " : "=m" (c)); \
|
||||
asm( "stw r4, %0 " : "=m" (d)); \
|
||||
asm( "stw r3, %0 " : "=m" (s) :: \
|
||||
"r3", "r4", "r5", "r6", "r7", "r8", "r9" );
|
||||
|
||||
#else
|
||||
|
||||
#define MULADDC_INIT \
|
||||
asm( "lwz %%r3, %0 " :: "m" (s)); \
|
||||
asm( "lwz %%r4, %0 " :: "m" (d)); \
|
||||
asm( "lwz %%r5, %0 " :: "m" (c)); \
|
||||
asm( "lwz %%r6, %0 " :: "m" (b)); \
|
||||
asm( "addi %r3, %r3, -4 " ); \
|
||||
asm( "addi %r4, %r4, -4 " ); \
|
||||
asm( "addic %r5, %r5, 0 " );
|
||||
|
||||
#define MULADDC_CORE \
|
||||
asm( "lwzu %r7, 4(%r3) " ); \
|
||||
asm( "mullw %r8, %r7, %r6 " ); \
|
||||
asm( "mulhwu %r9, %r7, %r6 " ); \
|
||||
asm( "adde %r8, %r8, %r5 " ); \
|
||||
asm( "lwz %r7, 4(%r4) " ); \
|
||||
asm( "addze %r5, %r9 " ); \
|
||||
asm( "addc %r8, %r8, %r7 " ); \
|
||||
asm( "stwu %r8, 4(%r4) " );
|
||||
|
||||
#define MULADDC_STOP \
|
||||
asm( "addze %r5, %r5 " ); \
|
||||
asm( "addi %r4, %r4, 4 " ); \
|
||||
asm( "addi %r3, %r3, 4 " ); \
|
||||
asm( "stw %%r5, %0 " : "=m" (c)); \
|
||||
asm( "stw %%r4, %0 " : "=m" (d)); \
|
||||
asm( "stw %%r3, %0 " : "=m" (s) :: \
|
||||
"r3", "r4", "r5", "r6", "r7", "r8", "r9" );
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* PPC32 */
|
||||
#endif /* PPC64 */
|
||||
|
||||
#if defined(__sparc__)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
asm( "ld %0, %%o0 " :: "m" (s)); \
|
||||
asm( "ld %0, %%o1 " :: "m" (d)); \
|
||||
asm( "ld %0, %%o2 " :: "m" (c)); \
|
||||
asm( "ld %0, %%o3 " :: "m" (b));
|
||||
|
||||
#define MULADDC_CORE \
|
||||
asm( "ld [%o0], %o4 " ); \
|
||||
asm( "inc 4, %o0 " ); \
|
||||
asm( "ld [%o1], %o5 " ); \
|
||||
asm( "umul %o3, %o4, %o4 " ); \
|
||||
asm( "addcc %o4, %o2, %o4 " ); \
|
||||
asm( "rd %y, %g1 " ); \
|
||||
asm( "addx %g1, 0, %g1 " ); \
|
||||
asm( "addcc %o4, %o5, %o4 " ); \
|
||||
asm( "st %o4, [%o1] " ); \
|
||||
asm( "addx %g1, 0, %o2 " ); \
|
||||
asm( "inc 4, %o1 " );
|
||||
|
||||
#define MULADDC_STOP \
|
||||
asm( "st %%o2, %0 " : "=m" (c)); \
|
||||
asm( "st %%o1, %0 " : "=m" (d)); \
|
||||
asm( "st %%o0, %0 " : "=m" (s) :: \
|
||||
"g1", "o0", "o1", "o2", "o3", "o4", "o5" );
|
||||
|
||||
#endif /* SPARCv8 */
|
||||
|
||||
#if defined(__microblaze__) || defined(microblaze)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
asm( "lwi r3, %0 " :: "m" (s)); \
|
||||
asm( "lwi r4, %0 " :: "m" (d)); \
|
||||
asm( "lwi r5, %0 " :: "m" (c)); \
|
||||
asm( "lwi r6, %0 " :: "m" (b)); \
|
||||
asm( "andi r7, r6, 0xffff" ); \
|
||||
asm( "bsrli r6, r6, 16 " );
|
||||
|
||||
#define MULADDC_CORE \
|
||||
asm( "lhui r8, r3, 0 " ); \
|
||||
asm( "addi r3, r3, 2 " ); \
|
||||
asm( "lhui r9, r3, 0 " ); \
|
||||
asm( "addi r3, r3, 2 " ); \
|
||||
asm( "mul r10, r9, r6 " ); \
|
||||
asm( "mul r11, r8, r7 " ); \
|
||||
asm( "mul r12, r9, r7 " ); \
|
||||
asm( "mul r13, r8, r6 " ); \
|
||||
asm( "bsrli r8, r10, 16 " ); \
|
||||
asm( "bsrli r9, r11, 16 " ); \
|
||||
asm( "add r13, r13, r8 " ); \
|
||||
asm( "add r13, r13, r9 " ); \
|
||||
asm( "bslli r10, r10, 16 " ); \
|
||||
asm( "bslli r11, r11, 16 " ); \
|
||||
asm( "add r12, r12, r10 " ); \
|
||||
asm( "addc r13, r13, r0 " ); \
|
||||
asm( "add r12, r12, r11 " ); \
|
||||
asm( "addc r13, r13, r0 " ); \
|
||||
asm( "lwi r10, r4, 0 " ); \
|
||||
asm( "add r12, r12, r10 " ); \
|
||||
asm( "addc r13, r13, r0 " ); \
|
||||
asm( "add r12, r12, r5 " ); \
|
||||
asm( "addc r5, r13, r0 " ); \
|
||||
asm( "swi r12, r4, 0 " ); \
|
||||
asm( "addi r4, r4, 4 " );
|
||||
|
||||
#define MULADDC_STOP \
|
||||
asm( "swi r5, %0 " : "=m" (c)); \
|
||||
asm( "swi r4, %0 " : "=m" (d)); \
|
||||
asm( "swi r3, %0 " : "=m" (s) :: \
|
||||
"r3", "r4" , "r5" , "r6" , "r7" , "r8" , \
|
||||
"r9", "r10", "r11", "r12", "r13" );
|
||||
|
||||
#endif /* MicroBlaze */
|
||||
|
||||
#if defined(__tricore__)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
asm( "ld.a %%a2, %0 " :: "m" (s)); \
|
||||
asm( "ld.a %%a3, %0 " :: "m" (d)); \
|
||||
asm( "ld.w %%d4, %0 " :: "m" (c)); \
|
||||
asm( "ld.w %%d1, %0 " :: "m" (b)); \
|
||||
asm( "xor %d5, %d5 " );
|
||||
|
||||
#define MULADDC_CORE \
|
||||
asm( "ld.w %d0, [%a2+] " ); \
|
||||
asm( "madd.u %e2, %e4, %d0, %d1 " ); \
|
||||
asm( "ld.w %d0, [%a3] " ); \
|
||||
asm( "addx %d2, %d2, %d0 " ); \
|
||||
asm( "addc %d3, %d3, 0 " ); \
|
||||
asm( "mov %d4, %d3 " ); \
|
||||
asm( "st.w [%a3+], %d2 " );
|
||||
|
||||
#define MULADDC_STOP \
|
||||
asm( "st.w %0, %%d4 " : "=m" (c)); \
|
||||
asm( "st.a %0, %%a3 " : "=m" (d)); \
|
||||
asm( "st.a %0, %%a2 " : "=m" (s) :: \
|
||||
"d0", "d1", "e2", "d4", "a2", "a3" );
|
||||
|
||||
#endif /* TriCore */
|
||||
|
||||
#if defined(__arm__)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
asm( "ldr r0, %0 " :: "m" (s)); \
|
||||
asm( "ldr r1, %0 " :: "m" (d)); \
|
||||
asm( "ldr r2, %0 " :: "m" (c)); \
|
||||
asm( "ldr r3, %0 " :: "m" (b));
|
||||
|
||||
#define MULADDC_CORE \
|
||||
asm( "ldr r4, [r0], #4 " ); \
|
||||
asm( "mov r5, #0 " ); \
|
||||
asm( "ldr r6, [r1] " ); \
|
||||
asm( "umlal r2, r5, r3, r4 " ); \
|
||||
asm( "adds r7, r6, r2 " ); \
|
||||
asm( "adc r2, r5, #0 " ); \
|
||||
asm( "str r7, [r1], #4 " );
|
||||
|
||||
#define MULADDC_STOP \
|
||||
asm( "str r2, %0 " : "=m" (c)); \
|
||||
asm( "str r1, %0 " : "=m" (d)); \
|
||||
asm( "str r0, %0 " : "=m" (s) :: \
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" );
|
||||
|
||||
#endif /* ARMv3 */
|
||||
|
||||
#if defined(__alpha__)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
asm( "ldq $1, %0 " :: "m" (s)); \
|
||||
asm( "ldq $2, %0 " :: "m" (d)); \
|
||||
asm( "ldq $3, %0 " :: "m" (c)); \
|
||||
asm( "ldq $4, %0 " :: "m" (b));
|
||||
|
||||
#define MULADDC_CORE \
|
||||
asm( "ldq $6, 0($1) " ); \
|
||||
asm( "addq $1, 8, $1 " ); \
|
||||
asm( "mulq $6, $4, $7 " ); \
|
||||
asm( "umulh $6, $4, $6 " ); \
|
||||
asm( "addq $7, $3, $7 " ); \
|
||||
asm( "cmpult $7, $3, $3 " ); \
|
||||
asm( "ldq $5, 0($2) " ); \
|
||||
asm( "addq $7, $5, $7 " ); \
|
||||
asm( "cmpult $7, $5, $5 " ); \
|
||||
asm( "stq $7, 0($2) " ); \
|
||||
asm( "addq $2, 8, $2 " ); \
|
||||
asm( "addq $6, $3, $3 " ); \
|
||||
asm( "addq $5, $3, $3 " );
|
||||
|
||||
#define MULADDC_STOP \
|
||||
asm( "stq $3, %0 " : "=m" (c)); \
|
||||
asm( "stq $2, %0 " : "=m" (d)); \
|
||||
asm( "stq $1, %0 " : "=m" (s) :: \
|
||||
"$1", "$2", "$3", "$4", "$5", "$6", "$7" );
|
||||
|
||||
#endif /* Alpha */
|
||||
|
||||
#if defined(__mips__)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
asm( "lw $10, %0 " :: "m" (s)); \
|
||||
asm( "lw $11, %0 " :: "m" (d)); \
|
||||
asm( "lw $12, %0 " :: "m" (c)); \
|
||||
asm( "lw $13, %0 " :: "m" (b));
|
||||
|
||||
#define MULADDC_CORE \
|
||||
asm( "lw $14, 0($10) " ); \
|
||||
asm( "multu $13, $14 " ); \
|
||||
asm( "addi $10, $10, 4 " ); \
|
||||
asm( "mflo $14 " ); \
|
||||
asm( "mfhi $9 " ); \
|
||||
asm( "addu $14, $12, $14 " ); \
|
||||
asm( "lw $15, 0($11) " ); \
|
||||
asm( "sltu $12, $14, $12 " ); \
|
||||
asm( "addu $15, $14, $15 " ); \
|
||||
asm( "sltu $14, $15, $14 " ); \
|
||||
asm( "addu $12, $12, $9 " ); \
|
||||
asm( "sw $15, 0($11) " ); \
|
||||
asm( "addu $12, $12, $14 " ); \
|
||||
asm( "addi $11, $11, 4 " );
|
||||
|
||||
#define MULADDC_STOP \
|
||||
asm( "sw $12, %0 " : "=m" (c)); \
|
||||
asm( "sw $11, %0 " : "=m" (d)); \
|
||||
asm( "sw $10, %0 " : "=m" (s) :: \
|
||||
"$9", "$10", "$11", "$12", "$13", "$14", "$15" );
|
||||
|
||||
#endif /* MIPS */
|
||||
#endif /* GNUC */
|
||||
|
||||
#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
__asm mov esi, s \
|
||||
__asm mov edi, d \
|
||||
__asm mov ecx, c \
|
||||
__asm mov ebx, b
|
||||
|
||||
#define MULADDC_CORE \
|
||||
__asm lodsd \
|
||||
__asm mul ebx \
|
||||
__asm add eax, ecx \
|
||||
__asm adc edx, 0 \
|
||||
__asm add eax, [edi] \
|
||||
__asm adc edx, 0 \
|
||||
__asm mov ecx, edx \
|
||||
__asm stosd
|
||||
|
||||
#if defined(POLARSSL_HAVE_SSE2)
|
||||
|
||||
#define EMIT __asm _emit
|
||||
|
||||
#define MULADDC_HUIT \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0xC9 \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0xC3 \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x1F \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x16 \
|
||||
EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \
|
||||
EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \
|
||||
EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \
|
||||
EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xDC \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xEE \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xFC \
|
||||
EMIT 0x0F EMIT 0x7E EMIT 0x0F \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \
|
||||
EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
|
||||
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \
|
||||
EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \
|
||||
EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
|
||||
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \
|
||||
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \
|
||||
EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xCD \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \
|
||||
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \
|
||||
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xCF \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \
|
||||
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \
|
||||
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \
|
||||
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \
|
||||
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xCC \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xDD \
|
||||
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \
|
||||
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xCE \
|
||||
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \
|
||||
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
|
||||
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
|
||||
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \
|
||||
EMIT 0x83 EMIT 0xC7 EMIT 0x20 \
|
||||
EMIT 0x83 EMIT 0xC6 EMIT 0x20 \
|
||||
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
|
||||
EMIT 0x0F EMIT 0x7E EMIT 0xC9
|
||||
|
||||
#define MULADDC_STOP \
|
||||
EMIT 0x0F EMIT 0x77 \
|
||||
__asm mov c, ecx \
|
||||
__asm mov d, edi \
|
||||
__asm mov s, esi \
|
||||
|
||||
#else
|
||||
|
||||
#define MULADDC_STOP \
|
||||
__asm mov c, ecx \
|
||||
__asm mov d, edi \
|
||||
__asm mov s, esi \
|
||||
|
||||
#endif /* SSE2 */
|
||||
#endif /* MSVC */
|
||||
|
||||
#endif /* POLARSSL_HAVE_ASM */
|
||||
|
||||
#if !defined(MULADDC_CORE)
|
||||
#if defined(POLARSSL_HAVE_LONGLONG)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
{ \
|
||||
t_dbl r; \
|
||||
t_int r0, r1;
|
||||
|
||||
#define MULADDC_CORE \
|
||||
r = *(s++) * (t_dbl) b; \
|
||||
r0 = r; \
|
||||
r1 = r >> biL; \
|
||||
r0 += c; r1 += (r0 < c); \
|
||||
r0 += *d; r1 += (r0 < *d); \
|
||||
c = r1; *(d++) = r0;
|
||||
|
||||
#define MULADDC_STOP \
|
||||
}
|
||||
|
||||
#else
|
||||
#define MULADDC_INIT \
|
||||
{ \
|
||||
t_int s0, s1, b0, b1; \
|
||||
t_int r0, r1, rx, ry; \
|
||||
b0 = ( b << biH ) >> biH; \
|
||||
b1 = ( b >> biH );
|
||||
|
||||
#define MULADDC_CORE \
|
||||
s0 = ( *s << biH ) >> biH; \
|
||||
s1 = ( *s >> biH ); s++; \
|
||||
rx = s0 * b1; r0 = s0 * b0; \
|
||||
ry = s1 * b0; r1 = s1 * b1; \
|
||||
r1 += ( rx >> biH ); \
|
||||
r1 += ( ry >> biH ); \
|
||||
rx <<= biH; ry <<= biH; \
|
||||
r0 += rx; r1 += (r0 < rx); \
|
||||
r0 += ry; r1 += (r0 < ry); \
|
||||
r0 += c; r1 += (r0 < c); \
|
||||
r0 += *d; r1 += (r0 < *d); \
|
||||
c = r1; *(d++) = r0;
|
||||
|
||||
#define MULADDC_STOP \
|
||||
}
|
||||
|
||||
#endif /* C (generic) */
|
||||
#endif /* C (longlong) */
|
||||
|
||||
#endif /* bn_mul.h */
|
|
@ -0,0 +1,329 @@
|
|||
/**
|
||||
* \file config.h
|
||||
*
|
||||
* Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
|
||||
*
|
||||
* Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the names of PolarSSL or XySSL nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This set of compile-time options may be used to enable
|
||||
* or disable features selectively, and reduce the global
|
||||
* memory footprint.
|
||||
*/
|
||||
#ifndef POLARSSL_CONFIG_H
|
||||
#define POLARSSL_CONFIG_H
|
||||
|
||||
#ifndef _CRT_SECURE_NO_DEPRECATE
|
||||
#define _CRT_SECURE_NO_DEPRECATE 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Uncomment if native integers are 8-bit wide.
|
||||
*
|
||||
#define POLARSSL_HAVE_INT8
|
||||
*/
|
||||
|
||||
/*
|
||||
* Uncomment if native integers are 16-bit wide.
|
||||
*
|
||||
#define POLARSSL_HAVE_INT16
|
||||
*/
|
||||
|
||||
/*
|
||||
* Uncomment if the compiler supports long long.
|
||||
*/
|
||||
#define POLARSSL_HAVE_LONGLONG
|
||||
|
||||
|
||||
/*
|
||||
* Uncomment to enable the use of assembly code.
|
||||
*/
|
||||
#define POLARSSL_HAVE_ASM
|
||||
|
||||
/*
|
||||
* Uncomment if the CPU supports SSE2 (IA-32 specific).
|
||||
*
|
||||
#define POLARSSL_HAVE_SSE2
|
||||
*/
|
||||
|
||||
/*
|
||||
* Enable all SSL/TLS debugging messages.
|
||||
*/
|
||||
#define POLARSSL_DEBUG_MSG
|
||||
|
||||
/*
|
||||
* Enable the checkup functions (*_self_test).
|
||||
*/
|
||||
#define POLARSSL_SELF_TEST
|
||||
|
||||
/*
|
||||
* Enable the prime-number generation code.
|
||||
*/
|
||||
#define POLARSSL_GENPRIME
|
||||
|
||||
/*
|
||||
* Uncomment this macro to store the AES tables in ROM.
|
||||
*
|
||||
#define POLARSSL_AES_ROM_TABLES
|
||||
*/
|
||||
|
||||
/*
|
||||
* Module: library/aes.c
|
||||
* Caller: library/ssl_tls.c
|
||||
*
|
||||
* This module enables the following ciphersuites:
|
||||
* SSL_RSA_AES_128_SHA
|
||||
* SSL_RSA_AES_256_SHA
|
||||
* SSL_EDH_RSA_AES_256_SHA
|
||||
*/
|
||||
#define POLARSSL_AES_C
|
||||
|
||||
/*
|
||||
* Module: library/arc4.c
|
||||
* Caller: library/ssl_tls.c
|
||||
*
|
||||
* This module enables the following ciphersuites:
|
||||
* SSL_RSA_RC4_128_MD5
|
||||
* SSL_RSA_RC4_128_SHA
|
||||
*/
|
||||
#define POLARSSL_ARC4_C
|
||||
|
||||
/*
|
||||
* Module: library/base64.c
|
||||
* Caller: library/x509parse.c
|
||||
*
|
||||
* This module is required for X.509 support.
|
||||
*/
|
||||
#define POLARSSL_BASE64_C
|
||||
|
||||
/*
|
||||
* Module: library/bignum.c
|
||||
* Caller: library/dhm.c
|
||||
* library/rsa.c
|
||||
* library/ssl_tls.c
|
||||
* library/x509parse.c
|
||||
*
|
||||
* This module is required for RSA and DHM support.
|
||||
*/
|
||||
#define POLARSSL_BIGNUM_C
|
||||
|
||||
/*
|
||||
* Module: library/camellia.c
|
||||
* Caller:
|
||||
*
|
||||
* This module enabled the following cipher suites:
|
||||
*/
|
||||
#define POLARSSL_CAMELLIA_C
|
||||
|
||||
/*
|
||||
* Module: library/certs.c
|
||||
* Caller:
|
||||
*
|
||||
* This module is used for testing (ssl_client/server).
|
||||
*/
|
||||
#define POLARSSL_CERTS_C
|
||||
|
||||
/*
|
||||
* Module: library/debug.c
|
||||
* Caller: library/ssl_cli.c
|
||||
* library/ssl_srv.c
|
||||
* library/ssl_tls.c
|
||||
*
|
||||
* This module provides debugging functions.
|
||||
*/
|
||||
#define POLARSSL_DEBUG_C
|
||||
|
||||
/*
|
||||
* Module: library/des.c
|
||||
* Caller: library/ssl_tls.c
|
||||
*
|
||||
* This module enables the following ciphersuites:
|
||||
* SSL_RSA_DES_168_SHA
|
||||
* SSL_EDH_RSA_DES_168_SHA
|
||||
*/
|
||||
#define POLARSSL_DES_C
|
||||
|
||||
/*
|
||||
* Module: library/dhm.c
|
||||
* Caller: library/ssl_cli.c
|
||||
* library/ssl_srv.c
|
||||
*
|
||||
* This module enables the following ciphersuites:
|
||||
* SSL_EDH_RSA_DES_168_SHA
|
||||
* SSL_EDH_RSA_AES_256_SHA
|
||||
*/
|
||||
#define POLARSSL_DHM_C
|
||||
|
||||
/*
|
||||
* Module: library/havege.c
|
||||
* Caller:
|
||||
*
|
||||
* This module enables the HAVEGE random number generator.
|
||||
*/
|
||||
#define POLARSSL_HAVEGE_C
|
||||
|
||||
/*
|
||||
* Module: library/md2.c
|
||||
* Caller: library/x509parse.c
|
||||
*
|
||||
* Uncomment to enable support for (rare) MD2-signed X.509 certs.
|
||||
*
|
||||
#define POLARSSL_MD2_C
|
||||
*/
|
||||
|
||||
/*
|
||||
* Module: library/md4.c
|
||||
* Caller: library/x509parse.c
|
||||
*
|
||||
* Uncomment to enable support for (rare) MD4-signed X.509 certs.
|
||||
*
|
||||
#define POLARSSL_MD4_C
|
||||
*/
|
||||
|
||||
/*
|
||||
* Module: library/md5.c
|
||||
* Caller: library/ssl_tls.c
|
||||
* library/x509parse.c
|
||||
*
|
||||
* This module is required for SSL/TLS and X.509.
|
||||
*/
|
||||
#define POLARSSL_MD5_C
|
||||
|
||||
/*
|
||||
* Module: library/net.c
|
||||
* Caller:
|
||||
*
|
||||
* This module provides TCP/IP networking routines.
|
||||
*/
|
||||
#define POLARSSL_NET_C
|
||||
|
||||
/*
|
||||
* Module: library/padlock.c
|
||||
* Caller: library/aes.c
|
||||
*
|
||||
* This modules adds support for the VIA PadLock on x86.
|
||||
*/
|
||||
#define POLARSSL_PADLOCK_C
|
||||
|
||||
/*
|
||||
* Module: library/rsa.c
|
||||
* Caller: library/ssl_cli.c
|
||||
* library/ssl_srv.c
|
||||
* library/ssl_tls.c
|
||||
* library/x509.c
|
||||
*
|
||||
* This module is required for SSL/TLS and MD5-signed certificates.
|
||||
*/
|
||||
#define POLARSSL_RSA_C
|
||||
|
||||
/*
|
||||
* Module: library/sha1.c
|
||||
* Caller: library/ssl_cli.c
|
||||
* library/ssl_srv.c
|
||||
* library/ssl_tls.c
|
||||
* library/x509parse.c
|
||||
*
|
||||
* This module is required for SSL/TLS and SHA1-signed certificates.
|
||||
*/
|
||||
#define POLARSSL_SHA1_C
|
||||
|
||||
/*
|
||||
* Module: library/sha2.c
|
||||
* Caller:
|
||||
*
|
||||
* This module adds support for SHA-224 and SHA-256.
|
||||
*/
|
||||
#define POLARSSL_SHA2_C
|
||||
|
||||
/*
|
||||
* Module: library/sha4.c
|
||||
* Caller:
|
||||
*
|
||||
* This module adds support for SHA-384 and SHA-512.
|
||||
*/
|
||||
#define POLARSSL_SHA4_C
|
||||
|
||||
/*
|
||||
* Module: library/ssl_cli.c
|
||||
* Caller:
|
||||
*
|
||||
* This module is required for SSL/TLS client support.
|
||||
*/
|
||||
#define POLARSSL_SSL_CLI_C
|
||||
|
||||
/*
|
||||
* Module: library/ssl_srv.c
|
||||
* Caller:
|
||||
*
|
||||
* This module is required for SSL/TLS server support.
|
||||
*/
|
||||
#define POLARSSL_SSL_SRV_C
|
||||
|
||||
/*
|
||||
* Module: library/ssl_tls.c
|
||||
* Caller: library/ssl_cli.c
|
||||
* library/ssl_srv.c
|
||||
*
|
||||
* This module is required for SSL/TLS.
|
||||
*/
|
||||
#define POLARSSL_SSL_TLS_C
|
||||
|
||||
/*
|
||||
* Module: library/timing.c
|
||||
* Caller: library/havege.c
|
||||
*
|
||||
* This module is used by the HAVEGE random number generator.
|
||||
*/
|
||||
#define POLARSSL_TIMING_C
|
||||
|
||||
/*
|
||||
* Module: library/x509parse.c
|
||||
* Caller: library/ssl_cli.c
|
||||
* library/ssl_srv.c
|
||||
* library/ssl_tls.c
|
||||
*
|
||||
* This module is required for X.509 certificate parsing.
|
||||
*/
|
||||
#define POLARSSL_X509_PARSE_C
|
||||
|
||||
/*
|
||||
* Module: library/x509_write.c
|
||||
* Caller:
|
||||
*
|
||||
* This module is required for X.509 certificate writing.
|
||||
*/
|
||||
#define POLARSSL_X509_WRITE_C
|
||||
|
||||
/*
|
||||
* Module: library/xtea.c
|
||||
* Caller:
|
||||
*/
|
||||
#define POLARSSL_XTEA_C
|
||||
|
||||
#endif /* config.h */
|
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* \file havege.h
|
||||
*
|
||||
* Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
|
||||
*
|
||||
* Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the names of PolarSSL or XySSL nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef POLARSSL_HAVEGE_H
|
||||
#define POLARSSL_HAVEGE_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 rng_st points to an HAVEGE state
|
||||
*
|
||||
* \return A random int
|
||||
*/
|
||||
int havege_rand( void *p_rng );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* havege.h */
|
|
@ -0,0 +1,309 @@
|
|||
/**
|
||||
* \file rsa.h
|
||||
*
|
||||
* Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
|
||||
*
|
||||
* Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the names of PolarSSL or XySSL nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef POLARSSL_RSA_H
|
||||
#define POLARSSL_RSA_H
|
||||
|
||||
#include "polarssl/bignum.h"
|
||||
|
||||
#define POLARSSL_ERR_RSA_BAD_INPUT_DATA -0x0400
|
||||
#define POLARSSL_ERR_RSA_INVALID_PADDING -0x0410
|
||||
#define POLARSSL_ERR_RSA_KEY_GEN_FAILED -0x0420
|
||||
#define POLARSSL_ERR_RSA_KEY_CHECK_FAILED -0x0430
|
||||
#define POLARSSL_ERR_RSA_PUBLIC_FAILED -0x0440
|
||||
#define POLARSSL_ERR_RSA_PRIVATE_FAILED -0x0450
|
||||
#define POLARSSL_ERR_RSA_VERIFY_FAILED -0x0460
|
||||
#define POLARSSL_ERR_RSA_OUTPUT_TO_LARGE -0x0470
|
||||
|
||||
/*
|
||||
* PKCS#1 constants
|
||||
*/
|
||||
#define RSA_RAW 0
|
||||
#define RSA_MD2 2
|
||||
#define RSA_MD4 3
|
||||
#define RSA_MD5 4
|
||||
#define RSA_SHA1 5
|
||||
#define RSA_SHA256 6
|
||||
|
||||
#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
|
||||
|
||||
/*
|
||||
* DigestInfo ::= SEQUENCE {
|
||||
* digestAlgorithm DigestAlgorithmIdentifier,
|
||||
* digest Digest }
|
||||
*
|
||||
* DigestAlgorithmIdentifier ::= AlgorithmIdentifier
|
||||
*
|
||||
* Digest ::= OCTET STRING
|
||||
*/
|
||||
#define ASN1_HASH_MDX \
|
||||
"\x30\x20\x30\x0C\x06\x08\x2A\x86\x48" \
|
||||
"\x86\xF7\x0D\x02\x00\x05\x00\x04\x10"
|
||||
|
||||
#define ASN1_HASH_SHA1 \
|
||||
"\x30\x21\x30\x09\x06\x05\x2B\x0E\x03" \
|
||||
"\x02\x1A\x05\x00\x04\x14"
|
||||
|
||||
/**
|
||||
* \brief RSA context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int ver; /*!< always 0 */
|
||||
int len; /*!< size(N) in chars */
|
||||
|
||||
mpi N; /*!< public modulus */
|
||||
mpi E; /*!< public exponent */
|
||||
|
||||
mpi D; /*!< private exponent */
|
||||
mpi P; /*!< 1st prime factor */
|
||||
mpi Q; /*!< 2nd prime factor */
|
||||
mpi DP; /*!< D % (P - 1) */
|
||||
mpi DQ; /*!< D % (Q - 1) */
|
||||
mpi QP; /*!< 1 / (Q % P) */
|
||||
|
||||
mpi RN; /*!< cached R^2 mod N */
|
||||
mpi RP; /*!< cached R^2 mod P */
|
||||
mpi RQ; /*!< cached R^2 mod Q */
|
||||
|
||||
int padding; /*!< 1.5 or OAEP/PSS */
|
||||
int hash_id; /*!< hash identifier */
|
||||
int (*f_rng)(void *); /*!< RNG function */
|
||||
void *p_rng; /*!< RNG parameter */
|
||||
}
|
||||
rsa_context;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Initialize an RSA context
|
||||
*
|
||||
* \param ctx RSA context to be initialized
|
||||
* \param padding RSA_PKCS_V15 or RSA_PKCS_V21
|
||||
* \param hash_id RSA_PKCS_V21 hash identifier
|
||||
* \param f_rng RNG function
|
||||
* \param p_rng RNG parameter
|
||||
*
|
||||
* \note The hash_id parameter is actually ignored
|
||||
* when using RSA_PKCS_V15 padding.
|
||||
*
|
||||
* \note Currently (xyssl-0.8), RSA_PKCS_V21 padding
|
||||
* is not supported.
|
||||
*/
|
||||
void rsa_init( rsa_context *ctx,
|
||||
int padding,
|
||||
int hash_id,
|
||||
int (*f_rng)(void *),
|
||||
void *p_rng );
|
||||
|
||||
/**
|
||||
* \brief Generate an RSA keypair
|
||||
*
|
||||
* \param ctx RSA context that will hold the key
|
||||
* \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 (especially f_rng and p_rng).
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||
*/
|
||||
int rsa_gen_key( rsa_context *ctx, 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( 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( 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.
|
||||
*
|
||||
* \note The input and output buffers must be large
|
||||
* enough (eg. 128 bytes if RSA-1024 is used).
|
||||
*/
|
||||
int rsa_public( rsa_context *ctx,
|
||||
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,
|
||||
unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief Add the message padding, then do an RSA operation
|
||||
*
|
||||
* \param ctx RSA context
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
* \param ilen contains the 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 mode, int ilen,
|
||||
unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief Do an RSA operation, then remove the message padding
|
||||
*
|
||||
* \param ctx RSA context
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
* \param input buffer holding the encrypted data
|
||||
* \param output buffer that will hold the plaintext
|
||||
* \param olen will contain the plaintext length
|
||||
* \param output_max_len maximum length of the output buffer
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note The output buffer must be as large as the size
|
||||
* of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
|
||||
* an error is thrown.
|
||||
*/
|
||||
int rsa_pkcs1_decrypt( rsa_context *ctx,
|
||||
int mode, int *olen,
|
||||
unsigned char *input,
|
||||
unsigned char *output,
|
||||
int output_max_len);
|
||||
|
||||
/**
|
||||
* \brief Do a private RSA to sign a message digest
|
||||
*
|
||||
* \param ctx RSA context
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
* \param hash_id RSA_RAW, RSA_MD{2,4,5} or RSA_SHA{1,256}
|
||||
* \param hashlen message digest length (for RSA_RAW only)
|
||||
* \param hash buffer holding the message digest
|
||||
* \param sig buffer that will hold the ciphertext
|
||||
*
|
||||
* \return 0 if the signing operation was successful,
|
||||
* or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note The "sig" buffer must be as large as the size
|
||||
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
|
||||
*/
|
||||
int rsa_pkcs1_sign( rsa_context *ctx,
|
||||
int mode,
|
||||
int hash_id,
|
||||
int hashlen,
|
||||
unsigned char *hash,
|
||||
unsigned char *sig );
|
||||
|
||||
/**
|
||||
* \brief Do a public RSA and check the message digest
|
||||
*
|
||||
* \param ctx points to an RSA public key
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
* \param hash_id RSA_RAW, RSA_MD{2,4,5} or RSA_SHA{1,256}
|
||||
* \param hashlen message digest length (for RSA_RAW only)
|
||||
* \param hash buffer holding the message digest
|
||||
* \param sig buffer holding the ciphertext
|
||||
*
|
||||
* \return 0 if the verify operation was successful,
|
||||
* or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note The "sig" buffer must be as large as the size
|
||||
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
|
||||
*/
|
||||
int rsa_pkcs1_verify( rsa_context *ctx,
|
||||
int mode,
|
||||
int hash_id,
|
||||
int hashlen,
|
||||
unsigned char *hash,
|
||||
unsigned char *sig );
|
||||
|
||||
/**
|
||||
* \brief Free the components of an RSA key
|
||||
*/
|
||||
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 */
|
|
@ -0,0 +1,150 @@
|
|||
/**
|
||||
* \file sha1.h
|
||||
*
|
||||
* Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
|
||||
*
|
||||
* Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the names of PolarSSL or XySSL nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef POLARSSL_SHA1_H
|
||||
#define POLARSSL_SHA1_H
|
||||
|
||||
/**
|
||||
* \brief SHA-1 context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned long total[2]; /*!< number of bytes processed */
|
||||
unsigned long 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, unsigned char *input, int 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] );
|
||||
|
||||
/**
|
||||
* \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( unsigned char *input, int 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, 1 if fopen failed,
|
||||
* or 2 if fread failed
|
||||
*/
|
||||
int sha1_file( 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, unsigned char *key, int 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, unsigned char *input, int 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 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( unsigned char *key, int keylen,
|
||||
unsigned char *input, int 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 */
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
* \file timing.h
|
||||
*
|
||||
* Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
|
||||
*
|
||||
* Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the names of PolarSSL or XySSL nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef POLARSSL_TIMING_H
|
||||
#define POLARSSL_TIMING_H
|
||||
|
||||
/**
|
||||
* \brief timer structure
|
||||
*/
|
||||
struct hr_time
|
||||
{
|
||||
unsigned char opaque[32];
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern 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
|
||||
*/
|
||||
void m_sleep( int milliseconds );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* timing.h */
|
|
@ -0,0 +1,549 @@
|
|||
/**
|
||||
* \file x509.h
|
||||
*
|
||||
* Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
|
||||
*
|
||||
* Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the names of PolarSSL or XySSL nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef POLARSSL_X509_H
|
||||
#define POLARSSL_X509_H
|
||||
|
||||
#include "polarssl/rsa.h"
|
||||
|
||||
#define POLARSSL_ERR_ASN1_OUT_OF_DATA -0x0014
|
||||
#define POLARSSL_ERR_ASN1_UNEXPECTED_TAG -0x0016
|
||||
#define POLARSSL_ERR_ASN1_INVALID_LENGTH -0x0018
|
||||
#define POLARSSL_ERR_ASN1_LENGTH_MISMATCH -0x001A
|
||||
#define POLARSSL_ERR_ASN1_INVALID_DATA -0x001C
|
||||
|
||||
#define POLARSSL_ERR_X509_FEATURE_UNAVAILABLE -0x0020
|
||||
#define POLARSSL_ERR_X509_CERT_INVALID_PEM -0x0040
|
||||
#define POLARSSL_ERR_X509_CERT_INVALID_FORMAT -0x0060
|
||||
#define POLARSSL_ERR_X509_CERT_INVALID_VERSION -0x0080
|
||||
#define POLARSSL_ERR_X509_CERT_INVALID_SERIAL -0x00A0
|
||||
#define POLARSSL_ERR_X509_CERT_INVALID_ALG -0x00C0
|
||||
#define POLARSSL_ERR_X509_CERT_INVALID_NAME -0x00E0
|
||||
#define POLARSSL_ERR_X509_CERT_INVALID_DATE -0x0100
|
||||
#define POLARSSL_ERR_X509_CERT_INVALID_PUBKEY -0x0120
|
||||
#define POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE -0x0140
|
||||
#define POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS -0x0160
|
||||
#define POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION -0x0180
|
||||
#define POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG -0x01A0
|
||||
#define POLARSSL_ERR_X509_CERT_UNKNOWN_PK_ALG -0x01C0
|
||||
#define POLARSSL_ERR_X509_CERT_SIG_MISMATCH -0x01E0
|
||||
#define POLARSSL_ERR_X509_CERT_VERIFY_FAILED -0x0200
|
||||
#define POLARSSL_ERR_X509_KEY_INVALID_PEM -0x0220
|
||||
#define POLARSSL_ERR_X509_KEY_INVALID_VERSION -0x0240
|
||||
#define POLARSSL_ERR_X509_KEY_INVALID_FORMAT -0x0260
|
||||
#define POLARSSL_ERR_X509_KEY_INVALID_ENC_IV -0x0280
|
||||
#define POLARSSL_ERR_X509_KEY_UNKNOWN_ENC_ALG -0x02A0
|
||||
#define POLARSSL_ERR_X509_KEY_PASSWORD_REQUIRED -0x02C0
|
||||
#define POLARSSL_ERR_X509_KEY_PASSWORD_MISMATCH -0x02E0
|
||||
#define POLARSSL_ERR_X509_POINT_ERROR -0x0300
|
||||
#define POLARSSL_ERR_X509_VALUE_TO_LENGTH -0x0320
|
||||
|
||||
#define BADCERT_EXPIRED 1
|
||||
#define BADCERT_REVOKED 2
|
||||
#define BADCERT_CN_MISMATCH 4
|
||||
#define BADCERT_NOT_TRUSTED 8
|
||||
|
||||
/*
|
||||
* DER constants
|
||||
*/
|
||||
#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_UNIVERSAL_STRING 0x1C
|
||||
#define ASN1_BMP_STRING 0x1E
|
||||
#define ASN1_PRIMITIVE 0x00
|
||||
#define ASN1_CONSTRUCTED 0x20
|
||||
#define ASN1_CONTEXT_SPECIFIC 0x80
|
||||
|
||||
/*
|
||||
* 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 "\x55\x04\x03"
|
||||
#define OID_PKCS1 "\x2A\x86\x48\x86\xF7\x0D\x01\x01"
|
||||
#define OID_PKCS1_RSA "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01"
|
||||
#define OID_PKCS1_RSA_SHA "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05"
|
||||
#define OID_PKCS9 "\x2A\x86\x48\x86\xF7\x0D\x01\x09"
|
||||
#define OID_PKCS9_EMAIL "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01"
|
||||
|
||||
/*
|
||||
* Structures for parsing X.509 certificates
|
||||
*/
|
||||
typedef struct _x509_buf
|
||||
{
|
||||
int tag;
|
||||
int len;
|
||||
unsigned char *p;
|
||||
}
|
||||
x509_buf;
|
||||
|
||||
typedef struct _x509_name
|
||||
{
|
||||
x509_buf oid;
|
||||
x509_buf val;
|
||||
struct _x509_name *next;
|
||||
}
|
||||
x509_name;
|
||||
|
||||
typedef struct _x509_time
|
||||
{
|
||||
int year, mon, day;
|
||||
int hour, min, sec;
|
||||
}
|
||||
x509_time;
|
||||
|
||||
typedef struct _x509_cert
|
||||
{
|
||||
x509_buf raw;
|
||||
x509_buf tbs;
|
||||
|
||||
int version;
|
||||
x509_buf serial;
|
||||
x509_buf sig_oid1;
|
||||
|
||||
x509_buf issuer_raw;
|
||||
x509_buf subject_raw;
|
||||
|
||||
x509_name issuer;
|
||||
x509_name subject;
|
||||
|
||||
x509_time valid_from;
|
||||
x509_time valid_to;
|
||||
|
||||
x509_buf pk_oid;
|
||||
rsa_context rsa;
|
||||
|
||||
x509_buf issuer_id;
|
||||
x509_buf subject_id;
|
||||
x509_buf v3_ext;
|
||||
|
||||
int ca_istrue;
|
||||
int max_pathlen;
|
||||
|
||||
x509_buf sig_oid2;
|
||||
x509_buf sig;
|
||||
|
||||
struct _x509_cert *next;
|
||||
}
|
||||
x509_cert;
|
||||
|
||||
/*
|
||||
* Structures for writing X.509 certificates
|
||||
*/
|
||||
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
|
||||
|
||||
/**
|
||||
* \brief Parse one or more certificates and add them
|
||||
* to the chained list
|
||||
*
|
||||
* \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 successful, or a specific X509 error code
|
||||
*/
|
||||
int x509parse_crt( x509_cert *crt, unsigned char *buf, int buflen );
|
||||
|
||||
/**
|
||||
* \brief Load one or more certificates and add them
|
||||
* to the chained list
|
||||
*
|
||||
* \param chain points to the start of the chain
|
||||
* \param path filename to read the certificates from
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 error code
|
||||
*/
|
||||
int x509parse_crtfile( x509_cert *crt, char *path );
|
||||
|
||||
/**
|
||||
* \brief Parse a private RSA key
|
||||
*
|
||||
* \param rsa RSA context to be initialized
|
||||
* \param buf input buffer
|
||||
* \param buflen size of the buffer
|
||||
* \param pwd password for decryption (optional)
|
||||
* \param pwdlen size of the password
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 error code
|
||||
*/
|
||||
int x509parse_key( rsa_context *rsa,
|
||||
unsigned char *buf, int buflen,
|
||||
unsigned char *pwd, int pwdlen );
|
||||
|
||||
/**
|
||||
* \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 pwd password to decrypt the file (can be NULL)
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 error code
|
||||
*/
|
||||
int x509parse_keyfile( rsa_context *rsa, char *path, char *password );
|
||||
|
||||
/**
|
||||
* \brief Store the certificate DN in printable form into buf;
|
||||
* no more than (end - buf) characters will be written.
|
||||
*/
|
||||
int x509parse_dn_gets( char *buf, char *end, x509_name *dn );
|
||||
|
||||
/**
|
||||
* \brief Returns an informational string about the
|
||||
* certificate.
|
||||
*/
|
||||
char *x509parse_cert_info( char *prefix, x509_cert *crt );
|
||||
|
||||
/**
|
||||
* \brief Return 0 if the certificate is still valid,
|
||||
* or BADCERT_EXPIRED
|
||||
*/
|
||||
int x509parse_expired( x509_cert *crt );
|
||||
|
||||
/**
|
||||
* \brief Verify the certificate signature
|
||||
*
|
||||
* \param crt a certificate to be verified
|
||||
* \param trust_ca the trusted CA chain
|
||||
* \param cn expected Common Name (can be set to
|
||||
* NULL if the CN must not be verified)
|
||||
* \param flags result of the verification
|
||||
*
|
||||
* \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
|
||||
*
|
||||
* \note TODO: add two arguments, depth and crl
|
||||
*/
|
||||
int x509parse_verify( x509_cert *crt,
|
||||
x509_cert *trust_ca,
|
||||
char *cn, int *flags );
|
||||
|
||||
/**
|
||||
* \brief Unallocate all certificate data
|
||||
*/
|
||||
void x509_free( x509_cert *crt );
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int x509_self_test( int verbose );
|
||||
|
||||
/**
|
||||
* \brief Write a certificate info file
|
||||
*
|
||||
* \param chain points to the raw certificate data
|
||||
* \param path filename to write the certificate to
|
||||
* \param format X509_OUTPUT_DER or X509_OUTPUT_PEM
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 error code
|
||||
*/
|
||||
int x509write_crtfile( x509_raw *chain,
|
||||
unsigned char *path,
|
||||
int format );
|
||||
|
||||
/**
|
||||
* \brief Write a certificate signing request message format file
|
||||
*
|
||||
* \param chain points to the raw certificate (with x509write_create_csr) data
|
||||
* \param path filename to write the certificate to
|
||||
* \param format X509_OUTPUT_DER or X509_OUTPUT_PEM
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 error code
|
||||
*/
|
||||
int x509write_csrfile( x509_raw *chain,
|
||||
unsigned char *path,
|
||||
int format );
|
||||
|
||||
/*
|
||||
* \brief Write a private RSA key into a file
|
||||
*
|
||||
* \param rsa points to an RSA key
|
||||
* \param path filename to write the key to
|
||||
* \param format X509_OUTPUT_DER or X509_OUTPUT_PEM
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 error code
|
||||
*/
|
||||
int x509write_keyfile( rsa_context *rsa,
|
||||
char *path,
|
||||
int format );
|
||||
|
||||
/**
|
||||
* \brief Add a public key to certificate
|
||||
*
|
||||
* \param chain points to the raw certificate data
|
||||
* \param pubkey points to an RSA key
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 error code
|
||||
*/
|
||||
int x509write_add_pubkey( x509_raw *chain, rsa_context *pubkey );
|
||||
|
||||
/**
|
||||
* \brief Create x509 subject/issuer field to raw certificate
|
||||
* from string or CA cert. Make string NULL if you will
|
||||
* use the CA copy function or make CA NULL then used
|
||||
* the string parse.
|
||||
*
|
||||
* \param chain points to the raw certificate data
|
||||
* \param names a string that can hold (separete with ";"):
|
||||
* CN=CommonName
|
||||
* -- O=Organization
|
||||
* -- OU=OrgUnit
|
||||
* -- ST=State
|
||||
* -- L=Locality
|
||||
* -- R=Email
|
||||
* -- C=Country
|
||||
* . Make that NULL if you didn't need that.
|
||||
* \param flag flag is X509_ISSUER or X509_SUBJECT that defined
|
||||
* where change
|
||||
* \param ca the certificate for copy data. Make that NULL if you
|
||||
* didn't need that.
|
||||
* \param ca_flag set the ca field from copy to crt
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 error code
|
||||
*/
|
||||
int x509write_add_customize ( x509_raw *crt,
|
||||
unsigned char *names,
|
||||
int flag,
|
||||
x509_cert *ca,
|
||||
int ca_flag );
|
||||
|
||||
/**
|
||||
* \brief Add x509 issuer field
|
||||
*
|
||||
* \param chain points to the raw certificate data
|
||||
* \param issuer a string holding (separete with ";"):
|
||||
* CN=CommonName
|
||||
* -- O=Organization
|
||||
* -- OU=OrgUnit
|
||||
* -- ST=State
|
||||
* -- L=Locality
|
||||
* -- R=Email
|
||||
* -- C=Country
|
||||
* . Set this to NULL if not needed.
|
||||
* \return 0 if successful, or a specific X509 error code
|
||||
*/
|
||||
int x509write_add_issuer( x509_raw *crt, unsigned char *issuer);
|
||||
|
||||
/**
|
||||
* \brief Add x509 subject field
|
||||
*
|
||||
* \param chain points to the raw certificate data
|
||||
* \param subject a string holding (separete with ";"):
|
||||
* CN=CommonName
|
||||
* -- O=Organization
|
||||
* -- OU=OrgUnit
|
||||
* -- ST=State
|
||||
* -- L=Locality
|
||||
* -- R=Email
|
||||
* -- C=Country
|
||||
* . Set this to NULL if not needed.
|
||||
* \return 0 if successful, or a specific X509 error code
|
||||
*/
|
||||
int x509write_add_subject( x509_raw *crt, unsigned char *subject);
|
||||
|
||||
/**
|
||||
* \brief Copy x509 issuer field from another certificate
|
||||
*
|
||||
* \param chain points to the raw certificate data
|
||||
* \param from_crt the certificate whose issuer is to be copied.
|
||||
* \return 0 if successful, or a specific X509 error code
|
||||
*/
|
||||
int x509write_copy_issuer(x509_raw *crt, x509_cert *from_crt);
|
||||
|
||||
/**
|
||||
* \brief Copy x509 subject field from another certificate
|
||||
*
|
||||
* \param chain points to the raw certificate data
|
||||
* \param from_crt the certificate whose subject is to be copied.
|
||||
* \return 0 if successful, or a specific X509 error code
|
||||
*/
|
||||
int x509write_copy_subject(x509_raw *crt, x509_cert *from_crt);
|
||||
|
||||
/**
|
||||
* \brief Copy x509 issuer field from the subject of another certificate
|
||||
*
|
||||
* \param chain points to the raw certificate data
|
||||
* \param from_crt the certificate whose subject is to be copied.
|
||||
* \return 0 if successful, or a specific X509 error code
|
||||
*/
|
||||
int x509write_copy_issuer_from_subject(x509_raw *crt, x509_cert *from_crt);
|
||||
|
||||
/**
|
||||
* \brief Copy x509 subject field from the issuer of another certificate
|
||||
*
|
||||
* \param chain points to the raw certificate data
|
||||
* \param from_crt the certificate whose issuer is to be copied.
|
||||
* \return 0 if successful, or a specific X509 error code
|
||||
*/
|
||||
int x509write_copy_subject_from_issuer(x509_raw *crt, x509_cert *from_crt);
|
||||
|
||||
/**
|
||||
* \brief Create x509 validity time in UTC
|
||||
*
|
||||
* \param chain points to the raw certificate data
|
||||
* \param before valid not before in format YYYY-MM-DD hh:mm:ss
|
||||
* \param after valid not after in format YYYY-MM-DD hh:mm:ss
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 error code
|
||||
*/
|
||||
int x509write_add_validity( x509_raw *crt,
|
||||
unsigned char *before,
|
||||
unsigned char *after );
|
||||
|
||||
/**
|
||||
* \brief Create a self-signed certificate
|
||||
*
|
||||
* \param chain points to the raw certificate data
|
||||
* \param rsa a private key to sign the certificate
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 error code
|
||||
*/
|
||||
int x509write_create_selfsign( x509_raw *crt, rsa_context *raw );
|
||||
|
||||
/**
|
||||
* \brief Create a certificate
|
||||
*
|
||||
* \param chain points to the raw certificate data
|
||||
* \param rsa a private key to sign the certificate
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 error code
|
||||
*/
|
||||
int x509write_create_sign( x509_raw *crt, rsa_context *raw );
|
||||
|
||||
/**
|
||||
* \brief Create a certificate signing request
|
||||
*
|
||||
* \param chain points to the raw certificate data. Didn't use the
|
||||
* same chain that u have use for certificate.
|
||||
* \param privkey a rsa private key
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 error code
|
||||
*/
|
||||
int x509write_create_csr( x509_raw *chain, rsa_context *privkey );
|
||||
|
||||
/**
|
||||
* \brief Serialize an rsa key into DER
|
||||
*
|
||||
* \param rsa a rsa key for output
|
||||
* \param node a x509 node for write into
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 error code
|
||||
*/
|
||||
int x509write_serialize_key( rsa_context *rsa, x509_node *node );
|
||||
|
||||
/**
|
||||
* \brief Unallocate all raw certificate data
|
||||
*/
|
||||
void x509write_free_raw( x509_raw *crt );
|
||||
|
||||
/**
|
||||
* \brief Allocate all raw certificate data
|
||||
*/
|
||||
void x509write_init_raw( x509_raw *crt );
|
||||
|
||||
/**
|
||||
* \brief Unallocate all node certificate data
|
||||
*/
|
||||
void x509write_free_node( x509_node *crt_node );
|
||||
|
||||
/**
|
||||
* \brief Allocate all node certificate data
|
||||
*/
|
||||
void x509write_init_node( x509_node *crt_node );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* x509.h */
|
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
* px5g - Embedded x509 key and certificate generator based on PolarSSL
|
||||
*
|
||||
* Copyright (C) 2009 Steven Barth <steven@midlink.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License, version 2.1 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "polarssl/havege.h"
|
||||
#include "polarssl/bignum.h"
|
||||
#include "polarssl/x509.h"
|
||||
#include "polarssl/rsa.h"
|
||||
|
||||
#define PX5G_VERSION "0.1"
|
||||
#define PX5G_COPY "Copyright (c) 2009 Steven Barth <steven@midlink.org>"
|
||||
#define PX5G_LICENSE "Licensed under the GNU Lesser General Public License v2.1"
|
||||
|
||||
int rsakey(char **arg) {
|
||||
havege_state hs;
|
||||
rsa_context rsa;
|
||||
|
||||
unsigned int ksize = 512;
|
||||
int exp = 65537;
|
||||
char *path = NULL;
|
||||
int flag = X509_OUTPUT_PEM;
|
||||
|
||||
while (*arg && **arg == '-') {
|
||||
if (!strcmp(*arg, "-out") && arg[1]) {
|
||||
path = arg[1];
|
||||
arg++;
|
||||
} else if (!strcmp(*arg, "-3")) {
|
||||
exp = 3;
|
||||
} else if (!strcmp(*arg, "-der")) {
|
||||
flag = X509_OUTPUT_DER;
|
||||
}
|
||||
arg++;
|
||||
}
|
||||
|
||||
if (*arg) {
|
||||
ksize = (unsigned int)atoi(*arg);
|
||||
}
|
||||
|
||||
havege_init(&hs);
|
||||
rsa_init(&rsa, RSA_PKCS_V15, 0, havege_rand, &hs);
|
||||
|
||||
fprintf(stderr, "Generating RSA private key, %i bit long modulus\n", ksize);
|
||||
if (rsa_gen_key(&rsa, ksize, exp)) {
|
||||
fprintf(stderr, "error: key generation failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (x509write_keyfile(&rsa, path, flag)) {
|
||||
fprintf(stderr, "error: I/O error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
rsa_free(&rsa);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int selfsigned(char **arg) {
|
||||
havege_state hs;
|
||||
rsa_context rsa;
|
||||
x509_node node;
|
||||
|
||||
char *subject = "";
|
||||
unsigned int ksize = 512;
|
||||
int exp = 65537;
|
||||
unsigned int days = 30;
|
||||
char *keypath = NULL, *certpath = NULL;
|
||||
int flag = X509_OUTPUT_PEM;
|
||||
time_t from = time(NULL), to;
|
||||
char fstr[20], tstr[20];
|
||||
|
||||
while (*arg && **arg == '-') {
|
||||
if (!strcmp(*arg, "-der")) {
|
||||
flag = X509_OUTPUT_DER;
|
||||
} else if (!strcmp(*arg, "-newkey") && arg[1]) {
|
||||
if (strncmp(arg[1], "rsa:", 4)) {
|
||||
fprintf(stderr, "error: invalid algorithm");
|
||||
return 1;
|
||||
}
|
||||
ksize = (unsigned int)atoi(arg[1] + 4);
|
||||
arg++;
|
||||
} else if (!strcmp(*arg, "-days") && arg[1]) {
|
||||
days = (unsigned int)atoi(arg[1]);
|
||||
arg++;
|
||||
} else if (!strcmp(*arg, "-keyout") && arg[1]) {
|
||||
keypath = arg[1];
|
||||
arg++;
|
||||
} else if (!strcmp(*arg, "-out") && arg[1]) {
|
||||
certpath = arg[1];
|
||||
arg++;
|
||||
} else if (!strcmp(*arg, "-subj") && arg[1]) {
|
||||
if (arg[1][0] != '/' || strchr(arg[1], ';')) {
|
||||
fprintf(stderr, "error: invalid subject");
|
||||
return 1;
|
||||
}
|
||||
subject = calloc(strlen(arg[1]) + 1, 1);
|
||||
char *oldc = arg[1] + 1, *newc = subject, *delim;
|
||||
do {
|
||||
delim = strchr(oldc, '=');
|
||||
if (!delim) {
|
||||
fprintf(stderr, "error: invalid subject");
|
||||
return 1;
|
||||
}
|
||||
memcpy(newc, oldc, delim - oldc + 1);
|
||||
newc += delim - oldc + 1;
|
||||
oldc = delim + 1;
|
||||
|
||||
delim = strchr(oldc, '/');
|
||||
if (!delim) {
|
||||
delim = arg[1] + strlen(arg[1]);
|
||||
}
|
||||
memcpy(newc, oldc, delim - oldc);
|
||||
newc += delim - oldc;
|
||||
*newc++ = ';';
|
||||
oldc = delim + 1;
|
||||
} while(*delim);
|
||||
arg++;
|
||||
}
|
||||
arg++;
|
||||
}
|
||||
|
||||
havege_init(&hs);
|
||||
rsa_init(&rsa, RSA_PKCS_V15, 0, havege_rand, &hs);
|
||||
x509write_init_node(&node);
|
||||
fprintf(stderr, "Generating RSA private key, %i bit long modulus\n", ksize);
|
||||
if (rsa_gen_key(&rsa, ksize, exp)) {
|
||||
fprintf(stderr, "error: key generation failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (keypath) {
|
||||
if (x509write_keyfile(&rsa, keypath, flag)) {
|
||||
fprintf(stderr, "error: I/O error\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
from = (from < 1000000000) ? 1000000000 : from;
|
||||
strftime(fstr, sizeof(fstr), "%F %H:%M:%S", gmtime(&from));
|
||||
to = from + 60 * 60 * 24 * days;
|
||||
strftime(tstr, sizeof(tstr), "%F %H:%M:%S", gmtime(&to));
|
||||
|
||||
x509_raw cert;
|
||||
x509write_init_raw(&cert);
|
||||
x509write_add_pubkey(&cert, &rsa);
|
||||
x509write_add_subject(&cert, (unsigned char*)subject);
|
||||
x509write_add_validity(&cert, (unsigned char*)fstr, (unsigned char*)tstr);
|
||||
fprintf(stderr, "Generating selfsigned certificate with subject '%s'"
|
||||
" and validity %s-%s\n", subject, fstr, tstr);
|
||||
if (x509write_create_selfsign(&cert, &rsa)) {
|
||||
fprintf(stderr, "error: certificate generation failed\n");
|
||||
}
|
||||
|
||||
if (x509write_crtfile(&cert, (unsigned char*)certpath, flag)) {
|
||||
fprintf(stderr, "error: I/O error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
x509write_free_raw(&cert);
|
||||
rsa_free(&rsa);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (!argv[1]) {
|
||||
//Usage
|
||||
} else if (!strcmp(argv[1], "rsakey")) {
|
||||
return rsakey(argv+2);
|
||||
} else if (!strcmp(argv[1], "selfsigned")) {
|
||||
return selfsigned(argv+2);
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"PX5G X.509 Certificate Generator Utility v" PX5G_VERSION "\n" PX5G_COPY
|
||||
"\nbased on PolarSSL by Christophe Devine and Paul Bakker\n\n");
|
||||
fprintf(stderr, "Usage: %s [rsakey|selfsigned]\n", *argv);
|
||||
return 1;
|
||||
}
|
Loading…
Reference in New Issue