/*
* RFC 1521 base64 encoding/decoding
*
- * Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org>
- * All rights reserved.
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
- * Joined copyright on original XySSL code with: Christophe Devine
+ * All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
/* $Cambridge: exim/src/src/pdkim/base64.c,v 1.3 2009/12/07 13:05:07 tom Exp $ */
+
#include "base64.h"
static const unsigned char base64_enc_map[64] =
* Encode a buffer into base64 format
*/
int base64_encode( unsigned char *dst, int *dlen,
- unsigned char *src, int slen )
+ const unsigned char *src, int slen )
{
int i, n;
int C1, C2, C3;
* Decode a base64-formatted buffer
*/
int base64_decode( unsigned char *dst, int *dlen,
- unsigned char *src, int slen )
+ const unsigned char *src, int slen )
{
int i, j, n;
unsigned long x;
/**
* \file base64.h
*
- * Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org>
- * All rights reserved.
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
- * Joined copyright on original XySSL code with: Christophe Devine
+ * All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* required buffer size in *dlen
*/
int base64_encode( unsigned char *dst, int *dlen,
- unsigned char *src, int slen );
+ const unsigned char *src, int slen );
/**
* \brief Decode a base64-formatted buffer
* required buffer size in *dlen
*/
int base64_decode( unsigned char *dst, int *dlen,
- unsigned char *src, int slen );
+ const unsigned char *src, int slen );
#ifdef __cplusplus
}
/*
* Multi-precision integer library
*
- * Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org>
- * All rights reserved.
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
- * Joined copyright on original XySSL code with: Christophe Devine
+ * All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
/* $Cambridge: exim/src/src/pdkim/bignum.c,v 1.3 2009/12/07 13:05:07 tom Exp $ */
-
#include "bignum.h"
#include "bn_mul.h"
/*
* Copy the contents of Y into X
*/
-int mpi_copy( mpi *X, mpi *Y )
+int mpi_copy( mpi *X, const mpi *Y )
{
int ret, i;
/*
* Return the number of least significant bits
*/
-int mpi_lsb( mpi *X )
+int mpi_lsb( const mpi *X )
{
int i, j, count = 0;
/*
* Return the number of most significant bits
*/
-int mpi_msb( mpi *X )
+int mpi_msb( const mpi *X )
{
int i, j;
/*
* Return the total size in bytes
*/
-int mpi_size( mpi *X )
+int mpi_size( const mpi *X )
{
return( ( mpi_msb( X ) + 7 ) >> 3 );
}
/*
* Import from an ASCII string
*/
-int mpi_read_string( mpi *X, int radix, char *s )
+int mpi_read_string( mpi *X, int radix, const char *s )
{
- int ret, i, j, n;
+ int ret, i, j, n, slen;
t_int d;
mpi T;
mpi_init( &T, NULL );
+ slen = strlen( s );
+
if( radix == 16 )
{
- n = BITS_TO_LIMBS( strlen( s ) << 2 );
+ n = BITS_TO_LIMBS( slen << 2 );
MPI_CHK( mpi_grow( X, n ) );
MPI_CHK( mpi_lset( X, 0 ) );
- for( i = strlen( s ) - 1, j = 0; i >= 0; i--, j++ )
+ for( i = slen - 1, j = 0; i >= 0; i--, j++ )
{
if( i == 0 && s[i] == '-' )
{
{
MPI_CHK( mpi_lset( X, 0 ) );
- for( i = 0; i < (int) strlen( s ); i++ )
+ for( i = 0; i < slen; i++ )
{
if( i == 0 && s[i] == '-' )
{
/*
* Export into an ASCII string
*/
-int mpi_write_string( mpi *X, int radix, char *s, int *slen )
+int mpi_write_string( const mpi *X, int radix, char *s, int *slen )
{
int ret = 0, n;
char *p;
/*
* Write X into an opened file (or stdout if fout == NULL)
*/
-int mpi_write_file( const char *p, mpi *X, int radix, FILE *fout )
+int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout )
{
int n, ret;
size_t slen;
size_t plen;
- char s[1024];
+ char s[2048];
n = sizeof( s );
memset( s, 0, n );
/*
* Import X from unsigned binary data, big endian
*/
-int mpi_read_binary( mpi *X, unsigned char *buf, int buflen )
+int mpi_read_binary( mpi *X, const unsigned char *buf, int buflen )
{
int ret, i, j, n;
/*
* Export X into unsigned binary data, big endian
*/
-int mpi_write_binary( mpi *X, unsigned char *buf, int buflen )
+int mpi_write_binary( const mpi *X, unsigned char *buf, int buflen )
{
int i, j, n;
/*
* Compare unsigned values
*/
-int mpi_cmp_abs( mpi *X, mpi *Y )
+int mpi_cmp_abs( const mpi *X, const mpi *Y )
{
int i, j;
/*
* Compare signed values
*/
-int mpi_cmp_mpi( mpi *X, mpi *Y )
+int mpi_cmp_mpi( const mpi *X, const mpi *Y )
{
int i, j;
/*
* Compare signed values
*/
-int mpi_cmp_int( mpi *X, int z )
+int mpi_cmp_int( const mpi *X, int z )
{
mpi Y;
t_int p[1];
/*
* Unsigned addition: X = |A| + |B| (HAC 14.7)
*/
-int mpi_add_abs( mpi *X, mpi *A, mpi *B )
+int mpi_add_abs( mpi *X, const mpi *A, const mpi *B )
{
int ret, i, j;
t_int *o, *p, c;
if( X == B )
{
- mpi *T = A; A = X; B = T;
+ const mpi *T = A; A = X; B = T;
}
if( X != A )
/*
* Unsigned substraction: X = |A| - |B| (HAC 14.9)
*/
-int mpi_sub_abs( mpi *X, mpi *A, mpi *B )
+int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B )
{
mpi TB;
int ret, n;
/*
* Signed addition: X = A + B
*/
-int mpi_add_mpi( mpi *X, mpi *A, mpi *B )
+int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B )
{
int ret, s = A->s;
/*
* Signed substraction: X = A - B
*/
-int mpi_sub_mpi( mpi *X, mpi *A, mpi *B )
+int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B )
{
int ret, s = A->s;
/*
* Signed addition: X = A + b
*/
-int mpi_add_int( mpi *X, mpi *A, int b )
+int mpi_add_int( mpi *X, const mpi *A, int b )
{
mpi _B;
t_int p[1];
/*
* Signed substraction: X = A - b
*/
-int mpi_sub_int( mpi *X, mpi *A, int b )
+int mpi_sub_int( mpi *X, const mpi *A, int b )
{
mpi _B;
t_int p[1];
/*
* Baseline multiplication: X = A * B (HAC 14.12)
*/
-int mpi_mul_mpi( mpi *X, mpi *A, mpi *B )
+int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B )
{
int ret, i, j;
mpi TA, TB;
/*
* Baseline multiplication: X = A * b
*/
-int mpi_mul_int( mpi *X, mpi *A, t_int b )
+int mpi_mul_int( mpi *X, const mpi *A, t_int b )
{
mpi _B;
t_int p[1];
/*
* Division by mpi: A = Q * B + R (HAC 14.20)
*/
-int mpi_div_mpi( mpi *Q, mpi *R, mpi *A, mpi *B )
+int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
{
int ret, i, n, t, k;
mpi X, Y, Z, T1, T2;
* 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 )
+int mpi_div_int( mpi *Q, mpi *R, const mpi *A, int b )
{
mpi _B;
t_int p[1];
/*
* Modulo: R = A mod B
*/
-int mpi_mod_mpi( mpi *R, mpi *A, mpi *B )
+int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B )
{
int ret;
/*
* Modulo: r = A mod b
*/
-int mpi_mod_int( t_int *r, mpi *A, int b )
+int mpi_mod_int( t_int *r, const mpi *A, int b )
{
int i;
t_int x, y, z;
/*
* Fast Montgomery initialization (thanks to Tom St Denis)
*/
-static void mpi_montg_init( t_int *mm, mpi *N )
+static void mpi_montg_init( t_int *mm, const mpi *N )
{
t_int x, m0 = N->p[0];
/*
* 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 )
+static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_int mm, const mpi *T )
{
int i, n, m;
t_int u0, u1, *d;
/*
* Montgomery reduction: A = A * R^-1 mod N
*/
-static void mpi_montred( mpi *A, mpi *N, t_int mm, mpi *T )
+static void mpi_montred( mpi *A, const mpi *N, t_int mm, const mpi *T )
{
t_int z = 1;
mpi U;
/*
* 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 mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
{
int ret, i, j, wsize, wbits;
int bufsize, nblimbs, nbits;
/*
* Greatest common divisor: G = gcd(A, B) (HAC 14.54)
*/
-int mpi_gcd( mpi *G, mpi *A, mpi *B )
+int mpi_gcd( mpi *G, const mpi *A, const mpi *B )
{
int ret, lz, lzt;
mpi TG, TA, TB;
/*
* Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
*/
-int mpi_inv_mod( mpi *X, mpi *A, mpi *N )
+int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N )
{
int ret;
mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
* W = |X| - 1
* R = W >> lsb( W )
*/
- s = mpi_lsb( &W );
MPI_CHK( mpi_sub_int( &W, X, 1 ) );
+ s = mpi_lsb( &W );
MPI_CHK( mpi_copy( &R, &W ) );
MPI_CHK( mpi_shift_r( &R, s ) );
/**
* \file bignum.h
*
- * Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org>
- * All rights reserved.
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
- * Joined copyright on original XySSL code with: Christophe Devine
+ * All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* \return 0 if successful,
* 1 if memory allocation failed
*/
-int mpi_copy( mpi *X, mpi *Y );
+int mpi_copy( mpi *X, const mpi *Y );
/**
* \brief Swap the contents of X and Y
*
* \param X MPI to use
*/
-int mpi_lsb( mpi *X );
+int mpi_lsb( const mpi *X );
/**
* \brief Return the number of most significant bits
*
* \param X MPI to use
*/
-int mpi_msb( mpi *X );
+int mpi_msb( const mpi *X );
/**
* \brief Return the total size in bytes
*
* \param X MPI to use
*/
-int mpi_size( mpi *X );
+int mpi_size( const mpi *X );
/**
* \brief Import from an ASCII string
*
* \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
*/
-int mpi_read_string( mpi *X, int radix, char *s );
+int mpi_read_string( mpi *X, int radix, const char *s );
/**
* \brief Export into an ASCII string
* \param s String buffer
* \param slen String buffer size
*
- * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
+ * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code.
+ * *slen is always updated to reflect the amount
+ * of data that has (or would have) been written.
*
* \note Call this function with *slen = 0 to obtain the
* minimum required buffer size in *slen.
*/
-int mpi_write_string( mpi *X, int radix, char *s, int *slen );
+int mpi_write_string( const mpi *X, int radix, char *s, int *slen );
/**
* \brief Read X from an opened file
*
* \note Set fout == NULL to print X on the console.
*/
-int mpi_write_file( const char *p, mpi *X, int radix, FILE *fout );
+int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout );
/**
* \brief Import X from unsigned binary data, big endian
* \return 0 if successful,
* 1 if memory allocation failed
*/
-int mpi_read_binary( mpi *X, unsigned char *buf, int buflen );
+int mpi_read_binary( mpi *X, const unsigned char *buf, int buflen );
/**
* \brief Export X into unsigned binary data, big endian
* \return 0 if successful,
* POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough
*/
-int mpi_write_binary( mpi *X, unsigned char *buf, int buflen );
+int mpi_write_binary( const mpi *X, unsigned char *buf, int buflen );
/**
* \brief Left-shift: X <<= count
* -1 if |X| is lesser than |Y| or
* 0 if |X| is equal to |Y|
*/
-int mpi_cmp_abs( mpi *X, mpi *Y );
+int mpi_cmp_abs( const mpi *X, const mpi *Y );
/**
* \brief Compare signed values
* -1 if X is lesser than Y or
* 0 if X is equal to Y
*/
-int mpi_cmp_mpi( mpi *X, mpi *Y );
+int mpi_cmp_mpi( const mpi *X, const mpi *Y );
/**
* \brief Compare signed values
* -1 if X is lesser than z or
* 0 if X is equal to z
*/
-int mpi_cmp_int( mpi *X, int z );
+int mpi_cmp_int( const 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 );
+int mpi_add_abs( mpi *X, const mpi *A, const 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 );
+int mpi_sub_abs( mpi *X, const mpi *A, const 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 );
+int mpi_add_mpi( mpi *X, const mpi *A, const 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 );
+int mpi_sub_mpi( mpi *X, const mpi *A, const 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 );
+int mpi_add_int( mpi *X, const 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 );
+int mpi_sub_int( mpi *X, const 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 );
+int mpi_mul_mpi( mpi *X, const mpi *A, const 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 );
+int mpi_mul_int( mpi *X, const mpi *A, t_int b );
/**
* \brief Division by mpi: A = Q * B + R
*
* \note Either Q or R can be NULL.
*/
-int mpi_div_mpi( mpi *Q, mpi *R, mpi *A, mpi *B );
+int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B );
/**
* \brief Division by int: A = Q * b + R
*
* \note Either Q or R can be NULL.
*/
-int mpi_div_int( mpi *Q, mpi *R, mpi *A, int b );
+int mpi_div_int( mpi *Q, mpi *R, const mpi *A, int b );
/**
* \brief Modulo: R = A mod B
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0,
* POLARSSL_ERR_MPI_NEGATIVE_VALUE if B < 0
*/
-int mpi_mod_mpi( mpi *R, mpi *A, mpi *B );
+int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B );
/**
* \brief Modulo: r = A mod b
*
- * \param a Destination t_int
+ * \param r Destination t_int
* \param A Left-hand MPI
* \param b Integer to divide by
*
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0,
* POLARSSL_ERR_MPI_NEGATIVE_VALUE if b < 0
*/
-int mpi_mod_int( t_int *r, mpi *A, int b );
+int mpi_mod_int( t_int *r, const mpi *A, int b );
/**
* \brief Sliding-window exponentiation: X = A^E mod N
* 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 );
+int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR );
/**
* \brief Greatest common divisor: G = gcd(A, B)
* \return 0 if successful,
* 1 if memory allocation failed
*/
-int mpi_gcd( mpi *G, mpi *A, mpi *B );
+int mpi_gcd( mpi *G, const mpi *A, const mpi *B );
/**
* \brief Modular inverse: X = A^-1 mod N
* 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 );
+int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N );
/**
* \brief Miller-Rabin primality test
/**
* \file bn_mul.h
*
- * Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org>
- * All rights reserved.
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
- * Joined copyright on original XySSL code with: Christophe Devine
+ * All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
if (ctx->mode == PDKIM_MODE_SIGN) {
rsa_context rsa;
- rsa_init(&rsa,RSA_PKCS_V15,0,NULL,NULL);
+ rsa_init(&rsa,RSA_PKCS_V15,0);
/* Perform private key operation */
if (rsa_parse_key(&rsa, (unsigned char *)sig->rsa_privkey,
rsa_context rsa;
char *dns_txt_name, *dns_txt_reply;
- rsa_init(&rsa,RSA_PKCS_V15,0,NULL,NULL);
+ rsa_init(&rsa,RSA_PKCS_V15,0);
dns_txt_name = malloc(PDKIM_DNS_TXT_MAX_NAMELEN);
if (dns_txt_name == NULL) return PDKIM_ERR_OOM;
/*
* The RSA public-key cryptosystem
*
- * Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org>
- * All rights reserved.
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
- * Joined copyright on original XySSL code with: Christophe Devine
+ * All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include <stdio.h>
+
/* *************** begin copy from x509parse.c ********************/
/*
* ASN.1 DER decoding routines
*/
static int asn1_get_len( unsigned char **p,
- unsigned char *end,
+ const unsigned char *end,
int *len )
{
if( ( end - *p ) < 1 )
}
static int asn1_get_tag( unsigned char **p,
- unsigned char *end,
+ const unsigned char *end,
int *len, int tag )
{
if( ( end - *p ) < 1 )
}
static int asn1_get_int( unsigned char **p,
- unsigned char *end,
+ const unsigned char *end,
int *val )
{
int ret, len;
}
static int asn1_get_mpi( unsigned char **p,
- unsigned char *end,
+ const unsigned char *end,
mpi *X )
{
int ret, len;
+
/*
* Initialize an RSA context
*/
void rsa_init( rsa_context *ctx,
int padding,
- int hash_id,
- int (*f_rng)(void *),
- void *p_rng )
+ int hash_id )
{
memset( ctx, 0, sizeof( rsa_context ) );
ctx->padding = padding;
ctx->hash_id = hash_id;
+}
+
+#if defined(POLARSSL_GENPRIME)
+
+/*
+ * Generate an RSA keypair
+ */
+int rsa_gen_key( rsa_context *ctx,
+ int (*f_rng)(void *),
+ void *p_rng,
+ int nbits, int exponent )
+{
+ int ret;
+ mpi P1, Q1, H, G;
+
+ if( f_rng == NULL || nbits < 128 || exponent < 3 )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ mpi_init( &P1, &Q1, &H, &G, NULL );
+
+ /*
+ * find primes P and Q with Q < P so that:
+ * GCD( E, (P-1)*(Q-1) ) == 1
+ */
+ MPI_CHK( mpi_lset( &ctx->E, exponent ) );
+
+ do
+ {
+ MPI_CHK( mpi_gen_prime( &ctx->P, ( nbits + 1 ) >> 1, 0,
+ f_rng, p_rng ) );
+
+ MPI_CHK( mpi_gen_prime( &ctx->Q, ( nbits + 1 ) >> 1, 0,
+ f_rng, p_rng ) );
+
+ if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
+ mpi_swap( &ctx->P, &ctx->Q );
+
+ if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
+ continue;
- ctx->f_rng = f_rng;
- ctx->p_rng = p_rng;
+ 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 )
+int rsa_check_pubkey( const rsa_context *ctx )
{
if( !ctx->N.p || !ctx->E.p )
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
/*
* Check a private RSA key
*/
-int rsa_check_privkey( rsa_context *ctx )
+int rsa_check_privkey( const rsa_context *ctx )
{
int ret;
- mpi PQ, DE, P1, Q1, H, I, G;
+ mpi PQ, DE, P1, Q1, H, I, G, G2, L1, L2;
if( ( ret = rsa_check_pubkey( ctx ) ) != 0 )
return( ret );
if( !ctx->P.p || !ctx->Q.p || !ctx->D.p )
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
- mpi_init( &PQ, &DE, &P1, &Q1, &H, &I, &G, NULL );
+ mpi_init( &PQ, &DE, &P1, &Q1, &H, &I, &G, &G2, &L1, &L2, NULL );
MPI_CHK( mpi_mul_mpi( &PQ, &ctx->P, &ctx->Q ) );
MPI_CHK( mpi_mul_mpi( &DE, &ctx->D, &ctx->E ) );
MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
- MPI_CHK( mpi_mod_mpi( &I, &DE, &H ) );
MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) );
+ MPI_CHK( mpi_gcd( &G2, &P1, &Q1 ) );
+ MPI_CHK( mpi_div_mpi( &L1, &L2, &H, &G2 ) );
+ MPI_CHK( mpi_mod_mpi( &I, &DE, &L1 ) );
+
+ /*
+ * Check for a valid PKCS1v2 private key
+ */
if( mpi_cmp_mpi( &PQ, &ctx->N ) == 0 &&
+ mpi_cmp_int( &L2, 0 ) == 0 &&
mpi_cmp_int( &I, 1 ) == 0 &&
mpi_cmp_int( &G, 1 ) == 0 )
{
- mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, NULL );
+ mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, &G2, &L1, &L2, NULL );
return( 0 );
}
+
cleanup:
- mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, NULL );
+ mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, &G2, &L1, &L2, NULL );
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED | ret );
}
* Do an RSA public key operation
*/
int rsa_public( rsa_context *ctx,
- unsigned char *input,
+ const unsigned char *input,
unsigned char *output )
{
int ret, olen;
* Do an RSA private key operation
*/
int rsa_private( rsa_context *ctx,
- unsigned char *input,
+ const unsigned char *input,
unsigned char *output )
{
int ret, olen;
* Add the message padding, then do an RSA operation
*/
int rsa_pkcs1_encrypt( rsa_context *ctx,
+ int (*f_rng)(void *),
+ void *p_rng,
int mode, int ilen,
- unsigned char *input,
+ const unsigned char *input,
unsigned char *output )
{
int nb_pad, olen;
{
case RSA_PKCS_V15:
- if( ilen < 0 || olen < ilen + 11 )
+ if( ilen < 0 || olen < ilen + 11 || f_rng == NULL )
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
nb_pad = olen - 3 - ilen;
while( nb_pad-- > 0 )
{
+ int rng_dl = 100;
+
do {
- *p = (unsigned char) rand();
- } while( *p == 0 );
+ *p = (unsigned char) f_rng( p_rng );
+ } while( *p == 0 && --rng_dl );
+
+ // Check if RNG failed to generate data
+ //
+ if( rng_dl == 0 )
+ return POLARSSL_ERR_RSA_RNG_FAILED;
+
p++;
}
*p++ = 0;
*/
int rsa_pkcs1_decrypt( rsa_context *ctx,
int mode, int *olen,
- unsigned char *input,
+ const unsigned char *input,
unsigned char *output,
int output_max_len)
{
int mode,
int hash_id,
int hashlen,
- unsigned char *hash,
+ const unsigned char *hash,
unsigned char *sig )
{
int nb_pad, olen;
int mode,
int hash_id,
int hashlen,
- unsigned char *hash,
+ const unsigned char *hash,
unsigned char *sig )
{
int ret, len, siglen;
&ctx->E, &ctx->N, NULL );
}
+
+/* PDKIM code (not copied from polarssl) */
/*
* Parse a public RSA key
/**
* \file rsa.h
*
- * Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org>
- * All rights reserved.
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
- * Joined copyright on original XySSL code with: Christophe Devine
+ * All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#define POLARSSL_ERR_RSA_PRIVATE_FAILED -0x0450
#define POLARSSL_ERR_RSA_VERIFY_FAILED -0x0460
#define POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE -0x0470
+#define POLARSSL_ERR_RSA_RNG_FAILED -0x0480
/* *************** begin copy from x509.h ************************/
/*
#define ASN1_T61_STRING 0x14
#define ASN1_IA5_STRING 0x16
#define ASN1_UTC_TIME 0x17
+#define ASN1_GENERALIZED_TIME 0x18
#define ASN1_UNIVERSAL_STRING 0x1C
#define ASN1_BMP_STRING 0x1E
#define ASN1_PRIMITIVE 0x00
#define ASN1_CONSTRUCTED 0x20
#define ASN1_CONTEXT_SPECIFIC 0x80
-
/* *************** end copy from x509.h ************************/
/*
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;
* \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
+ * \note Currently, 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 );
+ int hash_id);
/**
* \brief Generate an RSA keypair
*
* \param ctx RSA context that will hold the key
+ * \param f_rng RNG function
+ * \param p_rng RNG parameter
* \param nbits size of the public key in bits
* \param exponent public exponent (e.g., 65537)
*
* \note rsa_init() must be called beforehand to setup
- * the RSA context (especially f_rng and p_rng).
+ * the RSA context.
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*/
-int rsa_gen_key( rsa_context *ctx, int nbits, int exponent );
+int rsa_gen_key( rsa_context *ctx,
+ int (*f_rng)(void *),
+ void *p_rng,
+ int nbits, int exponent );
/**
* \brief Check a public RSA key
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*/
-int rsa_check_pubkey( rsa_context *ctx );
+int rsa_check_pubkey( const rsa_context *ctx );
/**
* \brief Check a private RSA key
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*/
-int rsa_check_privkey( rsa_context *ctx );
+int rsa_check_privkey( const rsa_context *ctx );
/**
* \brief Do an RSA public key operation
* enough (eg. 128 bytes if RSA-1024 is used).
*/
int rsa_public( rsa_context *ctx,
- unsigned char *input,
+ const unsigned char *input,
unsigned char *output );
/**
* enough (eg. 128 bytes if RSA-1024 is used).
*/
int rsa_private( rsa_context *ctx,
- unsigned char *input,
+ const unsigned char *input,
unsigned char *output );
/**
* \brief Add the message padding, then do an RSA operation
*
* \param ctx RSA context
+ * \param f_rng RNG function
+ * \param p_rng RNG parameter
* \param mode RSA_PUBLIC or RSA_PRIVATE
* \param ilen contains the plaintext length
* \param input buffer holding the data to be encrypted
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
*/
int rsa_pkcs1_encrypt( rsa_context *ctx,
+ int (*f_rng)(void *),
+ void *p_rng,
int mode, int ilen,
- unsigned char *input,
+ const unsigned char *input,
unsigned char *output );
/**
*/
int rsa_pkcs1_decrypt( rsa_context *ctx,
int mode, int *olen,
- unsigned char *input,
+ const unsigned char *input,
unsigned char *output,
int output_max_len );
int mode,
int hash_id,
int hashlen,
- unsigned char *hash,
+ const unsigned char *hash,
unsigned char *sig );
/**
*
* \param ctx points to an RSA public key
* \param mode RSA_PUBLIC or RSA_PRIVATE
- * \param hash_id SIG_RSA_RAW, RSA_MD{2,4,5} or RSA_SHA{1,256}
+ * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
* \param hashlen message digest length (for SIG_RSA_RAW only)
* \param hash buffer holding the message digest
* \param sig buffer holding the ciphertext
int mode,
int hash_id,
int hashlen,
- unsigned char *hash,
+ const unsigned char *hash,
unsigned char *sig );
/**
*/
void rsa_free( rsa_context *ctx );
+/* PDKIM declarations (not part of polarssl) */
int rsa_parse_public_key( rsa_context *rsa, unsigned char *buf, int buflen );
-
int rsa_parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
unsigned char *pwd, int pwdlen );
+
#ifdef __cplusplus
}
#endif
/*
* FIPS-180-1 compliant SHA-1 implementation
*
- * Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org>
- * All rights reserved.
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
- * Joined copyright on original XySSL code with: Christophe Devine
+ * All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
ctx->state[4] = 0xC3D2E1F0;
}
-static void sha1_process( sha1_context *ctx, unsigned char data[64] )
+static void sha1_process( sha1_context *ctx, const unsigned char data[64] )
{
unsigned long temp, W[16], A, B, C, D, E;
/*
* SHA-1 process buffer
*/
-void sha1_update( sha1_context *ctx, unsigned char *input, int ilen )
+void sha1_update( sha1_context *ctx, const unsigned char *input, int ilen )
{
int fill;
unsigned long left;
/*
* output = SHA-1( input buffer )
*/
-void sha1( unsigned char *input, int ilen, unsigned char output[20] )
+void sha1( const unsigned char *input, int ilen, unsigned char output[20] )
{
sha1_context ctx;
/*
* output = SHA-1( file contents )
*/
-int sha1_file( char *path, unsigned char output[20] )
+int sha1_file( const char *path, unsigned char output[20] )
{
FILE *f;
size_t n;
/*
* SHA-1 HMAC context setup
*/
-void sha1_hmac_starts( sha1_context *ctx, unsigned char *key, int keylen )
+void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key, int keylen )
{
int i;
unsigned char sum[20];
/*
* SHA-1 HMAC process buffer
*/
-void sha1_hmac_update( sha1_context *ctx, unsigned char *input, int ilen )
+void sha1_hmac_update( sha1_context *ctx, const unsigned char *input, int ilen )
{
sha1_update( ctx, input, ilen );
}
memset( tmpbuf, 0, sizeof( tmpbuf ) );
}
+/*
+ * SHA1 HMAC context reset
+ */
+void sha1_hmac_reset( sha1_context *ctx )
+{
+ sha1_starts( ctx );
+ sha1_update( ctx, ctx->ipad, 64 );
+}
+
/*
* output = HMAC-SHA-1( hmac key, input buffer )
*/
-void sha1_hmac( unsigned char *key, int keylen,
- unsigned char *input, int ilen,
+void sha1_hmac( const unsigned char *key, int keylen,
+ const unsigned char *input, int ilen,
unsigned char output[20] )
{
sha1_context ctx;
/**
* \file sha1.h
*
- * Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org>
- * All rights reserved.
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
- * Joined copyright on original XySSL code with: Christophe Devine
+ * All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
/**
* \brief SHA-1 context structure
*/
-
#ifndef HAVE_SHA1_CONTEXT
#define HAVE_SHA1_CONTEXT
typedef struct sha1_context sha1_context;
unsigned char opad[64]; /*!< HMAC: outer padding */
};
-
#ifdef __cplusplus
extern "C" {
#endif
* \param input buffer holding the data
* \param ilen length of the input data
*/
-void sha1_update( sha1_context *ctx, unsigned char *input, int ilen );
+void sha1_update( sha1_context *ctx, const unsigned char *input, int ilen );
/**
* \brief SHA-1 final digest
* \param ilen length of the input data
* \param output SHA-1 checksum result
*/
-void sha1( unsigned char *input, int ilen, unsigned char output[20] );
+void sha1( const unsigned char *input, int ilen, unsigned char output[20] );
/**
* \brief Output = SHA-1( file contents )
* \return 0 if successful, 1 if fopen failed,
* or 2 if fread failed
*/
-int sha1_file( char *path, unsigned char output[20] );
+int sha1_file( const char *path, unsigned char output[20] );
/**
* \brief SHA-1 HMAC context setup
* \param key HMAC secret key
* \param keylen length of the HMAC key
*/
-void sha1_hmac_starts( sha1_context *ctx, unsigned char *key, int keylen );
+void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key, int keylen );
/**
* \brief SHA-1 HMAC process buffer
* \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 );
+void sha1_hmac_update( sha1_context *ctx, const unsigned char *input, int ilen );
/**
* \brief SHA-1 HMAC final digest
*/
void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] );
+/**
+ * \brief SHA-1 HMAC context reset
+ *
+ * \param ctx HMAC context to be reset
+ */
+void sha1_hmac_reset( sha1_context *ctx );
+
/**
* \brief Output = HMAC-SHA-1( hmac key, input buffer )
*
* \param 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,
+void sha1_hmac( const unsigned char *key, int keylen,
+ const unsigned char *input, int ilen,
unsigned char output[20] );
#ifdef __cplusplus
/*
* FIPS-180-2 compliant SHA-256 implementation
*
- * Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org>
- * All rights reserved.
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
- * Joined copyright on original XySSL code with: Christophe Devine
+ * All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
ctx->is224 = is224;
}
-static void sha2_process( sha2_context *ctx, unsigned char data[64] )
+static void sha2_process( sha2_context *ctx, const unsigned char data[64] )
{
unsigned long temp1, temp2, W[64];
unsigned long A, B, C, D, E, F, G, H;
/*
* SHA-256 process buffer
*/
-void sha2_update( sha2_context *ctx, unsigned char *input, int ilen )
+void sha2_update( sha2_context *ctx, const unsigned char *input, int ilen )
{
int fill;
unsigned long left;
/*
* output = SHA-256( input buffer )
*/
-void sha2( unsigned char *input, int ilen,
+void sha2( const unsigned char *input, int ilen,
unsigned char output[32], int is224 )
{
sha2_context ctx;
/*
* output = SHA-256( file contents )
*/
-int sha2_file( char *path, unsigned char output[32], int is224 )
+int sha2_file( const char *path, unsigned char output[32], int is224 )
{
FILE *f;
size_t n;
/*
* SHA-256 HMAC context setup
*/
-void sha2_hmac_starts( sha2_context *ctx, unsigned char *key, int keylen,
+void sha2_hmac_starts( sha2_context *ctx, const unsigned char *key, int keylen,
int is224 )
{
int i;
/*
* SHA-256 HMAC process buffer
*/
-void sha2_hmac_update( sha2_context *ctx, unsigned char *input, int ilen )
+void sha2_hmac_update( sha2_context *ctx, const unsigned char *input, int ilen )
{
sha2_update( ctx, input, ilen );
}
memset( tmpbuf, 0, sizeof( tmpbuf ) );
}
+/*
+ * SHA-256 HMAC context reset
+ */
+void sha2_hmac_reset( sha2_context *ctx )
+{
+ sha2_starts( ctx, ctx->is224 );
+ sha2_update( ctx, ctx->ipad, 64 );
+}
+
/*
* output = HMAC-SHA-256( hmac key, input buffer )
*/
-void sha2_hmac( unsigned char *key, int keylen,
- unsigned char *input, int ilen,
+void sha2_hmac( const unsigned char *key, int keylen,
+ const unsigned char *input, int ilen,
unsigned char output[32], int is224 )
{
sha2_context ctx;
/**
* \file sha2.h
*
- * Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org>
- * All rights reserved.
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
- * Joined copyright on original XySSL code with: Christophe Devine
+ * All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* \param input buffer holding the data
* \param ilen length of the input data
*/
-void sha2_update( sha2_context *ctx, unsigned char *input, int ilen );
+void sha2_update( sha2_context *ctx, const unsigned char *input, int ilen );
/**
* \brief SHA-256 final digest
* \param output SHA-224/256 checksum result
* \param is224 0 = use SHA256, 1 = use SHA224
*/
-void sha2( unsigned char *input, int ilen,
+void sha2( const unsigned char *input, int ilen,
unsigned char output[32], int is224 );
/**
* \return 0 if successful, 1 if fopen failed,
* or 2 if fread failed
*/
-int sha2_file( char *path, unsigned char output[32], int is224 );
+int sha2_file( const char *path, unsigned char output[32], int is224 );
/**
* \brief SHA-256 HMAC context setup
* \param keylen length of the HMAC key
* \param is224 0 = use SHA256, 1 = use SHA224
*/
-void sha2_hmac_starts( sha2_context *ctx, unsigned char *key, int keylen,
+void sha2_hmac_starts( sha2_context *ctx, const unsigned char *key, int keylen,
int is224 );
/**
* \param input buffer holding the data
* \param ilen length of the input data
*/
-void sha2_hmac_update( sha2_context *ctx, unsigned char *input, int ilen );
+void sha2_hmac_update( sha2_context *ctx, const unsigned char *input, int ilen );
/**
* \brief SHA-256 HMAC final digest
*/
void sha2_hmac_finish( sha2_context *ctx, unsigned char output[32] );
+/**
+ * \brief SHA-256 HMAC context reset
+ *
+ * \param ctx HMAC context to be reset
+ */
+void sha2_hmac_reset( sha2_context *ctx );
+
/**
* \brief Output = HMAC-SHA-256( hmac key, input buffer )
*
* \param output HMAC-SHA-224/256 result
* \param is224 0 = use SHA256, 1 = use SHA224
*/
-void sha2_hmac( unsigned char *key, int keylen,
- unsigned char *input, int ilen,
+void sha2_hmac( const unsigned char *key, int keylen,
+ const unsigned char *input, int ilen,
unsigned char output[32], int is224 );
#ifdef __cplusplus