- RSASSA-PSS verification now properly handles salt lengths other than hlen

This commit is contained in:
Paul Bakker 2011-03-25 13:58:48 +00:00
parent fbc4a45f15
commit 53019ae6f7
2 changed files with 125 additions and 11 deletions

View file

@ -580,7 +580,7 @@ int rsa_pkcs1_sign( rsa_context *ctx,
unsigned char salt[POLARSSL_MD_MAX_SIZE]; unsigned char salt[POLARSSL_MD_MAX_SIZE];
const md_info_t *md_info; const md_info_t *md_info;
md_context_t md_ctx; md_context_t md_ctx;
int i, hlen, msb, offset = 0; int i, slen, hlen, msb, offset = 0;
#else #else
(void) f_rng; (void) f_rng;
(void) p_rng; (void) p_rng;
@ -733,6 +733,8 @@ int rsa_pkcs1_sign( rsa_context *ctx,
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
hlen = md_get_size( md_info ); hlen = md_get_size( md_info );
slen = hlen;
memset( sig, 0, olen ); memset( sig, 0, olen );
memset( &md_ctx, 0, sizeof( md_context_t ) ); memset( &md_ctx, 0, sizeof( md_context_t ) );
@ -740,9 +742,9 @@ int rsa_pkcs1_sign( rsa_context *ctx,
msb = mpi_msb( &ctx->N ) - 1; msb = mpi_msb( &ctx->N ) - 1;
// Generate salt of length hlen // Generate salt of length slen
// //
for( i = 0; i < hlen; ++i ) for( i = 0; i < slen; ++i )
salt[i] = (unsigned char) f_rng( p_rng ); salt[i] = (unsigned char) f_rng( p_rng );
// Note: EMSA-PSS encoding is over the length of N - 1 bits // Note: EMSA-PSS encoding is over the length of N - 1 bits
@ -750,15 +752,15 @@ int rsa_pkcs1_sign( rsa_context *ctx,
msb = mpi_msb( &ctx->N ) - 1; msb = mpi_msb( &ctx->N ) - 1;
p += olen - hlen * 2 - 2; p += olen - hlen * 2 - 2;
*p++ = 0x01; *p++ = 0x01;
memcpy( p, salt, hlen ); memcpy( p, salt, slen );
p += hlen; p += slen;
// Generate H = Hash( M' ) // Generate H = Hash( M' )
// //
md_starts( &md_ctx ); md_starts( &md_ctx );
md_update( &md_ctx, p, 8 ); md_update( &md_ctx, p, 8 );
md_update( &md_ctx, hash, hashlen ); md_update( &md_ctx, hash, hashlen );
md_update( &md_ctx, salt, hlen ); md_update( &md_ctx, salt, slen );
md_finish( &md_ctx, p ); md_finish( &md_ctx, p );
// Compensate for boundary condition when applying mask // Compensate for boundary condition when applying mask
@ -805,7 +807,7 @@ int rsa_pkcs1_verify( rsa_context *ctx,
unsigned char zeros[8]; unsigned char zeros[8];
const md_info_t *md_info; const md_info_t *md_info;
md_context_t md_ctx; md_context_t md_ctx;
int hlen, msb; int slen, hlen, msb;
#endif #endif
siglen = ctx->len; siglen = ctx->len;
@ -935,6 +937,8 @@ int rsa_pkcs1_verify( rsa_context *ctx,
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
hlen = md_get_size( md_info ); hlen = md_get_size( md_info );
slen = siglen - hlen - 1;
memset( &md_ctx, 0, sizeof( md_context_t ) ); memset( &md_ctx, 0, sizeof( md_context_t ) );
memset( zeros, 0, 8 ); memset( zeros, 0, 8 );
@ -967,15 +971,17 @@ int rsa_pkcs1_verify( rsa_context *ctx,
if( *p++ != 0x01 ) if( *p++ != 0x01 )
return( POLARSSL_ERR_RSA_INVALID_PADDING ); return( POLARSSL_ERR_RSA_INVALID_PADDING );
slen -= p - buf;
// Generate H = Hash( M' ) // Generate H = Hash( M' )
// //
md_starts( &md_ctx ); md_starts( &md_ctx );
md_update( &md_ctx, zeros, 8 ); md_update( &md_ctx, zeros, 8 );
md_update( &md_ctx, hash, hashlen ); md_update( &md_ctx, hash, hashlen );
md_update( &md_ctx, p, hlen ); md_update( &md_ctx, p, slen );
md_finish( &md_ctx, p ); md_finish( &md_ctx, p );
if( memcmp( p, p + hlen, hlen ) == 0 ) if( memcmp( p, p + slen, hlen ) == 0 )
return( 0 ); return( 0 );
else else
return( POLARSSL_ERR_RSA_VERIFY_FAILED ); return( POLARSSL_ERR_RSA_VERIFY_FAILED );

View file

@ -1827,8 +1827,6 @@ int x509parse_key( rsa_context *rsa, const unsigned char *key, int keylen,
#endif #endif
end = p + keylen; end = p + keylen;
memset( rsa, 0, sizeof( rsa_context ) );
/* /*
* RSAPrivateKey ::= SEQUENCE { * RSAPrivateKey ::= SEQUENCE {
* version Version, * version Version,
@ -1941,6 +1939,116 @@ int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
return( ret ); return( ret );
} }
/*
* Parse a public RSA key
*/
int x509parse_public_key( rsa_context *rsa, const unsigned char *key, int keylen )
{
int ret, len;
unsigned char *p, *end;
x509_buf alg_oid;
#if defined(POLARSSL_PEM_C)
pem_context pem;
pem_init( &pem );
ret = pem_read_buffer( &pem,
"-----BEGIN PUBLIC KEY-----",
"-----END PUBLIC KEY-----",
key, NULL, 0, &len );
if( ret == 0 )
{
/*
* Was PEM encoded
*/
keylen = pem.buflen;
}
else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
{
pem_free( &pem );
return( ret );
}
p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
#else
p = (unsigned char *) key;
#endif
end = p + keylen;
/*
* PublicKeyInfo ::= SEQUENCE {
* algorithm AlgorithmIdentifier,
* PublicKey BIT STRING
* }
*
* AlgorithmIdentifier ::= SEQUENCE {
* algorithm OBJECT IDENTIFIER,
* parameters ANY DEFINED BY algorithm OPTIONAL
* }
*
* RSAPublicKey ::= SEQUENCE {
* modulus INTEGER, -- n
* publicExponent INTEGER -- e
* }
*/
if( ( ret = asn1_get_tag( &p, end, &len,
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
{
#if defined(POLARSSL_PEM_C)
pem_free( &pem );
#endif
rsa_free( rsa );
return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
}
if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
{
#if defined(POLARSSL_PEM_C)
pem_free( &pem );
#endif
rsa_free( rsa );
return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
}
if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
{
#if defined(POLARSSL_PEM_C)
pem_free( &pem );
#endif
rsa_free( rsa );
return( ret );
}
rsa->len = mpi_size( &rsa->N );
#if defined(POLARSSL_PEM_C)
pem_free( &pem );
#endif
return( 0 );
}
/*
* Load and parse a public RSA key
*/
int x509parse_public_keyfile( rsa_context *rsa, const char *path )
{
int ret;
size_t n;
unsigned char *buf;
if ( load_file( path, &buf, &n ) )
return( 1 );
ret = x509parse_public_key( rsa, buf, (int) n );
memset( buf, 0, n + 1 );
free( buf );
return( ret );
}
/* /*
* Parse DHM parameters * Parse DHM parameters
*/ */