diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h index 48e96e5ce..8ea1c1572 100644 --- a/include/mbedtls/check_config.h +++ b/include/mbedtls/check_config.h @@ -107,7 +107,7 @@ #error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites" #endif -#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \ +#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \ !defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && \ !defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && \ !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && \ @@ -118,7 +118,8 @@ !defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) && \ !defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) && \ !defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) ) ) + !defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) ) ) #error "MBEDTLS_ECP_C defined, but not all prerequisites" #endif diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h index ee06b2fd2..8beb2af41 100644 --- a/include/mbedtls/pk.h +++ b/include/mbedtls/pk.h @@ -343,6 +343,10 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options, * * \note For RSA, md_alg may be MBEDTLS_MD_NONE if hash_len != 0. * For ECDSA, md_alg may never be MBEDTLS_MD_NONE. + * + * \note In order to ensure enough space for the signature, the + * \p sig buffer size must be of at least + * `max(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)` bytes. */ int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, diff --git a/include/mbedtls/rsa.h b/include/mbedtls/rsa.h index 23e0ebb0c..a1298da81 100644 --- a/include/mbedtls/rsa.h +++ b/include/mbedtls/rsa.h @@ -819,6 +819,7 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, * * \note The \p sig buffer must be as large as the size * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. + * A buffer length of #MBEDTLS_MPI_MAX_SIZE is always safe. * * \note For PKCS#1 v2.1 encoding, see comments on * mbedtls_rsa_rsassa_pss_sign() for details on @@ -862,6 +863,7 @@ int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx, * * \note The \p sig buffer must be as large as the size * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. + * A buffer length of #MBEDTLS_MPI_MAX_SIZE is always safe. */ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -902,6 +904,7 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx, * * \note The \p sig buffer must be as large as the size * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. + * A buffer length of #MBEDTLS_MPI_MAX_SIZE is always safe. * * \note The \p hash_id in the RSA context is the one used for the * encoding. \p md_alg in the function call is the type of hash diff --git a/library/x509write_crt.c b/library/x509write_crt.c index 4cdb941a1..905de4cfa 100644 --- a/library/x509write_crt.c +++ b/library/x509write_crt.c @@ -49,6 +49,16 @@ static void mbedtls_zeroize( void *v, size_t n ) { volatile unsigned char *p = v; while( n-- ) *p++ = 0; } +/* + * For the currently used signature algorithms the buffer to store any signature + * must be at least of size MAX(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE) + */ +#if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE +#define SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN +#else +#define SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE +#endif + void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx ) { memset( ctx, 0, sizeof( mbedtls_x509write_cert ) ); @@ -338,7 +348,7 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, size_t sig_oid_len = 0; unsigned char *c, *c2; unsigned char hash[64]; - unsigned char sig[MBEDTLS_MPI_MAX_SIZE]; + unsigned char sig[SIGNATURE_MAX_SIZE]; unsigned char tmp_buf[2048]; size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len; size_t len = 0; diff --git a/library/x509write_csr.c b/library/x509write_csr.c index d59354dc4..d6e8c1306 100644 --- a/library/x509write_csr.c +++ b/library/x509write_csr.c @@ -48,6 +48,16 @@ static void mbedtls_zeroize( void *v, size_t n ) { volatile unsigned char *p = v; while( n-- ) *p++ = 0; } +/* + * For the currently used signature algorithms the buffer to store any signature + * must be at least of size MAX(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE) + */ +#if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE +#define SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN +#else +#define SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE +#endif + void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx ) { memset( ctx, 0, sizeof( mbedtls_x509write_csr ) ); @@ -163,7 +173,7 @@ int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, s size_t sig_oid_len = 0; unsigned char *c, *c2; unsigned char hash[64]; - unsigned char sig[MBEDTLS_MPI_MAX_SIZE]; + unsigned char sig[SIGNATURE_MAX_SIZE]; unsigned char tmp_buf[2048]; size_t pub_len = 0, sig_and_oid_len = 0, sig_len; size_t len = 0; diff --git a/programs/pkey/pk_sign.c b/programs/pkey/pk_sign.c index 7ec46752a..0f08db972 100644 --- a/programs/pkey/pk_sign.c +++ b/programs/pkey/pk_sign.c @@ -59,6 +59,16 @@ int main( void ) #include #include +/* + * For the currently used signature algorithms the buffer to store any signature + * must be at least of size MAX(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE) + */ +#if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE +#define SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN +#else +#define SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE +#endif + int main( int argc, char *argv[] ) { FILE *f; @@ -68,7 +78,7 @@ int main( int argc, char *argv[] ) mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; unsigned char hash[32]; - unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; + unsigned char buf[SIGNATURE_MAX_SIZE]; char filename[512]; const char *pers = "mbedtls_pk_sign"; size_t olen = 0; diff --git a/tests/data_files/Makefile b/tests/data_files/Makefile index c10020c04..8fc4f76e6 100644 --- a/tests/data_files/Makefile +++ b/tests/data_files/Makefile @@ -733,6 +733,14 @@ server1.req.cert_type_empty: server1.key $(MBEDTLS_CERT_REQ) output_file=$@ filename=$< subject_name="C=NL,O=PolarSSL,CN=PolarSSL Server 1" md=SHA1 force_ns_cert_type=1 all_final += server1.req.cert_type_empty +### +### A generic SECP521R1 private key +### + +secp521r1_prv.der: + $(OPENSSL) ecparam -genkey -name secp521r1 -noout -out secp521r1_prv.der +all_final += secp521r1_prv.der + ################################################################ ### Generate certificates for CRT write check tests ################################################################ diff --git a/tests/data_files/secp521r1_prv.der b/tests/data_files/secp521r1_prv.der new file mode 100644 index 000000000..4d342bdc2 Binary files /dev/null and b/tests/data_files/secp521r1_prv.der differ diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 7130abcd6..5e5ae86b5 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -591,6 +591,23 @@ component_check_doxygen_warnings () { #### Build and test many configurations and targets ################################################################ +component_test_large_ecdsa_key_signature () { + + SMALL_MPI_MAX_SIZE=136 # Small enough to interfere with the EC signatures + + msg "build: cmake + MBEDTLS_MPI_MAX_SIZE=${SMALL_MPI_MAX_SIZE}, gcc, ASan" # ~ 1 min 50s + scripts/config.pl set MBEDTLS_MPI_MAX_SIZE $SMALL_MPI_MAX_SIZE + CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan . + make + + INEVITABLY_PRESENT_FILE=Makefile + SIGNATURE_FILE="${INEVITABLY_PRESENT_FILE}.sig" # Warning, this is rm -f'ed below + + msg "test: pk_sign secp521r1_prv.der for MBEDTLS_MPI_MAX_SIZE=${SMALL_MPI_MAX_SIZE} (ASan build)" # ~ 5s + if_build_succeeded programs/pkey/pk_sign tests/data_files/secp521r1_prv.der $INEVITABLY_PRESENT_FILE + rm -f $SIGNATURE_FILE +} + component_test_default_out_of_box () { msg "build: make, default config (out-of-box)" # ~1min make