+++ /dev/null
-#
-# Copyright (C) 2010-2014 Jo-Philipp Wich <xm@subsignal.org>
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=px5g-standalone
-PKG_RELEASE:=2
-
-PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
-
-include $(INCLUDE_DIR)/package.mk
-
-define Package/px5g-standalone
- SECTION:=utils
- CATEGORY:=Utilities
- SUBMENU:=Encryption
- TITLE:=X.509 certificate generator (standalone version)
- MAINTAINER:=Jo-Philipp Wich <xm@subsignal.org>
-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 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))
+++ /dev/null
-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)
+++ /dev/null
-/*
- * RFC 1521 base64 encoding/decoding
- *
- * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
- *
- * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the names of PolarSSL or XySSL nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "polarssl/config.h"
-
-#if defined(POLARSSL_BASE64_C)
-
-#include "polarssl/base64.h"
-
-static const unsigned char base64_enc_map[64] =
-{
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
- 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
- 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
- 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
- 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
- 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', '+', '/'
-};
-
-static const unsigned char base64_dec_map[128] =
-{
- 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
- 54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
- 127, 64, 127, 127, 127, 0, 1, 2, 3, 4,
- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 127, 127, 127, 127, 127, 127, 26, 27, 28,
- 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
- 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
- 49, 50, 51, 127, 127, 127, 127, 127
-};
-
-/*
- * Encode a buffer into base64 format
- */
-int base64_encode( unsigned char *dst, int *dlen,
- unsigned char *src, int slen )
-{
- int i, n;
- int C1, C2, C3;
- unsigned char *p;
-
- if( slen == 0 )
- return( 0 );
-
- n = (slen << 3) / 6;
-
- switch( (slen << 3) - (n * 6) )
- {
- case 2: n += 3; break;
- case 4: n += 2; break;
- default: break;
- }
-
- if( *dlen < n + 1 )
- {
- *dlen = n + 1;
- return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
- }
-
- n = (slen / 3) * 3;
-
- for( i = 0, p = dst; i < n; i += 3 )
- {
- C1 = *src++;
- C2 = *src++;
- C3 = *src++;
-
- *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
- *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
- *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
- *p++ = base64_enc_map[C3 & 0x3F];
- }
-
- if( i < slen )
- {
- C1 = *src++;
- C2 = ((i + 1) < slen) ? *src++ : 0;
-
- *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
- *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
-
- if( (i + 1) < slen )
- *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
- else *p++ = '=';
-
- *p++ = '=';
- }
-
- *dlen = p - dst;
- *p = 0;
-
- return( 0 );
-}
-
-/*
- * Decode a base64-formatted buffer
- */
-int base64_decode( unsigned char *dst, int *dlen,
- unsigned char *src, int slen )
-{
- int i, j, n;
- unsigned long x;
- unsigned char *p;
-
- for( i = j = n = 0; i < slen; i++ )
- {
- if( ( slen - i ) >= 2 &&
- src[i] == '\r' && src[i + 1] == '\n' )
- continue;
-
- if( src[i] == '\n' )
- continue;
-
- if( src[i] == '=' && ++j > 2 )
- return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
-
- if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
- return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
-
- if( base64_dec_map[src[i]] < 64 && j != 0 )
- return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
-
- n++;
- }
-
- if( n == 0 )
- return( 0 );
-
- n = ((n * 6) + 7) >> 3;
-
- if( *dlen < n )
- {
- *dlen = n;
- return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
- }
-
- for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
- {
- if( *src == '\r' || *src == '\n' )
- continue;
-
- j -= ( base64_dec_map[*src] == 64 );
- x = (x << 6) | ( base64_dec_map[*src] & 0x3F );
-
- if( ++n == 4 )
- {
- n = 0;
- if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
- if( j > 1 ) *p++ = (unsigned char)( x >> 8 );
- if( j > 2 ) *p++ = (unsigned char)( x );
- }
- }
-
- *dlen = p - dst;
-
- return( 0 );
-}
-
-#if defined(POLARSSL_SELF_TEST)
-
-#include <string.h>
-#include <stdio.h>
-
-static const unsigned char base64_test_dec[64] =
-{
- 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
- 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
- 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
- 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
- 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
- 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
- 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
- 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
-};
-
-static const unsigned char base64_test_enc[] =
- "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
- "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
-
-/*
- * Checkup routine
- */
-int base64_self_test( int verbose )
-{
- int len;
- unsigned char *src, buffer[128];
-
- if( verbose != 0 )
- printf( " Base64 encoding test: " );
-
- len = sizeof( buffer );
- src = (unsigned char *) base64_test_dec;
-
- if( base64_encode( buffer, &len, src, 64 ) != 0 ||
- memcmp( base64_test_enc, buffer, 88 ) != 0 )
- {
- if( verbose != 0 )
- printf( "failed\n" );
-
- return( 1 );
- }
-
- if( verbose != 0 )
- printf( "passed\n Base64 decoding test: " );
-
- len = sizeof( buffer );
- src = (unsigned char *) base64_test_enc;
-
- if( base64_decode( buffer, &len, src, 88 ) != 0 ||
- memcmp( base64_test_dec, buffer, 64 ) != 0 )
- {
- if( verbose != 0 )
- printf( "failed\n" );
-
- return( 1 );
- }
-
- if( verbose != 0 )
- printf( "passed\n\n" );
-
- return( 0 );
-}
-
-#endif
-
-#endif
+++ /dev/null
-/*
- * Multi-precision integer library
- *
- * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
- *
- * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the names of PolarSSL or XySSL nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/*
- * This 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 <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-
-#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
+++ /dev/null
-/*
- * The RSA public-key cryptosystem
- *
- * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
- *
- * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the names of PolarSSL or XySSL nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/*
- * RSA was designed by Ron Rivest, Adi Shamir and Len Adleman.
- *
- * http://theory.lcs.mit.edu/~rivest/rsapaper.pdf
- * http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf
- */
-
-#include "polarssl/config.h"
-
-#if defined(POLARSSL_RSA_C)
-
-#include "polarssl/rsa.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-/*
- * Initialize an RSA context
- */
-void rsa_init( rsa_context *ctx,
- int padding,
- int hash_id,
- int (*f_rng)(void *),
- void *p_rng )
-{
- memset( ctx, 0, sizeof( rsa_context ) );
-
- ctx->padding = padding;
- ctx->hash_id = hash_id;
-
- ctx->f_rng = f_rng;
- ctx->p_rng = p_rng;
-}
-
-#if defined(POLARSSL_GENPRIME)
-
-/*
- * Generate an RSA keypair
- */
-int rsa_gen_key( rsa_context *ctx, int nbits, int exponent )
-{
- int ret;
- mpi P1, Q1, H, G;
-
- if( ctx->f_rng == NULL || nbits < 128 || exponent < 3 )
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
-
- mpi_init( &P1, &Q1, &H, &G, NULL );
-
- /*
- * find primes P and Q with Q < P so that:
- * GCD( E, (P-1)*(Q-1) ) == 1
- */
- MPI_CHK( mpi_lset( &ctx->E, exponent ) );
-
- do
- {
- MPI_CHK( mpi_gen_prime( &ctx->P, ( nbits + 1 ) >> 1, 0,
- ctx->f_rng, ctx->p_rng ) );
-
- MPI_CHK( mpi_gen_prime( &ctx->Q, ( nbits + 1 ) >> 1, 0,
- ctx->f_rng, ctx->p_rng ) );
-
- if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
- mpi_swap( &ctx->P, &ctx->Q );
-
- if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
- continue;
-
- MPI_CHK( mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
- if( mpi_msb( &ctx->N ) != nbits )
- continue;
-
- MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
- MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
- MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
- MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) );
- }
- while( mpi_cmp_int( &G, 1 ) != 0 );
-
- /*
- * D = E^-1 mod ((P-1)*(Q-1))
- * DP = D mod (P - 1)
- * DQ = D mod (Q - 1)
- * QP = Q^-1 mod P
- */
- MPI_CHK( mpi_inv_mod( &ctx->D , &ctx->E, &H ) );
- MPI_CHK( mpi_mod_mpi( &ctx->DP, &ctx->D, &P1 ) );
- MPI_CHK( mpi_mod_mpi( &ctx->DQ, &ctx->D, &Q1 ) );
- MPI_CHK( mpi_inv_mod( &ctx->QP, &ctx->Q, &ctx->P ) );
-
- ctx->len = ( mpi_msb( &ctx->N ) + 7 ) >> 3;
-
-cleanup:
-
- mpi_free( &G, &H, &Q1, &P1, NULL );
-
- if( ret != 0 )
- {
- rsa_free( ctx );
- return( POLARSSL_ERR_RSA_KEY_GEN_FAILED | ret );
- }
-
- return( 0 );
-}
-
-#endif
-
-/*
- * Check a public RSA key
- */
-int rsa_check_pubkey( rsa_context *ctx )
-{
- if( ( ctx->N.p[0] & 1 ) == 0 ||
- ( ctx->E.p[0] & 1 ) == 0 )
- return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
-
- if( mpi_msb( &ctx->N ) < 128 ||
- mpi_msb( &ctx->N ) > 4096 )
- return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
-
- if( mpi_msb( &ctx->E ) < 2 ||
- mpi_msb( &ctx->E ) > 64 )
- return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
-
- return( 0 );
-}
-
-/*
- * Check a private RSA key
- */
-int rsa_check_privkey( rsa_context *ctx )
-{
- int ret;
- mpi PQ, DE, P1, Q1, H, I, G;
-
- if( ( ret = rsa_check_pubkey( ctx ) ) != 0 )
- return( ret );
-
- mpi_init( &PQ, &DE, &P1, &Q1, &H, &I, &G, NULL );
-
- MPI_CHK( mpi_mul_mpi( &PQ, &ctx->P, &ctx->Q ) );
- MPI_CHK( mpi_mul_mpi( &DE, &ctx->D, &ctx->E ) );
- MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
- MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
- MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
- MPI_CHK( mpi_mod_mpi( &I, &DE, &H ) );
- MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) );
-
- if( mpi_cmp_mpi( &PQ, &ctx->N ) == 0 &&
- mpi_cmp_int( &I, 1 ) == 0 &&
- mpi_cmp_int( &G, 1 ) == 0 )
- {
- mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, NULL );
- return( 0 );
- }
-
-cleanup:
-
- mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, NULL );
- return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED | ret );
-}
-
-/*
- * Do an RSA public key operation
- */
-int rsa_public( rsa_context *ctx,
- unsigned char *input,
- unsigned char *output )
-{
- int ret, olen;
- mpi T;
-
- mpi_init( &T, NULL );
-
- MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
-
- if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
- {
- mpi_free( &T, NULL );
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
- }
-
- olen = ctx->len;
- MPI_CHK( mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
- MPI_CHK( mpi_write_binary( &T, output, olen ) );
-
-cleanup:
-
- mpi_free( &T, NULL );
-
- if( ret != 0 )
- return( POLARSSL_ERR_RSA_PUBLIC_FAILED | ret );
-
- return( 0 );
-}
-
-/*
- * Do an RSA private key operation
- */
-int rsa_private( rsa_context *ctx,
- unsigned char *input,
- unsigned char *output )
-{
- int ret, olen;
- mpi T, T1, T2;
-
- mpi_init( &T, &T1, &T2, NULL );
-
- MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
-
- if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
- {
- mpi_free( &T, NULL );
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
- }
-
-#if 0
- MPI_CHK( mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) );
-#else
- /*
- * faster decryption using the CRT
- *
- * T1 = input ^ dP mod P
- * T2 = input ^ dQ mod Q
- */
- MPI_CHK( mpi_exp_mod( &T1, &T, &ctx->DP, &ctx->P, &ctx->RP ) );
- MPI_CHK( mpi_exp_mod( &T2, &T, &ctx->DQ, &ctx->Q, &ctx->RQ ) );
-
- /*
- * T = (T1 - T2) * (Q^-1 mod P) mod P
- */
- MPI_CHK( mpi_sub_mpi( &T, &T1, &T2 ) );
- MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->QP ) );
- MPI_CHK( mpi_mod_mpi( &T, &T1, &ctx->P ) );
-
- /*
- * output = T2 + T * Q
- */
- MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->Q ) );
- MPI_CHK( mpi_add_mpi( &T, &T2, &T1 ) );
-#endif
-
- olen = ctx->len;
- MPI_CHK( mpi_write_binary( &T, output, olen ) );
-
-cleanup:
-
- mpi_free( &T, &T1, &T2, NULL );
-
- if( ret != 0 )
- return( POLARSSL_ERR_RSA_PRIVATE_FAILED | ret );
-
- return( 0 );
-}
-
-/*
- * Add the message padding, then do an RSA operation
- */
-int rsa_pkcs1_encrypt( rsa_context *ctx,
- int mode, int ilen,
- unsigned char *input,
- unsigned char *output )
-{
- int nb_pad, olen;
- unsigned char *p = output;
-
- olen = ctx->len;
-
- switch( ctx->padding )
- {
- case RSA_PKCS_V15:
-
- if( ilen < 0 || olen < ilen + 11 )
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
-
- nb_pad = olen - 3 - ilen;
-
- *p++ = 0;
- *p++ = RSA_CRYPT;
-
- while( nb_pad-- > 0 )
- {
- do {
- *p = (unsigned char) rand();
- } while( *p == 0 );
- p++;
- }
- *p++ = 0;
- memcpy( p, input, ilen );
- break;
-
- default:
-
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
- }
-
- return( ( mode == RSA_PUBLIC )
- ? rsa_public( ctx, output, output )
- : rsa_private( ctx, output, output ) );
-}
-
-/*
- * Do an RSA operation, then remove the message padding
- */
-int rsa_pkcs1_decrypt( rsa_context *ctx,
- int mode, int *olen,
- unsigned char *input,
- unsigned char *output,
- int output_max_len)
-{
- int ret, ilen;
- unsigned char *p;
- unsigned char buf[512];
-
- ilen = ctx->len;
-
- if( ilen < 16 || ilen > (int) sizeof( buf ) )
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
-
- ret = ( mode == RSA_PUBLIC )
- ? rsa_public( ctx, input, buf )
- : rsa_private( ctx, input, buf );
-
- if( ret != 0 )
- return( ret );
-
- p = buf;
-
- switch( ctx->padding )
- {
- case RSA_PKCS_V15:
-
- if( *p++ != 0 || *p++ != RSA_CRYPT )
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
-
- while( *p != 0 )
- {
- if( p >= buf + ilen - 1 )
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
- p++;
- }
- p++;
- break;
-
- default:
-
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
- }
-
- if (ilen - (int)(p - buf) > output_max_len)
- return( POLARSSL_ERR_RSA_OUTPUT_TO_LARGE );
-
- *olen = ilen - (int)(p - buf);
- memcpy( output, p, *olen );
-
- return( 0 );
-}
-
-/*
- * Do an RSA operation to sign the message digest
- */
-int rsa_pkcs1_sign( rsa_context *ctx,
- int mode,
- int hash_id,
- int hashlen,
- unsigned char *hash,
- unsigned char *sig )
-{
- int nb_pad, olen;
- unsigned char *p = sig;
-
- olen = ctx->len;
-
- switch( ctx->padding )
- {
- case RSA_PKCS_V15:
-
- switch( hash_id )
- {
- case RSA_RAW:
- nb_pad = olen - 3 - hashlen;
- break;
-
- case RSA_MD2:
- case RSA_MD4:
- case RSA_MD5:
- nb_pad = olen - 3 - 34;
- break;
-
- case RSA_SHA1:
- nb_pad = olen - 3 - 35;
- break;
-
- default:
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
- }
-
- if( nb_pad < 8 )
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
-
- *p++ = 0;
- *p++ = RSA_SIGN;
- memset( p, 0xFF, nb_pad );
- p += nb_pad;
- *p++ = 0;
- break;
-
- default:
-
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
- }
-
- switch( hash_id )
- {
- case RSA_RAW:
- memcpy( p, hash, hashlen );
- break;
-
- case RSA_MD2:
- memcpy( p, ASN1_HASH_MDX, 18 );
- memcpy( p + 18, hash, 16 );
- p[13] = 2; break;
-
- case RSA_MD4:
- memcpy( p, ASN1_HASH_MDX, 18 );
- memcpy( p + 18, hash, 16 );
- p[13] = 4; break;
-
- case RSA_MD5:
- memcpy( p, ASN1_HASH_MDX, 18 );
- memcpy( p + 18, hash, 16 );
- p[13] = 5; break;
-
- case RSA_SHA1:
- memcpy( p, ASN1_HASH_SHA1, 15 );
- memcpy( p + 15, hash, 20 );
- break;
-
- default:
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
- }
-
- return( ( mode == RSA_PUBLIC )
- ? rsa_public( ctx, sig, sig )
- : rsa_private( ctx, sig, sig ) );
-}
-
-/*
- * Do an RSA operation and check the message digest
- */
-int rsa_pkcs1_verify( rsa_context *ctx,
- int mode,
- int hash_id,
- int hashlen,
- unsigned char *hash,
- unsigned char *sig )
-{
- int ret, len, siglen;
- unsigned char *p, c;
- unsigned char buf[512];
-
- siglen = ctx->len;
-
- if( siglen < 16 || siglen > (int) sizeof( buf ) )
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
-
- ret = ( mode == RSA_PUBLIC )
- ? rsa_public( ctx, sig, buf )
- : rsa_private( ctx, sig, buf );
-
- if( ret != 0 )
- return( ret );
-
- p = buf;
-
- switch( ctx->padding )
- {
- case RSA_PKCS_V15:
-
- if( *p++ != 0 || *p++ != RSA_SIGN )
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
-
- while( *p != 0 )
- {
- if( p >= buf + siglen - 1 || *p != 0xFF )
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
- p++;
- }
- p++;
- break;
-
- default:
-
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
- }
-
- len = siglen - (int)( p - buf );
-
- if( len == 34 )
- {
- c = p[13];
- p[13] = 0;
-
- if( memcmp( p, ASN1_HASH_MDX, 18 ) != 0 )
- return( POLARSSL_ERR_RSA_VERIFY_FAILED );
-
- if( ( c == 2 && hash_id == RSA_MD2 ) ||
- ( c == 4 && hash_id == RSA_MD4 ) ||
- ( c == 5 && hash_id == RSA_MD5 ) )
- {
- if( memcmp( p + 18, hash, 16 ) == 0 )
- return( 0 );
- else
- return( POLARSSL_ERR_RSA_VERIFY_FAILED );
- }
- }
-
- if( len == 35 && hash_id == RSA_SHA1 )
- {
- if( memcmp( p, ASN1_HASH_SHA1, 15 ) == 0 &&
- memcmp( p + 15, hash, 20 ) == 0 )
- return( 0 );
- else
- return( POLARSSL_ERR_RSA_VERIFY_FAILED );
- }
-
- if( len == hashlen && hash_id == RSA_RAW )
- {
- if( memcmp( p, hash, hashlen ) == 0 )
- return( 0 );
- else
- return( POLARSSL_ERR_RSA_VERIFY_FAILED );
- }
-
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
-}
-
-/*
- * Free the components of an RSA key
- */
-void rsa_free( rsa_context *ctx )
-{
- mpi_free( &ctx->RQ, &ctx->RP, &ctx->RN,
- &ctx->QP, &ctx->DQ, &ctx->DP,
- &ctx->Q, &ctx->P, &ctx->D,
- &ctx->E, &ctx->N, NULL );
-}
-
-#if defined(POLARSSL_SELF_TEST)
-
-#include "polarssl/sha1.h"
-
-/*
- * Example RSA-1024 keypair, for test purposes
- */
-#define KEY_LEN 128
-
-#define RSA_N "9292758453063D803DD603D5E777D788" \
- "8ED1D5BF35786190FA2F23EBC0848AEA" \
- "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
- "7130B9CED7ACDF54CFC7555AC14EEBAB" \
- "93A89813FBF3C4F8066D2D800F7C38A8" \
- "1AE31942917403FF4946B0A83D3D3E05" \
- "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
- "5E94BB77B07507233A0BC7BAC8F90F79"
-
-#define RSA_E "10001"
-
-#define RSA_D "24BF6185468786FDD303083D25E64EFC" \
- "66CA472BC44D253102F8B4A9D3BFA750" \
- "91386C0077937FE33FA3252D28855837" \
- "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
- "DF79C5CE07EE72C7F123142198164234" \
- "CABB724CF78B8173B9F880FC86322407" \
- "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
- "071513A1E85B5DFA031F21ECAE91A34D"
-
-#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
- "2C01CAD19EA484A87EA4377637E75500" \
- "FCB2005C5C7DD6EC4AC023CDA285D796" \
- "C3D9E75E1EFC42488BB4F1D13AC30A57"
-
-#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
- "E211C2B9E5DB1ED0BF61D0D9899620F4" \
- "910E4168387E3C30AA1E00C339A79508" \
- "8452DD96A9A5EA5D9DCA68DA636032AF"
-
-#define RSA_DP "C1ACF567564274FB07A0BBAD5D26E298" \
- "3C94D22288ACD763FD8E5600ED4A702D" \
- "F84198A5F06C2E72236AE490C93F07F8" \
- "3CC559CD27BC2D1CA488811730BB5725"
-
-#define RSA_DQ "4959CBF6F8FEF750AEE6977C155579C7" \
- "D8AAEA56749EA28623272E4F7D0592AF" \
- "7C1F1313CAC9471B5C523BFE592F517B" \
- "407A1BD76C164B93DA2D32A383E58357"
-
-#define RSA_QP "9AE7FBC99546432DF71896FC239EADAE" \
- "F38D18D2B2F0E2DD275AA977E2BF4411" \
- "F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \
- "A74206CEC169D74BF5A8C50D6F48EA08"
-
-#define PT_LEN 24
-#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
- "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
-
-/*
- * Checkup routine
- */
-int rsa_self_test( int verbose )
-{
- int len;
- rsa_context rsa;
- unsigned char sha1sum[20];
- unsigned char rsa_plaintext[PT_LEN];
- unsigned char rsa_decrypted[PT_LEN];
- unsigned char rsa_ciphertext[KEY_LEN];
-
- memset( &rsa, 0, sizeof( rsa_context ) );
-
- rsa.len = KEY_LEN;
- mpi_read_string( &rsa.N , 16, RSA_N );
- mpi_read_string( &rsa.E , 16, RSA_E );
- mpi_read_string( &rsa.D , 16, RSA_D );
- mpi_read_string( &rsa.P , 16, RSA_P );
- mpi_read_string( &rsa.Q , 16, RSA_Q );
- mpi_read_string( &rsa.DP, 16, RSA_DP );
- mpi_read_string( &rsa.DQ, 16, RSA_DQ );
- mpi_read_string( &rsa.QP, 16, RSA_QP );
-
- if( verbose != 0 )
- printf( " RSA key validation: " );
-
- if( rsa_check_pubkey( &rsa ) != 0 ||
- rsa_check_privkey( &rsa ) != 0 )
- {
- if( verbose != 0 )
- printf( "failed\n" );
-
- return( 1 );
- }
-
- if( verbose != 0 )
- printf( "passed\n PKCS#1 encryption : " );
-
- memcpy( rsa_plaintext, RSA_PT, PT_LEN );
-
- if( rsa_pkcs1_encrypt( &rsa, RSA_PUBLIC, PT_LEN,
- rsa_plaintext, rsa_ciphertext ) != 0 )
- {
- if( verbose != 0 )
- printf( "failed\n" );
-
- return( 1 );
- }
-
- if( verbose != 0 )
- printf( "passed\n PKCS#1 decryption : " );
-
- if( rsa_pkcs1_decrypt( &rsa, RSA_PRIVATE, &len,
- rsa_ciphertext, rsa_decrypted,
- sizeof(rsa_decrypted) ) != 0 )
- {
- if( verbose != 0 )
- printf( "failed\n" );
-
- return( 1 );
- }
-
- if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
- {
- if( verbose != 0 )
- printf( "failed\n" );
-
- return( 1 );
- }
-
- if( verbose != 0 )
- printf( "passed\n PKCS#1 data sign : " );
-
- sha1( rsa_plaintext, PT_LEN, sha1sum );
-
- if( rsa_pkcs1_sign( &rsa, RSA_PRIVATE, RSA_SHA1, 20,
- sha1sum, rsa_ciphertext ) != 0 )
- {
- if( verbose != 0 )
- printf( "failed\n" );
-
- return( 1 );
- }
-
- if( verbose != 0 )
- printf( "passed\n PKCS#1 sig. verify: " );
-
- if( rsa_pkcs1_verify( &rsa, RSA_PUBLIC, RSA_SHA1, 20,
- sha1sum, rsa_ciphertext ) != 0 )
- {
- if( verbose != 0 )
- printf( "failed\n" );
-
- return( 1 );
- }
-
- if( verbose != 0 )
- printf( "passed\n\n" );
-
- rsa_free( &rsa );
-
- return( 0 );
-}
-
-#endif
-
-#endif
+++ /dev/null
-/*
- * FIPS-180-1 compliant SHA-1 implementation
- *
- * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
- *
- * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the names of PolarSSL or XySSL nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/*
- * The SHA-1 standard was published by NIST in 1993.
- *
- * http://www.itl.nist.gov/fipspubs/fip180-1.htm
- */
-
-#include "polarssl/config.h"
-
-#if defined(POLARSSL_SHA1_C)
-
-#include "polarssl/sha1.h"
-
-#include <string.h>
-#include <stdio.h>
-
-/*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_ULONG_BE
-#define GET_ULONG_BE(n,b,i) \
-{ \
- (n) = ( (unsigned long) (b)[(i) ] << 24 ) \
- | ( (unsigned long) (b)[(i) + 1] << 16 ) \
- | ( (unsigned long) (b)[(i) + 2] << 8 ) \
- | ( (unsigned long) (b)[(i) + 3] ); \
-}
-#endif
-
-#ifndef PUT_ULONG_BE
-#define PUT_ULONG_BE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
-}
-#endif
-
-/*
- * SHA-1 context setup
- */
-void sha1_starts( sha1_context *ctx )
-{
- ctx->total[0] = 0;
- ctx->total[1] = 0;
-
- ctx->state[0] = 0x67452301;
- ctx->state[1] = 0xEFCDAB89;
- ctx->state[2] = 0x98BADCFE;
- ctx->state[3] = 0x10325476;
- ctx->state[4] = 0xC3D2E1F0;
-}
-
-static void sha1_process( sha1_context *ctx, unsigned char data[64] )
-{
- unsigned long temp, W[16], A, B, C, D, E;
-
- GET_ULONG_BE( W[ 0], data, 0 );
- GET_ULONG_BE( W[ 1], data, 4 );
- GET_ULONG_BE( W[ 2], data, 8 );
- GET_ULONG_BE( W[ 3], data, 12 );
- GET_ULONG_BE( W[ 4], data, 16 );
- GET_ULONG_BE( W[ 5], data, 20 );
- GET_ULONG_BE( W[ 6], data, 24 );
- GET_ULONG_BE( W[ 7], data, 28 );
- GET_ULONG_BE( W[ 8], data, 32 );
- GET_ULONG_BE( W[ 9], data, 36 );
- GET_ULONG_BE( W[10], data, 40 );
- GET_ULONG_BE( W[11], data, 44 );
- GET_ULONG_BE( W[12], data, 48 );
- GET_ULONG_BE( W[13], data, 52 );
- GET_ULONG_BE( W[14], data, 56 );
- GET_ULONG_BE( W[15], data, 60 );
-
-#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
-
-#define R(t) \
-( \
- temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
- W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \
- ( W[t & 0x0F] = S(temp,1) ) \
-)
-
-#define P(a,b,c,d,e,x) \
-{ \
- e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
-}
-
- A = ctx->state[0];
- B = ctx->state[1];
- C = ctx->state[2];
- D = ctx->state[3];
- E = ctx->state[4];
-
-#define F(x,y,z) (z ^ (x & (y ^ z)))
-#define K 0x5A827999
-
- P( A, B, C, D, E, W[0] );
- P( E, A, B, C, D, W[1] );
- P( D, E, A, B, C, W[2] );
- P( C, D, E, A, B, W[3] );
- P( B, C, D, E, A, W[4] );
- P( A, B, C, D, E, W[5] );
- P( E, A, B, C, D, W[6] );
- P( D, E, A, B, C, W[7] );
- P( C, D, E, A, B, W[8] );
- P( B, C, D, E, A, W[9] );
- P( A, B, C, D, E, W[10] );
- P( E, A, B, C, D, W[11] );
- P( D, E, A, B, C, W[12] );
- P( C, D, E, A, B, W[13] );
- P( B, C, D, E, A, W[14] );
- P( A, B, C, D, E, W[15] );
- P( E, A, B, C, D, R(16) );
- P( D, E, A, B, C, R(17) );
- P( C, D, E, A, B, R(18) );
- P( B, C, D, E, A, R(19) );
-
-#undef K
-#undef F
-
-#define F(x,y,z) (x ^ y ^ z)
-#define K 0x6ED9EBA1
-
- P( A, B, C, D, E, R(20) );
- P( E, A, B, C, D, R(21) );
- P( D, E, A, B, C, R(22) );
- P( C, D, E, A, B, R(23) );
- P( B, C, D, E, A, R(24) );
- P( A, B, C, D, E, R(25) );
- P( E, A, B, C, D, R(26) );
- P( D, E, A, B, C, R(27) );
- P( C, D, E, A, B, R(28) );
- P( B, C, D, E, A, R(29) );
- P( A, B, C, D, E, R(30) );
- P( E, A, B, C, D, R(31) );
- P( D, E, A, B, C, R(32) );
- P( C, D, E, A, B, R(33) );
- P( B, C, D, E, A, R(34) );
- P( A, B, C, D, E, R(35) );
- P( E, A, B, C, D, R(36) );
- P( D, E, A, B, C, R(37) );
- P( C, D, E, A, B, R(38) );
- P( B, C, D, E, A, R(39) );
-
-#undef K
-#undef F
-
-#define F(x,y,z) ((x & y) | (z & (x | y)))
-#define K 0x8F1BBCDC
-
- P( A, B, C, D, E, R(40) );
- P( E, A, B, C, D, R(41) );
- P( D, E, A, B, C, R(42) );
- P( C, D, E, A, B, R(43) );
- P( B, C, D, E, A, R(44) );
- P( A, B, C, D, E, R(45) );
- P( E, A, B, C, D, R(46) );
- P( D, E, A, B, C, R(47) );
- P( C, D, E, A, B, R(48) );
- P( B, C, D, E, A, R(49) );
- P( A, B, C, D, E, R(50) );
- P( E, A, B, C, D, R(51) );
- P( D, E, A, B, C, R(52) );
- P( C, D, E, A, B, R(53) );
- P( B, C, D, E, A, R(54) );
- P( A, B, C, D, E, R(55) );
- P( E, A, B, C, D, R(56) );
- P( D, E, A, B, C, R(57) );
- P( C, D, E, A, B, R(58) );
- P( B, C, D, E, A, R(59) );
-
-#undef K
-#undef F
-
-#define F(x,y,z) (x ^ y ^ z)
-#define K 0xCA62C1D6
-
- P( A, B, C, D, E, R(60) );
- P( E, A, B, C, D, R(61) );
- P( D, E, A, B, C, R(62) );
- P( C, D, E, A, B, R(63) );
- P( B, C, D, E, A, R(64) );
- P( A, B, C, D, E, R(65) );
- P( E, A, B, C, D, R(66) );
- P( D, E, A, B, C, R(67) );
- P( C, D, E, A, B, R(68) );
- P( B, C, D, E, A, R(69) );
- P( A, B, C, D, E, R(70) );
- P( E, A, B, C, D, R(71) );
- P( D, E, A, B, C, R(72) );
- P( C, D, E, A, B, R(73) );
- P( B, C, D, E, A, R(74) );
- P( A, B, C, D, E, R(75) );
- P( E, A, B, C, D, R(76) );
- P( D, E, A, B, C, R(77) );
- P( C, D, E, A, B, R(78) );
- P( B, C, D, E, A, R(79) );
-
-#undef K
-#undef F
-
- ctx->state[0] += A;
- ctx->state[1] += B;
- ctx->state[2] += C;
- ctx->state[3] += D;
- ctx->state[4] += E;
-}
-
-/*
- * SHA-1 process buffer
- */
-void sha1_update( sha1_context *ctx, unsigned char *input, int ilen )
-{
- int fill;
- unsigned long left;
-
- if( ilen <= 0 )
- return;
-
- left = ctx->total[0] & 0x3F;
- fill = 64 - left;
-
- ctx->total[0] += ilen;
- ctx->total[0] &= 0xFFFFFFFF;
-
- if( ctx->total[0] < (unsigned long) ilen )
- ctx->total[1]++;
-
- if( left && ilen >= fill )
- {
- memcpy( (void *) (ctx->buffer + left),
- (void *) input, fill );
- sha1_process( ctx, ctx->buffer );
- input += fill;
- ilen -= fill;
- left = 0;
- }
-
- while( ilen >= 64 )
- {
- sha1_process( ctx, input );
- input += 64;
- ilen -= 64;
- }
-
- if( ilen > 0 )
- {
- memcpy( (void *) (ctx->buffer + left),
- (void *) input, ilen );
- }
-}
-
-static const unsigned char sha1_padding[64] =
-{
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/*
- * SHA-1 final digest
- */
-void sha1_finish( sha1_context *ctx, unsigned char output[20] )
-{
- unsigned long last, padn;
- unsigned long high, low;
- unsigned char msglen[8];
-
- high = ( ctx->total[0] >> 29 )
- | ( ctx->total[1] << 3 );
- low = ( ctx->total[0] << 3 );
-
- PUT_ULONG_BE( high, msglen, 0 );
- PUT_ULONG_BE( low, msglen, 4 );
-
- last = ctx->total[0] & 0x3F;
- padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
-
- sha1_update( ctx, (unsigned char *) sha1_padding, padn );
- sha1_update( ctx, msglen, 8 );
-
- PUT_ULONG_BE( ctx->state[0], output, 0 );
- PUT_ULONG_BE( ctx->state[1], output, 4 );
- PUT_ULONG_BE( ctx->state[2], output, 8 );
- PUT_ULONG_BE( ctx->state[3], output, 12 );
- PUT_ULONG_BE( ctx->state[4], output, 16 );
-}
-
-/*
- * output = SHA-1( input buffer )
- */
-void sha1( unsigned char *input, int ilen, unsigned char output[20] )
-{
- sha1_context ctx;
-
- sha1_starts( &ctx );
- sha1_update( &ctx, input, ilen );
- sha1_finish( &ctx, output );
-
- memset( &ctx, 0, sizeof( sha1_context ) );
-}
-
-/*
- * output = SHA-1( file contents )
- */
-int sha1_file( char *path, unsigned char output[20] )
-{
- FILE *f;
- size_t n;
- sha1_context ctx;
- unsigned char buf[1024];
-
- if( ( f = fopen( path, "rb" ) ) == NULL )
- return( 1 );
-
- sha1_starts( &ctx );
-
- while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
- sha1_update( &ctx, buf, (int) n );
-
- sha1_finish( &ctx, output );
-
- memset( &ctx, 0, sizeof( sha1_context ) );
-
- if( ferror( f ) != 0 )
- {
- fclose( f );
- return( 2 );
- }
-
- fclose( f );
- return( 0 );
-}
-
-/*
- * SHA-1 HMAC context setup
- */
-void sha1_hmac_starts( sha1_context *ctx, unsigned char *key, int keylen )
-{
- int i;
- unsigned char sum[20];
-
- if( keylen > 64 )
- {
- sha1( key, keylen, sum );
- keylen = 20;
- key = sum;
- }
-
- memset( ctx->ipad, 0x36, 64 );
- memset( ctx->opad, 0x5C, 64 );
-
- for( i = 0; i < keylen; i++ )
- {
- ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
- ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
- }
-
- sha1_starts( ctx );
- sha1_update( ctx, ctx->ipad, 64 );
-
- memset( sum, 0, sizeof( sum ) );
-}
-
-/*
- * SHA-1 HMAC process buffer
- */
-void sha1_hmac_update( sha1_context *ctx, unsigned char *input, int ilen )
-{
- sha1_update( ctx, input, ilen );
-}
-
-/*
- * SHA-1 HMAC final digest
- */
-void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] )
-{
- unsigned char tmpbuf[20];
-
- sha1_finish( ctx, tmpbuf );
- sha1_starts( ctx );
- sha1_update( ctx, ctx->opad, 64 );
- sha1_update( ctx, tmpbuf, 20 );
- sha1_finish( ctx, output );
-
- memset( tmpbuf, 0, sizeof( tmpbuf ) );
-}
-
-/*
- * output = HMAC-SHA-1( hmac key, input buffer )
- */
-void sha1_hmac( unsigned char *key, int keylen,
- unsigned char *input, int ilen,
- unsigned char output[20] )
-{
- sha1_context ctx;
-
- sha1_hmac_starts( &ctx, key, keylen );
- sha1_hmac_update( &ctx, input, ilen );
- sha1_hmac_finish( &ctx, output );
-
- memset( &ctx, 0, sizeof( sha1_context ) );
-}
-
-#if defined(POLARSSL_SELF_TEST)
-/*
- * FIPS-180-1 test vectors
- */
-static unsigned char sha1_test_buf[3][57] =
-{
- { "abc" },
- { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
- { "" }
-};
-
-static const int sha1_test_buflen[3] =
-{
- 3, 56, 1000
-};
-
-static const unsigned char sha1_test_sum[3][20] =
-{
- { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
- 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D },
- { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
- 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 },
- { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
- 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F }
-};
-
-/*
- * RFC 2202 test vectors
- */
-static unsigned char sha1_hmac_test_key[7][26] =
-{
- { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
- "\x0B\x0B\x0B\x0B" },
- { "Jefe" },
- { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
- "\xAA\xAA\xAA\xAA" },
- { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
- "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
- { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
- "\x0C\x0C\x0C\x0C" },
- { "" }, /* 0xAA 80 times */
- { "" }
-};
-
-static const int sha1_hmac_test_keylen[7] =
-{
- 20, 4, 20, 25, 20, 80, 80
-};
-
-static unsigned char sha1_hmac_test_buf[7][74] =
-{
- { "Hi There" },
- { "what do ya want for nothing?" },
- { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
- "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
- "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
- "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
- "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
- { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
- "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
- "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
- "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
- "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
- { "Test With Truncation" },
- { "Test Using Larger Than Block-Size Key - Hash Key First" },
- { "Test Using Larger Than Block-Size Key and Larger"
- " Than One Block-Size Data" }
-};
-
-static const int sha1_hmac_test_buflen[7] =
-{
- 8, 28, 50, 50, 20, 54, 73
-};
-
-static const unsigned char sha1_hmac_test_sum[7][20] =
-{
- { 0xB6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xE2, 0x8B,
- 0xC0, 0xB6, 0xFB, 0x37, 0x8C, 0x8E, 0xF1, 0x46, 0xBE, 0x00 },
- { 0xEF, 0xFC, 0xDF, 0x6A, 0xE5, 0xEB, 0x2F, 0xA2, 0xD2, 0x74,
- 0x16, 0xD5, 0xF1, 0x84, 0xDF, 0x9C, 0x25, 0x9A, 0x7C, 0x79 },
- { 0x12, 0x5D, 0x73, 0x42, 0xB9, 0xAC, 0x11, 0xCD, 0x91, 0xA3,
- 0x9A, 0xF4, 0x8A, 0xA1, 0x7B, 0x4F, 0x63, 0xF1, 0x75, 0xD3 },
- { 0x4C, 0x90, 0x07, 0xF4, 0x02, 0x62, 0x50, 0xC6, 0xBC, 0x84,
- 0x14, 0xF9, 0xBF, 0x50, 0xC8, 0x6C, 0x2D, 0x72, 0x35, 0xDA },
- { 0x4C, 0x1A, 0x03, 0x42, 0x4B, 0x55, 0xE0, 0x7F, 0xE7, 0xF2,
- 0x7B, 0xE1 },
- { 0xAA, 0x4A, 0xE5, 0xE1, 0x52, 0x72, 0xD0, 0x0E, 0x95, 0x70,
- 0x56, 0x37, 0xCE, 0x8A, 0x3B, 0x55, 0xED, 0x40, 0x21, 0x12 },
- { 0xE8, 0xE9, 0x9D, 0x0F, 0x45, 0x23, 0x7D, 0x78, 0x6D, 0x6B,
- 0xBA, 0xA7, 0x96, 0x5C, 0x78, 0x08, 0xBB, 0xFF, 0x1A, 0x91 }
-};
-
-/*
- * Checkup routine
- */
-int sha1_self_test( int verbose )
-{
- int i, j, buflen;
- unsigned char buf[1024];
- unsigned char sha1sum[20];
- sha1_context ctx;
-
- /*
- * SHA-1
- */
- for( i = 0; i < 3; i++ )
- {
- if( verbose != 0 )
- printf( " SHA-1 test #%d: ", i + 1 );
-
- sha1_starts( &ctx );
-
- if( i == 2 )
- {
- memset( buf, 'a', buflen = 1000 );
-
- for( j = 0; j < 1000; j++ )
- sha1_update( &ctx, buf, buflen );
- }
- else
- sha1_update( &ctx, sha1_test_buf[i],
- sha1_test_buflen[i] );
-
- sha1_finish( &ctx, sha1sum );
-
- if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 )
- {
- if( verbose != 0 )
- printf( "failed\n" );
-
- return( 1 );
- }
-
- if( verbose != 0 )
- printf( "passed\n" );
- }
-
- if( verbose != 0 )
- printf( "\n" );
-
- for( i = 0; i < 7; i++ )
- {
- if( verbose != 0 )
- printf( " HMAC-SHA-1 test #%d: ", i + 1 );
-
- if( i == 5 || i == 6 )
- {
- memset( buf, '\xAA', buflen = 80 );
- sha1_hmac_starts( &ctx, buf, buflen );
- }
- else
- sha1_hmac_starts( &ctx, sha1_hmac_test_key[i],
- sha1_hmac_test_keylen[i] );
-
- sha1_hmac_update( &ctx, sha1_hmac_test_buf[i],
- sha1_hmac_test_buflen[i] );
-
- sha1_hmac_finish( &ctx, sha1sum );
-
- buflen = ( i == 4 ) ? 12 : 20;
-
- if( memcmp( sha1sum, sha1_hmac_test_sum[i], buflen ) != 0 )
- {
- if( verbose != 0 )
- printf( "failed\n" );
-
- return( 1 );
- }
-
- if( verbose != 0 )
- printf( "passed\n" );
- }
-
- if( verbose != 0 )
- printf( "\n" );
-
- return( 0 );
-}
-
-#endif
-
-#endif
+++ /dev/null
-/*
- * Portable interface to the CPU cycle counter
- *
- * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
- *
- * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the names of PolarSSL or XySSL nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "polarssl/config.h"
-
-#if defined(POLARSSL_TIMING_C)
-
-#include "polarssl/timing.h"
-
-#if defined(WIN32)
-
-#include <windows.h>
-#include <winbase.h>
-
-struct _hr_time
-{
- LARGE_INTEGER start;
-};
-
-#else
-
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <signal.h>
-#include <time.h>
-
-struct _hr_time
-{
- struct timeval start;
-};
-
-#endif
-
-#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
-
-unsigned long hardclock( void )
-{
- unsigned long tsc;
- __asm rdtsc
- __asm mov [tsc], eax
- return( tsc );
-}
-
-#else
-#if defined(__GNUC__) && defined(__i386__)
-
-unsigned long hardclock( void )
-{
- unsigned long tsc;
- asm( "rdtsc" : "=a" (tsc) );
- return( tsc );
-}
-
-#else
-#if defined(__GNUC__) && (defined(__amd64__) || defined(__x86_64__))
-
-unsigned long hardclock( void )
-{
- unsigned long lo, hi;
- asm( "rdtsc" : "=a" (lo), "=d" (hi) );
- return( lo | (hi << 32) );
-}
-
-#else
-#if defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
-
-unsigned long hardclock( void )
-{
- unsigned long tbl, tbu0, tbu1;
-
- do
- {
- asm( "mftbu %0" : "=r" (tbu0) );
- asm( "mftb %0" : "=r" (tbl ) );
- asm( "mftbu %0" : "=r" (tbu1) );
- }
- while( tbu0 != tbu1 );
-
- return( tbl );
-}
-
-#else
-#if defined(__GNUC__) && defined(__sparc__)
-
-unsigned long hardclock( void )
-{
- unsigned long tick;
- asm( ".byte 0x83, 0x41, 0x00, 0x00" );
- asm( "mov %%g1, %0" : "=r" (tick) );
- return( tick );
-}
-
-#else
-#if defined(__GNUC__) && defined(__alpha__)
-
-unsigned long hardclock( void )
-{
- unsigned long cc;
- asm( "rpcc %0" : "=r" (cc) );
- return( cc & 0xFFFFFFFF );
-}
-
-#else
-#if defined(__GNUC__) && defined(__ia64__)
-
-unsigned long hardclock( void )
-{
- unsigned long itc;
- asm( "mov %0 = ar.itc" : "=r" (itc) );
- return( itc );
-}
-
-#else
-
-static int hardclock_init = 0;
-static struct timeval tv_init;
-
-unsigned long hardclock( void )
-{
- struct timeval tv_cur;
-
- if( hardclock_init == 0 )
- {
- gettimeofday( &tv_init, NULL );
- hardclock_init = 1;
- }
-
- gettimeofday( &tv_cur, NULL );
- return( ( tv_cur.tv_sec - tv_init.tv_sec ) * 1000000
- + ( tv_cur.tv_usec - tv_init.tv_usec ) );
-}
-
-#endif /* generic */
-#endif /* IA-64 */
-#endif /* Alpha */
-#endif /* SPARC8 */
-#endif /* PowerPC */
-#endif /* AMD64 */
-#endif /* i586+ */
-
-int alarmed = 0;
-
-#if defined(WIN32)
-
-unsigned long get_timer( struct hr_time *val, int reset )
-{
- unsigned long delta;
- LARGE_INTEGER offset, hfreq;
- struct _hr_time *t = (struct _hr_time *) val;
-
- QueryPerformanceCounter( &offset );
- QueryPerformanceFrequency( &hfreq );
-
- delta = (unsigned long)( ( 1000 *
- ( offset.QuadPart - t->start.QuadPart ) ) /
- hfreq.QuadPart );
-
- if( reset )
- QueryPerformanceCounter( &t->start );
-
- return( delta );
-}
-
-DWORD WINAPI TimerProc( LPVOID uElapse )
-{
- Sleep( (DWORD) uElapse );
- alarmed = 1;
- return( TRUE );
-}
-
-void set_alarm( int seconds )
-{
- DWORD ThreadId;
-
- alarmed = 0;
- CloseHandle( CreateThread( NULL, 0, TimerProc,
- (LPVOID) ( seconds * 1000 ), 0, &ThreadId ) );
-}
-
-void m_sleep( int milliseconds )
-{
- Sleep( milliseconds );
-}
-
-#else
-
-unsigned long get_timer( struct hr_time *val, int reset )
-{
- unsigned long delta;
- struct timeval offset;
- struct _hr_time *t = (struct _hr_time *) val;
-
- gettimeofday( &offset, NULL );
-
- delta = ( offset.tv_sec - t->start.tv_sec ) * 1000
- + ( offset.tv_usec - t->start.tv_usec ) / 1000;
-
- if( reset )
- {
- t->start.tv_sec = offset.tv_sec;
- t->start.tv_usec = offset.tv_usec;
- }
-
- return( delta );
-}
-
-static void sighandler( int signum )
-{
- alarmed = 1;
- signal( signum, sighandler );
-}
-
-void set_alarm( int seconds )
-{
- alarmed = 0;
- signal( SIGALRM, sighandler );
- alarm( seconds );
-}
-
-void m_sleep( int milliseconds )
-{
- struct timeval tv;
-
- tv.tv_sec = milliseconds / 1000;
- tv.tv_usec = milliseconds * 1000;
-
- select( 0, NULL, NULL, NULL, &tv );
-}
-
-#endif
-
-#endif
+++ /dev/null
-/*
- * X.509 certificate and private key writing
- *
- * Copyright (C) 2006-2007 Pascal Vizeli <pvizeli@yahoo.de>
- * Modifications (C) 2009 Steven Barth <steven@midlink.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License, version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-/*
- * 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 <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <time.h>
-
-#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, "%s", 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;i<n;i+=64) {
- fprintf(ofstream,"%.64s\n",&base_buf[i]);
- }
-
- if (fprintf(ofstream, "%s", pem_epilog)<0) {
- is_err = -1;
- break;
- }
-
- free(base_buf);
- }
-
- fclose(ofstream);
-
- if (is_err == -1)
- return 1;
-
- return 0;
-}
-
-
-/*
- * add the owner public key to x509 certificate
- */
-int x509write_add_pubkey(x509_raw *chain, rsa_context *pubkey)
-{
- x509_node n_tmp, n_tmp2, *node;
- int ret;
-
- node = &chain->subpubkey;
-
- 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 random serial
- */
-static int get_random_serial(void)
-{
- int random = 0;
- FILE *fd;
-
- fd = fopen("/dev/urandom", "r");
-
- if (fd) {
- if (fread(&random, 1, sizeof(random), fd) != sizeof(random))
- random = 0;
-
- fclose(fd);
- }
-
- return random;
-}
-
-/*
- * 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
- */
- serial = get_random_serial();
-
- if (serial == 0)
- return 1;
-
- 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));
-}
-
+++ /dev/null
-/**
- * \file base64.h
- *
- * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
- *
- * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the names of PolarSSL or XySSL nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef POLARSSL_BASE64_H
-#define POLARSSL_BASE64_H
-
-#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL -0x0010
-#define POLARSSL_ERR_BASE64_INVALID_CHARACTER -0x0012
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \brief Encode a buffer into base64 format
- *
- * \param dst destination buffer
- * \param dlen size of the buffer
- * \param src source buffer
- * \param slen amount of data to be encoded
- *
- * \return 0 if successful, or POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL.
- * *dlen is always updated to reflect the amount
- * of data that has (or would have) been written.
- *
- * \note Call this function with *dlen = 0 to obtain the
- * required buffer size in *dlen
- */
-int base64_encode( unsigned char *dst, int *dlen,
- unsigned char *src, int slen );
-
-/**
- * \brief Decode a base64-formatted buffer
- *
- * \param dst destination buffer
- * \param dlen size of the buffer
- * \param src source buffer
- * \param slen amount of data to be decoded
- *
- * \return 0 if successful, POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL, or
- * POLARSSL_ERR_BASE64_INVALID_DATA if the input data is not
- * correct. *dlen is always updated to reflect the amount
- * of data that has (or would have) been written.
- *
- * \note Call this function with *dlen = 0 to obtain the
- * required buffer size in *dlen
- */
-int base64_decode( unsigned char *dst, int *dlen,
- unsigned char *src, int slen );
-
-/**
- * \brief Checkup routine
- *
- * \return 0 if successful, or 1 if the test failed
- */
-int base64_self_test( int verbose );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* base64.h */
+++ /dev/null
-/**
- * \file bignum.h
- *
- * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
- *
- * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the names of PolarSSL or XySSL nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef POLARSSL_BIGNUM_H
-#define POLARSSL_BIGNUM_H
-
-#include <stdio.h>
-
-#define POLARSSL_ERR_MPI_FILE_IO_ERROR -0x0002
-#define POLARSSL_ERR_MPI_BAD_INPUT_DATA -0x0004
-#define POLARSSL_ERR_MPI_INVALID_CHARACTER -0x0006
-#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL -0x0008
-#define POLARSSL_ERR_MPI_NEGATIVE_VALUE -0x000A
-#define POLARSSL_ERR_MPI_DIVISION_BY_ZERO -0x000C
-#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE -0x000E
-
-#define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup
-
-/*
- * Define the base integer type, architecture-wise
- */
-#if defined(POLARSSL_HAVE_INT8)
-typedef unsigned char t_int;
-typedef unsigned short t_dbl;
-#else
-#if defined(POLARSSL_HAVE_INT16)
-typedef unsigned short t_int;
-typedef unsigned long t_dbl;
-#else
- typedef unsigned long t_int;
- #if defined(_MSC_VER) && defined(_M_IX86)
- typedef unsigned __int64 t_dbl;
- #else
- #if defined(__amd64__) || defined(__x86_64__) || \
- defined(__ppc64__) || defined(__powerpc64__) || \
- defined(__ia64__) || defined(__alpha__)
- typedef unsigned int t_dbl __attribute__((mode(TI)));
- #else
- typedef unsigned long long t_dbl;
- #endif
- #endif
-#endif
-#endif
-
-/**
- * \brief MPI structure
- */
-typedef struct
-{
- int s; /*!< integer sign */
- int n; /*!< total # of limbs */
- t_int *p; /*!< pointer to limbs */
-}
-mpi;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \brief Initialize one or more mpi
- */
-void mpi_init( mpi *X, ... );
-
-/**
- * \brief Unallocate one or more mpi
- */
-void mpi_free( mpi *X, ... );
-
-/**
- * \brief Enlarge to the specified number of limbs
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_grow( mpi *X, int nblimbs );
-
-/**
- * \brief Copy the contents of Y into X
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_copy( mpi *X, mpi *Y );
-
-/**
- * \brief Swap the contents of X and Y
- */
-void mpi_swap( mpi *X, mpi *Y );
-
-/**
- * \brief Set value from integer
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_lset( mpi *X, int z );
-
-/**
- * \brief Return the number of least significant bits
- */
-int mpi_lsb( mpi *X );
-
-/**
- * \brief Return the number of most significant bits
- */
-int mpi_msb( mpi *X );
-
-/**
- * \brief Return the total size in bytes
- */
-int mpi_size( mpi *X );
-
-/**
- * \brief Import from an ASCII string
- *
- * \param X destination mpi
- * \param radix input numeric base
- * \param s null-terminated string buffer
- *
- * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
- */
-int mpi_read_string( mpi *X, int radix, char *s );
-
-/**
- * \brief Export into an ASCII string
- *
- * \param X source mpi
- * \param radix output numeric base
- * \param s string buffer
- * \param slen string buffer size
- *
- * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
- *
- * \note Call this function with *slen = 0 to obtain the
- * minimum required buffer size in *slen.
- */
-int mpi_write_string( mpi *X, int radix, char *s, int *slen );
-
-/**
- * \brief Read X from an opened file
- *
- * \param X destination mpi
- * \param radix input numeric base
- * \param fin input file handle
- *
- * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
- */
-int mpi_read_file( mpi *X, int radix, FILE *fin );
-
-/**
- * \brief Write X into an opened file, or stdout
- *
- * \param p prefix, can be NULL
- * \param X source mpi
- * \param radix output numeric base
- * \param fout output file handle
- *
- * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
- *
- * \note Set fout == NULL to print X on the console.
- */
-int mpi_write_file( char *p, mpi *X, int radix, FILE *fout );
-
-/**
- * \brief Import X from unsigned binary data, big endian
- *
- * \param X destination mpi
- * \param buf input buffer
- * \param buflen input buffer size
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_read_binary( mpi *X, unsigned char *buf, int buflen );
-
-/**
- * \brief Export X into unsigned binary data, big endian
- *
- * \param X source mpi
- * \param buf output buffer
- * \param buflen output buffer size
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough
- *
- * \note Call this function with *buflen = 0 to obtain the
- * minimum required buffer size in *buflen.
- */
-int mpi_write_binary( mpi *X, unsigned char *buf, int buflen );
-
-/**
- * \brief Left-shift: X <<= count
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_shift_l( mpi *X, int count );
-
-/**
- * \brief Right-shift: X >>= count
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_shift_r( mpi *X, int count );
-
-/**
- * \brief Compare unsigned values
- *
- * \return 1 if |X| is greater than |Y|,
- * -1 if |X| is lesser than |Y| or
- * 0 if |X| is equal to |Y|
- */
-int mpi_cmp_abs( mpi *X, mpi *Y );
-
-/**
- * \brief Compare signed values
- *
- * \return 1 if X is greater than Y,
- * -1 if X is lesser than Y or
- * 0 if X is equal to Y
- */
-int mpi_cmp_mpi( mpi *X, mpi *Y );
-
-/**
- * \brief Compare signed values
- *
- * \return 1 if X is greater than z,
- * -1 if X is lesser than z or
- * 0 if X is equal to z
- */
-int mpi_cmp_int( mpi *X, int z );
-
-/**
- * \brief Unsigned addition: X = |A| + |B|
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_add_abs( mpi *X, mpi *A, mpi *B );
-
-/**
- * \brief Unsigned substraction: X = |A| - |B|
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A
- */
-int mpi_sub_abs( mpi *X, mpi *A, mpi *B );
-
-/**
- * \brief Signed addition: X = A + B
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_add_mpi( mpi *X, mpi *A, mpi *B );
-
-/**
- * \brief Signed substraction: X = A - B
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_sub_mpi( mpi *X, mpi *A, mpi *B );
-
-/**
- * \brief Signed addition: X = A + b
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_add_int( mpi *X, mpi *A, int b );
-
-/**
- * \brief Signed substraction: X = A - b
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_sub_int( mpi *X, mpi *A, int b );
-
-/**
- * \brief Baseline multiplication: X = A * B
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_mul_mpi( mpi *X, mpi *A, mpi *B );
-
-/**
- * \brief Baseline multiplication: X = A * b
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_mul_int( mpi *X, mpi *A, t_int b );
-
-/**
- * \brief Division by mpi: A = Q * B + R
- *
- * \return 0 if successful,
- * 1 if memory allocation failed,
- * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0
- *
- * \note Either Q or R can be NULL.
- */
-int mpi_div_mpi( mpi *Q, mpi *R, mpi *A, mpi *B );
-
-/**
- * \brief Division by int: A = Q * b + R
- *
- * \return 0 if successful,
- * 1 if memory allocation failed,
- * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
- *
- * \note Either Q or R can be NULL.
- */
-int mpi_div_int( mpi *Q, mpi *R, mpi *A, int b );
-
-/**
- * \brief Modulo: R = A mod B
- *
- * \return 0 if successful,
- * 1 if memory allocation failed,
- * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0
- */
-int mpi_mod_mpi( mpi *R, mpi *A, mpi *B );
-
-/**
- * \brief Modulo: r = A mod b
- *
- * \return 0 if successful,
- * 1 if memory allocation failed,
- * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
- */
-int mpi_mod_int( t_int *r, mpi *A, int b );
-
-/**
- * \brief Sliding-window exponentiation: X = A^E mod N
- *
- * \return 0 if successful,
- * 1 if memory allocation failed,
- * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even
- *
- * \note _RR is used to avoid re-computing R*R mod N across
- * multiple calls, which speeds up things a bit. It can
- * be set to NULL if the extra performance is unneeded.
- */
-int mpi_exp_mod( mpi *X, mpi *A, mpi *E, mpi *N, mpi *_RR );
-
-/**
- * \brief Greatest common divisor: G = gcd(A, B)
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_gcd( mpi *G, mpi *A, mpi *B );
-
-/**
- * \brief Modular inverse: X = A^-1 mod N
- *
- * \return 0 if successful,
- * 1 if memory allocation failed,
- * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil
- * POLARSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N
- */
-int mpi_inv_mod( mpi *X, mpi *A, mpi *N );
-
-/**
- * \brief Miller-Rabin primality test
- *
- * \return 0 if successful (probably prime),
- * 1 if memory allocation failed,
- * POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime
- */
-int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng );
-
-/**
- * \brief Prime number generation
- *
- * \param X destination mpi
- * \param nbits required size of X in bits
- * \param dh_flag if 1, then (X-1)/2 will be prime too
- * \param f_rng RNG function
- * \param p_rng RNG parameter
- *
- * \return 0 if successful (probably prime),
- * 1 if memory allocation failed,
- * POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
- */
-int mpi_gen_prime( mpi *X, int nbits, int dh_flag,
- int (*f_rng)(void *), void *p_rng );
-
-/**
- * \brief Checkup routine
- *
- * \return 0 if successful, or 1 if the test failed
- */
-int mpi_self_test( int verbose );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* bignum.h */
+++ /dev/null
-/**
- * \file bn_mul.h
- *
- * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
- *
- * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the names of PolarSSL or XySSL nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/*
- * Multiply source vector [s] with b, add result
- * to destination vector [d] and set carry c.
- *
- * Currently supports:
- *
- * . IA-32 (386+) . AMD64 / EM64T
- * . IA-32 (SSE2) . Motorola 68000
- * . PowerPC, 32-bit . MicroBlaze
- * . PowerPC, 64-bit . TriCore
- * . SPARC v8 . ARM v3+
- * . Alpha . MIPS32
- * . C, longlong . C, generic
- */
-#ifndef POLARSSL_BN_MUL_H
-#define POLARSSL_BN_MUL_H
-
-#include "polarssl/config.h"
-
-#if defined(POLARSSL_HAVE_ASM)
-
-#if defined(__GNUC__)
-#if defined(__i386__)
-
-#define MULADDC_INIT \
- asm( "movl %%ebx, %0 " : "=m" (t)); \
- asm( "movl %0, %%esi " :: "m" (s)); \
- asm( "movl %0, %%edi " :: "m" (d)); \
- asm( "movl %0, %%ecx " :: "m" (c)); \
- asm( "movl %0, %%ebx " :: "m" (b));
-
-#define MULADDC_CORE \
- asm( "lodsl " ); \
- asm( "mull %ebx " ); \
- asm( "addl %ecx, %eax " ); \
- asm( "adcl $0, %edx " ); \
- asm( "addl (%edi), %eax " ); \
- asm( "adcl $0, %edx " ); \
- asm( "movl %edx, %ecx " ); \
- asm( "stosl " );
-
-#if defined(POLARSSL_HAVE_SSE2)
-
-#define MULADDC_HUIT \
- asm( "movd %ecx, %mm1 " ); \
- asm( "movd %ebx, %mm0 " ); \
- asm( "movd (%edi), %mm3 " ); \
- asm( "paddq %mm3, %mm1 " ); \
- asm( "movd (%esi), %mm2 " ); \
- asm( "pmuludq %mm0, %mm2 " ); \
- asm( "movd 4(%esi), %mm4 " ); \
- asm( "pmuludq %mm0, %mm4 " ); \
- asm( "movd 8(%esi), %mm6 " ); \
- asm( "pmuludq %mm0, %mm6 " ); \
- asm( "movd 12(%esi), %mm7 " ); \
- asm( "pmuludq %mm0, %mm7 " ); \
- asm( "paddq %mm2, %mm1 " ); \
- asm( "movd 4(%edi), %mm3 " ); \
- asm( "paddq %mm4, %mm3 " ); \
- asm( "movd 8(%edi), %mm5 " ); \
- asm( "paddq %mm6, %mm5 " ); \
- asm( "movd 12(%edi), %mm4 " ); \
- asm( "paddq %mm4, %mm7 " ); \
- asm( "movd %mm1, (%edi) " ); \
- asm( "movd 16(%esi), %mm2 " ); \
- asm( "pmuludq %mm0, %mm2 " ); \
- asm( "psrlq $32, %mm1 " ); \
- asm( "movd 20(%esi), %mm4 " ); \
- asm( "pmuludq %mm0, %mm4 " ); \
- asm( "paddq %mm3, %mm1 " ); \
- asm( "movd 24(%esi), %mm6 " ); \
- asm( "pmuludq %mm0, %mm6 " ); \
- asm( "movd %mm1, 4(%edi) " ); \
- asm( "psrlq $32, %mm1 " ); \
- asm( "movd 28(%esi), %mm3 " ); \
- asm( "pmuludq %mm0, %mm3 " ); \
- asm( "paddq %mm5, %mm1 " ); \
- asm( "movd 16(%edi), %mm5 " ); \
- asm( "paddq %mm5, %mm2 " ); \
- asm( "movd %mm1, 8(%edi) " ); \
- asm( "psrlq $32, %mm1 " ); \
- asm( "paddq %mm7, %mm1 " ); \
- asm( "movd 20(%edi), %mm5 " ); \
- asm( "paddq %mm5, %mm4 " ); \
- asm( "movd %mm1, 12(%edi) " ); \
- asm( "psrlq $32, %mm1 " ); \
- asm( "paddq %mm2, %mm1 " ); \
- asm( "movd 24(%edi), %mm5 " ); \
- asm( "paddq %mm5, %mm6 " ); \
- asm( "movd %mm1, 16(%edi) " ); \
- asm( "psrlq $32, %mm1 " ); \
- asm( "paddq %mm4, %mm1 " ); \
- asm( "movd 28(%edi), %mm5 " ); \
- asm( "paddq %mm5, %mm3 " ); \
- asm( "movd %mm1, 20(%edi) " ); \
- asm( "psrlq $32, %mm1 " ); \
- asm( "paddq %mm6, %mm1 " ); \
- asm( "movd %mm1, 24(%edi) " ); \
- asm( "psrlq $32, %mm1 " ); \
- asm( "paddq %mm3, %mm1 " ); \
- asm( "movd %mm1, 28(%edi) " ); \
- asm( "addl $32, %edi " ); \
- asm( "addl $32, %esi " ); \
- asm( "psrlq $32, %mm1 " ); \
- asm( "movd %mm1, %ecx " );
-
-#define MULADDC_STOP \
- asm( "emms " ); \
- asm( "movl %0, %%ebx " :: "m" (t)); \
- asm( "movl %%ecx, %0 " : "=m" (c)); \
- asm( "movl %%edi, %0 " : "=m" (d)); \
- asm( "movl %%esi, %0 " : "=m" (s) :: \
- "eax", "ecx", "edx", "esi", "edi" );
-
-#else
-
-#define MULADDC_STOP \
- asm( "movl %0, %%ebx " :: "m" (t)); \
- asm( "movl %%ecx, %0 " : "=m" (c)); \
- asm( "movl %%edi, %0 " : "=m" (d)); \
- asm( "movl %%esi, %0 " : "=m" (s) :: \
- "eax", "ecx", "edx", "esi", "edi" );
-
-#endif /* SSE2 */
-#endif /* i386 */
-
-#if defined(__amd64__) || defined (__x86_64__)
-
-#define MULADDC_INIT \
- asm( "movq %0, %%rsi " :: "m" (s)); \
- asm( "movq %0, %%rdi " :: "m" (d)); \
- asm( "movq %0, %%rcx " :: "m" (c)); \
- asm( "movq %0, %%rbx " :: "m" (b)); \
- asm( "xorq %r8, %r8 " );
-
-#define MULADDC_CORE \
- asm( "movq (%rsi),%rax " ); \
- asm( "mulq %rbx " ); \
- asm( "addq $8, %rsi " ); \
- asm( "addq %rcx, %rax " ); \
- asm( "movq %r8, %rcx " ); \
- asm( "adcq $0, %rdx " ); \
- asm( "nop " ); \
- asm( "addq %rax, (%rdi) " ); \
- asm( "adcq %rdx, %rcx " ); \
- asm( "addq $8, %rdi " );
-
-#define MULADDC_STOP \
- asm( "movq %%rcx, %0 " : "=m" (c)); \
- asm( "movq %%rdi, %0 " : "=m" (d)); \
- asm( "movq %%rsi, %0 " : "=m" (s) :: \
- "rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" );
-
-#endif /* AMD64 */
-
-#if defined(__mc68020__) || defined(__mcpu32__)
-
-#define MULADDC_INIT \
- asm( "movl %0, %%a2 " :: "m" (s)); \
- asm( "movl %0, %%a3 " :: "m" (d)); \
- asm( "movl %0, %%d3 " :: "m" (c)); \
- asm( "movl %0, %%d2 " :: "m" (b)); \
- asm( "moveq #0, %d0 " );
-
-#define MULADDC_CORE \
- asm( "movel %a2@+, %d1 " ); \
- asm( "mulul %d2, %d4:%d1 " ); \
- asm( "addl %d3, %d1 " ); \
- asm( "addxl %d0, %d4 " ); \
- asm( "moveq #0, %d3 " ); \
- asm( "addl %d1, %a3@+ " ); \
- asm( "addxl %d4, %d3 " );
-
-#define MULADDC_STOP \
- asm( "movl %%d3, %0 " : "=m" (c)); \
- asm( "movl %%a3, %0 " : "=m" (d)); \
- asm( "movl %%a2, %0 " : "=m" (s) :: \
- "d0", "d1", "d2", "d3", "d4", "a2", "a3" );
-
-#define MULADDC_HUIT \
- asm( "movel %a2@+, %d1 " ); \
- asm( "mulul %d2, %d4:%d1 " ); \
- asm( "addxl %d3, %d1 " ); \
- asm( "addxl %d0, %d4 " ); \
- asm( "addl %d1, %a3@+ " ); \
- asm( "movel %a2@+, %d1 " ); \
- asm( "mulul %d2, %d3:%d1 " ); \
- asm( "addxl %d4, %d1 " ); \
- asm( "addxl %d0, %d3 " ); \
- asm( "addl %d1, %a3@+ " ); \
- asm( "movel %a2@+, %d1 " ); \
- asm( "mulul %d2, %d4:%d1 " ); \
- asm( "addxl %d3, %d1 " ); \
- asm( "addxl %d0, %d4 " ); \
- asm( "addl %d1, %a3@+ " ); \
- asm( "movel %a2@+, %d1 " ); \
- asm( "mulul %d2, %d3:%d1 " ); \
- asm( "addxl %d4, %d1 " ); \
- asm( "addxl %d0, %d3 " ); \
- asm( "addl %d1, %a3@+ " ); \
- asm( "movel %a2@+, %d1 " ); \
- asm( "mulul %d2, %d4:%d1 " ); \
- asm( "addxl %d3, %d1 " ); \
- asm( "addxl %d0, %d4 " ); \
- asm( "addl %d1, %a3@+ " ); \
- asm( "movel %a2@+, %d1 " ); \
- asm( "mulul %d2, %d3:%d1 " ); \
- asm( "addxl %d4, %d1 " ); \
- asm( "addxl %d0, %d3 " ); \
- asm( "addl %d1, %a3@+ " ); \
- asm( "movel %a2@+, %d1 " ); \
- asm( "mulul %d2, %d4:%d1 " ); \
- asm( "addxl %d3, %d1 " ); \
- asm( "addxl %d0, %d4 " ); \
- asm( "addl %d1, %a3@+ " ); \
- asm( "movel %a2@+, %d1 " ); \
- asm( "mulul %d2, %d3:%d1 " ); \
- asm( "addxl %d4, %d1 " ); \
- asm( "addxl %d0, %d3 " ); \
- asm( "addl %d1, %a3@+ " ); \
- asm( "addxl %d0, %d3 " );
-
-#endif /* MC68000 */
-
-#if defined(__powerpc__) || defined(__ppc__)
-#if defined(__powerpc64__) || defined(__ppc64__)
-
-#if defined(__MACH__) && defined(__APPLE__)
-
-#define MULADDC_INIT \
- asm( "ld r3, %0 " :: "m" (s)); \
- asm( "ld r4, %0 " :: "m" (d)); \
- asm( "ld r5, %0 " :: "m" (c)); \
- asm( "ld r6, %0 " :: "m" (b)); \
- asm( "addi r3, r3, -8 " ); \
- asm( "addi r4, r4, -8 " ); \
- asm( "addic r5, r5, 0 " );
-
-#define MULADDC_CORE \
- asm( "ldu r7, 8(r3) " ); \
- asm( "mulld r8, r7, r6 " ); \
- asm( "mulhdu r9, r7, r6 " ); \
- asm( "adde r8, r8, r5 " ); \
- asm( "ld r7, 8(r4) " ); \
- asm( "addze r5, r9 " ); \
- asm( "addc r8, r8, r7 " ); \
- asm( "stdu r8, 8(r4) " );
-
-#define MULADDC_STOP \
- asm( "addze r5, r5 " ); \
- asm( "addi r4, r4, 8 " ); \
- asm( "addi r3, r3, 8 " ); \
- asm( "std r5, %0 " : "=m" (c)); \
- asm( "std r4, %0 " : "=m" (d)); \
- asm( "std r3, %0 " : "=m" (s) :: \
- "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
-
-#else
-
-#define MULADDC_INIT \
- asm( "ld %%r3, %0 " :: "m" (s)); \
- asm( "ld %%r4, %0 " :: "m" (d)); \
- asm( "ld %%r5, %0 " :: "m" (c)); \
- asm( "ld %%r6, %0 " :: "m" (b)); \
- asm( "addi %r3, %r3, -8 " ); \
- asm( "addi %r4, %r4, -8 " ); \
- asm( "addic %r5, %r5, 0 " );
-
-#define MULADDC_CORE \
- asm( "ldu %r7, 8(%r3) " ); \
- asm( "mulld %r8, %r7, %r6 " ); \
- asm( "mulhdu %r9, %r7, %r6 " ); \
- asm( "adde %r8, %r8, %r5 " ); \
- asm( "ld %r7, 8(%r4) " ); \
- asm( "addze %r5, %r9 " ); \
- asm( "addc %r8, %r8, %r7 " ); \
- asm( "stdu %r8, 8(%r4) " );
-
-#define MULADDC_STOP \
- asm( "addze %r5, %r5 " ); \
- asm( "addi %r4, %r4, 8 " ); \
- asm( "addi %r3, %r3, 8 " ); \
- asm( "std %%r5, %0 " : "=m" (c)); \
- asm( "std %%r4, %0 " : "=m" (d)); \
- asm( "std %%r3, %0 " : "=m" (s) :: \
- "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
-
-#endif
-
-#else /* PPC32 */
-
-#if defined(__MACH__) && defined(__APPLE__)
-
-#define MULADDC_INIT \
- asm( "lwz r3, %0 " :: "m" (s)); \
- asm( "lwz r4, %0 " :: "m" (d)); \
- asm( "lwz r5, %0 " :: "m" (c)); \
- asm( "lwz r6, %0 " :: "m" (b)); \
- asm( "addi r3, r3, -4 " ); \
- asm( "addi r4, r4, -4 " ); \
- asm( "addic r5, r5, 0 " );
-
-#define MULADDC_CORE \
- asm( "lwzu r7, 4(r3) " ); \
- asm( "mullw r8, r7, r6 " ); \
- asm( "mulhwu r9, r7, r6 " ); \
- asm( "adde r8, r8, r5 " ); \
- asm( "lwz r7, 4(r4) " ); \
- asm( "addze r5, r9 " ); \
- asm( "addc r8, r8, r7 " ); \
- asm( "stwu r8, 4(r4) " );
-
-#define MULADDC_STOP \
- asm( "addze r5, r5 " ); \
- asm( "addi r4, r4, 4 " ); \
- asm( "addi r3, r3, 4 " ); \
- asm( "stw r5, %0 " : "=m" (c)); \
- asm( "stw r4, %0 " : "=m" (d)); \
- asm( "stw r3, %0 " : "=m" (s) :: \
- "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
-
-#else
-
-#define MULADDC_INIT \
- asm( "lwz %%r3, %0 " :: "m" (s)); \
- asm( "lwz %%r4, %0 " :: "m" (d)); \
- asm( "lwz %%r5, %0 " :: "m" (c)); \
- asm( "lwz %%r6, %0 " :: "m" (b)); \
- asm( "addi %r3, %r3, -4 " ); \
- asm( "addi %r4, %r4, -4 " ); \
- asm( "addic %r5, %r5, 0 " );
-
-#define MULADDC_CORE \
- asm( "lwzu %r7, 4(%r3) " ); \
- asm( "mullw %r8, %r7, %r6 " ); \
- asm( "mulhwu %r9, %r7, %r6 " ); \
- asm( "adde %r8, %r8, %r5 " ); \
- asm( "lwz %r7, 4(%r4) " ); \
- asm( "addze %r5, %r9 " ); \
- asm( "addc %r8, %r8, %r7 " ); \
- asm( "stwu %r8, 4(%r4) " );
-
-#define MULADDC_STOP \
- asm( "addze %r5, %r5 " ); \
- asm( "addi %r4, %r4, 4 " ); \
- asm( "addi %r3, %r3, 4 " ); \
- asm( "stw %%r5, %0 " : "=m" (c)); \
- asm( "stw %%r4, %0 " : "=m" (d)); \
- asm( "stw %%r3, %0 " : "=m" (s) :: \
- "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
-
-#endif
-
-#endif /* PPC32 */
-#endif /* PPC64 */
-
-#if defined(__sparc__)
-
-#define MULADDC_INIT \
- asm( "ld %0, %%o0 " :: "m" (s)); \
- asm( "ld %0, %%o1 " :: "m" (d)); \
- asm( "ld %0, %%o2 " :: "m" (c)); \
- asm( "ld %0, %%o3 " :: "m" (b));
-
-#define MULADDC_CORE \
- asm( "ld [%o0], %o4 " ); \
- asm( "inc 4, %o0 " ); \
- asm( "ld [%o1], %o5 " ); \
- asm( "umul %o3, %o4, %o4 " ); \
- asm( "addcc %o4, %o2, %o4 " ); \
- asm( "rd %y, %g1 " ); \
- asm( "addx %g1, 0, %g1 " ); \
- asm( "addcc %o4, %o5, %o4 " ); \
- asm( "st %o4, [%o1] " ); \
- asm( "addx %g1, 0, %o2 " ); \
- asm( "inc 4, %o1 " );
-
-#define MULADDC_STOP \
- asm( "st %%o2, %0 " : "=m" (c)); \
- asm( "st %%o1, %0 " : "=m" (d)); \
- asm( "st %%o0, %0 " : "=m" (s) :: \
- "g1", "o0", "o1", "o2", "o3", "o4", "o5" );
-
-#endif /* SPARCv8 */
-
-#if defined(__microblaze__) || defined(microblaze)
-
-#define MULADDC_INIT \
- asm( "lwi r3, %0 " :: "m" (s)); \
- asm( "lwi r4, %0 " :: "m" (d)); \
- asm( "lwi r5, %0 " :: "m" (c)); \
- asm( "lwi r6, %0 " :: "m" (b)); \
- asm( "andi r7, r6, 0xffff" ); \
- asm( "bsrli r6, r6, 16 " );
-
-#define MULADDC_CORE \
- asm( "lhui r8, r3, 0 " ); \
- asm( "addi r3, r3, 2 " ); \
- asm( "lhui r9, r3, 0 " ); \
- asm( "addi r3, r3, 2 " ); \
- asm( "mul r10, r9, r6 " ); \
- asm( "mul r11, r8, r7 " ); \
- asm( "mul r12, r9, r7 " ); \
- asm( "mul r13, r8, r6 " ); \
- asm( "bsrli r8, r10, 16 " ); \
- asm( "bsrli r9, r11, 16 " ); \
- asm( "add r13, r13, r8 " ); \
- asm( "add r13, r13, r9 " ); \
- asm( "bslli r10, r10, 16 " ); \
- asm( "bslli r11, r11, 16 " ); \
- asm( "add r12, r12, r10 " ); \
- asm( "addc r13, r13, r0 " ); \
- asm( "add r12, r12, r11 " ); \
- asm( "addc r13, r13, r0 " ); \
- asm( "lwi r10, r4, 0 " ); \
- asm( "add r12, r12, r10 " ); \
- asm( "addc r13, r13, r0 " ); \
- asm( "add r12, r12, r5 " ); \
- asm( "addc r5, r13, r0 " ); \
- asm( "swi r12, r4, 0 " ); \
- asm( "addi r4, r4, 4 " );
-
-#define MULADDC_STOP \
- asm( "swi r5, %0 " : "=m" (c)); \
- asm( "swi r4, %0 " : "=m" (d)); \
- asm( "swi r3, %0 " : "=m" (s) :: \
- "r3", "r4" , "r5" , "r6" , "r7" , "r8" , \
- "r9", "r10", "r11", "r12", "r13" );
-
-#endif /* MicroBlaze */
-
-#if defined(__tricore__)
-
-#define MULADDC_INIT \
- asm( "ld.a %%a2, %0 " :: "m" (s)); \
- asm( "ld.a %%a3, %0 " :: "m" (d)); \
- asm( "ld.w %%d4, %0 " :: "m" (c)); \
- asm( "ld.w %%d1, %0 " :: "m" (b)); \
- asm( "xor %d5, %d5 " );
-
-#define MULADDC_CORE \
- asm( "ld.w %d0, [%a2+] " ); \
- asm( "madd.u %e2, %e4, %d0, %d1 " ); \
- asm( "ld.w %d0, [%a3] " ); \
- asm( "addx %d2, %d2, %d0 " ); \
- asm( "addc %d3, %d3, 0 " ); \
- asm( "mov %d4, %d3 " ); \
- asm( "st.w [%a3+], %d2 " );
-
-#define MULADDC_STOP \
- asm( "st.w %0, %%d4 " : "=m" (c)); \
- asm( "st.a %0, %%a3 " : "=m" (d)); \
- asm( "st.a %0, %%a2 " : "=m" (s) :: \
- "d0", "d1", "e2", "d4", "a2", "a3" );
-
-#endif /* TriCore */
-
-#if defined(__arm__)
-
-#define MULADDC_INIT \
- asm( "ldr r0, %0 " :: "m" (s)); \
- asm( "ldr r1, %0 " :: "m" (d)); \
- asm( "ldr r2, %0 " :: "m" (c)); \
- asm( "ldr r3, %0 " :: "m" (b));
-
-#define MULADDC_CORE \
- asm( "ldr r4, [r0], #4 " ); \
- asm( "mov r5, #0 " ); \
- asm( "ldr r6, [r1] " ); \
- asm( "umlal r2, r5, r3, r4 " ); \
- asm( "adds r7, r6, r2 " ); \
- asm( "adc r2, r5, #0 " ); \
- asm( "str r7, [r1], #4 " );
-
-#define MULADDC_STOP \
- asm( "str r2, %0 " : "=m" (c)); \
- asm( "str r1, %0 " : "=m" (d)); \
- asm( "str r0, %0 " : "=m" (s) :: \
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" );
-
-#endif /* ARMv3 */
-
-#if defined(__alpha__)
-
-#define MULADDC_INIT \
- asm( "ldq $1, %0 " :: "m" (s)); \
- asm( "ldq $2, %0 " :: "m" (d)); \
- asm( "ldq $3, %0 " :: "m" (c)); \
- asm( "ldq $4, %0 " :: "m" (b));
-
-#define MULADDC_CORE \
- asm( "ldq $6, 0($1) " ); \
- asm( "addq $1, 8, $1 " ); \
- asm( "mulq $6, $4, $7 " ); \
- asm( "umulh $6, $4, $6 " ); \
- asm( "addq $7, $3, $7 " ); \
- asm( "cmpult $7, $3, $3 " ); \
- asm( "ldq $5, 0($2) " ); \
- asm( "addq $7, $5, $7 " ); \
- asm( "cmpult $7, $5, $5 " ); \
- asm( "stq $7, 0($2) " ); \
- asm( "addq $2, 8, $2 " ); \
- asm( "addq $6, $3, $3 " ); \
- asm( "addq $5, $3, $3 " );
-
-#define MULADDC_STOP \
- asm( "stq $3, %0 " : "=m" (c)); \
- asm( "stq $2, %0 " : "=m" (d)); \
- asm( "stq $1, %0 " : "=m" (s) :: \
- "$1", "$2", "$3", "$4", "$5", "$6", "$7" );
-
-#endif /* Alpha */
-
-#if defined(__mips__)
-
-#define MULADDC_INIT \
- asm( "lw $10, %0 " :: "m" (s)); \
- asm( "lw $11, %0 " :: "m" (d)); \
- asm( "lw $12, %0 " :: "m" (c)); \
- asm( "lw $13, %0 " :: "m" (b));
-
-#define MULADDC_CORE \
- asm( "lw $14, 0($10) " ); \
- asm( "multu $13, $14 " ); \
- asm( "addi $10, $10, 4 " ); \
- asm( "mflo $14 " ); \
- asm( "mfhi $9 " ); \
- asm( "addu $14, $12, $14 " ); \
- asm( "lw $15, 0($11) " ); \
- asm( "sltu $12, $14, $12 " ); \
- asm( "addu $15, $14, $15 " ); \
- asm( "sltu $14, $15, $14 " ); \
- asm( "addu $12, $12, $9 " ); \
- asm( "sw $15, 0($11) " ); \
- asm( "addu $12, $12, $14 " ); \
- asm( "addi $11, $11, 4 " );
-
-#define MULADDC_STOP \
- asm( "sw $12, %0 " : "=m" (c)); \
- asm( "sw $11, %0 " : "=m" (d)); \
- asm( "sw $10, %0 " : "=m" (s) :: \
- "$9", "$10", "$11", "$12", "$13", "$14", "$15" );
-
-#endif /* MIPS */
-#endif /* GNUC */
-
-#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
-
-#define MULADDC_INIT \
- __asm mov esi, s \
- __asm mov edi, d \
- __asm mov ecx, c \
- __asm mov ebx, b
-
-#define MULADDC_CORE \
- __asm lodsd \
- __asm mul ebx \
- __asm add eax, ecx \
- __asm adc edx, 0 \
- __asm add eax, [edi] \
- __asm adc edx, 0 \
- __asm mov ecx, edx \
- __asm stosd
-
-#if defined(POLARSSL_HAVE_SSE2)
-
-#define EMIT __asm _emit
-
-#define MULADDC_HUIT \
- EMIT 0x0F EMIT 0x6E EMIT 0xC9 \
- EMIT 0x0F EMIT 0x6E EMIT 0xC3 \
- EMIT 0x0F EMIT 0x6E EMIT 0x1F \
- EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
- EMIT 0x0F EMIT 0x6E EMIT 0x16 \
- EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
- EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \
- EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
- EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \
- EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
- EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \
- EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
- EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xDC \
- EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xEE \
- EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \
- EMIT 0x0F EMIT 0xD4 EMIT 0xFC \
- EMIT 0x0F EMIT 0x7E EMIT 0x0F \
- EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \
- EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
- EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
- EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \
- EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
- EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \
- EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
- EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \
- EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
- EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \
- EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xCD \
- EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \
- EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \
- EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xCF \
- EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \
- EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \
- EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
- EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \
- EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \
- EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xCC \
- EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \
- EMIT 0x0F EMIT 0xD4 EMIT 0xDD \
- EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \
- EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xCE \
- EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \
- EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
- EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \
- EMIT 0x83 EMIT 0xC7 EMIT 0x20 \
- EMIT 0x83 EMIT 0xC6 EMIT 0x20 \
- EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
- EMIT 0x0F EMIT 0x7E EMIT 0xC9
-
-#define MULADDC_STOP \
- EMIT 0x0F EMIT 0x77 \
- __asm mov c, ecx \
- __asm mov d, edi \
- __asm mov s, esi \
-
-#else
-
-#define MULADDC_STOP \
- __asm mov c, ecx \
- __asm mov d, edi \
- __asm mov s, esi \
-
-#endif /* SSE2 */
-#endif /* MSVC */
-
-#endif /* POLARSSL_HAVE_ASM */
-
-#if !defined(MULADDC_CORE)
-#if defined(POLARSSL_HAVE_LONGLONG)
-
-#define MULADDC_INIT \
-{ \
- t_dbl r; \
- t_int r0, r1;
-
-#define MULADDC_CORE \
- r = *(s++) * (t_dbl) b; \
- r0 = r; \
- r1 = r >> biL; \
- r0 += c; r1 += (r0 < c); \
- r0 += *d; r1 += (r0 < *d); \
- c = r1; *(d++) = r0;
-
-#define MULADDC_STOP \
-}
-
-#else
-#define MULADDC_INIT \
-{ \
- t_int s0, s1, b0, b1; \
- t_int r0, r1, rx, ry; \
- b0 = ( b << biH ) >> biH; \
- b1 = ( b >> biH );
-
-#define MULADDC_CORE \
- s0 = ( *s << biH ) >> biH; \
- s1 = ( *s >> biH ); s++; \
- rx = s0 * b1; r0 = s0 * b0; \
- ry = s1 * b0; r1 = s1 * b1; \
- r1 += ( rx >> biH ); \
- r1 += ( ry >> biH ); \
- rx <<= biH; ry <<= biH; \
- r0 += rx; r1 += (r0 < rx); \
- r0 += ry; r1 += (r0 < ry); \
- r0 += c; r1 += (r0 < c); \
- r0 += *d; r1 += (r0 < *d); \
- c = r1; *(d++) = r0;
-
-#define MULADDC_STOP \
-}
-
-#endif /* C (generic) */
-#endif /* C (longlong) */
-
-#endif /* bn_mul.h */
+++ /dev/null
-/**
- * \file config.h
- *
- * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
- *
- * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the names of PolarSSL or XySSL nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * This set of compile-time options may be used to enable
- * or disable features selectively, and reduce the global
- * memory footprint.
- */
-#ifndef POLARSSL_CONFIG_H
-#define POLARSSL_CONFIG_H
-
-#ifndef _CRT_SECURE_NO_DEPRECATE
-#define _CRT_SECURE_NO_DEPRECATE 1
-#endif
-
-/*
- * Uncomment if native integers are 8-bit wide.
- *
-#define POLARSSL_HAVE_INT8
- */
-
-/*
- * Uncomment if native integers are 16-bit wide.
- *
-#define POLARSSL_HAVE_INT16
- */
-
-/*
- * Uncomment if the compiler supports long long.
-#define POLARSSL_HAVE_LONGLONG
- */
-
-
-/*
- * Uncomment to enable the use of assembly code.
- */
-/* #define POLARSSL_HAVE_ASM */
-
-/*
- * Uncomment if the CPU supports SSE2 (IA-32 specific).
- *
-#define POLARSSL_HAVE_SSE2
- */
-
-/*
- * Enable all SSL/TLS debugging messages.
- */
-#define POLARSSL_DEBUG_MSG
-
-/*
- * Enable the checkup functions (*_self_test).
- */
-#define POLARSSL_SELF_TEST
-
-/*
- * Enable the prime-number generation code.
- */
-#define POLARSSL_GENPRIME
-
-/*
- * Uncomment this macro to store the AES tables in ROM.
- *
-#define POLARSSL_AES_ROM_TABLES
- */
-
-/*
- * Module: library/aes.c
- * Caller: library/ssl_tls.c
- *
- * This module enables the following ciphersuites:
- * SSL_RSA_AES_128_SHA
- * SSL_RSA_AES_256_SHA
- * SSL_EDH_RSA_AES_256_SHA
- */
-#define POLARSSL_AES_C
-
-/*
- * Module: library/arc4.c
- * Caller: library/ssl_tls.c
- *
- * This module enables the following ciphersuites:
- * SSL_RSA_RC4_128_MD5
- * SSL_RSA_RC4_128_SHA
- */
-#define POLARSSL_ARC4_C
-
-/*
- * Module: library/base64.c
- * Caller: library/x509parse.c
- *
- * This module is required for X.509 support.
- */
-#define POLARSSL_BASE64_C
-
-/*
- * Module: library/bignum.c
- * Caller: library/dhm.c
- * library/rsa.c
- * library/ssl_tls.c
- * library/x509parse.c
- *
- * This module is required for RSA and DHM support.
- */
-#define POLARSSL_BIGNUM_C
-
-/*
- * Module: library/camellia.c
- * Caller:
- *
- * This module enabled the following cipher suites:
- */
-#define POLARSSL_CAMELLIA_C
-
-/*
- * Module: library/certs.c
- * Caller:
- *
- * This module is used for testing (ssl_client/server).
- */
-#define POLARSSL_CERTS_C
-
-/*
- * Module: library/debug.c
- * Caller: library/ssl_cli.c
- * library/ssl_srv.c
- * library/ssl_tls.c
- *
- * This module provides debugging functions.
- */
-#define POLARSSL_DEBUG_C
-
-/*
- * Module: library/des.c
- * Caller: library/ssl_tls.c
- *
- * This module enables the following ciphersuites:
- * SSL_RSA_DES_168_SHA
- * SSL_EDH_RSA_DES_168_SHA
- */
-#define POLARSSL_DES_C
-
-/*
- * Module: library/dhm.c
- * Caller: library/ssl_cli.c
- * library/ssl_srv.c
- *
- * This module enables the following ciphersuites:
- * SSL_EDH_RSA_DES_168_SHA
- * SSL_EDH_RSA_AES_256_SHA
- */
-#define POLARSSL_DHM_C
-
-/*
- * Module: library/havege.c
- * Caller:
- *
- * This module enables the HAVEGE random number generator.
- */
-#define POLARSSL_HAVEGE_C
-
-/*
- * Module: library/md2.c
- * Caller: library/x509parse.c
- *
- * Uncomment to enable support for (rare) MD2-signed X.509 certs.
- *
-#define POLARSSL_MD2_C
- */
-
-/*
- * Module: library/md4.c
- * Caller: library/x509parse.c
- *
- * Uncomment to enable support for (rare) MD4-signed X.509 certs.
- *
-#define POLARSSL_MD4_C
- */
-
-/*
- * Module: library/md5.c
- * Caller: library/ssl_tls.c
- * library/x509parse.c
- *
- * This module is required for SSL/TLS and X.509.
- */
-#define POLARSSL_MD5_C
-
-/*
- * Module: library/net.c
- * Caller:
- *
- * This module provides TCP/IP networking routines.
- */
-#define POLARSSL_NET_C
-
-/*
- * Module: library/padlock.c
- * Caller: library/aes.c
- *
- * This modules adds support for the VIA PadLock on x86.
- */
-#define POLARSSL_PADLOCK_C
-
-/*
- * Module: library/rsa.c
- * Caller: library/ssl_cli.c
- * library/ssl_srv.c
- * library/ssl_tls.c
- * library/x509.c
- *
- * This module is required for SSL/TLS and MD5-signed certificates.
- */
-#define POLARSSL_RSA_C
-
-/*
- * Module: library/sha1.c
- * Caller: library/ssl_cli.c
- * library/ssl_srv.c
- * library/ssl_tls.c
- * library/x509parse.c
- *
- * This module is required for SSL/TLS and SHA1-signed certificates.
- */
-#define POLARSSL_SHA1_C
-
-/*
- * Module: library/sha2.c
- * Caller:
- *
- * This module adds support for SHA-224 and SHA-256.
- */
-#define POLARSSL_SHA2_C
-
-/*
- * Module: library/sha4.c
- * Caller:
- *
- * This module adds support for SHA-384 and SHA-512.
- */
-#define POLARSSL_SHA4_C
-
-/*
- * Module: library/ssl_cli.c
- * Caller:
- *
- * This module is required for SSL/TLS client support.
- */
-#define POLARSSL_SSL_CLI_C
-
-/*
- * Module: library/ssl_srv.c
- * Caller:
- *
- * This module is required for SSL/TLS server support.
- */
-#define POLARSSL_SSL_SRV_C
-
-/*
- * Module: library/ssl_tls.c
- * Caller: library/ssl_cli.c
- * library/ssl_srv.c
- *
- * This module is required for SSL/TLS.
- */
-#define POLARSSL_SSL_TLS_C
-
-/*
- * Module: library/timing.c
- * Caller: library/havege.c
- *
- * This module is used by the HAVEGE random number generator.
- */
-#define POLARSSL_TIMING_C
-
-/*
- * Module: library/x509parse.c
- * Caller: library/ssl_cli.c
- * library/ssl_srv.c
- * library/ssl_tls.c
- *
- * This module is required for X.509 certificate parsing.
- */
-#define POLARSSL_X509_PARSE_C
-
-/*
- * Module: library/x509_write.c
- * Caller:
- *
- * This module is required for X.509 certificate writing.
- */
-#define POLARSSL_X509_WRITE_C
-
-/*
- * Module: library/xtea.c
- * Caller:
- */
-#define POLARSSL_XTEA_C
-
-#endif /* config.h */
+++ /dev/null
-/**
- * \file rsa.h
- *
- * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
- *
- * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the names of PolarSSL or XySSL nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef POLARSSL_RSA_H
-#define POLARSSL_RSA_H
-
-#include "polarssl/bignum.h"
-
-#define POLARSSL_ERR_RSA_BAD_INPUT_DATA -0x0400
-#define POLARSSL_ERR_RSA_INVALID_PADDING -0x0410
-#define POLARSSL_ERR_RSA_KEY_GEN_FAILED -0x0420
-#define POLARSSL_ERR_RSA_KEY_CHECK_FAILED -0x0430
-#define POLARSSL_ERR_RSA_PUBLIC_FAILED -0x0440
-#define POLARSSL_ERR_RSA_PRIVATE_FAILED -0x0450
-#define POLARSSL_ERR_RSA_VERIFY_FAILED -0x0460
-#define POLARSSL_ERR_RSA_OUTPUT_TO_LARGE -0x0470
-
-/*
- * PKCS#1 constants
- */
-#define RSA_RAW 0
-#define RSA_MD2 2
-#define RSA_MD4 3
-#define RSA_MD5 4
-#define RSA_SHA1 5
-#define RSA_SHA256 6
-
-#define RSA_PUBLIC 0
-#define RSA_PRIVATE 1
-
-#define RSA_PKCS_V15 0
-#define RSA_PKCS_V21 1
-
-#define RSA_SIGN 1
-#define RSA_CRYPT 2
-
-/*
- * DigestInfo ::= SEQUENCE {
- * digestAlgorithm DigestAlgorithmIdentifier,
- * digest Digest }
- *
- * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
- *
- * Digest ::= OCTET STRING
- */
-#define ASN1_HASH_MDX \
- "\x30\x20\x30\x0C\x06\x08\x2A\x86\x48" \
- "\x86\xF7\x0D\x02\x00\x05\x00\x04\x10"
-
-#define ASN1_HASH_SHA1 \
- "\x30\x21\x30\x09\x06\x05\x2B\x0E\x03" \
- "\x02\x1A\x05\x00\x04\x14"
-
-/**
- * \brief RSA context structure
- */
-typedef struct
-{
- int ver; /*!< always 0 */
- int len; /*!< size(N) in chars */
-
- mpi N; /*!< public modulus */
- mpi E; /*!< public exponent */
-
- mpi D; /*!< private exponent */
- mpi P; /*!< 1st prime factor */
- mpi Q; /*!< 2nd prime factor */
- mpi DP; /*!< D % (P - 1) */
- mpi DQ; /*!< D % (Q - 1) */
- mpi QP; /*!< 1 / (Q % P) */
-
- mpi RN; /*!< cached R^2 mod N */
- mpi RP; /*!< cached R^2 mod P */
- mpi RQ; /*!< cached R^2 mod Q */
-
- int padding; /*!< 1.5 or OAEP/PSS */
- int hash_id; /*!< hash identifier */
- int (*f_rng)(void *); /*!< RNG function */
- void *p_rng; /*!< RNG parameter */
-}
-rsa_context;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \brief Initialize an RSA context
- *
- * \param ctx RSA context to be initialized
- * \param padding RSA_PKCS_V15 or RSA_PKCS_V21
- * \param hash_id RSA_PKCS_V21 hash identifier
- * \param f_rng RNG function
- * \param p_rng RNG parameter
- *
- * \note The hash_id parameter is actually ignored
- * when using RSA_PKCS_V15 padding.
- *
- * \note Currently (xyssl-0.8), RSA_PKCS_V21 padding
- * is not supported.
- */
-void rsa_init( rsa_context *ctx,
- int padding,
- int hash_id,
- int (*f_rng)(void *),
- void *p_rng );
-
-/**
- * \brief Generate an RSA keypair
- *
- * \param ctx RSA context that will hold the key
- * \param nbits size of the public key in bits
- * \param exponent public exponent (e.g., 65537)
- *
- * \note rsa_init() must be called beforehand to setup
- * the RSA context (especially f_rng and p_rng).
- *
- * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
- */
-int rsa_gen_key( rsa_context *ctx, int nbits, int exponent );
-
-/**
- * \brief Check a public RSA key
- *
- * \param ctx RSA context to be checked
- *
- * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
- */
-int rsa_check_pubkey( rsa_context *ctx );
-
-/**
- * \brief Check a private RSA key
- *
- * \param ctx RSA context to be checked
- *
- * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
- */
-int rsa_check_privkey( rsa_context *ctx );
-
-/**
- * \brief Do an RSA public key operation
- *
- * \param ctx RSA context
- * \param input input buffer
- * \param output output buffer
- *
- * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
- *
- * \note This function does NOT take care of message
- * padding. Also, be sure to set input[0] = 0.
- *
- * \note The input and output buffers must be large
- * enough (eg. 128 bytes if RSA-1024 is used).
- */
-int rsa_public( rsa_context *ctx,
- unsigned char *input,
- unsigned char *output );
-
-/**
- * \brief Do an RSA private key operation
- *
- * \param ctx RSA context
- * \param input input buffer
- * \param output output buffer
- *
- * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
- *
- * \note The input and output buffers must be large
- * enough (eg. 128 bytes if RSA-1024 is used).
- */
-int rsa_private( rsa_context *ctx,
- unsigned char *input,
- unsigned char *output );
-
-/**
- * \brief Add the message padding, then do an RSA operation
- *
- * \param ctx RSA context
- * \param mode RSA_PUBLIC or RSA_PRIVATE
- * \param ilen contains the the plaintext length
- * \param input buffer holding the data to be encrypted
- * \param output buffer that will hold the ciphertext
- *
- * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
- *
- * \note The output buffer must be as large as the size
- * of ctx->N (eg. 128 bytes if RSA-1024 is used).
- */
-int rsa_pkcs1_encrypt( rsa_context *ctx,
- int mode, int ilen,
- unsigned char *input,
- unsigned char *output );
-
-/**
- * \brief Do an RSA operation, then remove the message padding
- *
- * \param ctx RSA context
- * \param mode RSA_PUBLIC or RSA_PRIVATE
- * \param input buffer holding the encrypted data
- * \param output buffer that will hold the plaintext
- * \param olen will contain the plaintext length
- * \param output_max_len maximum length of the output buffer
- *
- * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
- *
- * \note The output buffer must be as large as the size
- * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
- * an error is thrown.
- */
-int rsa_pkcs1_decrypt( rsa_context *ctx,
- int mode, int *olen,
- unsigned char *input,
- unsigned char *output,
- int output_max_len);
-
-/**
- * \brief Do a private RSA to sign a message digest
- *
- * \param ctx RSA context
- * \param mode RSA_PUBLIC or RSA_PRIVATE
- * \param hash_id RSA_RAW, RSA_MD{2,4,5} or RSA_SHA{1,256}
- * \param hashlen message digest length (for RSA_RAW only)
- * \param hash buffer holding the message digest
- * \param sig buffer that will hold the ciphertext
- *
- * \return 0 if the signing operation was successful,
- * or an POLARSSL_ERR_RSA_XXX error code
- *
- * \note The "sig" buffer must be as large as the size
- * of ctx->N (eg. 128 bytes if RSA-1024 is used).
- */
-int rsa_pkcs1_sign( rsa_context *ctx,
- int mode,
- int hash_id,
- int hashlen,
- unsigned char *hash,
- unsigned char *sig );
-
-/**
- * \brief Do a public RSA and check the message digest
- *
- * \param ctx points to an RSA public key
- * \param mode RSA_PUBLIC or RSA_PRIVATE
- * \param hash_id RSA_RAW, RSA_MD{2,4,5} or RSA_SHA{1,256}
- * \param hashlen message digest length (for RSA_RAW only)
- * \param hash buffer holding the message digest
- * \param sig buffer holding the ciphertext
- *
- * \return 0 if the verify operation was successful,
- * or an POLARSSL_ERR_RSA_XXX error code
- *
- * \note The "sig" buffer must be as large as the size
- * of ctx->N (eg. 128 bytes if RSA-1024 is used).
- */
-int rsa_pkcs1_verify( rsa_context *ctx,
- int mode,
- int hash_id,
- int hashlen,
- unsigned char *hash,
- unsigned char *sig );
-
-/**
- * \brief Free the components of an RSA key
- */
-void rsa_free( rsa_context *ctx );
-
-/**
- * \brief Checkup routine
- *
- * \return 0 if successful, or 1 if the test failed
- */
-int rsa_self_test( int verbose );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* rsa.h */
+++ /dev/null
-/**
- * \file sha1.h
- *
- * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
- *
- * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the names of PolarSSL or XySSL nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef POLARSSL_SHA1_H
-#define POLARSSL_SHA1_H
-
-/**
- * \brief SHA-1 context structure
- */
-typedef struct
-{
- unsigned long total[2]; /*!< number of bytes processed */
- unsigned long state[5]; /*!< intermediate digest state */
- unsigned char buffer[64]; /*!< data block being processed */
-
- unsigned char ipad[64]; /*!< HMAC: inner padding */
- unsigned char opad[64]; /*!< HMAC: outer padding */
-}
-sha1_context;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \brief SHA-1 context setup
- *
- * \param ctx context to be initialized
- */
-void sha1_starts( sha1_context *ctx );
-
-/**
- * \brief SHA-1 process buffer
- *
- * \param ctx SHA-1 context
- * \param input buffer holding the data
- * \param ilen length of the input data
- */
-void sha1_update( sha1_context *ctx, unsigned char *input, int ilen );
-
-/**
- * \brief SHA-1 final digest
- *
- * \param ctx SHA-1 context
- * \param output SHA-1 checksum result
- */
-void sha1_finish( sha1_context *ctx, unsigned char output[20] );
-
-/**
- * \brief Output = SHA-1( input buffer )
- *
- * \param input buffer holding the data
- * \param ilen length of the input data
- * \param output SHA-1 checksum result
- */
-void sha1( unsigned char *input, int ilen, unsigned char output[20] );
-
-/**
- * \brief Output = SHA-1( file contents )
- *
- * \param path input file name
- * \param output SHA-1 checksum result
- *
- * \return 0 if successful, 1 if fopen failed,
- * or 2 if fread failed
- */
-int sha1_file( char *path, unsigned char output[20] );
-
-/**
- * \brief SHA-1 HMAC context setup
- *
- * \param ctx HMAC context to be initialized
- * \param key HMAC secret key
- * \param keylen length of the HMAC key
- */
-void sha1_hmac_starts( sha1_context *ctx, unsigned char *key, int keylen );
-
-/**
- * \brief SHA-1 HMAC process buffer
- *
- * \param ctx HMAC context
- * \param input buffer holding the data
- * \param ilen length of the input data
- */
-void sha1_hmac_update( sha1_context *ctx, unsigned char *input, int ilen );
-
-/**
- * \brief SHA-1 HMAC final digest
- *
- * \param ctx HMAC context
- * \param output SHA-1 HMAC checksum result
- */
-void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] );
-
-/**
- * \brief Output = HMAC-SHA-1( hmac key, input buffer )
- *
- * \param key HMAC secret key
- * \param keylen length of the HMAC key
- * \param input buffer holding the data
- * \param ilen length of the input data
- * \param output HMAC-SHA-1 result
- */
-void sha1_hmac( unsigned char *key, int keylen,
- unsigned char *input, int ilen,
- unsigned char output[20] );
-
-/**
- * \brief Checkup routine
- *
- * \return 0 if successful, or 1 if the test failed
- */
-int sha1_self_test( int verbose );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* sha1.h */
+++ /dev/null
-/**
- * \file timing.h
- *
- * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
- *
- * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the names of PolarSSL or XySSL nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef POLARSSL_TIMING_H
-#define POLARSSL_TIMING_H
-
-/**
- * \brief timer structure
- */
-struct hr_time
-{
- unsigned char opaque[32];
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern int alarmed;
-
-/**
- * \brief Return the CPU cycle counter value
- */
-unsigned long hardclock( void );
-
-/**
- * \brief Return the elapsed time in milliseconds
- *
- * \param val points to a timer structure
- * \param reset if set to 1, the timer is restarted
- */
-unsigned long get_timer( struct hr_time *val, int reset );
-
-/**
- * \brief Setup an alarm clock
- *
- * \param seconds delay before the "alarmed" flag is set
- */
-void set_alarm( int seconds );
-
-/**
- * \brief Sleep for a certain amount of time
- */
-void m_sleep( int milliseconds );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* timing.h */
+++ /dev/null
-/**
- * \file x509.h
- *
- * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
- *
- * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the names of PolarSSL or XySSL nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef POLARSSL_X509_H
-#define POLARSSL_X509_H
-
-#include "polarssl/rsa.h"
-
-#define POLARSSL_ERR_ASN1_OUT_OF_DATA -0x0014
-#define POLARSSL_ERR_ASN1_UNEXPECTED_TAG -0x0016
-#define POLARSSL_ERR_ASN1_INVALID_LENGTH -0x0018
-#define POLARSSL_ERR_ASN1_LENGTH_MISMATCH -0x001A
-#define POLARSSL_ERR_ASN1_INVALID_DATA -0x001C
-
-#define POLARSSL_ERR_X509_FEATURE_UNAVAILABLE -0x0020
-#define POLARSSL_ERR_X509_CERT_INVALID_PEM -0x0040
-#define POLARSSL_ERR_X509_CERT_INVALID_FORMAT -0x0060
-#define POLARSSL_ERR_X509_CERT_INVALID_VERSION -0x0080
-#define POLARSSL_ERR_X509_CERT_INVALID_SERIAL -0x00A0
-#define POLARSSL_ERR_X509_CERT_INVALID_ALG -0x00C0
-#define POLARSSL_ERR_X509_CERT_INVALID_NAME -0x00E0
-#define POLARSSL_ERR_X509_CERT_INVALID_DATE -0x0100
-#define POLARSSL_ERR_X509_CERT_INVALID_PUBKEY -0x0120
-#define POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE -0x0140
-#define POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS -0x0160
-#define POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION -0x0180
-#define POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG -0x01A0
-#define POLARSSL_ERR_X509_CERT_UNKNOWN_PK_ALG -0x01C0
-#define POLARSSL_ERR_X509_CERT_SIG_MISMATCH -0x01E0
-#define POLARSSL_ERR_X509_CERT_VERIFY_FAILED -0x0200
-#define POLARSSL_ERR_X509_KEY_INVALID_PEM -0x0220
-#define POLARSSL_ERR_X509_KEY_INVALID_VERSION -0x0240
-#define POLARSSL_ERR_X509_KEY_INVALID_FORMAT -0x0260
-#define POLARSSL_ERR_X509_KEY_INVALID_ENC_IV -0x0280
-#define POLARSSL_ERR_X509_KEY_UNKNOWN_ENC_ALG -0x02A0
-#define POLARSSL_ERR_X509_KEY_PASSWORD_REQUIRED -0x02C0
-#define POLARSSL_ERR_X509_KEY_PASSWORD_MISMATCH -0x02E0
-#define POLARSSL_ERR_X509_POINT_ERROR -0x0300
-#define POLARSSL_ERR_X509_VALUE_TO_LENGTH -0x0320
-
-#define BADCERT_EXPIRED 1
-#define BADCERT_REVOKED 2
-#define BADCERT_CN_MISMATCH 4
-#define BADCERT_NOT_TRUSTED 8
-
-/*
- * DER constants
- */
-#define ASN1_BOOLEAN 0x01
-#define ASN1_INTEGER 0x02
-#define ASN1_BIT_STRING 0x03
-#define ASN1_OCTET_STRING 0x04
-#define ASN1_NULL 0x05
-#define ASN1_OID 0x06
-#define ASN1_UTF8_STRING 0x0C
-#define ASN1_SEQUENCE 0x10
-#define ASN1_SET 0x11
-#define ASN1_PRINTABLE_STRING 0x13
-#define ASN1_T61_STRING 0x14
-#define ASN1_IA5_STRING 0x16
-#define ASN1_UTC_TIME 0x17
-#define ASN1_UNIVERSAL_STRING 0x1C
-#define ASN1_BMP_STRING 0x1E
-#define ASN1_PRIMITIVE 0x00
-#define ASN1_CONSTRUCTED 0x20
-#define ASN1_CONTEXT_SPECIFIC 0x80
-
-/*
- * various object identifiers
- */
-#define X520_COMMON_NAME 3
-#define X520_COUNTRY 6
-#define X520_LOCALITY 7
-#define X520_STATE 8
-#define X520_ORGANIZATION 10
-#define X520_ORG_UNIT 11
-#define PKCS9_EMAIL 1
-
-#define X509_OUTPUT_DER 0x01
-#define X509_OUTPUT_PEM 0x02
-#define PEM_LINE_LENGTH 72
-#define X509_ISSUER 0x01
-#define X509_SUBJECT 0x02
-
-#define OID_X520 "\x55\x04"
-#define OID_CN "\x55\x04\x03"
-#define OID_PKCS1 "\x2A\x86\x48\x86\xF7\x0D\x01\x01"
-#define OID_PKCS1_RSA "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01"
-#define OID_PKCS1_RSA_SHA "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05"
-#define OID_PKCS9 "\x2A\x86\x48\x86\xF7\x0D\x01\x09"
-#define OID_PKCS9_EMAIL "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01"
-
-/*
- * Structures for parsing X.509 certificates
- */
-typedef struct _x509_buf
-{
- int tag;
- int len;
- unsigned char *p;
-}
-x509_buf;
-
-typedef struct _x509_name
-{
- x509_buf oid;
- x509_buf val;
- struct _x509_name *next;
-}
-x509_name;
-
-typedef struct _x509_time
-{
- int year, mon, day;
- int hour, min, sec;
-}
-x509_time;
-
-typedef struct _x509_cert
-{
- x509_buf raw;
- x509_buf tbs;
-
- int version;
- x509_buf serial;
- x509_buf sig_oid1;
-
- x509_buf issuer_raw;
- x509_buf subject_raw;
-
- x509_name issuer;
- x509_name subject;
-
- x509_time valid_from;
- x509_time valid_to;
-
- x509_buf pk_oid;
- rsa_context rsa;
-
- x509_buf issuer_id;
- x509_buf subject_id;
- x509_buf v3_ext;
-
- int ca_istrue;
- int max_pathlen;
-
- x509_buf sig_oid2;
- x509_buf sig;
-
- struct _x509_cert *next;
-}
-x509_cert;
-
-/*
- * Structures for writing X.509 certificates
- */
-typedef struct _x509_node
-{
- unsigned char *data;
- unsigned char *p;
- unsigned char *end;
-
- size_t len;
-}
-x509_node;
-
-typedef struct _x509_raw
-{
- x509_node raw;
- x509_node tbs;
-
- x509_node version;
- x509_node serial;
- x509_node tbs_signalg;
- x509_node issuer;
- x509_node validity;
- x509_node subject;
- x509_node subpubkey;
-
- x509_node signalg;
- x509_node sign;
-}
-x509_raw;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \brief Parse one or more certificates and add them
- * to the chained list
- *
- * \param chain points to the start of the chain
- * \param buf buffer holding the certificate data
- * \param buflen size of the buffer
- *
- * \return 0 if successful, or a specific X509 error code
- */
-int x509parse_crt( x509_cert *crt, unsigned char *buf, int buflen );
-
-/**
- * \brief Load one or more certificates and add them
- * to the chained list
- *
- * \param chain points to the start of the chain
- * \param path filename to read the certificates from
- *
- * \return 0 if successful, or a specific X509 error code
- */
-int x509parse_crtfile( x509_cert *crt, char *path );
-
-/**
- * \brief Parse a private RSA key
- *
- * \param rsa RSA context to be initialized
- * \param buf input buffer
- * \param buflen size of the buffer
- * \param pwd password for decryption (optional)
- * \param pwdlen size of the password
- *
- * \return 0 if successful, or a specific X509 error code
- */
-int x509parse_key( rsa_context *rsa,
- unsigned char *buf, int buflen,
- unsigned char *pwd, int pwdlen );
-
-/**
- * \brief Load and parse a private RSA key
- *
- * \param rsa RSA context to be initialized
- * \param path filename to read the private key from
- * \param pwd password to decrypt the file (can be NULL)
- *
- * \return 0 if successful, or a specific X509 error code
- */
-int x509parse_keyfile( rsa_context *rsa, char *path, char *password );
-
-/**
- * \brief Store the certificate DN in printable form into buf;
- * no more than (end - buf) characters will be written.
- */
-int x509parse_dn_gets( char *buf, char *end, x509_name *dn );
-
-/**
- * \brief Returns an informational string about the
- * certificate.
- */
-char *x509parse_cert_info( char *prefix, x509_cert *crt );
-
-/**
- * \brief Return 0 if the certificate is still valid,
- * or BADCERT_EXPIRED
- */
-int x509parse_expired( x509_cert *crt );
-
-/**
- * \brief Verify the certificate signature
- *
- * \param crt a certificate to be verified
- * \param trust_ca the trusted CA chain
- * \param cn expected Common Name (can be set to
- * NULL if the CN must not be verified)
- * \param flags result of the verification
- *
- * \return 0 if successful or POLARSSL_ERR_X509_SIG_VERIFY_FAILED,
- * in which case *flags will have one or more of
- * the following values set:
- * BADCERT_EXPIRED --
- * BADCERT_REVOKED --
- * BADCERT_CN_MISMATCH --
- * BADCERT_NOT_TRUSTED
- *
- * \note TODO: add two arguments, depth and crl
- */
-int x509parse_verify( x509_cert *crt,
- x509_cert *trust_ca,
- char *cn, int *flags );
-
-/**
- * \brief Unallocate all certificate data
- */
-void x509_free( x509_cert *crt );
-
-/**
- * \brief Checkup routine
- *
- * \return 0 if successful, or 1 if the test failed
- */
-int x509_self_test( int verbose );
-
-/**
- * \brief Write a certificate info file
- *
- * \param chain points to the raw certificate data
- * \param path filename to write the certificate to
- * \param format X509_OUTPUT_DER or X509_OUTPUT_PEM
- *
- * \return 0 if successful, or a specific X509 error code
- */
-int x509write_crtfile( x509_raw *chain,
- unsigned char *path,
- int format );
-
-/**
- * \brief Write a certificate signing request message format file
- *
- * \param chain points to the raw certificate (with x509write_create_csr) data
- * \param path filename to write the certificate to
- * \param format X509_OUTPUT_DER or X509_OUTPUT_PEM
- *
- * \return 0 if successful, or a specific X509 error code
- */
-int x509write_csrfile( x509_raw *chain,
- unsigned char *path,
- int format );
-
-/*
- * \brief Write a private RSA key into a file
- *
- * \param rsa points to an RSA key
- * \param path filename to write the key to
- * \param format X509_OUTPUT_DER or X509_OUTPUT_PEM
- *
- * \return 0 if successful, or a specific X509 error code
- */
-int x509write_keyfile( rsa_context *rsa,
- char *path,
- int format );
-
-/**
- * \brief Add a public key to certificate
- *
- * \param chain points to the raw certificate data
- * \param pubkey points to an RSA key
- *
- * \return 0 if successful, or a specific X509 error code
- */
-int x509write_add_pubkey( x509_raw *chain, rsa_context *pubkey );
-
-/**
- * \brief Create x509 subject/issuer field to raw certificate
- * from string or CA cert. Make string NULL if you will
- * use the CA copy function or make CA NULL then used
- * the string parse.
- *
- * \param chain points to the raw certificate data
- * \param names a string that can hold (separete with ";"):
- * CN=CommonName
- * -- O=Organization
- * -- OU=OrgUnit
- * -- ST=State
- * -- L=Locality
- * -- R=Email
- * -- C=Country
- * . Make that NULL if you didn't need that.
- * \param flag flag is X509_ISSUER or X509_SUBJECT that defined
- * where change
- * \param ca the certificate for copy data. Make that NULL if you
- * didn't need that.
- * \param ca_flag set the ca field from copy to crt
- *
- * \return 0 if successful, or a specific X509 error code
- */
-int x509write_add_customize ( x509_raw *crt,
- unsigned char *names,
- int flag,
- x509_cert *ca,
- int ca_flag );
-
-/**
-* \brief Add x509 issuer field
-*
-* \param chain points to the raw certificate data
-* \param issuer a string holding (separete with ";"):
-* CN=CommonName
-* -- O=Organization
-* -- OU=OrgUnit
-* -- ST=State
-* -- L=Locality
-* -- R=Email
-* -- C=Country
-* . Set this to NULL if not needed.
-* \return 0 if successful, or a specific X509 error code
-*/
-int x509write_add_issuer( x509_raw *crt, unsigned char *issuer);
-
-/**
- * \brief Add x509 subject field
- *
- * \param chain points to the raw certificate data
- * \param subject a string holding (separete with ";"):
- * CN=CommonName
- * -- O=Organization
- * -- OU=OrgUnit
- * -- ST=State
- * -- L=Locality
- * -- R=Email
- * -- C=Country
- * . Set this to NULL if not needed.
- * \return 0 if successful, or a specific X509 error code
- */
-int x509write_add_subject( x509_raw *crt, unsigned char *subject);
-
-/**
-* \brief Copy x509 issuer field from another certificate
-*
-* \param chain points to the raw certificate data
-* \param from_crt the certificate whose issuer is to be copied.
-* \return 0 if successful, or a specific X509 error code
-*/
-int x509write_copy_issuer(x509_raw *crt, x509_cert *from_crt);
-
-/**
-* \brief Copy x509 subject field from another certificate
-*
-* \param chain points to the raw certificate data
-* \param from_crt the certificate whose subject is to be copied.
-* \return 0 if successful, or a specific X509 error code
-*/
-int x509write_copy_subject(x509_raw *crt, x509_cert *from_crt);
-
-/**
-* \brief Copy x509 issuer field from the subject of another certificate
-*
-* \param chain points to the raw certificate data
-* \param from_crt the certificate whose subject is to be copied.
-* \return 0 if successful, or a specific X509 error code
-*/
-int x509write_copy_issuer_from_subject(x509_raw *crt, x509_cert *from_crt);
-
-/**
-* \brief Copy x509 subject field from the issuer of another certificate
-*
-* \param chain points to the raw certificate data
-* \param from_crt the certificate whose issuer is to be copied.
-* \return 0 if successful, or a specific X509 error code
-*/
-int x509write_copy_subject_from_issuer(x509_raw *crt, x509_cert *from_crt);
-
-/**
- * \brief Create x509 validity time in UTC
- *
- * \param chain points to the raw certificate data
- * \param before valid not before in format YYYY-MM-DD hh:mm:ss
- * \param after valid not after in format YYYY-MM-DD hh:mm:ss
- *
- * \return 0 if successful, or a specific X509 error code
- */
-int x509write_add_validity( x509_raw *crt,
- unsigned char *before,
- unsigned char *after );
-
-/**
- * \brief Create a self-signed certificate
- *
- * \param chain points to the raw certificate data
- * \param rsa a private key to sign the certificate
- *
- * \return 0 if successful, or a specific X509 error code
- */
-int x509write_create_selfsign( x509_raw *crt, rsa_context *raw );
-
-/**
- * \brief Create a certificate
- *
- * \param chain points to the raw certificate data
- * \param rsa a private key to sign the certificate
- *
- * \return 0 if successful, or a specific X509 error code
- */
-int x509write_create_sign( x509_raw *crt, rsa_context *raw );
-
-/**
- * \brief Create a certificate signing request
- *
- * \param chain points to the raw certificate data. Didn't use the
- * same chain that u have use for certificate.
- * \param privkey a rsa private key
- *
- * \return 0 if successful, or a specific X509 error code
- */
-int x509write_create_csr( x509_raw *chain, rsa_context *privkey );
-
-/**
- * \brief Serialize an rsa key into DER
- *
- * \param rsa a rsa key for output
- * \param node a x509 node for write into
- *
- * \return 0 if successful, or a specific X509 error code
- */
-int x509write_serialize_key( rsa_context *rsa, x509_node *node );
-
-/**
- * \brief Unallocate all raw certificate data
- */
-void x509write_free_raw( x509_raw *crt );
-
-/**
- * \brief Allocate all raw certificate data
- */
-void x509write_init_raw( x509_raw *crt );
-
-/**
- * \brief Unallocate all node certificate data
- */
-void x509write_free_node( x509_node *crt_node );
-
-/**
- * \brief Allocate all node certificate data
- */
-void x509write_init_node( x509_node *crt_node );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* x509.h */
+++ /dev/null
-/*
- * px5g - Embedded x509 key and certificate generator based on PolarSSL
- *
- * Copyright (C) 2009 Steven Barth <steven@midlink.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License, version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include "polarssl/bignum.h"
-#include "polarssl/x509.h"
-#include "polarssl/rsa.h"
-
-#define PX5G_VERSION "0.1"
-#define PX5G_COPY "Copyright (c) 2009 Steven Barth <steven@midlink.org>"
-#define PX5G_LICENSE "Licensed under the GNU Lesser General Public License v2.1"
-
-static int urandom_fd;
-
-static int _urandom(void *ctx)
-{
- int ret;
- read(urandom_fd, &ret, sizeof(ret));
- return ret;
-}
-
-
-int rsakey(char **arg) {
- 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);
- }
-
- rsa_init(&rsa, RSA_PKCS_V15, 0, _urandom, NULL);
-
- 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) {
- 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++;
- }
-
- rsa_init(&rsa, RSA_PKCS_V15, 0, _urandom, NULL);
- 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[]) {
- urandom_fd = open("/dev/urandom", O_RDONLY);
- if (urandom_fd < 0) {
- perror("open(/dev/urandom)");
- return 1;
- }
-
- 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;
-}
PKG_NAME:=px5g
PKG_RELEASE:=4
PKG_LICENSE:=LGPL-2.1
-PKG_BUILD_DIR:=$(BUILD_DIR)/px5g
+PKG_BUILD_DIR:=$(BUILD_DIR)/px5g-$(BUILD_VARIANT)
PKG_USE_MIPS16:=0
+PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
+
include $(INCLUDE_DIR)/package.mk
define Package/px5g-mbedtls
CATEGORY:=Utilities
SUBMENU:=Encryption
TITLE:=X.509 certificate generator (using mbedtls)
- MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
DEPENDS:=+libmbedtls
PROVIDES:=px5g
+ VARIANT:=mbedtls
endef
define Package/px5g-mbedtls/description
and PEM format for use with stunnel, uhttpd and others.
endef
+define Package/px5g-standalone
+ SECTION:=utils
+ CATEGORY:=Utilities
+ SUBMENU:=Encryption
+ TITLE:=X.509 certificate generator (standalone)
+ VARIANT:=standalone
+endef
+Package/px5g-standalone/description = $(Package/px5g-mbedtls/description)
+
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
endef
TARGET_LDFLAGS := -lmbedtls -lmbedx509 -lmbedcrypto
+ifeq ($(BUILD_VARIANT),standalone)
+ TARGET_LDFLAGS := -Wl,-Bstatic $(TARGET_LDFLAGS) -Wl,-Bdynamic
+endif
+
+TARGET_CFLAGS += -Wl,--gc-sections
+
define Build/Compile
$(TARGET_CC) $(TARGET_CFLAGS) -o $(PKG_BUILD_DIR)/px5g px5g.c $(TARGET_LDFLAGS)
endef
$(INSTALL_BIN) $(PKG_BUILD_DIR)/px5g $(1)/usr/sbin/px5g
endef
+Package/px5g-standalone/install = $(Package/px5g-mbedtls/install)
+
$(eval $(call BuildPackage,px5g-mbedtls))
+$(eval $(call BuildPackage,px5g-standalone))