diff --git a/ChangeLog b/ChangeLog index 7df0e7c69..23e59dccd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,8 @@ Features Changes * x509_crt_info() now prints information about parsed extensions as well + * pk_verify() now returns a specific error code when the signature is valid + but shorter than the supplied length. Security * Avoid potential timing leak in ecdsa_sign() by blinding modular division. diff --git a/include/polarssl/error.h b/include/polarssl/error.h index 83102bd3a..d27b0e555 100644 --- a/include/polarssl/error.h +++ b/include/polarssl/error.h @@ -83,7 +83,7 @@ * PEM 1 9 * PKCS#12 1 4 (Started from top) * X509 2 18 - * PK 2 13 (Started from top) + * PK 2 14 (Started from top, plus 0x2000) * DHM 3 9 * PKCS5 3 4 (Started from top) * RSA 4 9 diff --git a/include/polarssl/pk.h b/include/polarssl/pk.h index b764d5554..cebe0574d 100644 --- a/include/polarssl/pk.h +++ b/include/polarssl/pk.h @@ -57,6 +57,7 @@ #define POLARSSL_ERR_PK_INVALID_ALG -0x2A80 /**< The algorithm tag or value is invalid. */ #define POLARSSL_ERR_PK_UNKNOWN_NAMED_CURVE -0x2A00 /**< Elliptic curve is unsupported (only NIST curves are supported). */ #define POLARSSL_ERR_PK_FEATURE_UNAVAILABLE -0x2980 /**< Unavailable feature, e.g. RSA disabled for RSA key. */ +#define POLARSSL_ERR_PK_SIG_LEN_MISMATCH -0x2000 /**< The signature is valid but its length is less than expected. */ #if defined(POLARSSL_RSA_C) @@ -288,6 +289,8 @@ int pk_can_do( pk_context *ctx, pk_type_t type ); * \param sig_len Signature length * * \return 0 on success (signature is valid), + * POLARSSL_ERR_PK_SIG_LEN_MISMATCH if the signature is + * valid but its actual length is less than sig_len, * or a specific error code. * * \note If hash_len is 0, then the length associated with md_alg diff --git a/library/error.c b/library/error.c index 2e6bba6c4..b2e834601 100644 --- a/library/error.c +++ b/library/error.c @@ -308,6 +308,8 @@ void polarssl_strerror( int ret, char *buf, size_t buflen ) snprintf( buf, buflen, "PK - Elliptic curve is unsupported (only NIST curves are supported)" ); if( use_ret == -(POLARSSL_ERR_PK_FEATURE_UNAVAILABLE) ) snprintf( buf, buflen, "PK - Unavailable feature, e.g. RSA disabled for RSA key" ); + if( use_ret == -(POLARSSL_ERR_PK_SIG_LEN_MISMATCH) ) + snprintf( buf, buflen, "PK - The signature is valid but its length is less than expected" ); #endif /* POLARSSL_PK_C */ #if defined(POLARSSL_PKCS12_C) diff --git a/library/pk_wrap.c b/library/pk_wrap.c index 61e78feb2..2a4da03d8 100644 --- a/library/pk_wrap.c +++ b/library/pk_wrap.c @@ -64,11 +64,20 @@ static int rsa_verify_wrap( void *ctx, md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len ) { - if( sig_len != ((rsa_context *) ctx)->len ) + int ret; + + if( sig_len < ((rsa_context *) ctx)->len ) return( POLARSSL_ERR_RSA_VERIFY_FAILED ); - return( rsa_pkcs1_verify( (rsa_context *) ctx, NULL, NULL, - RSA_PUBLIC, md_alg, (unsigned int) hash_len, hash, sig ) ); + if( ( ret = rsa_pkcs1_verify( (rsa_context *) ctx, NULL, NULL, + RSA_PUBLIC, md_alg, + (unsigned int) hash_len, hash, sig ) ) != 0 ) + return( ret ); + + if( sig_len > ((rsa_context *) ctx)->len ) + return( POLARSSL_ERR_PK_SIG_LEN_MISMATCH ); + + return( 0 ); } static int rsa_sign_wrap( void *ctx, md_type_t md_alg, @@ -292,10 +301,16 @@ static int ecdsa_verify_wrap( void *ctx, md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len ) { + int ret; ((void) md_alg); - return( ecdsa_read_signature( (ecdsa_context *) ctx, - hash, hash_len, sig, sig_len ) ); + ret = ecdsa_read_signature( (ecdsa_context *) ctx, + hash, hash_len, sig, sig_len ); + + if( ret == POLARSSL_ERR_ECP_SIG_LEN_MISMATCH ) + return( POLARSSL_ERR_PK_SIG_LEN_MISMATCH ); + + return( ret ); } static int ecdsa_sign_wrap( void *ctx, md_type_t md_alg,