From: Felix Fietkau Date: Fri, 21 Mar 2014 15:55:23 +0000 (+0000) Subject: px5g: rename the old package to px5g-standalone, add a new one that links against... X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=eb225996ee9591eaa4ad74cd6040038bd35b92cb;p=openwrt%2Fstaging%2Flynxis%2Fomap.git px5g: rename the old package to px5g-standalone, add a new one that links against polarssl Signed-off-by: Felix Fietkau SVN-Revision: 40000 --- diff --git a/package/utils/px5g-standalone/Makefile b/package/utils/px5g-standalone/Makefile new file mode 100644 index 0000000000..25777967bc --- /dev/null +++ b/package/utils/px5g-standalone/Makefile @@ -0,0 +1,40 @@ +# +# Copyright (C) 2010 Jo-Philipp Wich +# +# 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-standalone + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Standalone X.509 certificate generator (standalone version) + MAINTAINER:=Jo-Philipp Wich +endef + +define Package/px5g-standalone/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-standalone/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/px5g $(1)/usr/sbin/px5g +endef + +$(eval $(call BuildPackage,px5g-standalone)) diff --git a/package/utils/px5g-standalone/src/Makefile b/package/utils/px5g-standalone/src/Makefile new file mode 100644 index 0000000000..2bd95739cb --- /dev/null +++ b/package/utils/px5g-standalone/src/Makefile @@ -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) diff --git a/package/utils/px5g-standalone/src/library/base64.c b/package/utils/px5g-standalone/src/library/base64.c new file mode 100644 index 0000000000..b7cc5b84ea --- /dev/null +++ b/package/utils/px5g-standalone/src/library/base64.c @@ -0,0 +1,264 @@ +/* + * RFC 1521 base64 encoding/decoding + * + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine + * + * Copyright (C) 2009 Paul Bakker + * + * 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 +#include + +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 diff --git a/package/utils/px5g-standalone/src/library/bignum.c b/package/utils/px5g-standalone/src/library/bignum.c new file mode 100644 index 0000000000..8b7c12ff00 --- /dev/null +++ b/package/utils/px5g-standalone/src/library/bignum.c @@ -0,0 +1,2010 @@ +/* + * Multi-precision integer library + * + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine + * + * Copyright (C) 2009 Paul Bakker + * + * 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 MPI implementation is based on: + * + * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf + * http://www.stillhq.com/extracted/gnupg-api/mpi/ + * http://math.libtomcrypt.com/files/tommath.pdf + */ + +#include "polarssl/config.h" + +#if defined(POLARSSL_BIGNUM_C) + +#include "polarssl/bignum.h" +#include "polarssl/bn_mul.h" + +#include +#include +#include + +#define ciL ((int) sizeof(t_int)) /* chars in limb */ +#define biL (ciL << 3) /* bits in limb */ +#define biH (ciL << 2) /* half limb size */ + +/* + * Convert between bits/chars and number of limbs + */ +#define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL) +#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL) + +/* + * Initialize one or more mpi + */ +void mpi_init( mpi *X, ... ) +{ + va_list args; + + va_start( args, X ); + + while( X != NULL ) + { + X->s = 1; + X->n = 0; + X->p = NULL; + + X = va_arg( args, mpi* ); + } + + va_end( args ); +} + +/* + * Unallocate one or more mpi + */ +void mpi_free( mpi *X, ... ) +{ + va_list args; + + va_start( args, X ); + + while( X != NULL ) + { + if( X->p != NULL ) + { + memset( X->p, 0, X->n * ciL ); + free( X->p ); + } + + X->s = 1; + X->n = 0; + X->p = NULL; + + X = va_arg( args, mpi* ); + } + + va_end( args ); +} + +/* + * Enlarge to the specified number of limbs + */ +int mpi_grow( mpi *X, int nblimbs ) +{ + t_int *p; + + if( X->n < nblimbs ) + { + if( ( p = (t_int *) malloc( nblimbs * ciL ) ) == NULL ) + return( 1 ); + + memset( p, 0, nblimbs * ciL ); + + if( X->p != NULL ) + { + memcpy( p, X->p, X->n * ciL ); + memset( X->p, 0, X->n * ciL ); + free( X->p ); + } + + X->n = nblimbs; + X->p = p; + } + + return( 0 ); +} + +/* + * Copy the contents of Y into X + */ +int mpi_copy( mpi *X, mpi *Y ) +{ + int ret, i; + + if( X == Y ) + return( 0 ); + + for( i = Y->n - 1; i > 0; i-- ) + if( Y->p[i] != 0 ) + break; + i++; + + X->s = Y->s; + + MPI_CHK( mpi_grow( X, i ) ); + + memset( X->p, 0, X->n * ciL ); + memcpy( X->p, Y->p, i * ciL ); + +cleanup: + + return( ret ); +} + +/* + * Swap the contents of X and Y + */ +void mpi_swap( mpi *X, mpi *Y ) +{ + mpi T; + + memcpy( &T, X, sizeof( mpi ) ); + memcpy( X, Y, sizeof( mpi ) ); + memcpy( Y, &T, sizeof( mpi ) ); +} + +/* + * Set value from integer + */ +int mpi_lset( mpi *X, int z ) +{ + int ret; + + MPI_CHK( mpi_grow( X, 1 ) ); + memset( X->p, 0, X->n * ciL ); + + X->p[0] = ( z < 0 ) ? -z : z; + X->s = ( z < 0 ) ? -1 : 1; + +cleanup: + + return( ret ); +} + +/* + * Return the number of least significant bits + */ +int mpi_lsb( mpi *X ) +{ + int i, j, count = 0; + + for( i = 0; i < X->n; i++ ) + for( j = 0; j < (int) biL; j++, count++ ) + if( ( ( X->p[i] >> j ) & 1 ) != 0 ) + return( count ); + + return( 0 ); +} + +/* + * Return the number of most significant bits + */ +int mpi_msb( mpi *X ) +{ + int i, j; + + for( i = X->n - 1; i > 0; i-- ) + if( X->p[i] != 0 ) + break; + + for( j = biL - 1; j >= 0; j-- ) + if( ( ( X->p[i] >> j ) & 1 ) != 0 ) + break; + + return( ( i * biL ) + j + 1 ); +} + +/* + * Return the total size in bytes + */ +int mpi_size( mpi *X ) +{ + return( ( mpi_msb( X ) + 7 ) >> 3 ); +} + +/* + * Convert an ASCII character to digit value + */ +static int mpi_get_digit( t_int *d, int radix, char c ) +{ + *d = 255; + + if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30; + if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37; + if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57; + + if( *d >= (t_int) radix ) + return( POLARSSL_ERR_MPI_INVALID_CHARACTER ); + + return( 0 ); +} + +/* + * Import from an ASCII string + */ +int mpi_read_string( mpi *X, int radix, char *s ) +{ + int ret, i, j, n; + t_int d; + mpi T; + + if( radix < 2 || radix > 16 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + mpi_init( &T, NULL ); + + if( radix == 16 ) + { + n = BITS_TO_LIMBS( strlen( s ) << 2 ); + + MPI_CHK( mpi_grow( X, n ) ); + MPI_CHK( mpi_lset( X, 0 ) ); + + for( i = strlen( s ) - 1, j = 0; i >= 0; i--, j++ ) + { + if( i == 0 && s[i] == '-' ) + { + X->s = -1; + break; + } + + MPI_CHK( mpi_get_digit( &d, radix, s[i] ) ); + X->p[j / (2 * ciL)] |= d << ( (j % (2 * ciL)) << 2 ); + } + } + else + { + MPI_CHK( mpi_lset( X, 0 ) ); + + for( i = 0; i < (int) strlen( s ); i++ ) + { + if( i == 0 && s[i] == '-' ) + { + X->s = -1; + continue; + } + + MPI_CHK( mpi_get_digit( &d, radix, s[i] ) ); + MPI_CHK( mpi_mul_int( &T, X, radix ) ); + MPI_CHK( mpi_add_int( X, &T, d ) ); + } + } + +cleanup: + + mpi_free( &T, NULL ); + + return( ret ); +} + +/* + * Helper to write the digits high-order first + */ +static int mpi_write_hlp( mpi *X, int radix, char **p ) +{ + int ret; + t_int r; + + if( radix < 2 || radix > 16 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + MPI_CHK( mpi_mod_int( &r, X, radix ) ); + MPI_CHK( mpi_div_int( X, NULL, X, radix ) ); + + if( mpi_cmp_int( X, 0 ) != 0 ) + MPI_CHK( mpi_write_hlp( X, radix, p ) ); + + if( r < 10 ) + *(*p)++ = (char)( r + 0x30 ); + else + *(*p)++ = (char)( r + 0x37 ); + +cleanup: + + return( ret ); +} + +/* + * Export into an ASCII string + */ +int mpi_write_string( mpi *X, int radix, char *s, int *slen ) +{ + int ret = 0, n; + char *p; + mpi T; + + if( radix < 2 || radix > 16 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + n = mpi_msb( X ); + if( radix >= 4 ) n >>= 1; + if( radix >= 16 ) n >>= 1; + n += 3; + + if( *slen < n ) + { + *slen = n; + return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL ); + } + + p = s; + mpi_init( &T, NULL ); + + if( X->s == -1 ) + *p++ = '-'; + + if( radix == 16 ) + { + int c, i, j, k; + + for( i = X->n - 1, k = 0; i >= 0; i-- ) + { + for( j = ciL - 1; j >= 0; j-- ) + { + c = ( X->p[i] >> (j << 3) ) & 0xFF; + + if( c == 0 && k == 0 && (i + j) != 0 ) + continue; + + p += sprintf( p, "%02X", c ); + k = 1; + } + } + } + else + { + MPI_CHK( mpi_copy( &T, X ) ); + MPI_CHK( mpi_write_hlp( &T, radix, &p ) ); + } + + *p++ = '\0'; + *slen = p - s; + +cleanup: + + mpi_free( &T, NULL ); + + return( ret ); +} + +/* + * Read X from an opened file + */ +int mpi_read_file( mpi *X, int radix, FILE *fin ) +{ + t_int d; + int slen; + char *p; + char s[1024]; + + memset( s, 0, sizeof( s ) ); + if( fgets( s, sizeof( s ) - 1, fin ) == NULL ) + return( POLARSSL_ERR_MPI_FILE_IO_ERROR ); + + slen = strlen( s ); + if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; } + if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; } + + p = s + slen; + while( --p >= s ) + if( mpi_get_digit( &d, radix, *p ) != 0 ) + break; + + return( mpi_read_string( X, radix, p + 1 ) ); +} + +/* + * Write X into an opened file (or stdout if fout == NULL) + */ +int mpi_write_file( char *p, mpi *X, int radix, FILE *fout ) +{ + int n, ret; + size_t slen; + size_t plen; + char s[1024]; + + n = sizeof( s ); + memset( s, 0, n ); + n -= 2; + + MPI_CHK( mpi_write_string( X, radix, s, (int *) &n ) ); + + if( p == NULL ) p = ""; + + plen = strlen( p ); + slen = strlen( s ); + s[slen++] = '\r'; + s[slen++] = '\n'; + + if( fout != NULL ) + { + if( fwrite( p, 1, plen, fout ) != plen || + fwrite( s, 1, slen, fout ) != slen ) + return( POLARSSL_ERR_MPI_FILE_IO_ERROR ); + } + else + printf( "%s%s", p, s ); + +cleanup: + + return( ret ); +} + +/* + * Import X from unsigned binary data, big endian + */ +int mpi_read_binary( mpi *X, unsigned char *buf, int buflen ) +{ + int ret, i, j, n; + + for( n = 0; n < buflen; n++ ) + if( buf[n] != 0 ) + break; + + MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) ); + MPI_CHK( mpi_lset( X, 0 ) ); + + for( i = buflen - 1, j = 0; i >= n; i--, j++ ) + X->p[j / ciL] |= ((t_int) buf[i]) << ((j % ciL) << 3); + +cleanup: + + return( ret ); +} + +/* + * Export X into unsigned binary data, big endian + */ +int mpi_write_binary( mpi *X, unsigned char *buf, int buflen ) +{ + int i, j, n; + + n = mpi_size( X ); + + if( buflen < n ) + return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL ); + + memset( buf, 0, buflen ); + + for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- ) + buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) ); + + return( 0 ); +} + +/* + * Left-shift: X <<= count + */ +int mpi_shift_l( mpi *X, int count ) +{ + int ret, i, v0, t1; + t_int r0 = 0, r1; + + v0 = count / (biL ); + t1 = count & (biL - 1); + + i = mpi_msb( X ) + count; + + if( X->n * (int) biL < i ) + MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) ); + + ret = 0; + + /* + * shift by count / limb_size + */ + if( v0 > 0 ) + { + for( i = X->n - 1; i >= v0; i-- ) + X->p[i] = X->p[i - v0]; + + for( ; i >= 0; i-- ) + X->p[i] = 0; + } + + /* + * shift by count % limb_size + */ + if( t1 > 0 ) + { + for( i = v0; i < X->n; i++ ) + { + r1 = X->p[i] >> (biL - t1); + X->p[i] <<= t1; + X->p[i] |= r0; + r0 = r1; + } + } + +cleanup: + + return( ret ); +} + +/* + * Right-shift: X >>= count + */ +int mpi_shift_r( mpi *X, int count ) +{ + int i, v0, v1; + t_int r0 = 0, r1; + + v0 = count / biL; + v1 = count & (biL - 1); + + /* + * shift by count / limb_size + */ + if( v0 > 0 ) + { + for( i = 0; i < X->n - v0; i++ ) + X->p[i] = X->p[i + v0]; + + for( ; i < X->n; i++ ) + X->p[i] = 0; + } + + /* + * shift by count % limb_size + */ + if( v1 > 0 ) + { + for( i = X->n - 1; i >= 0; i-- ) + { + r1 = X->p[i] << (biL - v1); + X->p[i] >>= v1; + X->p[i] |= r0; + r0 = r1; + } + } + + return( 0 ); +} + +/* + * Compare unsigned values + */ +int mpi_cmp_abs( mpi *X, mpi *Y ) +{ + int i, j; + + for( i = X->n - 1; i >= 0; i-- ) + if( X->p[i] != 0 ) + break; + + for( j = Y->n - 1; j >= 0; j-- ) + if( Y->p[j] != 0 ) + break; + + if( i < 0 && j < 0 ) + return( 0 ); + + if( i > j ) return( 1 ); + if( j > i ) return( -1 ); + + for( ; i >= 0; i-- ) + { + if( X->p[i] > Y->p[i] ) return( 1 ); + if( X->p[i] < Y->p[i] ) return( -1 ); + } + + return( 0 ); +} + +/* + * Compare signed values + */ +int mpi_cmp_mpi( mpi *X, mpi *Y ) +{ + int i, j; + + for( i = X->n - 1; i >= 0; i-- ) + if( X->p[i] != 0 ) + break; + + for( j = Y->n - 1; j >= 0; j-- ) + if( Y->p[j] != 0 ) + break; + + if( i < 0 && j < 0 ) + return( 0 ); + + if( i > j ) return( X->s ); + if( j > i ) return( -X->s ); + + if( X->s > 0 && Y->s < 0 ) return( 1 ); + if( Y->s > 0 && X->s < 0 ) return( -1 ); + + for( ; i >= 0; i-- ) + { + if( X->p[i] > Y->p[i] ) return( X->s ); + if( X->p[i] < Y->p[i] ) return( -X->s ); + } + + return( 0 ); +} + +/* + * Compare signed values + */ +int mpi_cmp_int( mpi *X, int z ) +{ + mpi Y; + t_int p[1]; + + *p = ( z < 0 ) ? -z : z; + Y.s = ( z < 0 ) ? -1 : 1; + Y.n = 1; + Y.p = p; + + return( mpi_cmp_mpi( X, &Y ) ); +} + +/* + * Unsigned addition: X = |A| + |B| (HAC 14.7) + */ +int mpi_add_abs( mpi *X, mpi *A, mpi *B ) +{ + int ret, i, j; + t_int *o, *p, c; + + if( X == B ) + { + mpi *T = A; A = X; B = T; + } + + if( X != A ) + MPI_CHK( mpi_copy( X, A ) ); + + for( j = B->n - 1; j >= 0; j-- ) + if( B->p[j] != 0 ) + break; + + MPI_CHK( mpi_grow( X, j + 1 ) ); + + o = B->p; p = X->p; c = 0; + + for( i = 0; i <= j; i++, o++, p++ ) + { + *p += c; c = ( *p < c ); + *p += *o; c += ( *p < *o ); + } + + while( c != 0 ) + { + if( i >= X->n ) + { + MPI_CHK( mpi_grow( X, i + 1 ) ); + p = X->p + i; + } + + *p += c; c = ( *p < c ); i++; + } + +cleanup: + + return( ret ); +} + +/* + * Helper for mpi substraction + */ +static void mpi_sub_hlp( int n, t_int *s, t_int *d ) +{ + int i; + t_int c, z; + + for( i = c = 0; i < n; i++, s++, d++ ) + { + z = ( *d < c ); *d -= c; + c = ( *d < *s ) + z; *d -= *s; + } + + while( c != 0 ) + { + z = ( *d < c ); *d -= c; + c = z; i++; d++; + } +} + +/* + * Unsigned substraction: X = |A| - |B| (HAC 14.9) + */ +int mpi_sub_abs( mpi *X, mpi *A, mpi *B ) +{ + mpi TB; + int ret, n; + + if( mpi_cmp_abs( A, B ) < 0 ) + return( POLARSSL_ERR_MPI_NEGATIVE_VALUE ); + + mpi_init( &TB, NULL ); + + if( X == B ) + { + MPI_CHK( mpi_copy( &TB, B ) ); + B = &TB; + } + + if( X != A ) + MPI_CHK( mpi_copy( X, A ) ); + + ret = 0; + + for( n = B->n - 1; n >= 0; n-- ) + if( B->p[n] != 0 ) + break; + + mpi_sub_hlp( n + 1, B->p, X->p ); + +cleanup: + + mpi_free( &TB, NULL ); + + return( ret ); +} + +/* + * Signed addition: X = A + B + */ +int mpi_add_mpi( mpi *X, mpi *A, mpi *B ) +{ + int ret, s = A->s; + + if( A->s * B->s < 0 ) + { + if( mpi_cmp_abs( A, B ) >= 0 ) + { + MPI_CHK( mpi_sub_abs( X, A, B ) ); + X->s = s; + } + else + { + MPI_CHK( mpi_sub_abs( X, B, A ) ); + X->s = -s; + } + } + else + { + MPI_CHK( mpi_add_abs( X, A, B ) ); + X->s = s; + } + +cleanup: + + return( ret ); +} + +/* + * Signed substraction: X = A - B + */ +int mpi_sub_mpi( mpi *X, mpi *A, mpi *B ) +{ + int ret, s = A->s; + + if( A->s * B->s > 0 ) + { + if( mpi_cmp_abs( A, B ) >= 0 ) + { + MPI_CHK( mpi_sub_abs( X, A, B ) ); + X->s = s; + } + else + { + MPI_CHK( mpi_sub_abs( X, B, A ) ); + X->s = -s; + } + } + else + { + MPI_CHK( mpi_add_abs( X, A, B ) ); + X->s = s; + } + +cleanup: + + return( ret ); +} + +/* + * Signed addition: X = A + b + */ +int mpi_add_int( mpi *X, mpi *A, int b ) +{ + mpi _B; + t_int p[1]; + + p[0] = ( b < 0 ) ? -b : b; + _B.s = ( b < 0 ) ? -1 : 1; + _B.n = 1; + _B.p = p; + + return( mpi_add_mpi( X, A, &_B ) ); +} + +/* + * Signed substraction: X = A - b + */ +int mpi_sub_int( mpi *X, mpi *A, int b ) +{ + mpi _B; + t_int p[1]; + + p[0] = ( b < 0 ) ? -b : b; + _B.s = ( b < 0 ) ? -1 : 1; + _B.n = 1; + _B.p = p; + + return( mpi_sub_mpi( X, A, &_B ) ); +} + +/* + * Helper for mpi multiplication + */ +static void mpi_mul_hlp( int i, t_int *s, t_int *d, t_int b ) +{ + t_int c = 0, t = 0; + +#if defined(MULADDC_HUIT) + for( ; i >= 8; i -= 8 ) + { + MULADDC_INIT + MULADDC_HUIT + MULADDC_STOP + } + + for( ; i > 0; i-- ) + { + MULADDC_INIT + MULADDC_CORE + MULADDC_STOP + } +#else + for( ; i >= 16; i -= 16 ) + { + MULADDC_INIT + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_STOP + } + + for( ; i >= 8; i -= 8 ) + { + MULADDC_INIT + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_STOP + } + + for( ; i > 0; i-- ) + { + MULADDC_INIT + MULADDC_CORE + MULADDC_STOP + } +#endif + + t++; + + do { + *d += c; c = ( *d < c ); d++; + } + while( c != 0 ); +} + +/* + * Baseline multiplication: X = A * B (HAC 14.12) + */ +int mpi_mul_mpi( mpi *X, mpi *A, mpi *B ) +{ + int ret, i, j; + mpi TA, TB; + + mpi_init( &TA, &TB, NULL ); + + if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; } + if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; } + + for( i = A->n - 1; i >= 0; i-- ) + if( A->p[i] != 0 ) + break; + + for( j = B->n - 1; j >= 0; j-- ) + if( B->p[j] != 0 ) + break; + + MPI_CHK( mpi_grow( X, i + j + 2 ) ); + MPI_CHK( mpi_lset( X, 0 ) ); + + for( i++; j >= 0; j-- ) + mpi_mul_hlp( i, A->p, X->p + j, B->p[j] ); + + X->s = A->s * B->s; + +cleanup: + + mpi_free( &TB, &TA, NULL ); + + return( ret ); +} + +/* + * Baseline multiplication: X = A * b + */ +int mpi_mul_int( mpi *X, mpi *A, t_int b ) +{ + mpi _B; + t_int p[1]; + + _B.s = 1; + _B.n = 1; + _B.p = p; + p[0] = b; + + return( mpi_mul_mpi( X, A, &_B ) ); +} + +/* + * Division by mpi: A = Q * B + R (HAC 14.20) + */ +int mpi_div_mpi( mpi *Q, mpi *R, mpi *A, mpi *B ) +{ + int ret, i, n, t, k; + mpi X, Y, Z, T1, T2; + + if( mpi_cmp_int( B, 0 ) == 0 ) + return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO ); + + mpi_init( &X, &Y, &Z, &T1, &T2, NULL ); + + if( mpi_cmp_abs( A, B ) < 0 ) + { + if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) ); + if( R != NULL ) MPI_CHK( mpi_copy( R, A ) ); + return( 0 ); + } + + MPI_CHK( mpi_copy( &X, A ) ); + MPI_CHK( mpi_copy( &Y, B ) ); + X.s = Y.s = 1; + + MPI_CHK( mpi_grow( &Z, A->n + 2 ) ); + MPI_CHK( mpi_lset( &Z, 0 ) ); + MPI_CHK( mpi_grow( &T1, 2 ) ); + MPI_CHK( mpi_grow( &T2, 3 ) ); + + k = mpi_msb( &Y ) % biL; + if( k < (int) biL - 1 ) + { + k = biL - 1 - k; + MPI_CHK( mpi_shift_l( &X, k ) ); + MPI_CHK( mpi_shift_l( &Y, k ) ); + } + else k = 0; + + n = X.n - 1; + t = Y.n - 1; + mpi_shift_l( &Y, biL * (n - t) ); + + while( mpi_cmp_mpi( &X, &Y ) >= 0 ) + { + Z.p[n - t]++; + mpi_sub_mpi( &X, &X, &Y ); + } + mpi_shift_r( &Y, biL * (n - t) ); + + for( i = n; i > t ; i-- ) + { + if( X.p[i] >= Y.p[t] ) + Z.p[i - t - 1] = ~0; + else + { +#if defined(POLARSSL_HAVE_LONGLONG) + t_dbl r; + + r = (t_dbl) X.p[i] << biL; + r |= (t_dbl) X.p[i - 1]; + r /= Y.p[t]; + if( r > ((t_dbl) 1 << biL) - 1) + r = ((t_dbl) 1 << biL) - 1; + + Z.p[i - t - 1] = (t_int) r; +#else + /* + * __udiv_qrnnd_c, from gmp/longlong.h + */ + t_int q0, q1, r0, r1; + t_int d0, d1, d, m; + + d = Y.p[t]; + d0 = ( d << biH ) >> biH; + d1 = ( d >> biH ); + + q1 = X.p[i] / d1; + r1 = X.p[i] - d1 * q1; + r1 <<= biH; + r1 |= ( X.p[i - 1] >> biH ); + + m = q1 * d0; + if( r1 < m ) + { + q1--, r1 += d; + while( r1 >= d && r1 < m ) + q1--, r1 += d; + } + r1 -= m; + + q0 = r1 / d1; + r0 = r1 - d1 * q0; + r0 <<= biH; + r0 |= ( X.p[i - 1] << biH ) >> biH; + + m = q0 * d0; + if( r0 < m ) + { + q0--, r0 += d; + while( r0 >= d && r0 < m ) + q0--, r0 += d; + } + r0 -= m; + + Z.p[i - t - 1] = ( q1 << biH ) | q0; +#endif + } + + Z.p[i - t - 1]++; + do + { + Z.p[i - t - 1]--; + + MPI_CHK( mpi_lset( &T1, 0 ) ); + T1.p[0] = (t < 1) ? 0 : Y.p[t - 1]; + T1.p[1] = Y.p[t]; + MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) ); + + MPI_CHK( mpi_lset( &T2, 0 ) ); + T2.p[0] = (i < 2) ? 0 : X.p[i - 2]; + T2.p[1] = (i < 1) ? 0 : X.p[i - 1]; + T2.p[2] = X.p[i]; + } + while( mpi_cmp_mpi( &T1, &T2 ) > 0 ); + + MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) ); + MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) ); + MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) ); + + if( mpi_cmp_int( &X, 0 ) < 0 ) + { + MPI_CHK( mpi_copy( &T1, &Y ) ); + MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) ); + MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) ); + Z.p[i - t - 1]--; + } + } + + if( Q != NULL ) + { + mpi_copy( Q, &Z ); + Q->s = A->s * B->s; + } + + if( R != NULL ) + { + mpi_shift_r( &X, k ); + mpi_copy( R, &X ); + + R->s = A->s; + if( mpi_cmp_int( R, 0 ) == 0 ) + R->s = 1; + } + +cleanup: + + mpi_free( &X, &Y, &Z, &T1, &T2, NULL ); + + return( ret ); +} + +/* + * Division by int: A = Q * b + R + * + * Returns 0 if successful + * 1 if memory allocation failed + * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0 + */ +int mpi_div_int( mpi *Q, mpi *R, mpi *A, int b ) +{ + mpi _B; + t_int p[1]; + + p[0] = ( b < 0 ) ? -b : b; + _B.s = ( b < 0 ) ? -1 : 1; + _B.n = 1; + _B.p = p; + + return( mpi_div_mpi( Q, R, A, &_B ) ); +} + +/* + * Modulo: R = A mod B + */ +int mpi_mod_mpi( mpi *R, mpi *A, mpi *B ) +{ + int ret; + + MPI_CHK( mpi_div_mpi( NULL, R, A, B ) ); + + while( mpi_cmp_int( R, 0 ) < 0 ) + MPI_CHK( mpi_add_mpi( R, R, B ) ); + + while( mpi_cmp_mpi( R, B ) >= 0 ) + MPI_CHK( mpi_sub_mpi( R, R, B ) ); + +cleanup: + + return( ret ); +} + +/* + * Modulo: r = A mod b + */ +int mpi_mod_int( t_int *r, mpi *A, int b ) +{ + int i; + t_int x, y, z; + + if( b == 0 ) + return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO ); + + if( b < 0 ) + b = -b; + + /* + * handle trivial cases + */ + if( b == 1 ) + { + *r = 0; + return( 0 ); + } + + if( b == 2 ) + { + *r = A->p[0] & 1; + return( 0 ); + } + + /* + * general case + */ + for( i = A->n - 1, y = 0; i >= 0; i-- ) + { + x = A->p[i]; + y = ( y << biH ) | ( x >> biH ); + z = y / b; + y -= z * b; + + x <<= biH; + y = ( y << biH ) | ( x >> biH ); + z = y / b; + y -= z * b; + } + + *r = y; + + return( 0 ); +} + +/* + * Fast Montgomery initialization (thanks to Tom St Denis) + */ +static void mpi_montg_init( t_int *mm, mpi *N ) +{ + t_int x, m0 = N->p[0]; + + x = m0; + x += ( ( m0 + 2 ) & 4 ) << 1; + x *= ( 2 - ( m0 * x ) ); + + if( biL >= 16 ) x *= ( 2 - ( m0 * x ) ); + if( biL >= 32 ) x *= ( 2 - ( m0 * x ) ); + if( biL >= 64 ) x *= ( 2 - ( m0 * x ) ); + + *mm = ~x + 1; +} + +/* + * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36) + */ +static void mpi_montmul( mpi *A, mpi *B, mpi *N, t_int mm, mpi *T ) +{ + int i, n, m; + t_int u0, u1, *d; + + memset( T->p, 0, T->n * ciL ); + + d = T->p; + n = N->n; + m = ( B->n < n ) ? B->n : n; + + for( i = 0; i < n; i++ ) + { + /* + * T = (T + u0*B + u1*N) / 2^biL + */ + u0 = A->p[i]; + u1 = ( d[0] + u0 * B->p[0] ) * mm; + + mpi_mul_hlp( m, B->p, d, u0 ); + mpi_mul_hlp( n, N->p, d, u1 ); + + *d++ = u0; d[n + 1] = 0; + } + + memcpy( A->p, d, (n + 1) * ciL ); + + if( mpi_cmp_abs( A, N ) >= 0 ) + mpi_sub_hlp( n, N->p, A->p ); + else + /* prevent timing attacks */ + mpi_sub_hlp( n, A->p, T->p ); +} + +/* + * Montgomery reduction: A = A * R^-1 mod N + */ +static void mpi_montred( mpi *A, mpi *N, t_int mm, mpi *T ) +{ + t_int z = 1; + mpi U; + + U.n = U.s = z; + U.p = &z; + + mpi_montmul( A, &U, N, mm, T ); +} + +/* + * Sliding-window exponentiation: X = A^E mod N (HAC 14.85) + */ +int mpi_exp_mod( mpi *X, mpi *A, mpi *E, mpi *N, mpi *_RR ) +{ + int ret, i, j, wsize, wbits; + int bufsize, nblimbs, nbits; + t_int ei, mm, state; + mpi RR, T, W[64]; + + if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + /* + * Init temps and window size + */ + mpi_montg_init( &mm, N ); + mpi_init( &RR, &T, NULL ); + memset( W, 0, sizeof( W ) ); + + i = mpi_msb( E ); + + wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 : + ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1; + + j = N->n + 1; + MPI_CHK( mpi_grow( X, j ) ); + MPI_CHK( mpi_grow( &W[1], j ) ); + MPI_CHK( mpi_grow( &T, j * 2 ) ); + + /* + * If 1st call, pre-compute R^2 mod N + */ + if( _RR == NULL || _RR->p == NULL ) + { + MPI_CHK( mpi_lset( &RR, 1 ) ); + MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) ); + MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) ); + + if( _RR != NULL ) + memcpy( _RR, &RR, sizeof( mpi ) ); + } + else + memcpy( &RR, _RR, sizeof( mpi ) ); + + /* + * W[1] = A * R^2 * R^-1 mod N = A * R mod N + */ + if( mpi_cmp_mpi( A, N ) >= 0 ) + mpi_mod_mpi( &W[1], A, N ); + else mpi_copy( &W[1], A ); + + mpi_montmul( &W[1], &RR, N, mm, &T ); + + /* + * X = R^2 * R^-1 mod N = R mod N + */ + MPI_CHK( mpi_copy( X, &RR ) ); + mpi_montred( X, N, mm, &T ); + + if( wsize > 1 ) + { + /* + * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1) + */ + j = 1 << (wsize - 1); + + MPI_CHK( mpi_grow( &W[j], N->n + 1 ) ); + MPI_CHK( mpi_copy( &W[j], &W[1] ) ); + + for( i = 0; i < wsize - 1; i++ ) + mpi_montmul( &W[j], &W[j], N, mm, &T ); + + /* + * W[i] = W[i - 1] * W[1] + */ + for( i = j + 1; i < (1 << wsize); i++ ) + { + MPI_CHK( mpi_grow( &W[i], N->n + 1 ) ); + MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) ); + + mpi_montmul( &W[i], &W[1], N, mm, &T ); + } + } + + nblimbs = E->n; + bufsize = 0; + nbits = 0; + wbits = 0; + state = 0; + + while( 1 ) + { + if( bufsize == 0 ) + { + if( nblimbs-- == 0 ) + break; + + bufsize = sizeof( t_int ) << 3; + } + + bufsize--; + + ei = (E->p[nblimbs] >> bufsize) & 1; + + /* + * skip leading 0s + */ + if( ei == 0 && state == 0 ) + continue; + + if( ei == 0 && state == 1 ) + { + /* + * out of window, square X + */ + mpi_montmul( X, X, N, mm, &T ); + continue; + } + + /* + * add ei to current window + */ + state = 2; + + nbits++; + wbits |= (ei << (wsize - nbits)); + + if( nbits == wsize ) + { + /* + * X = X^wsize R^-1 mod N + */ + for( i = 0; i < wsize; i++ ) + mpi_montmul( X, X, N, mm, &T ); + + /* + * X = X * W[wbits] R^-1 mod N + */ + mpi_montmul( X, &W[wbits], N, mm, &T ); + + state--; + nbits = 0; + wbits = 0; + } + } + + /* + * process the remaining bits + */ + for( i = 0; i < nbits; i++ ) + { + mpi_montmul( X, X, N, mm, &T ); + + wbits <<= 1; + + if( (wbits & (1 << wsize)) != 0 ) + mpi_montmul( X, &W[1], N, mm, &T ); + } + + /* + * X = A^E * R * R^-1 mod N = A^E mod N + */ + mpi_montred( X, N, mm, &T ); + +cleanup: + + for( i = (1 << (wsize - 1)); i < (1 << wsize); i++ ) + mpi_free( &W[i], NULL ); + + if( _RR != NULL ) + mpi_free( &W[1], &T, NULL ); + else mpi_free( &W[1], &T, &RR, NULL ); + + return( ret ); +} + +/* + * Greatest common divisor: G = gcd(A, B) (HAC 14.54) + */ +int mpi_gcd( mpi *G, mpi *A, mpi *B ) +{ + int ret, lz, lzt; + mpi TG, TA, TB; + + mpi_init( &TG, &TA, &TB, NULL ); + + MPI_CHK( mpi_copy( &TA, A ) ); + MPI_CHK( mpi_copy( &TB, B ) ); + + lz = mpi_lsb( &TA ); + lzt = mpi_lsb( &TB ); + + if ( lzt < lz ) + lz = lzt; + + MPI_CHK( mpi_shift_r( &TA, lz ) ); + MPI_CHK( mpi_shift_r( &TB, lz ) ); + + TA.s = TB.s = 1; + + while( mpi_cmp_int( &TA, 0 ) != 0 ) + { + MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) ); + MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) ); + + if( mpi_cmp_mpi( &TA, &TB ) >= 0 ) + { + MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) ); + MPI_CHK( mpi_shift_r( &TA, 1 ) ); + } + else + { + MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) ); + MPI_CHK( mpi_shift_r( &TB, 1 ) ); + } + } + + MPI_CHK( mpi_shift_l( &TB, lz ) ); + MPI_CHK( mpi_copy( G, &TB ) ); + +cleanup: + + mpi_free( &TB, &TA, &TG, NULL ); + + return( ret ); +} + +#if defined(POLARSSL_GENPRIME) + +/* + * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64) + */ +int mpi_inv_mod( mpi *X, mpi *A, mpi *N ) +{ + int ret; + mpi G, TA, TU, U1, U2, TB, TV, V1, V2; + + if( mpi_cmp_int( N, 0 ) <= 0 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + mpi_init( &TA, &TU, &U1, &U2, &G, + &TB, &TV, &V1, &V2, NULL ); + + MPI_CHK( mpi_gcd( &G, A, N ) ); + + if( mpi_cmp_int( &G, 1 ) != 0 ) + { + ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE; + goto cleanup; + } + + MPI_CHK( mpi_mod_mpi( &TA, A, N ) ); + MPI_CHK( mpi_copy( &TU, &TA ) ); + MPI_CHK( mpi_copy( &TB, N ) ); + MPI_CHK( mpi_copy( &TV, N ) ); + + MPI_CHK( mpi_lset( &U1, 1 ) ); + MPI_CHK( mpi_lset( &U2, 0 ) ); + MPI_CHK( mpi_lset( &V1, 0 ) ); + MPI_CHK( mpi_lset( &V2, 1 ) ); + + do + { + while( ( TU.p[0] & 1 ) == 0 ) + { + MPI_CHK( mpi_shift_r( &TU, 1 ) ); + + if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 ) + { + MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) ); + MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) ); + } + + MPI_CHK( mpi_shift_r( &U1, 1 ) ); + MPI_CHK( mpi_shift_r( &U2, 1 ) ); + } + + while( ( TV.p[0] & 1 ) == 0 ) + { + MPI_CHK( mpi_shift_r( &TV, 1 ) ); + + if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 ) + { + MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) ); + MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) ); + } + + MPI_CHK( mpi_shift_r( &V1, 1 ) ); + MPI_CHK( mpi_shift_r( &V2, 1 ) ); + } + + if( mpi_cmp_mpi( &TU, &TV ) >= 0 ) + { + MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) ); + MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) ); + MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) ); + } + else + { + MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) ); + MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) ); + MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) ); + } + } + while( mpi_cmp_int( &TU, 0 ) != 0 ); + + while( mpi_cmp_int( &V1, 0 ) < 0 ) + MPI_CHK( mpi_add_mpi( &V1, &V1, N ) ); + + while( mpi_cmp_mpi( &V1, N ) >= 0 ) + MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) ); + + MPI_CHK( mpi_copy( X, &V1 ) ); + +cleanup: + + mpi_free( &V2, &V1, &TV, &TB, &G, + &U2, &U1, &TU, &TA, NULL ); + + return( ret ); +} + +static const int small_prime[] = +{ + 3, 5, 7, 11, 13, 17, 19, 23, + 29, 31, 37, 41, 43, 47, 53, 59, + 61, 67, 71, 73, 79, 83, 89, 97, + 101, 103, 107, 109, 113, 127, 131, 137, + 139, 149, 151, 157, 163, 167, 173, 179, + 181, 191, 193, 197, 199, 211, 223, 227, + 229, 233, 239, 241, 251, 257, 263, 269, + 271, 277, 281, 283, 293, 307, 311, 313, + 317, 331, 337, 347, 349, 353, 359, 367, + 373, 379, 383, 389, 397, 401, 409, 419, + 421, 431, 433, 439, 443, 449, 457, 461, + 463, 467, 479, 487, 491, 499, 503, 509, + 521, 523, 541, 547, 557, 563, 569, 571, + 577, 587, 593, 599, 601, 607, 613, 617, + 619, 631, 641, 643, 647, 653, 659, 661, + 673, 677, 683, 691, 701, 709, 719, 727, + 733, 739, 743, 751, 757, 761, 769, 773, + 787, 797, 809, 811, 821, 823, 827, 829, + 839, 853, 857, 859, 863, 877, 881, 883, + 887, 907, 911, 919, 929, 937, 941, 947, + 953, 967, 971, 977, 983, 991, 997, -103 +}; + +/* + * Miller-Rabin primality test (HAC 4.24) + */ +int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng ) +{ + int ret, i, j, n, s, xs; + mpi W, R, T, A, RR; + unsigned char *p; + + if( mpi_cmp_int( X, 0 ) == 0 ) + return( 0 ); + + mpi_init( &W, &R, &T, &A, &RR, NULL ); + + xs = X->s; X->s = 1; + + /* + * test trivial factors first + */ + if( ( X->p[0] & 1 ) == 0 ) + return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); + + for( i = 0; small_prime[i] > 0; i++ ) + { + t_int r; + + if( mpi_cmp_int( X, small_prime[i] ) <= 0 ) + return( 0 ); + + MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) ); + + if( r == 0 ) + return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); + } + + /* + * W = |X| - 1 + * R = W >> lsb( W ) + */ + s = mpi_lsb( &W ); + MPI_CHK( mpi_sub_int( &W, X, 1 ) ); + MPI_CHK( mpi_copy( &R, &W ) ); + MPI_CHK( mpi_shift_r( &R, s ) ); + + i = mpi_msb( X ); + /* + * HAC, table 4.4 + */ + n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 : + ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 : + ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 ); + + for( i = 0; i < n; i++ ) + { + /* + * pick a random A, 1 < A < |X| - 1 + */ + MPI_CHK( mpi_grow( &A, X->n ) ); + + p = (unsigned char *) A.p; + for( j = 0; j < A.n * ciL; j++ ) + *p++ = (unsigned char) f_rng( p_rng ); + + j = mpi_msb( &A ) - mpi_msb( &W ); + MPI_CHK( mpi_shift_r( &A, j + 1 ) ); + A.p[0] |= 3; + + /* + * A = A^R mod |X| + */ + MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) ); + + if( mpi_cmp_mpi( &A, &W ) == 0 || + mpi_cmp_int( &A, 1 ) == 0 ) + continue; + + j = 1; + while( j < s && mpi_cmp_mpi( &A, &W ) != 0 ) + { + /* + * A = A * A mod |X| + */ + MPI_CHK( mpi_mul_mpi( &T, &A, &A ) ); + MPI_CHK( mpi_mod_mpi( &A, &T, X ) ); + + if( mpi_cmp_int( &A, 1 ) == 0 ) + break; + + j++; + } + + /* + * not prime if A != |X| - 1 or A == 1 + */ + if( mpi_cmp_mpi( &A, &W ) != 0 || + mpi_cmp_int( &A, 1 ) == 0 ) + { + ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE; + break; + } + } + +cleanup: + + X->s = xs; + + mpi_free( &RR, &A, &T, &R, &W, NULL ); + + return( ret ); +} + +/* + * Prime number generation + */ +int mpi_gen_prime( mpi *X, int nbits, int dh_flag, + int (*f_rng)(void *), void *p_rng ) +{ + int ret, k, n; + unsigned char *p; + mpi Y; + + if( nbits < 3 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + mpi_init( &Y, NULL ); + + n = BITS_TO_LIMBS( nbits ); + + MPI_CHK( mpi_grow( X, n ) ); + MPI_CHK( mpi_lset( X, 0 ) ); + + p = (unsigned char *) X->p; + for( k = 0; k < X->n * ciL; k++ ) + *p++ = (unsigned char) f_rng( p_rng ); + + k = mpi_msb( X ); + if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) ); + if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) ); + + X->p[0] |= 3; + + if( dh_flag == 0 ) + { + while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 ) + { + if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE ) + goto cleanup; + + MPI_CHK( mpi_add_int( X, X, 2 ) ); + } + } + else + { + MPI_CHK( mpi_sub_int( &Y, X, 1 ) ); + MPI_CHK( mpi_shift_r( &Y, 1 ) ); + + while( 1 ) + { + if( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) == 0 ) + { + if( ( ret = mpi_is_prime( &Y, f_rng, p_rng ) ) == 0 ) + break; + + if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE ) + goto cleanup; + } + + if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE ) + goto cleanup; + + MPI_CHK( mpi_add_int( &Y, X, 1 ) ); + MPI_CHK( mpi_add_int( X, X, 2 ) ); + MPI_CHK( mpi_shift_r( &Y, 1 ) ); + } + } + +cleanup: + + mpi_free( &Y, NULL ); + + return( ret ); +} + +#endif + +#if defined(POLARSSL_SELF_TEST) + +#define GCD_PAIR_COUNT 3 + +static const int gcd_pairs[GCD_PAIR_COUNT][3] = +{ + { 693, 609, 21 }, + { 1764, 868, 28 }, + { 768454923, 542167814, 1 } +}; + +/* + * Checkup routine + */ +int mpi_self_test( int verbose ) +{ + int ret, i; + mpi A, E, N, X, Y, U, V; + + mpi_init( &A, &E, &N, &X, &Y, &U, &V, NULL ); + + MPI_CHK( mpi_read_string( &A, 16, + "EFE021C2645FD1DC586E69184AF4A31E" \ + "D5F53E93B5F123FA41680867BA110131" \ + "944FE7952E2517337780CB0DB80E61AA" \ + "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) ); + + MPI_CHK( mpi_read_string( &E, 16, + "B2E7EFD37075B9F03FF989C7C5051C20" \ + "34D2A323810251127E7BF8625A4F49A5" \ + "F3E27F4DA8BD59C47D6DAABA4C8127BD" \ + "5B5C25763222FEFCCFC38B832366C29E" ) ); + + MPI_CHK( mpi_read_string( &N, 16, + "0066A198186C18C10B2F5ED9B522752A" \ + "9830B69916E535C8F047518A889A43A5" \ + "94B6BED27A168D31D4A52F88925AA8F5" ) ); + + MPI_CHK( mpi_mul_mpi( &X, &A, &N ) ); + + MPI_CHK( mpi_read_string( &U, 16, + "602AB7ECA597A3D6B56FF9829A5E8B85" \ + "9E857EA95A03512E2BAE7391688D264A" \ + "A5663B0341DB9CCFD2C4C5F421FEC814" \ + "8001B72E848A38CAE1C65F78E56ABDEF" \ + "E12D3C039B8A02D6BE593F0BBBDA56F1" \ + "ECF677152EF804370C1A305CAF3B5BF1" \ + "30879B56C61DE584A0F53A2447A51E" ) ); + + if( verbose != 0 ) + printf( " MPI test #1 (mul_mpi): " ); + + if( mpi_cmp_mpi( &X, &U ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + printf( "passed\n" ); + + MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) ); + + MPI_CHK( mpi_read_string( &U, 16, + "256567336059E52CAE22925474705F39A94" ) ); + + MPI_CHK( mpi_read_string( &V, 16, + "6613F26162223DF488E9CD48CC132C7A" \ + "0AC93C701B001B092E4E5B9F73BCD27B" \ + "9EE50D0657C77F374E903CDFA4C642" ) ); + + if( verbose != 0 ) + printf( " MPI test #2 (div_mpi): " ); + + if( mpi_cmp_mpi( &X, &U ) != 0 || + mpi_cmp_mpi( &Y, &V ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + printf( "passed\n" ); + + MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) ); + + MPI_CHK( mpi_read_string( &U, 16, + "36E139AEA55215609D2816998ED020BB" \ + "BD96C37890F65171D948E9BC7CBAA4D9" \ + "325D24D6A3C12710F10A09FA08AB87" ) ); + + if( verbose != 0 ) + printf( " MPI test #3 (exp_mod): " ); + + if( mpi_cmp_mpi( &X, &U ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + printf( "passed\n" ); + + MPI_CHK( mpi_inv_mod( &X, &A, &N ) ); + + MPI_CHK( mpi_read_string( &U, 16, + "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \ + "C3DBA76456363A10869622EAC2DD84EC" \ + "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) ); + + if( verbose != 0 ) + printf( " MPI test #4 (inv_mod): " ); + + if( mpi_cmp_mpi( &X, &U ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + printf( "passed\n" ); + + if( verbose != 0 ) + printf( " MPI test #5 (simple gcd): " ); + + for ( i = 0; i < GCD_PAIR_COUNT; i++) + { + MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) ); + MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) ); + + MPI_CHK( mpi_gcd( &A, &X, &Y ) ); + + if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 ) + { + if( verbose != 0 ) + printf( "failed at %d\n", i ); + + return( 1 ); + } + } + + if( verbose != 0 ) + printf( "passed\n" ); + +cleanup: + + if( ret != 0 && verbose != 0 ) + printf( "Unexpected error, return code = %08X\n", ret ); + + mpi_free( &V, &U, &Y, &X, &N, &E, &A, NULL ); + + if( verbose != 0 ) + printf( "\n" ); + + return( ret ); +} + +#endif + +#endif diff --git a/package/utils/px5g-standalone/src/library/havege.c b/package/utils/px5g-standalone/src/library/havege.c new file mode 100644 index 0000000000..266299d3bb --- /dev/null +++ b/package/utils/px5g-standalone/src/library/havege.c @@ -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 + * + * 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 +#include + +#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 + +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 \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 diff --git a/package/utils/px5g-standalone/src/library/rsa.c b/package/utils/px5g-standalone/src/library/rsa.c new file mode 100644 index 0000000000..131b6c6c9c --- /dev/null +++ b/package/utils/px5g-standalone/src/library/rsa.c @@ -0,0 +1,750 @@ +/* + * The RSA public-key cryptosystem + * + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine + * + * Copyright (C) 2009 Paul Bakker + * + * 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 +#include +#include + +/* + * 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 diff --git a/package/utils/px5g-standalone/src/library/sha1.c b/package/utils/px5g-standalone/src/library/sha1.c new file mode 100644 index 0000000000..54a4416f31 --- /dev/null +++ b/package/utils/px5g-standalone/src/library/sha1.c @@ -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 + * + * 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 +#include + +/* + * 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 diff --git a/package/utils/px5g-standalone/src/library/timing.c b/package/utils/px5g-standalone/src/library/timing.c new file mode 100644 index 0000000000..6b7ab740e1 --- /dev/null +++ b/package/utils/px5g-standalone/src/library/timing.c @@ -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 + * + * 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 +#include + +struct _hr_time +{ + LARGE_INTEGER start; +}; + +#else + +#include +#include +#include +#include +#include + +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 diff --git a/package/utils/px5g-standalone/src/library/x509write.c b/package/utils/px5g-standalone/src/library/x509write.c new file mode 100644 index 0000000000..fabee20ea6 --- /dev/null +++ b/package/utils/px5g-standalone/src/library/x509write.c @@ -0,0 +1,1139 @@ +/* + * X.509 certificate and private key writing + * + * Copyright (C) 2006-2007 Pascal Vizeli + * Modifications (C) 2009 Steven Barth + * + * 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 + */ +/* + * The ITU-T X.509 standard defines a certificat format for PKI. + * + * http://www.ietf.org/rfc/rfc2459.txt + * http://www.ietf.org/rfc/rfc3279.txt + * + * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc + * + * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf + * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf + * + * For CRS: + * http://www.faqs.org/rfcs/rfc2314.html + */ +#include "polarssl/config.h" +#include "polarssl/x509.h" +#include "polarssl/base64.h" +#include "polarssl/sha1.h" + +#include +#include +#include +#include +#include + +#define and && +#define or || + +#if defined _MSC_VER && !defined snprintf +#define snprintf _snprintf +#endif + +static int x509write_realloc_node(x509_node *node, size_t larger); +static int x509write_file(x509_node *node, char *path, int format, const char* pem_prolog, const char* pem_epilog); + +/* + * evaluate how mani octet have this integer + */ +static int asn1_eval_octet(unsigned int digit) +{ + int i, byte; + + for (byte = 4, i = 24; i >= 0; i -= 8, --byte) + if (((digit >> i) & 0xFF) != 0) + return byte; + + return 0; +} + +/* + * write the asn.1 lenght form into p + */ +static int asn1_add_len(unsigned int size, x509_node *node) +{ + if (size > 127) { + + /* long size */ + int byte = asn1_eval_octet(size); + int i = 0; + + *(node->p) = (0x80 | byte) & 0xFF; + ++node->p; + + for (i = byte; i > 0; --i) { + + *(node->p) = (size >> ((i - 1) * 8)) & 0xFF; + ++node->p; + } + + } else { + + /* short size */ + *(node->p) = size & 0xFF; + if (size != 0) + ++node->p; + } + + return 0; +} + +/* + * write a ans.1 object into p + */ +static int asn1_add_obj(unsigned char *value, unsigned int size, int tag, + x509_node *node) +{ + int tl = 2; + + if (tag == ASN1_BIT_STRING) + ++tl; + + if (size > 127) + x509write_realloc_node(node, (size_t) size + tl + + asn1_eval_octet(size)); + else + x509write_realloc_node(node, (size_t) size + tl); + + if (node->data == NULL) + return 1; + + /* tag */ + *(node->p) = tag & 0xFF; + ++node->p; + + /* len */ + if (tag == ASN1_BIT_STRING) { + asn1_add_len((unsigned int) size + 1, node); + *(node->p) = 0x00; + ++node->p; + } else { + asn1_add_len((unsigned int) size, node); + } + + /* value */ + if (size > 0) { + + memcpy(node->p, value, (size_t) size); + if ((node->p += size -1) != node->end) + return POLARSSL_ERR_X509_POINT_ERROR; + } else { + /* make nothing -> NULL */ + } + + return 0; +} + +/* + * write a asn.1 conform integer object + */ +static int asn1_add_int(signed int value, x509_node *node) +{ + signed int i = 0, neg = 1; + unsigned int byte, u_val = 0, tmp_val = 0; + + /* if negate? */ + if (value < 0) { + neg = -1; + u_val = ~value; + } else { + u_val = value; + } + + byte = asn1_eval_octet(u_val); + /* 0 isn't NULL */ + if (byte == 0) + byte = 1; + + /* ASN.1 integer is signed! */ + if (byte < 4 and ((u_val >> ((byte -1) * 8)) & 0xFF) == 0x80) + byte += 1; + + if (x509write_realloc_node(node, (size_t) byte + 2) != 0) + return 1; + + /* tag */ + *(node->p) = ASN1_INTEGER; + ++node->p; + + /* len */ + asn1_add_len(byte, node); + + /* value */ + for (i = byte; i > 0; --i) { + + tmp_val = (u_val >> ((i - 1) * 8)) & 0xFF; + if (neg == 1) + *(node->p) = tmp_val; + else + *(node->p) = ~tmp_val; + + if (i > 1) + ++node->p; + } + + if (node->p != node->end) + return POLARSSL_ERR_X509_POINT_ERROR; + + return 0; +} + +/* + * write a asn.1 conform mpi object + */ +static int asn1_add_mpi(mpi *value, int tag, x509_node *node) +{ + size_t size = (mpi_msb(value) / 8) + 1; + unsigned char *buf; + int buf_len = (int) size, tl = 2; + + if (tag == ASN1_BIT_STRING) + ++tl; + + if (size > 127) + x509write_realloc_node(node, size + (size_t) tl + + asn1_eval_octet((unsigned int)size)); + else + x509write_realloc_node(node, size + (size_t) tl); + + if (node->data == NULL) + return 1; + + buf = (unsigned char*) malloc(size); + if (mpi_write_binary(value, buf, buf_len) != 0) + return POLARSSL_ERR_MPI_BUFFER_TOO_SMALL; + + /* tag */ + *(node->p) = tag & 0xFF; + ++node->p; + + /* len */ + if (tag == ASN1_BIT_STRING) { + asn1_add_len((unsigned int) size + 1, node); + *(node->p) = 0x00; + ++node->p; + } else { + asn1_add_len((unsigned int) size, node); + } + + /* value */ + memcpy(node->p, buf, size); + free(buf); + + if ((node->p += (int) size -1) != node->end) + return POLARSSL_ERR_X509_POINT_ERROR; + + return 0; +} + +/* + * write a node into asn.1 conform object + */ +static int asn1_append_tag(x509_node *node, int tag) +{ + int tl = 2; + + x509_node tmp; + x509write_init_node(&tmp); + + if (tag == ASN1_BIT_STRING) + ++tl; + + if (node->len > 127) + x509write_realloc_node(&tmp, node->len + (size_t) tl + + asn1_eval_octet((unsigned int)node->len)); + else + x509write_realloc_node(&tmp, node->len + (size_t) tl); + + if (tmp.data == NULL) { + x509write_free_node(&tmp); + return 1; + } + + /* tag */ + *(tmp.p) = tag & 0xFF; + ++tmp.p; + + /* len */ + if (tag == ASN1_BIT_STRING) { + asn1_add_len((unsigned int) node->len + 1, &tmp); + *(tmp.p) = 0x00; + ++tmp.p; + } else { + asn1_add_len((unsigned int) node->len, &tmp); + } + + /* value */ + memcpy(tmp.p, node->data, node->len); + + /* good? */ + if ((tmp.p += (int) node->len -1) != tmp.end) { + x509write_free_node(&tmp); + return POLARSSL_ERR_X509_POINT_ERROR; + } + + free(node->data); + node->data = tmp.data; + node->p = tmp.p; + node->end = tmp.end; + node->len = tmp.len; + + return 0; +} + +/* + * write nodes into a asn.1 object + */ +static int asn1_append_nodes(x509_node *node, int tag, int anz, ...) +{ + va_list ap; + size_t size = 0; + x509_node *tmp; + int count; + + va_start(ap, anz); + count = anz; + + while (count--) { + + tmp = va_arg(ap, x509_node*); + if (tmp->data != NULL) + size += tmp->len; + } + + if ( size > 127) { + if (x509write_realloc_node(node, size + (size_t) 2 + + asn1_eval_octet(size)) != 0) + return 1; + } else { + if (x509write_realloc_node(node, size + (size_t) 2) != 0) + return 1; + } + + /* tag */ + *(node->p) = tag & 0xFF; + ++node->p; + + /* len */ + asn1_add_len(size, node); + + /* value */ + va_start(ap, anz); + count = anz; + + while (count--) { + + tmp = va_arg(ap, x509_node*); + if (tmp->data != NULL) { + + memcpy(node->p, tmp->data, tmp->len); + if ((node->p += (int) tmp->len -1) != node->end) + ++node->p; + } + } + + va_end(ap); + return 0; +} + +/* + * write a ASN.1 conform object identifiere include a "tag" + */ +static int asn1_add_oid(x509_node *node, unsigned char *oid, size_t len, + int tag, int tag_val, unsigned char *value, size_t val_len) +{ + int ret; + x509_node tmp; + + x509write_init_node(&tmp); + + /* OBJECT IDENTIFIER */ + if ((ret = asn1_add_obj(oid, len, ASN1_OID, &tmp)) != 0) { + x509write_free_node(&tmp); + return ret; + } + + /* value */ + if ((ret = asn1_add_obj(value, val_len, tag_val, &tmp)) != 0) { + x509write_free_node(&tmp); + return ret; + } + + /* SET/SEQUENCE */ + if ((ret = asn1_append_nodes(node, tag, 1, &tmp)) != 0) { + x509write_free_node(&tmp); + return ret; + } + + x509write_free_node(&tmp); + return 0; +} + +/* + * utcTime UTCTime + */ +static int asn1_add_date_utc(unsigned char *time, x509_node *node) +{ + unsigned char date[13], *sp; + x509_time xtime; + int ret; + + sscanf((char*)time, "%d-%d-%d %d:%d:%d", &xtime.year, &xtime.mon, + &xtime.day, &xtime.hour, &xtime.min, &xtime.sec); + + /* convert to YY */ + if (xtime.year > 2000) + xtime.year -= 2000; + else + xtime.year -= 1900; + + snprintf((char*)date, 13, "%2d%2d%2d%2d%2d%2d", xtime.year, xtime.mon, xtime.day, + xtime.hour, xtime.min, xtime.sec); + + /* replace ' ' to '0' */ + for (sp = date; *sp != '\0'; ++sp) + if (*sp == '\x20') + *sp = '\x30'; + + date[12] = 'Z'; + + if ((ret = asn1_add_obj(date, 13, ASN1_UTC_TIME, node)) != 0) + return ret; + + return 0; +} + +/* + * serialize an rsa key into DER + */ + +int x509write_serialize_key(rsa_context *rsa, x509_node *node) +{ + int ret = 0; + x509write_init_node(node); + + /* vers, n, e, d, p, q, dp, dq, pq */ + if ((ret = asn1_add_int(rsa->ver, node)) != 0) + return ret; + if ((ret = asn1_add_mpi(&rsa->N, ASN1_INTEGER, node)) != 0) + return ret; + if ((ret = asn1_add_mpi(&rsa->E, ASN1_INTEGER, node)) != 0) + return ret; + if ((ret = asn1_add_mpi(&rsa->D, ASN1_INTEGER, node)) != 0) + return ret; + if ((ret = asn1_add_mpi(&rsa->P, ASN1_INTEGER, node)) != 0) + return ret; + if ((ret = asn1_add_mpi(&rsa->Q, ASN1_INTEGER, node)) != 0) + return ret; + if ((ret = asn1_add_mpi(&rsa->DP, ASN1_INTEGER, node)) != 0) + return ret; + if ((ret = asn1_add_mpi(&rsa->DQ, ASN1_INTEGER, node)) != 0) + return ret; + if ((ret = asn1_add_mpi(&rsa->QP, ASN1_INTEGER, node)) != 0) + return ret; + if ((ret = asn1_append_tag(node, ASN1_CONSTRUCTED | ASN1_SEQUENCE)) != 0) + return ret; + + return 0; +} + +/* + * write a der/pem encoded rsa private key into a file + */ +int x509write_keyfile(rsa_context *rsa, char *path, int out_flag) +{ + int ret = 0; + const char key_beg[] = "-----BEGIN RSA PRIVATE KEY-----\n", + key_end[] = "-----END RSA PRIVATE KEY-----\n"; + x509_node node; + + x509write_init_node(&node); + if ((ret = x509write_serialize_key(rsa,&node)) != 0) { + x509write_free_node(&node); + return ret; + } + + ret = x509write_file(&node,path,out_flag,key_beg,key_end); + x509write_free_node(&node); + + return ret; +} + + +/* + * reasize the memory for node + */ +static int x509write_realloc_node(x509_node *node, size_t larger) +{ + /* init len */ + if (node->data == NULL) { + node->len = 0; + node->data = malloc(larger); + if(node->data == NULL) + return 1; + } else { + /* realloc memory */ + if ((node->data = realloc(node->data, node->len + larger)) == NULL) + return 1; + } + + /* init pointer */ + node->p = &node->data[node->len]; + node->len += larger; + node->end = &node->data[node->len -1]; + + return 0; +} + +/* + * init node + */ +void x509write_init_node(x509_node *node) +{ + memset(node, 0, sizeof(x509_node)); +} + +/* + * clean memory + */ +void x509write_free_node(x509_node *node) +{ + if (node->data != NULL) + free(node->data); + node->p = NULL; + node->end = NULL; + node->len = 0; +} + +/* + * write a x509 certificate into file + */ +int x509write_crtfile(x509_raw *chain, unsigned char *path, int out_flag) +{ + const char cer_beg[] = "-----BEGIN CERTIFICATE-----\n", + cer_end[] = "-----END CERTIFICATE-----\n"; + + return x509write_file(&chain->raw, (char*)path, out_flag, cer_beg, cer_end); +} + +/* + * write a x509 certificate into file + */ +int x509write_csrfile(x509_raw *chain, unsigned char *path, int out_flag) +{ + const char cer_beg[] = "-----BEGIN CERTIFICATE REQUEST-----\n", + cer_end[] = "-----END CERTIFICATE REQUEST-----\n"; + + return x509write_file(&chain->raw, (char*)path, out_flag, cer_beg, cer_end); +} + +/* + * write an x509 file + */ +static int x509write_file(x509_node *node, char *path, int format, + const char* pem_prolog, const char* pem_epilog) +{ + FILE *ofstream = stdout; + int is_err = 1, buf_len, i, n; + unsigned char* base_buf; + + if (path) { + if ((ofstream = fopen(path, "wb")) == NULL) + return 1; + } + + switch (format) { + case X509_OUTPUT_DER: + if (fwrite(node->data, 1, node->len, ofstream) + != node->len) + is_err = -1; + break; + + case X509_OUTPUT_PEM: + if (fprintf(ofstream,pem_prolog)<0) { + is_err = -1; + break; + } + + buf_len = node->len << 1; + base_buf = (unsigned char*) malloc((size_t)buf_len); + memset(base_buf,0,buf_len); + if (base64_encode(base_buf, &buf_len, node->data, + (int) node->len) != 0) { + is_err = -1; + break; + } + + n=strlen((char*)base_buf); + for(i=0;isubpubkey; + + x509write_init_node(&n_tmp); + x509write_init_node(&n_tmp2); + + /* + * RSAPublicKey ::= SEQUENCE { + * modulus INTEGER, -- n + * publicExponent INTEGER -- e + * } + */ + if ((ret = asn1_add_mpi(&pubkey->N, ASN1_INTEGER, &n_tmp)) != 0) { + x509write_free_node(&n_tmp); + x509write_free_node(&n_tmp2); + return ret; + } + if ((ret = asn1_add_mpi(&pubkey->E, ASN1_INTEGER, &n_tmp)) != 0) { + x509write_free_node(&n_tmp); + x509write_free_node(&n_tmp2); + return ret; + } + if ((ret = asn1_append_tag(&n_tmp, ASN1_CONSTRUCTED | ASN1_SEQUENCE)) + != 0) { + x509write_free_node(&n_tmp); + x509write_free_node(&n_tmp2); + return ret; + } + + /* + * SubjectPublicKeyInfo ::= SEQUENCE { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING } + */ + if ((ret = asn1_append_tag(&n_tmp, ASN1_BIT_STRING)) != 0) { + x509write_free_node(&n_tmp); + x509write_free_node(&n_tmp2); + return ret; + } + if ((ret = asn1_add_oid(&n_tmp2, (unsigned char*)OID_PKCS1_RSA, 9, + ASN1_CONSTRUCTED | ASN1_SEQUENCE, ASN1_NULL, + (unsigned char *)"", 0)) != 0) { + x509write_free_node(&n_tmp); + x509write_free_node(&n_tmp2); + return ret; + } + + if ((ret = asn1_append_nodes(node, ASN1_CONSTRUCTED | ASN1_SEQUENCE, 2, + &n_tmp2, &n_tmp))) { + x509write_free_node(&n_tmp); + x509write_free_node(&n_tmp2); + return ret; + } + + x509write_free_node(&n_tmp); + x509write_free_node(&n_tmp2); + return 0; +} + +/* + * RelativeDistinguishedName ::= + * SET OF AttributeTypeAndValue + * + * AttributeTypeAndValue ::= SEQUENCE { + * type AttributeType, + * value AttributeValue } + */ +static int x509write_add_name(x509_node *node, unsigned char *oid, + unsigned int oid_len, unsigned char *value, int len, int value_tag) +{ + int ret; + x509_node n_tmp; + + x509write_init_node(&n_tmp); + + if ((ret = asn1_add_oid(&n_tmp, oid, oid_len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE, value_tag, + value, len))) { + x509write_free_node(&n_tmp); + return ret; + } + + if ((asn1_append_nodes(node, ASN1_CONSTRUCTED | ASN1_SET, 1, &n_tmp)) + != 0) { + x509write_free_node(&n_tmp); + return ret; + } + + x509write_free_node(&n_tmp); + return 0; +} + +/* + * Parse the name string and add to node + */ +static int x509write_parse_names(x509_node *node, unsigned char *names) +{ + unsigned char *sp, *begin = NULL; + unsigned char oid[3] = OID_X520, tag[4], *tag_sp = tag; + unsigned char *C = NULL, *CN = NULL, *O = NULL, *OU = NULL, + *ST = NULL, *L = NULL, *R = NULL; + int C_len = 0, CN_len = 0, O_len = 0, OU_len = 0, ST_len = 0, + L_len = 0, R_len = 0; + int ret = 0, is_tag = 1, is_begin = -1, len = 0; + + + for (sp = names; ; ++sp) { + + /* filter tag */ + if (is_tag == 1) { + + if (tag_sp == &tag[3]) + return POLARSSL_ERR_X509_VALUE_TO_LENGTH; + + /* is tag end? */ + if (*sp == '=') { + is_tag = -1; + *tag_sp = '\0'; + is_begin = 1; + /* set len 0 (reset) */ + len = 0; + } else { + /* tag hasn't ' '! */ + if (*sp != ' ') { + *tag_sp = *sp; + ++tag_sp; + } + } + /* filter value */ + } else { + + /* set pointer of value begin */ + if (is_begin == 1) { + begin = sp; + is_begin = -1; + } + + /* is value at end? */ + if (*sp == ';' or *sp == '\0') { + is_tag = 1; + + /* common name */ + if (tag[0] == 'C' and tag[1] == 'N') { + CN = begin; + CN_len = len; + + /* organization */ + } else if (tag[0] == 'O' and tag[1] == '\0') { + O = begin; + O_len = len; + + /* country */ + } else if (tag[0] == 'C' and tag[1] == '\0') { + C = begin; + C_len = len; + + /* organisation unit */ + } else if (tag[0] == 'O' and tag[1] == 'U') { + OU = begin; + OU_len = len; + + /* state */ + } else if (tag[0] == 'S' and tag[1] == 'T') { + ST = begin; + ST_len = len; + + /* locality */ + } else if (tag[0] == 'L' and tag[1] == '\0') { + L = begin; + L_len = len; + + /* email */ + } else if (tag[0] == 'R' and tag[1] == '\0') { + R = begin; + R_len = len; + } + + /* set tag poiner to begin */ + tag_sp = tag; + + /* is at end? */ + if (*sp == '\0' or *(sp +1) == '\0') + break; + } else { + ++len; + } + } + + /* make saver */ + if (*sp == '\0') + break; + } /* end for */ + + /* country */ + if (C != NULL) { + oid[2] = X520_COUNTRY; + if ((ret = x509write_add_name(node, oid, 3, C, C_len, + ASN1_PRINTABLE_STRING)) != 0) + return ret; + } + + /* state */ + if (ST != NULL) { + oid[2] = X520_STATE; + if ((ret = x509write_add_name(node, oid, 3, ST, ST_len, + ASN1_PRINTABLE_STRING)) != 0) + return ret; + } + + /* locality */ + if (L != NULL) { + oid[2] = X520_LOCALITY; + if ((ret = x509write_add_name(node, oid, 3, L, L_len, + ASN1_PRINTABLE_STRING)) != 0) + return ret; + } + + /* organization */ + if (O != NULL) { + oid[2] = X520_ORGANIZATION; + if ((ret = x509write_add_name(node, oid, 3, O, O_len, + ASN1_PRINTABLE_STRING)) != 0) + return ret; + } + + /* organisation unit */ + if (OU != NULL) { + oid[2] = X520_ORG_UNIT; + if ((ret = x509write_add_name(node, oid, 3, OU, OU_len, + ASN1_PRINTABLE_STRING)) != 0) + return ret; + } + + /* common name */ + if (CN != NULL) { + oid[2] = X520_COMMON_NAME; + if ((ret = x509write_add_name(node, oid, 3, CN, CN_len, + ASN1_PRINTABLE_STRING)) != 0) + return ret; + } + + /* email */ + if (R != NULL) { + if ((ret = x509write_add_name(node, (unsigned char*)OID_PKCS9_EMAIL, + 9, R, R_len, ASN1_IA5_STRING)) != 0) + return ret; + } + + if ((asn1_append_tag(node, ASN1_CONSTRUCTED | ASN1_SEQUENCE)) != 0) + return ret; + + return 0; +} + +/* + * Copy raw data from orginal ca to node + */ +static int x509write_copy_from_raw(x509_node *node, x509_buf *raw) +{ + if (x509write_realloc_node(node, raw->len) != 0) + return 1; + + memcpy(node->p, raw->p, (size_t)raw->len); + if ((node->p += raw->len -1) != node->end) + return POLARSSL_ERR_X509_POINT_ERROR; + + return 0; +} + +/* + * Add the issuer + */ + +int x509write_add_issuer(x509_raw *crt, unsigned char *issuer) +{ + return x509write_parse_names(&crt->issuer, issuer); +} + +/* + * Add the subject + */ +int x509write_add_subject(x509_raw *crt, unsigned char *subject) +{ + return x509write_parse_names(&crt->subject, subject); +} + +/* + * Copy issuer line from another cert to issuer + */ +int x509write_copy_issuer(x509_raw *crt, x509_cert *from_crt) +{ + return x509write_copy_from_raw(&crt->issuer, &from_crt->issuer_raw); +} + +/* + * Copy subject line from another cert + */ +int x509write_copy_subject(x509_raw *crt, x509_cert *from_crt) +{ + return x509write_copy_from_raw(&crt->subject, &from_crt->subject_raw); +} + +/* + * Copy subject line form antoher cert into issuer + */ +int x509write_copy_issuer_form_subject(x509_raw *crt, + x509_cert *from_crt) +{ + return x509write_copy_from_raw(&crt->issuer, &from_crt->subject_raw); +} + +/* + * Copy issuer line from another cert into subject + */ +int x509write_copy_subject_from_issuer(x509_raw *crt, + x509_cert * from_crt) +{ + return x509write_copy_from_raw(&crt->subject, &from_crt->issuer_raw); +} + +/* + * Validity ::= SEQUENCE { + * notBefore Time, + * notAfter Time } + * + * Time ::= CHOICE { + * utcTime UTCTime, + * generalTime GeneralizedTime } + */ +/* TODO: No handle GeneralizedTime! */ +int x509write_add_validity(x509_raw *chain, unsigned char *befor, + unsigned char *after) +{ + int ret; + + x509_node *node = &chain->validity; + + /* notBefore */ + if ((ret = asn1_add_date_utc(befor, node)) != 0) + return ret; + + /* notAfter */ + if ((ret = asn1_add_date_utc(after, node)) != 0) + return ret; + + if ((ret = asn1_append_tag(node, ASN1_CONSTRUCTED | ASN1_SEQUENCE)) != 0) + return ret; + + return 0; +} + +/* + * make hash from tbs and sign that with private key + */ +static int x509write_make_sign(x509_raw *chain, rsa_context *privkey) +{ + int ret; + unsigned char hash[20], *sign; + size_t sign_len = (size_t) mpi_size(&privkey->N); + + /* make hash */ + sha1(chain->tbs.data, chain->tbs.len, hash); + + /* create sign */ + sign = (unsigned char *) malloc(sign_len); + if (sign == NULL) + return 1; + + if ((ret = rsa_pkcs1_sign(privkey, RSA_PRIVATE, RSA_SHA1, 20, hash, + sign)) != 0) + return ret; + + if ((ret = asn1_add_obj(sign, sign_len, ASN1_BIT_STRING, + &chain->sign)) != 0) + return ret; + + /* + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL } + */ + return asn1_add_oid(&chain->signalg, (unsigned char*)OID_PKCS1_RSA_SHA, 9, + ASN1_CONSTRUCTED | ASN1_SEQUENCE, ASN1_NULL, + (unsigned char*)"", 0); +} + +/* + * Create a self signed certificate + */ +int x509write_create_sign(x509_raw *chain, rsa_context *privkey) +{ + int ret, serial; + + /* + * Version ::= INTEGER { v1(0), v2(1), v3(2) } + */ + if ((ret = asn1_add_int(2, &chain->version)) != 0) + return ret; + + if ((ret = asn1_append_tag(&chain->version, ASN1_CONTEXT_SPECIFIC | + ASN1_CONSTRUCTED)) != 0) + return ret; + + + /* + * CertificateSerialNumber ::= INTEGER + */ + srand((unsigned int) time(NULL)); + serial = rand(); + if ((ret = asn1_add_int(serial, &chain->serial)) != 0) + return ret; + + /* + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL } + */ + if ((ret = asn1_add_oid(&chain->tbs_signalg, + (unsigned char*)OID_PKCS1_RSA_SHA, 9, ASN1_CONSTRUCTED | + ASN1_SEQUENCE, ASN1_NULL, (unsigned char*)"", 0)) != 0) + return ret; + + /* + * Create the tbs + */ + if ((ret = asn1_append_nodes(&chain->tbs, ASN1_CONSTRUCTED | + ASN1_SEQUENCE, 7, &chain->version, &chain->serial, + &chain->tbs_signalg, &chain->issuer, &chain->validity, + &chain->subject, &chain->subpubkey)) != 0) + return ret; + + /* make signing */ + if ((ret = x509write_make_sign(chain, privkey)) != 0) + return ret; + + /* finishing */ + if ((ret = asn1_append_nodes(&chain->raw, ASN1_CONSTRUCTED | + ASN1_SEQUENCE, 3, &chain->tbs, &chain->signalg, + &chain->sign)) != 0) + return ret; + + return 0; +} + +int x509write_create_selfsign(x509_raw *chain, rsa_context *privkey) +{ + /* + * On self signed certificate are subject and issuer the same + */ + x509write_free_node(&chain->issuer); + chain->issuer = chain->subject; + return x509write_create_sign(chain, privkey); +} + +/* + * CertificationRequestInfo ::= SEQUENCE { + * version Version, + * subject Name, + * subjectPublicKeyInfo SubjectPublicKeyInfo, + * attributes [0] IMPLICIT Attributes } + * + * CertificationRequest ::= SEQUENCE { + * certificationRequestInfo CertificationRequestInfo, + * signatureAlgorithm SignatureAlgorithmIdentifier, + * signature Signature } + * + * It use chain.serail for attributes! + * + */ +int x509write_create_csr(x509_raw *chain, rsa_context *privkey) +{ + int ret; + + /* version ::= INTEGER */ + if ((ret = asn1_add_int(0, &chain->version)) != 0) + return ret; + + /* write attributes */ + if ((ret = asn1_add_obj((unsigned char*)"", 0, ASN1_CONTEXT_SPECIFIC | + ASN1_CONSTRUCTED, &chain->serial)) != 0) + return ret; + + /* create CertificationRequestInfo */ + if ((ret = asn1_append_nodes(&chain->tbs, ASN1_CONSTRUCTED | + ASN1_SEQUENCE, 4, &chain->version, &chain->subject, + &chain->subpubkey, &chain->serial)) != 0) + return ret; + + /* make signing */ + if ((ret = x509write_make_sign(chain, privkey)) != 0) + return ret; + + /* finish */ + if ((ret = asn1_append_nodes(&chain->raw, ASN1_CONSTRUCTED | ASN1_SEQUENCE, + 3, &chain->tbs, &chain->signalg, &chain->sign)) != 0) + return ret; + + return ret; +} + +/* + * Free memory + */ +void x509write_free_raw(x509_raw *chain) +{ + x509write_free_node(&chain->raw); + x509write_free_node(&chain->tbs); + x509write_free_node(&chain->version); + x509write_free_node(&chain->serial); + x509write_free_node(&chain->tbs_signalg); + x509write_free_node(&chain->issuer); + x509write_free_node(&chain->validity); + if (chain->subject.data != chain->issuer.data) + x509write_free_node(&chain->subject); + x509write_free_node(&chain->subpubkey); + x509write_free_node(&chain->signalg); + x509write_free_node(&chain->sign); +} + +void x509write_init_raw(x509_raw *chain) +{ + memset((void *) chain, 0, sizeof(x509_raw)); +} + diff --git a/package/utils/px5g-standalone/src/polarssl/base64.h b/package/utils/px5g-standalone/src/polarssl/base64.h new file mode 100644 index 0000000000..c48267b1b5 --- /dev/null +++ b/package/utils/px5g-standalone/src/polarssl/base64.h @@ -0,0 +1,93 @@ +/** + * \file base64.h + * + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine + * + * Copyright (C) 2009 Paul Bakker + * + * 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 */ diff --git a/package/utils/px5g-standalone/src/polarssl/bignum.h b/package/utils/px5g-standalone/src/polarssl/bignum.h new file mode 100644 index 0000000000..c667303329 --- /dev/null +++ b/package/utils/px5g-standalone/src/polarssl/bignum.h @@ -0,0 +1,437 @@ +/** + * \file bignum.h + * + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine + * + * Copyright (C) 2009 Paul Bakker + * + * 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 + +#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 */ diff --git a/package/utils/px5g-standalone/src/polarssl/bn_mul.h b/package/utils/px5g-standalone/src/polarssl/bn_mul.h new file mode 100644 index 0000000000..f6d34da58a --- /dev/null +++ b/package/utils/px5g-standalone/src/polarssl/bn_mul.h @@ -0,0 +1,731 @@ +/** + * \file bn_mul.h + * + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine + * + * Copyright (C) 2009 Paul Bakker + * + * 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 */ diff --git a/package/utils/px5g-standalone/src/polarssl/config.h b/package/utils/px5g-standalone/src/polarssl/config.h new file mode 100644 index 0000000000..ad3f9a7f39 --- /dev/null +++ b/package/utils/px5g-standalone/src/polarssl/config.h @@ -0,0 +1,329 @@ +/** + * \file config.h + * + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine + * + * Copyright (C) 2009 Paul Bakker + * + * 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 */ diff --git a/package/utils/px5g-standalone/src/polarssl/havege.h b/package/utils/px5g-standalone/src/polarssl/havege.h new file mode 100644 index 0000000000..c27cecac0f --- /dev/null +++ b/package/utils/px5g-standalone/src/polarssl/havege.h @@ -0,0 +1,75 @@ +/** + * \file havege.h + * + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine + * + * Copyright (C) 2009 Paul Bakker + * + * 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 */ diff --git a/package/utils/px5g-standalone/src/polarssl/rsa.h b/package/utils/px5g-standalone/src/polarssl/rsa.h new file mode 100644 index 0000000000..b31dc2f144 --- /dev/null +++ b/package/utils/px5g-standalone/src/polarssl/rsa.h @@ -0,0 +1,309 @@ +/** + * \file rsa.h + * + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine + * + * Copyright (C) 2009 Paul Bakker + * + * 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 */ diff --git a/package/utils/px5g-standalone/src/polarssl/sha1.h b/package/utils/px5g-standalone/src/polarssl/sha1.h new file mode 100644 index 0000000000..3ca7dc3195 --- /dev/null +++ b/package/utils/px5g-standalone/src/polarssl/sha1.h @@ -0,0 +1,150 @@ +/** + * \file sha1.h + * + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine + * + * Copyright (C) 2009 Paul Bakker + * + * 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 */ diff --git a/package/utils/px5g-standalone/src/polarssl/timing.h b/package/utils/px5g-standalone/src/polarssl/timing.h new file mode 100644 index 0000000000..62d627f61b --- /dev/null +++ b/package/utils/px5g-standalone/src/polarssl/timing.h @@ -0,0 +1,81 @@ +/** + * \file timing.h + * + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine + * + * Copyright (C) 2009 Paul Bakker + * + * 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 */ diff --git a/package/utils/px5g-standalone/src/polarssl/x509.h b/package/utils/px5g-standalone/src/polarssl/x509.h new file mode 100644 index 0000000000..908a1dbf51 --- /dev/null +++ b/package/utils/px5g-standalone/src/polarssl/x509.h @@ -0,0 +1,549 @@ +/** + * \file x509.h + * + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine + * + * Copyright (C) 2009 Paul Bakker + * + * 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 */ diff --git a/package/utils/px5g-standalone/src/px5g.c b/package/utils/px5g-standalone/src/px5g.c new file mode 100644 index 0000000000..cf50ad28e2 --- /dev/null +++ b/package/utils/px5g-standalone/src/px5g.c @@ -0,0 +1,200 @@ +/* + * px5g - Embedded x509 key and certificate generator based on PolarSSL + * + * Copyright (C) 2009 Steven Barth + * + * 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 +#include +#include +#include +#include +#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 " +#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; + if (to < from) + to = INT_MAX; + 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; +} diff --git a/package/utils/px5g/Makefile b/package/utils/px5g/Makefile index ad4ec40580..9c0caa7b8d 100644 --- a/package/utils/px5g/Makefile +++ b/package/utils/px5g/Makefile @@ -10,15 +10,17 @@ include $(TOPDIR)/rules.mk PKG_NAME:=px5g PKG_RELEASE:=1 -PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) +PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT) +PKG_USE_MIPS16:=0 include $(INCLUDE_DIR)/package.mk define Package/px5g SECTION:=utils CATEGORY:=Utilities - TITLE:=Standalone X.509 certificate generator + TITLE:=X.509 certificate generator (using PolarSSL) MAINTAINER:=Jo-Philipp Wich + DEPENDS:=+libpolarssl endef define Package/px5g/description @@ -29,7 +31,10 @@ endef define Build/Prepare mkdir -p $(PKG_BUILD_DIR) - $(CP) ./src/* $(PKG_BUILD_DIR)/ +endef + +define Build/Compile + $(TARGET_CC) $(TARGET_CFLAGS) -o $(PKG_BUILD_DIR)/px5g px5g.c -lpolarssl endef define Package/px5g/install diff --git a/package/utils/px5g/px5g.c b/package/utils/px5g/px5g.c new file mode 100644 index 0000000000..6b977081e1 --- /dev/null +++ b/package/utils/px5g/px5g.c @@ -0,0 +1,269 @@ +/* + * px5g - Embedded x509 key and certificate generator based on PolarSSL + * + * Copyright (C) 2009 Steven Barth + * Copyright (C) 2014 Felix Fietkau + * + * 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 + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define PX5G_VERSION "0.2" +#define PX5G_COPY "Copyright (c) 2009 Steven Barth " +#define PX5G_LICENSE "Licensed under the GNU Lesser General Public License v2.1" + +static int urandom_fd; +static char buf[16384]; + +static int _urandom(void *ctx, unsigned char *out, size_t len) +{ + read(urandom_fd, out, len); + return 0; +} + +static void write_file(const char *path, int len, bool pem) +{ + FILE *f = stdout; + const char *buf_start = buf; + + if (!pem) + buf_start += sizeof(buf) - len; + + if (!len) { + fprintf(stderr, "No data to write\n"); + exit(1); + } + + if (!f) { + fprintf(stderr, "error: I/O error\n"); + exit(1); + } + + if (path) + f = fopen(path, "w"); + + fwrite(buf_start, 1, len, f); + fclose(f); +} + +static void write_key(pk_context *key, const char *path, bool pem) +{ + int len = 0; + + if (pem) { + if (pk_write_key_pem(key, (void *) buf, sizeof(buf)) == 0) + len = strlen(buf); + } else { + len = pk_write_key_der(key, (void *) buf, sizeof(buf)); + if (len < 0) + len = 0; + } + + write_file(path, len, pem); +} + +static void gen_key(pk_context *key, int ksize, int exp, bool pem) +{ + pk_init(key); + pk_init_ctx(key, pk_info_from_type(POLARSSL_PK_RSA)); + fprintf(stderr, "Generating RSA private key, %i bit long modulus\n", ksize); + if (rsa_gen_key(pk_rsa(*key), _urandom, NULL, ksize, exp)) { + fprintf(stderr, "error: key generation failed\n"); + exit(1); + } +} + +int rsakey(char **arg) +{ + pk_context key; + unsigned int ksize = 512; + int exp = 65537; + char *path = NULL; + bool pem = true; + + 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")) { + pem = false; + } + arg++; + } + + if (*arg) + ksize = (unsigned int)atoi(*arg); + + gen_key(&key, ksize, exp, pem); + write_key(&key, path, pem); + + pk_free(&key); + + return 0; +} + +int selfsigned(char **arg) +{ + pk_context key; + x509write_cert cert; + mpi serial; + + char *subject = ""; + unsigned int ksize = 512; + int exp = 65537; + unsigned int days = 30; + char *keypath = NULL, *certpath = NULL; + bool pem = true; + time_t from = time(NULL), to; + char fstr[20], tstr[20]; + int len; + + while (*arg && **arg == '-') { + if (!strcmp(*arg, "-der")) { + pem = false; + } 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++; + } + + gen_key(&key, ksize, exp, pem); + + if (keypath) + write_key(&key, keypath, pem); + + from = (from < 1000000000) ? 1000000000 : from; + strftime(fstr, sizeof(fstr), "%Y%m%d%H%M%S", gmtime(&from)); + to = from + 60 * 60 * 24 * days; + if (to < from) + to = INT_MAX; + strftime(tstr, sizeof(tstr), "%Y%m%d%H%M%S", gmtime(&to)); + + fprintf(stderr, "Generating selfsigned certificate with subject '%s'" + " and validity %s-%s\n", subject, fstr, tstr); + + x509write_crt_init(&cert); + x509write_crt_set_md_alg(&cert, POLARSSL_MD_SHA1); + x509write_crt_set_issuer_key(&cert, &key); + x509write_crt_set_subject_key(&cert, &key); + x509write_crt_set_subject_name(&cert, subject); + x509write_crt_set_issuer_name(&cert, subject); + x509write_crt_set_validity(&cert, fstr, tstr); + x509write_crt_set_basic_constraints(&cert, 0, -1); + x509write_crt_set_subject_key_identifier(&cert); + x509write_crt_set_authority_key_identifier(&cert); + + mpi_init(&serial); + mpi_read_string(&serial, 10, "1"); + x509write_crt_set_serial(&cert, &serial); + + if (pem) { + if (x509write_crt_pem(&cert, (void *) buf, sizeof(buf), _urandom, NULL) < 0) { + fprintf(stderr, "Failed to generate certificate\n"); + return 1; + } + + len = strlen(buf); + } else { + len = x509write_crt_der(&cert, (void *) buf, sizeof(buf), _urandom, NULL); + if (len < 0) { + fprintf(stderr, "Failed to generate certificate: %d\n", len); + return 1; + } + } + write_file(certpath, len, pem); + + x509write_crt_free(&cert); + mpi_free(&serial); + pk_free(&key); + + return 0; +} + +int main(int argc, char *argv[]) +{ + urandom_fd = open("/dev/urandom", O_RDONLY); + + 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; +} diff --git a/package/utils/px5g/src/Makefile b/package/utils/px5g/src/Makefile deleted file mode 100644 index 2bd95739cb..0000000000 --- a/package/utils/px5g/src/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -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) diff --git a/package/utils/px5g/src/library/base64.c b/package/utils/px5g/src/library/base64.c deleted file mode 100644 index b7cc5b84ea..0000000000 --- a/package/utils/px5g/src/library/base64.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * RFC 1521 base64 encoding/decoding - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * 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 -#include - -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 diff --git a/package/utils/px5g/src/library/bignum.c b/package/utils/px5g/src/library/bignum.c deleted file mode 100644 index 8b7c12ff00..0000000000 --- a/package/utils/px5g/src/library/bignum.c +++ /dev/null @@ -1,2010 +0,0 @@ -/* - * Multi-precision integer library - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * 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 MPI implementation is based on: - * - * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf - * http://www.stillhq.com/extracted/gnupg-api/mpi/ - * http://math.libtomcrypt.com/files/tommath.pdf - */ - -#include "polarssl/config.h" - -#if defined(POLARSSL_BIGNUM_C) - -#include "polarssl/bignum.h" -#include "polarssl/bn_mul.h" - -#include -#include -#include - -#define ciL ((int) sizeof(t_int)) /* chars in limb */ -#define biL (ciL << 3) /* bits in limb */ -#define biH (ciL << 2) /* half limb size */ - -/* - * Convert between bits/chars and number of limbs - */ -#define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL) -#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL) - -/* - * Initialize one or more mpi - */ -void mpi_init( mpi *X, ... ) -{ - va_list args; - - va_start( args, X ); - - while( X != NULL ) - { - X->s = 1; - X->n = 0; - X->p = NULL; - - X = va_arg( args, mpi* ); - } - - va_end( args ); -} - -/* - * Unallocate one or more mpi - */ -void mpi_free( mpi *X, ... ) -{ - va_list args; - - va_start( args, X ); - - while( X != NULL ) - { - if( X->p != NULL ) - { - memset( X->p, 0, X->n * ciL ); - free( X->p ); - } - - X->s = 1; - X->n = 0; - X->p = NULL; - - X = va_arg( args, mpi* ); - } - - va_end( args ); -} - -/* - * Enlarge to the specified number of limbs - */ -int mpi_grow( mpi *X, int nblimbs ) -{ - t_int *p; - - if( X->n < nblimbs ) - { - if( ( p = (t_int *) malloc( nblimbs * ciL ) ) == NULL ) - return( 1 ); - - memset( p, 0, nblimbs * ciL ); - - if( X->p != NULL ) - { - memcpy( p, X->p, X->n * ciL ); - memset( X->p, 0, X->n * ciL ); - free( X->p ); - } - - X->n = nblimbs; - X->p = p; - } - - return( 0 ); -} - -/* - * Copy the contents of Y into X - */ -int mpi_copy( mpi *X, mpi *Y ) -{ - int ret, i; - - if( X == Y ) - return( 0 ); - - for( i = Y->n - 1; i > 0; i-- ) - if( Y->p[i] != 0 ) - break; - i++; - - X->s = Y->s; - - MPI_CHK( mpi_grow( X, i ) ); - - memset( X->p, 0, X->n * ciL ); - memcpy( X->p, Y->p, i * ciL ); - -cleanup: - - return( ret ); -} - -/* - * Swap the contents of X and Y - */ -void mpi_swap( mpi *X, mpi *Y ) -{ - mpi T; - - memcpy( &T, X, sizeof( mpi ) ); - memcpy( X, Y, sizeof( mpi ) ); - memcpy( Y, &T, sizeof( mpi ) ); -} - -/* - * Set value from integer - */ -int mpi_lset( mpi *X, int z ) -{ - int ret; - - MPI_CHK( mpi_grow( X, 1 ) ); - memset( X->p, 0, X->n * ciL ); - - X->p[0] = ( z < 0 ) ? -z : z; - X->s = ( z < 0 ) ? -1 : 1; - -cleanup: - - return( ret ); -} - -/* - * Return the number of least significant bits - */ -int mpi_lsb( mpi *X ) -{ - int i, j, count = 0; - - for( i = 0; i < X->n; i++ ) - for( j = 0; j < (int) biL; j++, count++ ) - if( ( ( X->p[i] >> j ) & 1 ) != 0 ) - return( count ); - - return( 0 ); -} - -/* - * Return the number of most significant bits - */ -int mpi_msb( mpi *X ) -{ - int i, j; - - for( i = X->n - 1; i > 0; i-- ) - if( X->p[i] != 0 ) - break; - - for( j = biL - 1; j >= 0; j-- ) - if( ( ( X->p[i] >> j ) & 1 ) != 0 ) - break; - - return( ( i * biL ) + j + 1 ); -} - -/* - * Return the total size in bytes - */ -int mpi_size( mpi *X ) -{ - return( ( mpi_msb( X ) + 7 ) >> 3 ); -} - -/* - * Convert an ASCII character to digit value - */ -static int mpi_get_digit( t_int *d, int radix, char c ) -{ - *d = 255; - - if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30; - if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37; - if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57; - - if( *d >= (t_int) radix ) - return( POLARSSL_ERR_MPI_INVALID_CHARACTER ); - - return( 0 ); -} - -/* - * Import from an ASCII string - */ -int mpi_read_string( mpi *X, int radix, char *s ) -{ - int ret, i, j, n; - t_int d; - mpi T; - - if( radix < 2 || radix > 16 ) - return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); - - mpi_init( &T, NULL ); - - if( radix == 16 ) - { - n = BITS_TO_LIMBS( strlen( s ) << 2 ); - - MPI_CHK( mpi_grow( X, n ) ); - MPI_CHK( mpi_lset( X, 0 ) ); - - for( i = strlen( s ) - 1, j = 0; i >= 0; i--, j++ ) - { - if( i == 0 && s[i] == '-' ) - { - X->s = -1; - break; - } - - MPI_CHK( mpi_get_digit( &d, radix, s[i] ) ); - X->p[j / (2 * ciL)] |= d << ( (j % (2 * ciL)) << 2 ); - } - } - else - { - MPI_CHK( mpi_lset( X, 0 ) ); - - for( i = 0; i < (int) strlen( s ); i++ ) - { - if( i == 0 && s[i] == '-' ) - { - X->s = -1; - continue; - } - - MPI_CHK( mpi_get_digit( &d, radix, s[i] ) ); - MPI_CHK( mpi_mul_int( &T, X, radix ) ); - MPI_CHK( mpi_add_int( X, &T, d ) ); - } - } - -cleanup: - - mpi_free( &T, NULL ); - - return( ret ); -} - -/* - * Helper to write the digits high-order first - */ -static int mpi_write_hlp( mpi *X, int radix, char **p ) -{ - int ret; - t_int r; - - if( radix < 2 || radix > 16 ) - return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); - - MPI_CHK( mpi_mod_int( &r, X, radix ) ); - MPI_CHK( mpi_div_int( X, NULL, X, radix ) ); - - if( mpi_cmp_int( X, 0 ) != 0 ) - MPI_CHK( mpi_write_hlp( X, radix, p ) ); - - if( r < 10 ) - *(*p)++ = (char)( r + 0x30 ); - else - *(*p)++ = (char)( r + 0x37 ); - -cleanup: - - return( ret ); -} - -/* - * Export into an ASCII string - */ -int mpi_write_string( mpi *X, int radix, char *s, int *slen ) -{ - int ret = 0, n; - char *p; - mpi T; - - if( radix < 2 || radix > 16 ) - return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); - - n = mpi_msb( X ); - if( radix >= 4 ) n >>= 1; - if( radix >= 16 ) n >>= 1; - n += 3; - - if( *slen < n ) - { - *slen = n; - return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL ); - } - - p = s; - mpi_init( &T, NULL ); - - if( X->s == -1 ) - *p++ = '-'; - - if( radix == 16 ) - { - int c, i, j, k; - - for( i = X->n - 1, k = 0; i >= 0; i-- ) - { - for( j = ciL - 1; j >= 0; j-- ) - { - c = ( X->p[i] >> (j << 3) ) & 0xFF; - - if( c == 0 && k == 0 && (i + j) != 0 ) - continue; - - p += sprintf( p, "%02X", c ); - k = 1; - } - } - } - else - { - MPI_CHK( mpi_copy( &T, X ) ); - MPI_CHK( mpi_write_hlp( &T, radix, &p ) ); - } - - *p++ = '\0'; - *slen = p - s; - -cleanup: - - mpi_free( &T, NULL ); - - return( ret ); -} - -/* - * Read X from an opened file - */ -int mpi_read_file( mpi *X, int radix, FILE *fin ) -{ - t_int d; - int slen; - char *p; - char s[1024]; - - memset( s, 0, sizeof( s ) ); - if( fgets( s, sizeof( s ) - 1, fin ) == NULL ) - return( POLARSSL_ERR_MPI_FILE_IO_ERROR ); - - slen = strlen( s ); - if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; } - if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; } - - p = s + slen; - while( --p >= s ) - if( mpi_get_digit( &d, radix, *p ) != 0 ) - break; - - return( mpi_read_string( X, radix, p + 1 ) ); -} - -/* - * Write X into an opened file (or stdout if fout == NULL) - */ -int mpi_write_file( char *p, mpi *X, int radix, FILE *fout ) -{ - int n, ret; - size_t slen; - size_t plen; - char s[1024]; - - n = sizeof( s ); - memset( s, 0, n ); - n -= 2; - - MPI_CHK( mpi_write_string( X, radix, s, (int *) &n ) ); - - if( p == NULL ) p = ""; - - plen = strlen( p ); - slen = strlen( s ); - s[slen++] = '\r'; - s[slen++] = '\n'; - - if( fout != NULL ) - { - if( fwrite( p, 1, plen, fout ) != plen || - fwrite( s, 1, slen, fout ) != slen ) - return( POLARSSL_ERR_MPI_FILE_IO_ERROR ); - } - else - printf( "%s%s", p, s ); - -cleanup: - - return( ret ); -} - -/* - * Import X from unsigned binary data, big endian - */ -int mpi_read_binary( mpi *X, unsigned char *buf, int buflen ) -{ - int ret, i, j, n; - - for( n = 0; n < buflen; n++ ) - if( buf[n] != 0 ) - break; - - MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) ); - MPI_CHK( mpi_lset( X, 0 ) ); - - for( i = buflen - 1, j = 0; i >= n; i--, j++ ) - X->p[j / ciL] |= ((t_int) buf[i]) << ((j % ciL) << 3); - -cleanup: - - return( ret ); -} - -/* - * Export X into unsigned binary data, big endian - */ -int mpi_write_binary( mpi *X, unsigned char *buf, int buflen ) -{ - int i, j, n; - - n = mpi_size( X ); - - if( buflen < n ) - return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL ); - - memset( buf, 0, buflen ); - - for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- ) - buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) ); - - return( 0 ); -} - -/* - * Left-shift: X <<= count - */ -int mpi_shift_l( mpi *X, int count ) -{ - int ret, i, v0, t1; - t_int r0 = 0, r1; - - v0 = count / (biL ); - t1 = count & (biL - 1); - - i = mpi_msb( X ) + count; - - if( X->n * (int) biL < i ) - MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) ); - - ret = 0; - - /* - * shift by count / limb_size - */ - if( v0 > 0 ) - { - for( i = X->n - 1; i >= v0; i-- ) - X->p[i] = X->p[i - v0]; - - for( ; i >= 0; i-- ) - X->p[i] = 0; - } - - /* - * shift by count % limb_size - */ - if( t1 > 0 ) - { - for( i = v0; i < X->n; i++ ) - { - r1 = X->p[i] >> (biL - t1); - X->p[i] <<= t1; - X->p[i] |= r0; - r0 = r1; - } - } - -cleanup: - - return( ret ); -} - -/* - * Right-shift: X >>= count - */ -int mpi_shift_r( mpi *X, int count ) -{ - int i, v0, v1; - t_int r0 = 0, r1; - - v0 = count / biL; - v1 = count & (biL - 1); - - /* - * shift by count / limb_size - */ - if( v0 > 0 ) - { - for( i = 0; i < X->n - v0; i++ ) - X->p[i] = X->p[i + v0]; - - for( ; i < X->n; i++ ) - X->p[i] = 0; - } - - /* - * shift by count % limb_size - */ - if( v1 > 0 ) - { - for( i = X->n - 1; i >= 0; i-- ) - { - r1 = X->p[i] << (biL - v1); - X->p[i] >>= v1; - X->p[i] |= r0; - r0 = r1; - } - } - - return( 0 ); -} - -/* - * Compare unsigned values - */ -int mpi_cmp_abs( mpi *X, mpi *Y ) -{ - int i, j; - - for( i = X->n - 1; i >= 0; i-- ) - if( X->p[i] != 0 ) - break; - - for( j = Y->n - 1; j >= 0; j-- ) - if( Y->p[j] != 0 ) - break; - - if( i < 0 && j < 0 ) - return( 0 ); - - if( i > j ) return( 1 ); - if( j > i ) return( -1 ); - - for( ; i >= 0; i-- ) - { - if( X->p[i] > Y->p[i] ) return( 1 ); - if( X->p[i] < Y->p[i] ) return( -1 ); - } - - return( 0 ); -} - -/* - * Compare signed values - */ -int mpi_cmp_mpi( mpi *X, mpi *Y ) -{ - int i, j; - - for( i = X->n - 1; i >= 0; i-- ) - if( X->p[i] != 0 ) - break; - - for( j = Y->n - 1; j >= 0; j-- ) - if( Y->p[j] != 0 ) - break; - - if( i < 0 && j < 0 ) - return( 0 ); - - if( i > j ) return( X->s ); - if( j > i ) return( -X->s ); - - if( X->s > 0 && Y->s < 0 ) return( 1 ); - if( Y->s > 0 && X->s < 0 ) return( -1 ); - - for( ; i >= 0; i-- ) - { - if( X->p[i] > Y->p[i] ) return( X->s ); - if( X->p[i] < Y->p[i] ) return( -X->s ); - } - - return( 0 ); -} - -/* - * Compare signed values - */ -int mpi_cmp_int( mpi *X, int z ) -{ - mpi Y; - t_int p[1]; - - *p = ( z < 0 ) ? -z : z; - Y.s = ( z < 0 ) ? -1 : 1; - Y.n = 1; - Y.p = p; - - return( mpi_cmp_mpi( X, &Y ) ); -} - -/* - * Unsigned addition: X = |A| + |B| (HAC 14.7) - */ -int mpi_add_abs( mpi *X, mpi *A, mpi *B ) -{ - int ret, i, j; - t_int *o, *p, c; - - if( X == B ) - { - mpi *T = A; A = X; B = T; - } - - if( X != A ) - MPI_CHK( mpi_copy( X, A ) ); - - for( j = B->n - 1; j >= 0; j-- ) - if( B->p[j] != 0 ) - break; - - MPI_CHK( mpi_grow( X, j + 1 ) ); - - o = B->p; p = X->p; c = 0; - - for( i = 0; i <= j; i++, o++, p++ ) - { - *p += c; c = ( *p < c ); - *p += *o; c += ( *p < *o ); - } - - while( c != 0 ) - { - if( i >= X->n ) - { - MPI_CHK( mpi_grow( X, i + 1 ) ); - p = X->p + i; - } - - *p += c; c = ( *p < c ); i++; - } - -cleanup: - - return( ret ); -} - -/* - * Helper for mpi substraction - */ -static void mpi_sub_hlp( int n, t_int *s, t_int *d ) -{ - int i; - t_int c, z; - - for( i = c = 0; i < n; i++, s++, d++ ) - { - z = ( *d < c ); *d -= c; - c = ( *d < *s ) + z; *d -= *s; - } - - while( c != 0 ) - { - z = ( *d < c ); *d -= c; - c = z; i++; d++; - } -} - -/* - * Unsigned substraction: X = |A| - |B| (HAC 14.9) - */ -int mpi_sub_abs( mpi *X, mpi *A, mpi *B ) -{ - mpi TB; - int ret, n; - - if( mpi_cmp_abs( A, B ) < 0 ) - return( POLARSSL_ERR_MPI_NEGATIVE_VALUE ); - - mpi_init( &TB, NULL ); - - if( X == B ) - { - MPI_CHK( mpi_copy( &TB, B ) ); - B = &TB; - } - - if( X != A ) - MPI_CHK( mpi_copy( X, A ) ); - - ret = 0; - - for( n = B->n - 1; n >= 0; n-- ) - if( B->p[n] != 0 ) - break; - - mpi_sub_hlp( n + 1, B->p, X->p ); - -cleanup: - - mpi_free( &TB, NULL ); - - return( ret ); -} - -/* - * Signed addition: X = A + B - */ -int mpi_add_mpi( mpi *X, mpi *A, mpi *B ) -{ - int ret, s = A->s; - - if( A->s * B->s < 0 ) - { - if( mpi_cmp_abs( A, B ) >= 0 ) - { - MPI_CHK( mpi_sub_abs( X, A, B ) ); - X->s = s; - } - else - { - MPI_CHK( mpi_sub_abs( X, B, A ) ); - X->s = -s; - } - } - else - { - MPI_CHK( mpi_add_abs( X, A, B ) ); - X->s = s; - } - -cleanup: - - return( ret ); -} - -/* - * Signed substraction: X = A - B - */ -int mpi_sub_mpi( mpi *X, mpi *A, mpi *B ) -{ - int ret, s = A->s; - - if( A->s * B->s > 0 ) - { - if( mpi_cmp_abs( A, B ) >= 0 ) - { - MPI_CHK( mpi_sub_abs( X, A, B ) ); - X->s = s; - } - else - { - MPI_CHK( mpi_sub_abs( X, B, A ) ); - X->s = -s; - } - } - else - { - MPI_CHK( mpi_add_abs( X, A, B ) ); - X->s = s; - } - -cleanup: - - return( ret ); -} - -/* - * Signed addition: X = A + b - */ -int mpi_add_int( mpi *X, mpi *A, int b ) -{ - mpi _B; - t_int p[1]; - - p[0] = ( b < 0 ) ? -b : b; - _B.s = ( b < 0 ) ? -1 : 1; - _B.n = 1; - _B.p = p; - - return( mpi_add_mpi( X, A, &_B ) ); -} - -/* - * Signed substraction: X = A - b - */ -int mpi_sub_int( mpi *X, mpi *A, int b ) -{ - mpi _B; - t_int p[1]; - - p[0] = ( b < 0 ) ? -b : b; - _B.s = ( b < 0 ) ? -1 : 1; - _B.n = 1; - _B.p = p; - - return( mpi_sub_mpi( X, A, &_B ) ); -} - -/* - * Helper for mpi multiplication - */ -static void mpi_mul_hlp( int i, t_int *s, t_int *d, t_int b ) -{ - t_int c = 0, t = 0; - -#if defined(MULADDC_HUIT) - for( ; i >= 8; i -= 8 ) - { - MULADDC_INIT - MULADDC_HUIT - MULADDC_STOP - } - - for( ; i > 0; i-- ) - { - MULADDC_INIT - MULADDC_CORE - MULADDC_STOP - } -#else - for( ; i >= 16; i -= 16 ) - { - MULADDC_INIT - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - MULADDC_STOP - } - - for( ; i >= 8; i -= 8 ) - { - MULADDC_INIT - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - MULADDC_STOP - } - - for( ; i > 0; i-- ) - { - MULADDC_INIT - MULADDC_CORE - MULADDC_STOP - } -#endif - - t++; - - do { - *d += c; c = ( *d < c ); d++; - } - while( c != 0 ); -} - -/* - * Baseline multiplication: X = A * B (HAC 14.12) - */ -int mpi_mul_mpi( mpi *X, mpi *A, mpi *B ) -{ - int ret, i, j; - mpi TA, TB; - - mpi_init( &TA, &TB, NULL ); - - if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; } - if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; } - - for( i = A->n - 1; i >= 0; i-- ) - if( A->p[i] != 0 ) - break; - - for( j = B->n - 1; j >= 0; j-- ) - if( B->p[j] != 0 ) - break; - - MPI_CHK( mpi_grow( X, i + j + 2 ) ); - MPI_CHK( mpi_lset( X, 0 ) ); - - for( i++; j >= 0; j-- ) - mpi_mul_hlp( i, A->p, X->p + j, B->p[j] ); - - X->s = A->s * B->s; - -cleanup: - - mpi_free( &TB, &TA, NULL ); - - return( ret ); -} - -/* - * Baseline multiplication: X = A * b - */ -int mpi_mul_int( mpi *X, mpi *A, t_int b ) -{ - mpi _B; - t_int p[1]; - - _B.s = 1; - _B.n = 1; - _B.p = p; - p[0] = b; - - return( mpi_mul_mpi( X, A, &_B ) ); -} - -/* - * Division by mpi: A = Q * B + R (HAC 14.20) - */ -int mpi_div_mpi( mpi *Q, mpi *R, mpi *A, mpi *B ) -{ - int ret, i, n, t, k; - mpi X, Y, Z, T1, T2; - - if( mpi_cmp_int( B, 0 ) == 0 ) - return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO ); - - mpi_init( &X, &Y, &Z, &T1, &T2, NULL ); - - if( mpi_cmp_abs( A, B ) < 0 ) - { - if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) ); - if( R != NULL ) MPI_CHK( mpi_copy( R, A ) ); - return( 0 ); - } - - MPI_CHK( mpi_copy( &X, A ) ); - MPI_CHK( mpi_copy( &Y, B ) ); - X.s = Y.s = 1; - - MPI_CHK( mpi_grow( &Z, A->n + 2 ) ); - MPI_CHK( mpi_lset( &Z, 0 ) ); - MPI_CHK( mpi_grow( &T1, 2 ) ); - MPI_CHK( mpi_grow( &T2, 3 ) ); - - k = mpi_msb( &Y ) % biL; - if( k < (int) biL - 1 ) - { - k = biL - 1 - k; - MPI_CHK( mpi_shift_l( &X, k ) ); - MPI_CHK( mpi_shift_l( &Y, k ) ); - } - else k = 0; - - n = X.n - 1; - t = Y.n - 1; - mpi_shift_l( &Y, biL * (n - t) ); - - while( mpi_cmp_mpi( &X, &Y ) >= 0 ) - { - Z.p[n - t]++; - mpi_sub_mpi( &X, &X, &Y ); - } - mpi_shift_r( &Y, biL * (n - t) ); - - for( i = n; i > t ; i-- ) - { - if( X.p[i] >= Y.p[t] ) - Z.p[i - t - 1] = ~0; - else - { -#if defined(POLARSSL_HAVE_LONGLONG) - t_dbl r; - - r = (t_dbl) X.p[i] << biL; - r |= (t_dbl) X.p[i - 1]; - r /= Y.p[t]; - if( r > ((t_dbl) 1 << biL) - 1) - r = ((t_dbl) 1 << biL) - 1; - - Z.p[i - t - 1] = (t_int) r; -#else - /* - * __udiv_qrnnd_c, from gmp/longlong.h - */ - t_int q0, q1, r0, r1; - t_int d0, d1, d, m; - - d = Y.p[t]; - d0 = ( d << biH ) >> biH; - d1 = ( d >> biH ); - - q1 = X.p[i] / d1; - r1 = X.p[i] - d1 * q1; - r1 <<= biH; - r1 |= ( X.p[i - 1] >> biH ); - - m = q1 * d0; - if( r1 < m ) - { - q1--, r1 += d; - while( r1 >= d && r1 < m ) - q1--, r1 += d; - } - r1 -= m; - - q0 = r1 / d1; - r0 = r1 - d1 * q0; - r0 <<= biH; - r0 |= ( X.p[i - 1] << biH ) >> biH; - - m = q0 * d0; - if( r0 < m ) - { - q0--, r0 += d; - while( r0 >= d && r0 < m ) - q0--, r0 += d; - } - r0 -= m; - - Z.p[i - t - 1] = ( q1 << biH ) | q0; -#endif - } - - Z.p[i - t - 1]++; - do - { - Z.p[i - t - 1]--; - - MPI_CHK( mpi_lset( &T1, 0 ) ); - T1.p[0] = (t < 1) ? 0 : Y.p[t - 1]; - T1.p[1] = Y.p[t]; - MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) ); - - MPI_CHK( mpi_lset( &T2, 0 ) ); - T2.p[0] = (i < 2) ? 0 : X.p[i - 2]; - T2.p[1] = (i < 1) ? 0 : X.p[i - 1]; - T2.p[2] = X.p[i]; - } - while( mpi_cmp_mpi( &T1, &T2 ) > 0 ); - - MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) ); - MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) ); - MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) ); - - if( mpi_cmp_int( &X, 0 ) < 0 ) - { - MPI_CHK( mpi_copy( &T1, &Y ) ); - MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) ); - MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) ); - Z.p[i - t - 1]--; - } - } - - if( Q != NULL ) - { - mpi_copy( Q, &Z ); - Q->s = A->s * B->s; - } - - if( R != NULL ) - { - mpi_shift_r( &X, k ); - mpi_copy( R, &X ); - - R->s = A->s; - if( mpi_cmp_int( R, 0 ) == 0 ) - R->s = 1; - } - -cleanup: - - mpi_free( &X, &Y, &Z, &T1, &T2, NULL ); - - return( ret ); -} - -/* - * Division by int: A = Q * b + R - * - * Returns 0 if successful - * 1 if memory allocation failed - * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0 - */ -int mpi_div_int( mpi *Q, mpi *R, mpi *A, int b ) -{ - mpi _B; - t_int p[1]; - - p[0] = ( b < 0 ) ? -b : b; - _B.s = ( b < 0 ) ? -1 : 1; - _B.n = 1; - _B.p = p; - - return( mpi_div_mpi( Q, R, A, &_B ) ); -} - -/* - * Modulo: R = A mod B - */ -int mpi_mod_mpi( mpi *R, mpi *A, mpi *B ) -{ - int ret; - - MPI_CHK( mpi_div_mpi( NULL, R, A, B ) ); - - while( mpi_cmp_int( R, 0 ) < 0 ) - MPI_CHK( mpi_add_mpi( R, R, B ) ); - - while( mpi_cmp_mpi( R, B ) >= 0 ) - MPI_CHK( mpi_sub_mpi( R, R, B ) ); - -cleanup: - - return( ret ); -} - -/* - * Modulo: r = A mod b - */ -int mpi_mod_int( t_int *r, mpi *A, int b ) -{ - int i; - t_int x, y, z; - - if( b == 0 ) - return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO ); - - if( b < 0 ) - b = -b; - - /* - * handle trivial cases - */ - if( b == 1 ) - { - *r = 0; - return( 0 ); - } - - if( b == 2 ) - { - *r = A->p[0] & 1; - return( 0 ); - } - - /* - * general case - */ - for( i = A->n - 1, y = 0; i >= 0; i-- ) - { - x = A->p[i]; - y = ( y << biH ) | ( x >> biH ); - z = y / b; - y -= z * b; - - x <<= biH; - y = ( y << biH ) | ( x >> biH ); - z = y / b; - y -= z * b; - } - - *r = y; - - return( 0 ); -} - -/* - * Fast Montgomery initialization (thanks to Tom St Denis) - */ -static void mpi_montg_init( t_int *mm, mpi *N ) -{ - t_int x, m0 = N->p[0]; - - x = m0; - x += ( ( m0 + 2 ) & 4 ) << 1; - x *= ( 2 - ( m0 * x ) ); - - if( biL >= 16 ) x *= ( 2 - ( m0 * x ) ); - if( biL >= 32 ) x *= ( 2 - ( m0 * x ) ); - if( biL >= 64 ) x *= ( 2 - ( m0 * x ) ); - - *mm = ~x + 1; -} - -/* - * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36) - */ -static void mpi_montmul( mpi *A, mpi *B, mpi *N, t_int mm, mpi *T ) -{ - int i, n, m; - t_int u0, u1, *d; - - memset( T->p, 0, T->n * ciL ); - - d = T->p; - n = N->n; - m = ( B->n < n ) ? B->n : n; - - for( i = 0; i < n; i++ ) - { - /* - * T = (T + u0*B + u1*N) / 2^biL - */ - u0 = A->p[i]; - u1 = ( d[0] + u0 * B->p[0] ) * mm; - - mpi_mul_hlp( m, B->p, d, u0 ); - mpi_mul_hlp( n, N->p, d, u1 ); - - *d++ = u0; d[n + 1] = 0; - } - - memcpy( A->p, d, (n + 1) * ciL ); - - if( mpi_cmp_abs( A, N ) >= 0 ) - mpi_sub_hlp( n, N->p, A->p ); - else - /* prevent timing attacks */ - mpi_sub_hlp( n, A->p, T->p ); -} - -/* - * Montgomery reduction: A = A * R^-1 mod N - */ -static void mpi_montred( mpi *A, mpi *N, t_int mm, mpi *T ) -{ - t_int z = 1; - mpi U; - - U.n = U.s = z; - U.p = &z; - - mpi_montmul( A, &U, N, mm, T ); -} - -/* - * Sliding-window exponentiation: X = A^E mod N (HAC 14.85) - */ -int mpi_exp_mod( mpi *X, mpi *A, mpi *E, mpi *N, mpi *_RR ) -{ - int ret, i, j, wsize, wbits; - int bufsize, nblimbs, nbits; - t_int ei, mm, state; - mpi RR, T, W[64]; - - if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 ) - return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); - - /* - * Init temps and window size - */ - mpi_montg_init( &mm, N ); - mpi_init( &RR, &T, NULL ); - memset( W, 0, sizeof( W ) ); - - i = mpi_msb( E ); - - wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 : - ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1; - - j = N->n + 1; - MPI_CHK( mpi_grow( X, j ) ); - MPI_CHK( mpi_grow( &W[1], j ) ); - MPI_CHK( mpi_grow( &T, j * 2 ) ); - - /* - * If 1st call, pre-compute R^2 mod N - */ - if( _RR == NULL || _RR->p == NULL ) - { - MPI_CHK( mpi_lset( &RR, 1 ) ); - MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) ); - MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) ); - - if( _RR != NULL ) - memcpy( _RR, &RR, sizeof( mpi ) ); - } - else - memcpy( &RR, _RR, sizeof( mpi ) ); - - /* - * W[1] = A * R^2 * R^-1 mod N = A * R mod N - */ - if( mpi_cmp_mpi( A, N ) >= 0 ) - mpi_mod_mpi( &W[1], A, N ); - else mpi_copy( &W[1], A ); - - mpi_montmul( &W[1], &RR, N, mm, &T ); - - /* - * X = R^2 * R^-1 mod N = R mod N - */ - MPI_CHK( mpi_copy( X, &RR ) ); - mpi_montred( X, N, mm, &T ); - - if( wsize > 1 ) - { - /* - * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1) - */ - j = 1 << (wsize - 1); - - MPI_CHK( mpi_grow( &W[j], N->n + 1 ) ); - MPI_CHK( mpi_copy( &W[j], &W[1] ) ); - - for( i = 0; i < wsize - 1; i++ ) - mpi_montmul( &W[j], &W[j], N, mm, &T ); - - /* - * W[i] = W[i - 1] * W[1] - */ - for( i = j + 1; i < (1 << wsize); i++ ) - { - MPI_CHK( mpi_grow( &W[i], N->n + 1 ) ); - MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) ); - - mpi_montmul( &W[i], &W[1], N, mm, &T ); - } - } - - nblimbs = E->n; - bufsize = 0; - nbits = 0; - wbits = 0; - state = 0; - - while( 1 ) - { - if( bufsize == 0 ) - { - if( nblimbs-- == 0 ) - break; - - bufsize = sizeof( t_int ) << 3; - } - - bufsize--; - - ei = (E->p[nblimbs] >> bufsize) & 1; - - /* - * skip leading 0s - */ - if( ei == 0 && state == 0 ) - continue; - - if( ei == 0 && state == 1 ) - { - /* - * out of window, square X - */ - mpi_montmul( X, X, N, mm, &T ); - continue; - } - - /* - * add ei to current window - */ - state = 2; - - nbits++; - wbits |= (ei << (wsize - nbits)); - - if( nbits == wsize ) - { - /* - * X = X^wsize R^-1 mod N - */ - for( i = 0; i < wsize; i++ ) - mpi_montmul( X, X, N, mm, &T ); - - /* - * X = X * W[wbits] R^-1 mod N - */ - mpi_montmul( X, &W[wbits], N, mm, &T ); - - state--; - nbits = 0; - wbits = 0; - } - } - - /* - * process the remaining bits - */ - for( i = 0; i < nbits; i++ ) - { - mpi_montmul( X, X, N, mm, &T ); - - wbits <<= 1; - - if( (wbits & (1 << wsize)) != 0 ) - mpi_montmul( X, &W[1], N, mm, &T ); - } - - /* - * X = A^E * R * R^-1 mod N = A^E mod N - */ - mpi_montred( X, N, mm, &T ); - -cleanup: - - for( i = (1 << (wsize - 1)); i < (1 << wsize); i++ ) - mpi_free( &W[i], NULL ); - - if( _RR != NULL ) - mpi_free( &W[1], &T, NULL ); - else mpi_free( &W[1], &T, &RR, NULL ); - - return( ret ); -} - -/* - * Greatest common divisor: G = gcd(A, B) (HAC 14.54) - */ -int mpi_gcd( mpi *G, mpi *A, mpi *B ) -{ - int ret, lz, lzt; - mpi TG, TA, TB; - - mpi_init( &TG, &TA, &TB, NULL ); - - MPI_CHK( mpi_copy( &TA, A ) ); - MPI_CHK( mpi_copy( &TB, B ) ); - - lz = mpi_lsb( &TA ); - lzt = mpi_lsb( &TB ); - - if ( lzt < lz ) - lz = lzt; - - MPI_CHK( mpi_shift_r( &TA, lz ) ); - MPI_CHK( mpi_shift_r( &TB, lz ) ); - - TA.s = TB.s = 1; - - while( mpi_cmp_int( &TA, 0 ) != 0 ) - { - MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) ); - MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) ); - - if( mpi_cmp_mpi( &TA, &TB ) >= 0 ) - { - MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) ); - MPI_CHK( mpi_shift_r( &TA, 1 ) ); - } - else - { - MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) ); - MPI_CHK( mpi_shift_r( &TB, 1 ) ); - } - } - - MPI_CHK( mpi_shift_l( &TB, lz ) ); - MPI_CHK( mpi_copy( G, &TB ) ); - -cleanup: - - mpi_free( &TB, &TA, &TG, NULL ); - - return( ret ); -} - -#if defined(POLARSSL_GENPRIME) - -/* - * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64) - */ -int mpi_inv_mod( mpi *X, mpi *A, mpi *N ) -{ - int ret; - mpi G, TA, TU, U1, U2, TB, TV, V1, V2; - - if( mpi_cmp_int( N, 0 ) <= 0 ) - return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); - - mpi_init( &TA, &TU, &U1, &U2, &G, - &TB, &TV, &V1, &V2, NULL ); - - MPI_CHK( mpi_gcd( &G, A, N ) ); - - if( mpi_cmp_int( &G, 1 ) != 0 ) - { - ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE; - goto cleanup; - } - - MPI_CHK( mpi_mod_mpi( &TA, A, N ) ); - MPI_CHK( mpi_copy( &TU, &TA ) ); - MPI_CHK( mpi_copy( &TB, N ) ); - MPI_CHK( mpi_copy( &TV, N ) ); - - MPI_CHK( mpi_lset( &U1, 1 ) ); - MPI_CHK( mpi_lset( &U2, 0 ) ); - MPI_CHK( mpi_lset( &V1, 0 ) ); - MPI_CHK( mpi_lset( &V2, 1 ) ); - - do - { - while( ( TU.p[0] & 1 ) == 0 ) - { - MPI_CHK( mpi_shift_r( &TU, 1 ) ); - - if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 ) - { - MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) ); - MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) ); - } - - MPI_CHK( mpi_shift_r( &U1, 1 ) ); - MPI_CHK( mpi_shift_r( &U2, 1 ) ); - } - - while( ( TV.p[0] & 1 ) == 0 ) - { - MPI_CHK( mpi_shift_r( &TV, 1 ) ); - - if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 ) - { - MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) ); - MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) ); - } - - MPI_CHK( mpi_shift_r( &V1, 1 ) ); - MPI_CHK( mpi_shift_r( &V2, 1 ) ); - } - - if( mpi_cmp_mpi( &TU, &TV ) >= 0 ) - { - MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) ); - MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) ); - MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) ); - } - else - { - MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) ); - MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) ); - MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) ); - } - } - while( mpi_cmp_int( &TU, 0 ) != 0 ); - - while( mpi_cmp_int( &V1, 0 ) < 0 ) - MPI_CHK( mpi_add_mpi( &V1, &V1, N ) ); - - while( mpi_cmp_mpi( &V1, N ) >= 0 ) - MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) ); - - MPI_CHK( mpi_copy( X, &V1 ) ); - -cleanup: - - mpi_free( &V2, &V1, &TV, &TB, &G, - &U2, &U1, &TU, &TA, NULL ); - - return( ret ); -} - -static const int small_prime[] = -{ - 3, 5, 7, 11, 13, 17, 19, 23, - 29, 31, 37, 41, 43, 47, 53, 59, - 61, 67, 71, 73, 79, 83, 89, 97, - 101, 103, 107, 109, 113, 127, 131, 137, - 139, 149, 151, 157, 163, 167, 173, 179, - 181, 191, 193, 197, 199, 211, 223, 227, - 229, 233, 239, 241, 251, 257, 263, 269, - 271, 277, 281, 283, 293, 307, 311, 313, - 317, 331, 337, 347, 349, 353, 359, 367, - 373, 379, 383, 389, 397, 401, 409, 419, - 421, 431, 433, 439, 443, 449, 457, 461, - 463, 467, 479, 487, 491, 499, 503, 509, - 521, 523, 541, 547, 557, 563, 569, 571, - 577, 587, 593, 599, 601, 607, 613, 617, - 619, 631, 641, 643, 647, 653, 659, 661, - 673, 677, 683, 691, 701, 709, 719, 727, - 733, 739, 743, 751, 757, 761, 769, 773, - 787, 797, 809, 811, 821, 823, 827, 829, - 839, 853, 857, 859, 863, 877, 881, 883, - 887, 907, 911, 919, 929, 937, 941, 947, - 953, 967, 971, 977, 983, 991, 997, -103 -}; - -/* - * Miller-Rabin primality test (HAC 4.24) - */ -int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng ) -{ - int ret, i, j, n, s, xs; - mpi W, R, T, A, RR; - unsigned char *p; - - if( mpi_cmp_int( X, 0 ) == 0 ) - return( 0 ); - - mpi_init( &W, &R, &T, &A, &RR, NULL ); - - xs = X->s; X->s = 1; - - /* - * test trivial factors first - */ - if( ( X->p[0] & 1 ) == 0 ) - return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); - - for( i = 0; small_prime[i] > 0; i++ ) - { - t_int r; - - if( mpi_cmp_int( X, small_prime[i] ) <= 0 ) - return( 0 ); - - MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) ); - - if( r == 0 ) - return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); - } - - /* - * W = |X| - 1 - * R = W >> lsb( W ) - */ - s = mpi_lsb( &W ); - MPI_CHK( mpi_sub_int( &W, X, 1 ) ); - MPI_CHK( mpi_copy( &R, &W ) ); - MPI_CHK( mpi_shift_r( &R, s ) ); - - i = mpi_msb( X ); - /* - * HAC, table 4.4 - */ - n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 : - ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 : - ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 ); - - for( i = 0; i < n; i++ ) - { - /* - * pick a random A, 1 < A < |X| - 1 - */ - MPI_CHK( mpi_grow( &A, X->n ) ); - - p = (unsigned char *) A.p; - for( j = 0; j < A.n * ciL; j++ ) - *p++ = (unsigned char) f_rng( p_rng ); - - j = mpi_msb( &A ) - mpi_msb( &W ); - MPI_CHK( mpi_shift_r( &A, j + 1 ) ); - A.p[0] |= 3; - - /* - * A = A^R mod |X| - */ - MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) ); - - if( mpi_cmp_mpi( &A, &W ) == 0 || - mpi_cmp_int( &A, 1 ) == 0 ) - continue; - - j = 1; - while( j < s && mpi_cmp_mpi( &A, &W ) != 0 ) - { - /* - * A = A * A mod |X| - */ - MPI_CHK( mpi_mul_mpi( &T, &A, &A ) ); - MPI_CHK( mpi_mod_mpi( &A, &T, X ) ); - - if( mpi_cmp_int( &A, 1 ) == 0 ) - break; - - j++; - } - - /* - * not prime if A != |X| - 1 or A == 1 - */ - if( mpi_cmp_mpi( &A, &W ) != 0 || - mpi_cmp_int( &A, 1 ) == 0 ) - { - ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE; - break; - } - } - -cleanup: - - X->s = xs; - - mpi_free( &RR, &A, &T, &R, &W, NULL ); - - return( ret ); -} - -/* - * Prime number generation - */ -int mpi_gen_prime( mpi *X, int nbits, int dh_flag, - int (*f_rng)(void *), void *p_rng ) -{ - int ret, k, n; - unsigned char *p; - mpi Y; - - if( nbits < 3 ) - return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); - - mpi_init( &Y, NULL ); - - n = BITS_TO_LIMBS( nbits ); - - MPI_CHK( mpi_grow( X, n ) ); - MPI_CHK( mpi_lset( X, 0 ) ); - - p = (unsigned char *) X->p; - for( k = 0; k < X->n * ciL; k++ ) - *p++ = (unsigned char) f_rng( p_rng ); - - k = mpi_msb( X ); - if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) ); - if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) ); - - X->p[0] |= 3; - - if( dh_flag == 0 ) - { - while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 ) - { - if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE ) - goto cleanup; - - MPI_CHK( mpi_add_int( X, X, 2 ) ); - } - } - else - { - MPI_CHK( mpi_sub_int( &Y, X, 1 ) ); - MPI_CHK( mpi_shift_r( &Y, 1 ) ); - - while( 1 ) - { - if( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) == 0 ) - { - if( ( ret = mpi_is_prime( &Y, f_rng, p_rng ) ) == 0 ) - break; - - if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE ) - goto cleanup; - } - - if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE ) - goto cleanup; - - MPI_CHK( mpi_add_int( &Y, X, 1 ) ); - MPI_CHK( mpi_add_int( X, X, 2 ) ); - MPI_CHK( mpi_shift_r( &Y, 1 ) ); - } - } - -cleanup: - - mpi_free( &Y, NULL ); - - return( ret ); -} - -#endif - -#if defined(POLARSSL_SELF_TEST) - -#define GCD_PAIR_COUNT 3 - -static const int gcd_pairs[GCD_PAIR_COUNT][3] = -{ - { 693, 609, 21 }, - { 1764, 868, 28 }, - { 768454923, 542167814, 1 } -}; - -/* - * Checkup routine - */ -int mpi_self_test( int verbose ) -{ - int ret, i; - mpi A, E, N, X, Y, U, V; - - mpi_init( &A, &E, &N, &X, &Y, &U, &V, NULL ); - - MPI_CHK( mpi_read_string( &A, 16, - "EFE021C2645FD1DC586E69184AF4A31E" \ - "D5F53E93B5F123FA41680867BA110131" \ - "944FE7952E2517337780CB0DB80E61AA" \ - "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) ); - - MPI_CHK( mpi_read_string( &E, 16, - "B2E7EFD37075B9F03FF989C7C5051C20" \ - "34D2A323810251127E7BF8625A4F49A5" \ - "F3E27F4DA8BD59C47D6DAABA4C8127BD" \ - "5B5C25763222FEFCCFC38B832366C29E" ) ); - - MPI_CHK( mpi_read_string( &N, 16, - "0066A198186C18C10B2F5ED9B522752A" \ - "9830B69916E535C8F047518A889A43A5" \ - "94B6BED27A168D31D4A52F88925AA8F5" ) ); - - MPI_CHK( mpi_mul_mpi( &X, &A, &N ) ); - - MPI_CHK( mpi_read_string( &U, 16, - "602AB7ECA597A3D6B56FF9829A5E8B85" \ - "9E857EA95A03512E2BAE7391688D264A" \ - "A5663B0341DB9CCFD2C4C5F421FEC814" \ - "8001B72E848A38CAE1C65F78E56ABDEF" \ - "E12D3C039B8A02D6BE593F0BBBDA56F1" \ - "ECF677152EF804370C1A305CAF3B5BF1" \ - "30879B56C61DE584A0F53A2447A51E" ) ); - - if( verbose != 0 ) - printf( " MPI test #1 (mul_mpi): " ); - - if( mpi_cmp_mpi( &X, &U ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - printf( "passed\n" ); - - MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) ); - - MPI_CHK( mpi_read_string( &U, 16, - "256567336059E52CAE22925474705F39A94" ) ); - - MPI_CHK( mpi_read_string( &V, 16, - "6613F26162223DF488E9CD48CC132C7A" \ - "0AC93C701B001B092E4E5B9F73BCD27B" \ - "9EE50D0657C77F374E903CDFA4C642" ) ); - - if( verbose != 0 ) - printf( " MPI test #2 (div_mpi): " ); - - if( mpi_cmp_mpi( &X, &U ) != 0 || - mpi_cmp_mpi( &Y, &V ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - printf( "passed\n" ); - - MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) ); - - MPI_CHK( mpi_read_string( &U, 16, - "36E139AEA55215609D2816998ED020BB" \ - "BD96C37890F65171D948E9BC7CBAA4D9" \ - "325D24D6A3C12710F10A09FA08AB87" ) ); - - if( verbose != 0 ) - printf( " MPI test #3 (exp_mod): " ); - - if( mpi_cmp_mpi( &X, &U ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - printf( "passed\n" ); - - MPI_CHK( mpi_inv_mod( &X, &A, &N ) ); - - MPI_CHK( mpi_read_string( &U, 16, - "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \ - "C3DBA76456363A10869622EAC2DD84EC" \ - "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) ); - - if( verbose != 0 ) - printf( " MPI test #4 (inv_mod): " ); - - if( mpi_cmp_mpi( &X, &U ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - printf( "passed\n" ); - - if( verbose != 0 ) - printf( " MPI test #5 (simple gcd): " ); - - for ( i = 0; i < GCD_PAIR_COUNT; i++) - { - MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) ); - MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) ); - - MPI_CHK( mpi_gcd( &A, &X, &Y ) ); - - if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 ) - { - if( verbose != 0 ) - printf( "failed at %d\n", i ); - - return( 1 ); - } - } - - if( verbose != 0 ) - printf( "passed\n" ); - -cleanup: - - if( ret != 0 && verbose != 0 ) - printf( "Unexpected error, return code = %08X\n", ret ); - - mpi_free( &V, &U, &Y, &X, &N, &E, &A, NULL ); - - if( verbose != 0 ) - printf( "\n" ); - - return( ret ); -} - -#endif - -#endif diff --git a/package/utils/px5g/src/library/havege.c b/package/utils/px5g/src/library/havege.c deleted file mode 100644 index 266299d3bb..0000000000 --- a/package/utils/px5g/src/library/havege.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * HAVEGE: HArdware Volatile Entropy Gathering and Expansion - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * 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 -#include - -#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 - -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 \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 diff --git a/package/utils/px5g/src/library/rsa.c b/package/utils/px5g/src/library/rsa.c deleted file mode 100644 index 131b6c6c9c..0000000000 --- a/package/utils/px5g/src/library/rsa.c +++ /dev/null @@ -1,750 +0,0 @@ -/* - * The RSA public-key cryptosystem - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * 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 -#include -#include - -/* - * 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 diff --git a/package/utils/px5g/src/library/sha1.c b/package/utils/px5g/src/library/sha1.c deleted file mode 100644 index 54a4416f31..0000000000 --- a/package/utils/px5g/src/library/sha1.c +++ /dev/null @@ -1,622 +0,0 @@ -/* - * FIPS-180-1 compliant SHA-1 implementation - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * 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 -#include - -/* - * 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 diff --git a/package/utils/px5g/src/library/timing.c b/package/utils/px5g/src/library/timing.c deleted file mode 100644 index 6b7ab740e1..0000000000 --- a/package/utils/px5g/src/library/timing.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Portable interface to the CPU cycle counter - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * 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 -#include - -struct _hr_time -{ - LARGE_INTEGER start; -}; - -#else - -#include -#include -#include -#include -#include - -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 diff --git a/package/utils/px5g/src/library/x509write.c b/package/utils/px5g/src/library/x509write.c deleted file mode 100644 index fabee20ea6..0000000000 --- a/package/utils/px5g/src/library/x509write.c +++ /dev/null @@ -1,1139 +0,0 @@ -/* - * X.509 certificate and private key writing - * - * Copyright (C) 2006-2007 Pascal Vizeli - * Modifications (C) 2009 Steven Barth - * - * 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 - */ -/* - * The ITU-T X.509 standard defines a certificat format for PKI. - * - * http://www.ietf.org/rfc/rfc2459.txt - * http://www.ietf.org/rfc/rfc3279.txt - * - * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc - * - * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf - * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf - * - * For CRS: - * http://www.faqs.org/rfcs/rfc2314.html - */ -#include "polarssl/config.h" -#include "polarssl/x509.h" -#include "polarssl/base64.h" -#include "polarssl/sha1.h" - -#include -#include -#include -#include -#include - -#define and && -#define or || - -#if defined _MSC_VER && !defined snprintf -#define snprintf _snprintf -#endif - -static int x509write_realloc_node(x509_node *node, size_t larger); -static int x509write_file(x509_node *node, char *path, int format, const char* pem_prolog, const char* pem_epilog); - -/* - * evaluate how mani octet have this integer - */ -static int asn1_eval_octet(unsigned int digit) -{ - int i, byte; - - for (byte = 4, i = 24; i >= 0; i -= 8, --byte) - if (((digit >> i) & 0xFF) != 0) - return byte; - - return 0; -} - -/* - * write the asn.1 lenght form into p - */ -static int asn1_add_len(unsigned int size, x509_node *node) -{ - if (size > 127) { - - /* long size */ - int byte = asn1_eval_octet(size); - int i = 0; - - *(node->p) = (0x80 | byte) & 0xFF; - ++node->p; - - for (i = byte; i > 0; --i) { - - *(node->p) = (size >> ((i - 1) * 8)) & 0xFF; - ++node->p; - } - - } else { - - /* short size */ - *(node->p) = size & 0xFF; - if (size != 0) - ++node->p; - } - - return 0; -} - -/* - * write a ans.1 object into p - */ -static int asn1_add_obj(unsigned char *value, unsigned int size, int tag, - x509_node *node) -{ - int tl = 2; - - if (tag == ASN1_BIT_STRING) - ++tl; - - if (size > 127) - x509write_realloc_node(node, (size_t) size + tl + - asn1_eval_octet(size)); - else - x509write_realloc_node(node, (size_t) size + tl); - - if (node->data == NULL) - return 1; - - /* tag */ - *(node->p) = tag & 0xFF; - ++node->p; - - /* len */ - if (tag == ASN1_BIT_STRING) { - asn1_add_len((unsigned int) size + 1, node); - *(node->p) = 0x00; - ++node->p; - } else { - asn1_add_len((unsigned int) size, node); - } - - /* value */ - if (size > 0) { - - memcpy(node->p, value, (size_t) size); - if ((node->p += size -1) != node->end) - return POLARSSL_ERR_X509_POINT_ERROR; - } else { - /* make nothing -> NULL */ - } - - return 0; -} - -/* - * write a asn.1 conform integer object - */ -static int asn1_add_int(signed int value, x509_node *node) -{ - signed int i = 0, neg = 1; - unsigned int byte, u_val = 0, tmp_val = 0; - - /* if negate? */ - if (value < 0) { - neg = -1; - u_val = ~value; - } else { - u_val = value; - } - - byte = asn1_eval_octet(u_val); - /* 0 isn't NULL */ - if (byte == 0) - byte = 1; - - /* ASN.1 integer is signed! */ - if (byte < 4 and ((u_val >> ((byte -1) * 8)) & 0xFF) == 0x80) - byte += 1; - - if (x509write_realloc_node(node, (size_t) byte + 2) != 0) - return 1; - - /* tag */ - *(node->p) = ASN1_INTEGER; - ++node->p; - - /* len */ - asn1_add_len(byte, node); - - /* value */ - for (i = byte; i > 0; --i) { - - tmp_val = (u_val >> ((i - 1) * 8)) & 0xFF; - if (neg == 1) - *(node->p) = tmp_val; - else - *(node->p) = ~tmp_val; - - if (i > 1) - ++node->p; - } - - if (node->p != node->end) - return POLARSSL_ERR_X509_POINT_ERROR; - - return 0; -} - -/* - * write a asn.1 conform mpi object - */ -static int asn1_add_mpi(mpi *value, int tag, x509_node *node) -{ - size_t size = (mpi_msb(value) / 8) + 1; - unsigned char *buf; - int buf_len = (int) size, tl = 2; - - if (tag == ASN1_BIT_STRING) - ++tl; - - if (size > 127) - x509write_realloc_node(node, size + (size_t) tl + - asn1_eval_octet((unsigned int)size)); - else - x509write_realloc_node(node, size + (size_t) tl); - - if (node->data == NULL) - return 1; - - buf = (unsigned char*) malloc(size); - if (mpi_write_binary(value, buf, buf_len) != 0) - return POLARSSL_ERR_MPI_BUFFER_TOO_SMALL; - - /* tag */ - *(node->p) = tag & 0xFF; - ++node->p; - - /* len */ - if (tag == ASN1_BIT_STRING) { - asn1_add_len((unsigned int) size + 1, node); - *(node->p) = 0x00; - ++node->p; - } else { - asn1_add_len((unsigned int) size, node); - } - - /* value */ - memcpy(node->p, buf, size); - free(buf); - - if ((node->p += (int) size -1) != node->end) - return POLARSSL_ERR_X509_POINT_ERROR; - - return 0; -} - -/* - * write a node into asn.1 conform object - */ -static int asn1_append_tag(x509_node *node, int tag) -{ - int tl = 2; - - x509_node tmp; - x509write_init_node(&tmp); - - if (tag == ASN1_BIT_STRING) - ++tl; - - if (node->len > 127) - x509write_realloc_node(&tmp, node->len + (size_t) tl + - asn1_eval_octet((unsigned int)node->len)); - else - x509write_realloc_node(&tmp, node->len + (size_t) tl); - - if (tmp.data == NULL) { - x509write_free_node(&tmp); - return 1; - } - - /* tag */ - *(tmp.p) = tag & 0xFF; - ++tmp.p; - - /* len */ - if (tag == ASN1_BIT_STRING) { - asn1_add_len((unsigned int) node->len + 1, &tmp); - *(tmp.p) = 0x00; - ++tmp.p; - } else { - asn1_add_len((unsigned int) node->len, &tmp); - } - - /* value */ - memcpy(tmp.p, node->data, node->len); - - /* good? */ - if ((tmp.p += (int) node->len -1) != tmp.end) { - x509write_free_node(&tmp); - return POLARSSL_ERR_X509_POINT_ERROR; - } - - free(node->data); - node->data = tmp.data; - node->p = tmp.p; - node->end = tmp.end; - node->len = tmp.len; - - return 0; -} - -/* - * write nodes into a asn.1 object - */ -static int asn1_append_nodes(x509_node *node, int tag, int anz, ...) -{ - va_list ap; - size_t size = 0; - x509_node *tmp; - int count; - - va_start(ap, anz); - count = anz; - - while (count--) { - - tmp = va_arg(ap, x509_node*); - if (tmp->data != NULL) - size += tmp->len; - } - - if ( size > 127) { - if (x509write_realloc_node(node, size + (size_t) 2 + - asn1_eval_octet(size)) != 0) - return 1; - } else { - if (x509write_realloc_node(node, size + (size_t) 2) != 0) - return 1; - } - - /* tag */ - *(node->p) = tag & 0xFF; - ++node->p; - - /* len */ - asn1_add_len(size, node); - - /* value */ - va_start(ap, anz); - count = anz; - - while (count--) { - - tmp = va_arg(ap, x509_node*); - if (tmp->data != NULL) { - - memcpy(node->p, tmp->data, tmp->len); - if ((node->p += (int) tmp->len -1) != node->end) - ++node->p; - } - } - - va_end(ap); - return 0; -} - -/* - * write a ASN.1 conform object identifiere include a "tag" - */ -static int asn1_add_oid(x509_node *node, unsigned char *oid, size_t len, - int tag, int tag_val, unsigned char *value, size_t val_len) -{ - int ret; - x509_node tmp; - - x509write_init_node(&tmp); - - /* OBJECT IDENTIFIER */ - if ((ret = asn1_add_obj(oid, len, ASN1_OID, &tmp)) != 0) { - x509write_free_node(&tmp); - return ret; - } - - /* value */ - if ((ret = asn1_add_obj(value, val_len, tag_val, &tmp)) != 0) { - x509write_free_node(&tmp); - return ret; - } - - /* SET/SEQUENCE */ - if ((ret = asn1_append_nodes(node, tag, 1, &tmp)) != 0) { - x509write_free_node(&tmp); - return ret; - } - - x509write_free_node(&tmp); - return 0; -} - -/* - * utcTime UTCTime - */ -static int asn1_add_date_utc(unsigned char *time, x509_node *node) -{ - unsigned char date[13], *sp; - x509_time xtime; - int ret; - - sscanf((char*)time, "%d-%d-%d %d:%d:%d", &xtime.year, &xtime.mon, - &xtime.day, &xtime.hour, &xtime.min, &xtime.sec); - - /* convert to YY */ - if (xtime.year > 2000) - xtime.year -= 2000; - else - xtime.year -= 1900; - - snprintf((char*)date, 13, "%2d%2d%2d%2d%2d%2d", xtime.year, xtime.mon, xtime.day, - xtime.hour, xtime.min, xtime.sec); - - /* replace ' ' to '0' */ - for (sp = date; *sp != '\0'; ++sp) - if (*sp == '\x20') - *sp = '\x30'; - - date[12] = 'Z'; - - if ((ret = asn1_add_obj(date, 13, ASN1_UTC_TIME, node)) != 0) - return ret; - - return 0; -} - -/* - * serialize an rsa key into DER - */ - -int x509write_serialize_key(rsa_context *rsa, x509_node *node) -{ - int ret = 0; - x509write_init_node(node); - - /* vers, n, e, d, p, q, dp, dq, pq */ - if ((ret = asn1_add_int(rsa->ver, node)) != 0) - return ret; - if ((ret = asn1_add_mpi(&rsa->N, ASN1_INTEGER, node)) != 0) - return ret; - if ((ret = asn1_add_mpi(&rsa->E, ASN1_INTEGER, node)) != 0) - return ret; - if ((ret = asn1_add_mpi(&rsa->D, ASN1_INTEGER, node)) != 0) - return ret; - if ((ret = asn1_add_mpi(&rsa->P, ASN1_INTEGER, node)) != 0) - return ret; - if ((ret = asn1_add_mpi(&rsa->Q, ASN1_INTEGER, node)) != 0) - return ret; - if ((ret = asn1_add_mpi(&rsa->DP, ASN1_INTEGER, node)) != 0) - return ret; - if ((ret = asn1_add_mpi(&rsa->DQ, ASN1_INTEGER, node)) != 0) - return ret; - if ((ret = asn1_add_mpi(&rsa->QP, ASN1_INTEGER, node)) != 0) - return ret; - if ((ret = asn1_append_tag(node, ASN1_CONSTRUCTED | ASN1_SEQUENCE)) != 0) - return ret; - - return 0; -} - -/* - * write a der/pem encoded rsa private key into a file - */ -int x509write_keyfile(rsa_context *rsa, char *path, int out_flag) -{ - int ret = 0; - const char key_beg[] = "-----BEGIN RSA PRIVATE KEY-----\n", - key_end[] = "-----END RSA PRIVATE KEY-----\n"; - x509_node node; - - x509write_init_node(&node); - if ((ret = x509write_serialize_key(rsa,&node)) != 0) { - x509write_free_node(&node); - return ret; - } - - ret = x509write_file(&node,path,out_flag,key_beg,key_end); - x509write_free_node(&node); - - return ret; -} - - -/* - * reasize the memory for node - */ -static int x509write_realloc_node(x509_node *node, size_t larger) -{ - /* init len */ - if (node->data == NULL) { - node->len = 0; - node->data = malloc(larger); - if(node->data == NULL) - return 1; - } else { - /* realloc memory */ - if ((node->data = realloc(node->data, node->len + larger)) == NULL) - return 1; - } - - /* init pointer */ - node->p = &node->data[node->len]; - node->len += larger; - node->end = &node->data[node->len -1]; - - return 0; -} - -/* - * init node - */ -void x509write_init_node(x509_node *node) -{ - memset(node, 0, sizeof(x509_node)); -} - -/* - * clean memory - */ -void x509write_free_node(x509_node *node) -{ - if (node->data != NULL) - free(node->data); - node->p = NULL; - node->end = NULL; - node->len = 0; -} - -/* - * write a x509 certificate into file - */ -int x509write_crtfile(x509_raw *chain, unsigned char *path, int out_flag) -{ - const char cer_beg[] = "-----BEGIN CERTIFICATE-----\n", - cer_end[] = "-----END CERTIFICATE-----\n"; - - return x509write_file(&chain->raw, (char*)path, out_flag, cer_beg, cer_end); -} - -/* - * write a x509 certificate into file - */ -int x509write_csrfile(x509_raw *chain, unsigned char *path, int out_flag) -{ - const char cer_beg[] = "-----BEGIN CERTIFICATE REQUEST-----\n", - cer_end[] = "-----END CERTIFICATE REQUEST-----\n"; - - return x509write_file(&chain->raw, (char*)path, out_flag, cer_beg, cer_end); -} - -/* - * write an x509 file - */ -static int x509write_file(x509_node *node, char *path, int format, - const char* pem_prolog, const char* pem_epilog) -{ - FILE *ofstream = stdout; - int is_err = 1, buf_len, i, n; - unsigned char* base_buf; - - if (path) { - if ((ofstream = fopen(path, "wb")) == NULL) - return 1; - } - - switch (format) { - case X509_OUTPUT_DER: - if (fwrite(node->data, 1, node->len, ofstream) - != node->len) - is_err = -1; - break; - - case X509_OUTPUT_PEM: - if (fprintf(ofstream,pem_prolog)<0) { - is_err = -1; - break; - } - - buf_len = node->len << 1; - base_buf = (unsigned char*) malloc((size_t)buf_len); - memset(base_buf,0,buf_len); - if (base64_encode(base_buf, &buf_len, node->data, - (int) node->len) != 0) { - is_err = -1; - break; - } - - n=strlen((char*)base_buf); - for(i=0;isubpubkey; - - x509write_init_node(&n_tmp); - x509write_init_node(&n_tmp2); - - /* - * RSAPublicKey ::= SEQUENCE { - * modulus INTEGER, -- n - * publicExponent INTEGER -- e - * } - */ - if ((ret = asn1_add_mpi(&pubkey->N, ASN1_INTEGER, &n_tmp)) != 0) { - x509write_free_node(&n_tmp); - x509write_free_node(&n_tmp2); - return ret; - } - if ((ret = asn1_add_mpi(&pubkey->E, ASN1_INTEGER, &n_tmp)) != 0) { - x509write_free_node(&n_tmp); - x509write_free_node(&n_tmp2); - return ret; - } - if ((ret = asn1_append_tag(&n_tmp, ASN1_CONSTRUCTED | ASN1_SEQUENCE)) - != 0) { - x509write_free_node(&n_tmp); - x509write_free_node(&n_tmp2); - return ret; - } - - /* - * SubjectPublicKeyInfo ::= SEQUENCE { - * algorithm AlgorithmIdentifier, - * subjectPublicKey BIT STRING } - */ - if ((ret = asn1_append_tag(&n_tmp, ASN1_BIT_STRING)) != 0) { - x509write_free_node(&n_tmp); - x509write_free_node(&n_tmp2); - return ret; - } - if ((ret = asn1_add_oid(&n_tmp2, (unsigned char*)OID_PKCS1_RSA, 9, - ASN1_CONSTRUCTED | ASN1_SEQUENCE, ASN1_NULL, - (unsigned char *)"", 0)) != 0) { - x509write_free_node(&n_tmp); - x509write_free_node(&n_tmp2); - return ret; - } - - if ((ret = asn1_append_nodes(node, ASN1_CONSTRUCTED | ASN1_SEQUENCE, 2, - &n_tmp2, &n_tmp))) { - x509write_free_node(&n_tmp); - x509write_free_node(&n_tmp2); - return ret; - } - - x509write_free_node(&n_tmp); - x509write_free_node(&n_tmp2); - return 0; -} - -/* - * RelativeDistinguishedName ::= - * SET OF AttributeTypeAndValue - * - * AttributeTypeAndValue ::= SEQUENCE { - * type AttributeType, - * value AttributeValue } - */ -static int x509write_add_name(x509_node *node, unsigned char *oid, - unsigned int oid_len, unsigned char *value, int len, int value_tag) -{ - int ret; - x509_node n_tmp; - - x509write_init_node(&n_tmp); - - if ((ret = asn1_add_oid(&n_tmp, oid, oid_len, - ASN1_CONSTRUCTED | ASN1_SEQUENCE, value_tag, - value, len))) { - x509write_free_node(&n_tmp); - return ret; - } - - if ((asn1_append_nodes(node, ASN1_CONSTRUCTED | ASN1_SET, 1, &n_tmp)) - != 0) { - x509write_free_node(&n_tmp); - return ret; - } - - x509write_free_node(&n_tmp); - return 0; -} - -/* - * Parse the name string and add to node - */ -static int x509write_parse_names(x509_node *node, unsigned char *names) -{ - unsigned char *sp, *begin = NULL; - unsigned char oid[3] = OID_X520, tag[4], *tag_sp = tag; - unsigned char *C = NULL, *CN = NULL, *O = NULL, *OU = NULL, - *ST = NULL, *L = NULL, *R = NULL; - int C_len = 0, CN_len = 0, O_len = 0, OU_len = 0, ST_len = 0, - L_len = 0, R_len = 0; - int ret = 0, is_tag = 1, is_begin = -1, len = 0; - - - for (sp = names; ; ++sp) { - - /* filter tag */ - if (is_tag == 1) { - - if (tag_sp == &tag[3]) - return POLARSSL_ERR_X509_VALUE_TO_LENGTH; - - /* is tag end? */ - if (*sp == '=') { - is_tag = -1; - *tag_sp = '\0'; - is_begin = 1; - /* set len 0 (reset) */ - len = 0; - } else { - /* tag hasn't ' '! */ - if (*sp != ' ') { - *tag_sp = *sp; - ++tag_sp; - } - } - /* filter value */ - } else { - - /* set pointer of value begin */ - if (is_begin == 1) { - begin = sp; - is_begin = -1; - } - - /* is value at end? */ - if (*sp == ';' or *sp == '\0') { - is_tag = 1; - - /* common name */ - if (tag[0] == 'C' and tag[1] == 'N') { - CN = begin; - CN_len = len; - - /* organization */ - } else if (tag[0] == 'O' and tag[1] == '\0') { - O = begin; - O_len = len; - - /* country */ - } else if (tag[0] == 'C' and tag[1] == '\0') { - C = begin; - C_len = len; - - /* organisation unit */ - } else if (tag[0] == 'O' and tag[1] == 'U') { - OU = begin; - OU_len = len; - - /* state */ - } else if (tag[0] == 'S' and tag[1] == 'T') { - ST = begin; - ST_len = len; - - /* locality */ - } else if (tag[0] == 'L' and tag[1] == '\0') { - L = begin; - L_len = len; - - /* email */ - } else if (tag[0] == 'R' and tag[1] == '\0') { - R = begin; - R_len = len; - } - - /* set tag poiner to begin */ - tag_sp = tag; - - /* is at end? */ - if (*sp == '\0' or *(sp +1) == '\0') - break; - } else { - ++len; - } - } - - /* make saver */ - if (*sp == '\0') - break; - } /* end for */ - - /* country */ - if (C != NULL) { - oid[2] = X520_COUNTRY; - if ((ret = x509write_add_name(node, oid, 3, C, C_len, - ASN1_PRINTABLE_STRING)) != 0) - return ret; - } - - /* state */ - if (ST != NULL) { - oid[2] = X520_STATE; - if ((ret = x509write_add_name(node, oid, 3, ST, ST_len, - ASN1_PRINTABLE_STRING)) != 0) - return ret; - } - - /* locality */ - if (L != NULL) { - oid[2] = X520_LOCALITY; - if ((ret = x509write_add_name(node, oid, 3, L, L_len, - ASN1_PRINTABLE_STRING)) != 0) - return ret; - } - - /* organization */ - if (O != NULL) { - oid[2] = X520_ORGANIZATION; - if ((ret = x509write_add_name(node, oid, 3, O, O_len, - ASN1_PRINTABLE_STRING)) != 0) - return ret; - } - - /* organisation unit */ - if (OU != NULL) { - oid[2] = X520_ORG_UNIT; - if ((ret = x509write_add_name(node, oid, 3, OU, OU_len, - ASN1_PRINTABLE_STRING)) != 0) - return ret; - } - - /* common name */ - if (CN != NULL) { - oid[2] = X520_COMMON_NAME; - if ((ret = x509write_add_name(node, oid, 3, CN, CN_len, - ASN1_PRINTABLE_STRING)) != 0) - return ret; - } - - /* email */ - if (R != NULL) { - if ((ret = x509write_add_name(node, (unsigned char*)OID_PKCS9_EMAIL, - 9, R, R_len, ASN1_IA5_STRING)) != 0) - return ret; - } - - if ((asn1_append_tag(node, ASN1_CONSTRUCTED | ASN1_SEQUENCE)) != 0) - return ret; - - return 0; -} - -/* - * Copy raw data from orginal ca to node - */ -static int x509write_copy_from_raw(x509_node *node, x509_buf *raw) -{ - if (x509write_realloc_node(node, raw->len) != 0) - return 1; - - memcpy(node->p, raw->p, (size_t)raw->len); - if ((node->p += raw->len -1) != node->end) - return POLARSSL_ERR_X509_POINT_ERROR; - - return 0; -} - -/* - * Add the issuer - */ - -int x509write_add_issuer(x509_raw *crt, unsigned char *issuer) -{ - return x509write_parse_names(&crt->issuer, issuer); -} - -/* - * Add the subject - */ -int x509write_add_subject(x509_raw *crt, unsigned char *subject) -{ - return x509write_parse_names(&crt->subject, subject); -} - -/* - * Copy issuer line from another cert to issuer - */ -int x509write_copy_issuer(x509_raw *crt, x509_cert *from_crt) -{ - return x509write_copy_from_raw(&crt->issuer, &from_crt->issuer_raw); -} - -/* - * Copy subject line from another cert - */ -int x509write_copy_subject(x509_raw *crt, x509_cert *from_crt) -{ - return x509write_copy_from_raw(&crt->subject, &from_crt->subject_raw); -} - -/* - * Copy subject line form antoher cert into issuer - */ -int x509write_copy_issuer_form_subject(x509_raw *crt, - x509_cert *from_crt) -{ - return x509write_copy_from_raw(&crt->issuer, &from_crt->subject_raw); -} - -/* - * Copy issuer line from another cert into subject - */ -int x509write_copy_subject_from_issuer(x509_raw *crt, - x509_cert * from_crt) -{ - return x509write_copy_from_raw(&crt->subject, &from_crt->issuer_raw); -} - -/* - * Validity ::= SEQUENCE { - * notBefore Time, - * notAfter Time } - * - * Time ::= CHOICE { - * utcTime UTCTime, - * generalTime GeneralizedTime } - */ -/* TODO: No handle GeneralizedTime! */ -int x509write_add_validity(x509_raw *chain, unsigned char *befor, - unsigned char *after) -{ - int ret; - - x509_node *node = &chain->validity; - - /* notBefore */ - if ((ret = asn1_add_date_utc(befor, node)) != 0) - return ret; - - /* notAfter */ - if ((ret = asn1_add_date_utc(after, node)) != 0) - return ret; - - if ((ret = asn1_append_tag(node, ASN1_CONSTRUCTED | ASN1_SEQUENCE)) != 0) - return ret; - - return 0; -} - -/* - * make hash from tbs and sign that with private key - */ -static int x509write_make_sign(x509_raw *chain, rsa_context *privkey) -{ - int ret; - unsigned char hash[20], *sign; - size_t sign_len = (size_t) mpi_size(&privkey->N); - - /* make hash */ - sha1(chain->tbs.data, chain->tbs.len, hash); - - /* create sign */ - sign = (unsigned char *) malloc(sign_len); - if (sign == NULL) - return 1; - - if ((ret = rsa_pkcs1_sign(privkey, RSA_PRIVATE, RSA_SHA1, 20, hash, - sign)) != 0) - return ret; - - if ((ret = asn1_add_obj(sign, sign_len, ASN1_BIT_STRING, - &chain->sign)) != 0) - return ret; - - /* - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL } - */ - return asn1_add_oid(&chain->signalg, (unsigned char*)OID_PKCS1_RSA_SHA, 9, - ASN1_CONSTRUCTED | ASN1_SEQUENCE, ASN1_NULL, - (unsigned char*)"", 0); -} - -/* - * Create a self signed certificate - */ -int x509write_create_sign(x509_raw *chain, rsa_context *privkey) -{ - int ret, serial; - - /* - * Version ::= INTEGER { v1(0), v2(1), v3(2) } - */ - if ((ret = asn1_add_int(2, &chain->version)) != 0) - return ret; - - if ((ret = asn1_append_tag(&chain->version, ASN1_CONTEXT_SPECIFIC | - ASN1_CONSTRUCTED)) != 0) - return ret; - - - /* - * CertificateSerialNumber ::= INTEGER - */ - srand((unsigned int) time(NULL)); - serial = rand(); - if ((ret = asn1_add_int(serial, &chain->serial)) != 0) - return ret; - - /* - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL } - */ - if ((ret = asn1_add_oid(&chain->tbs_signalg, - (unsigned char*)OID_PKCS1_RSA_SHA, 9, ASN1_CONSTRUCTED | - ASN1_SEQUENCE, ASN1_NULL, (unsigned char*)"", 0)) != 0) - return ret; - - /* - * Create the tbs - */ - if ((ret = asn1_append_nodes(&chain->tbs, ASN1_CONSTRUCTED | - ASN1_SEQUENCE, 7, &chain->version, &chain->serial, - &chain->tbs_signalg, &chain->issuer, &chain->validity, - &chain->subject, &chain->subpubkey)) != 0) - return ret; - - /* make signing */ - if ((ret = x509write_make_sign(chain, privkey)) != 0) - return ret; - - /* finishing */ - if ((ret = asn1_append_nodes(&chain->raw, ASN1_CONSTRUCTED | - ASN1_SEQUENCE, 3, &chain->tbs, &chain->signalg, - &chain->sign)) != 0) - return ret; - - return 0; -} - -int x509write_create_selfsign(x509_raw *chain, rsa_context *privkey) -{ - /* - * On self signed certificate are subject and issuer the same - */ - x509write_free_node(&chain->issuer); - chain->issuer = chain->subject; - return x509write_create_sign(chain, privkey); -} - -/* - * CertificationRequestInfo ::= SEQUENCE { - * version Version, - * subject Name, - * subjectPublicKeyInfo SubjectPublicKeyInfo, - * attributes [0] IMPLICIT Attributes } - * - * CertificationRequest ::= SEQUENCE { - * certificationRequestInfo CertificationRequestInfo, - * signatureAlgorithm SignatureAlgorithmIdentifier, - * signature Signature } - * - * It use chain.serail for attributes! - * - */ -int x509write_create_csr(x509_raw *chain, rsa_context *privkey) -{ - int ret; - - /* version ::= INTEGER */ - if ((ret = asn1_add_int(0, &chain->version)) != 0) - return ret; - - /* write attributes */ - if ((ret = asn1_add_obj((unsigned char*)"", 0, ASN1_CONTEXT_SPECIFIC | - ASN1_CONSTRUCTED, &chain->serial)) != 0) - return ret; - - /* create CertificationRequestInfo */ - if ((ret = asn1_append_nodes(&chain->tbs, ASN1_CONSTRUCTED | - ASN1_SEQUENCE, 4, &chain->version, &chain->subject, - &chain->subpubkey, &chain->serial)) != 0) - return ret; - - /* make signing */ - if ((ret = x509write_make_sign(chain, privkey)) != 0) - return ret; - - /* finish */ - if ((ret = asn1_append_nodes(&chain->raw, ASN1_CONSTRUCTED | ASN1_SEQUENCE, - 3, &chain->tbs, &chain->signalg, &chain->sign)) != 0) - return ret; - - return ret; -} - -/* - * Free memory - */ -void x509write_free_raw(x509_raw *chain) -{ - x509write_free_node(&chain->raw); - x509write_free_node(&chain->tbs); - x509write_free_node(&chain->version); - x509write_free_node(&chain->serial); - x509write_free_node(&chain->tbs_signalg); - x509write_free_node(&chain->issuer); - x509write_free_node(&chain->validity); - if (chain->subject.data != chain->issuer.data) - x509write_free_node(&chain->subject); - x509write_free_node(&chain->subpubkey); - x509write_free_node(&chain->signalg); - x509write_free_node(&chain->sign); -} - -void x509write_init_raw(x509_raw *chain) -{ - memset((void *) chain, 0, sizeof(x509_raw)); -} - diff --git a/package/utils/px5g/src/polarssl/base64.h b/package/utils/px5g/src/polarssl/base64.h deleted file mode 100644 index c48267b1b5..0000000000 --- a/package/utils/px5g/src/polarssl/base64.h +++ /dev/null @@ -1,93 +0,0 @@ -/** - * \file base64.h - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * 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 */ diff --git a/package/utils/px5g/src/polarssl/bignum.h b/package/utils/px5g/src/polarssl/bignum.h deleted file mode 100644 index c667303329..0000000000 --- a/package/utils/px5g/src/polarssl/bignum.h +++ /dev/null @@ -1,437 +0,0 @@ -/** - * \file bignum.h - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * 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 - -#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 */ diff --git a/package/utils/px5g/src/polarssl/bn_mul.h b/package/utils/px5g/src/polarssl/bn_mul.h deleted file mode 100644 index f6d34da58a..0000000000 --- a/package/utils/px5g/src/polarssl/bn_mul.h +++ /dev/null @@ -1,731 +0,0 @@ -/** - * \file bn_mul.h - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * 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 */ diff --git a/package/utils/px5g/src/polarssl/config.h b/package/utils/px5g/src/polarssl/config.h deleted file mode 100644 index ad3f9a7f39..0000000000 --- a/package/utils/px5g/src/polarssl/config.h +++ /dev/null @@ -1,329 +0,0 @@ -/** - * \file config.h - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * 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 */ diff --git a/package/utils/px5g/src/polarssl/havege.h b/package/utils/px5g/src/polarssl/havege.h deleted file mode 100644 index c27cecac0f..0000000000 --- a/package/utils/px5g/src/polarssl/havege.h +++ /dev/null @@ -1,75 +0,0 @@ -/** - * \file havege.h - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * 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 */ diff --git a/package/utils/px5g/src/polarssl/rsa.h b/package/utils/px5g/src/polarssl/rsa.h deleted file mode 100644 index b31dc2f144..0000000000 --- a/package/utils/px5g/src/polarssl/rsa.h +++ /dev/null @@ -1,309 +0,0 @@ -/** - * \file rsa.h - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * 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 */ diff --git a/package/utils/px5g/src/polarssl/sha1.h b/package/utils/px5g/src/polarssl/sha1.h deleted file mode 100644 index 3ca7dc3195..0000000000 --- a/package/utils/px5g/src/polarssl/sha1.h +++ /dev/null @@ -1,150 +0,0 @@ -/** - * \file sha1.h - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * 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 */ diff --git a/package/utils/px5g/src/polarssl/timing.h b/package/utils/px5g/src/polarssl/timing.h deleted file mode 100644 index 62d627f61b..0000000000 --- a/package/utils/px5g/src/polarssl/timing.h +++ /dev/null @@ -1,81 +0,0 @@ -/** - * \file timing.h - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * 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 */ diff --git a/package/utils/px5g/src/polarssl/x509.h b/package/utils/px5g/src/polarssl/x509.h deleted file mode 100644 index 908a1dbf51..0000000000 --- a/package/utils/px5g/src/polarssl/x509.h +++ /dev/null @@ -1,549 +0,0 @@ -/** - * \file x509.h - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * 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 */ diff --git a/package/utils/px5g/src/px5g.c b/package/utils/px5g/src/px5g.c deleted file mode 100644 index cf50ad28e2..0000000000 --- a/package/utils/px5g/src/px5g.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * px5g - Embedded x509 key and certificate generator based on PolarSSL - * - * Copyright (C) 2009 Steven Barth - * - * 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 -#include -#include -#include -#include -#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 " -#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; - if (to < from) - to = INT_MAX; - 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; -}