From 55db24ca506cf5831bd31e32d26e5db2cc0264f9 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 17 Oct 2017 19:01:38 +0200 Subject: [PATCH 1/5] RSA: Fix buffer overflow in PSS signature verification Fix buffer overflow in RSA-PSS signature verification when the hash is too large for the key size. Found by Seth Terashima, Qualcomm. Added a non-regression test and a positive test with the smallest permitted key size for a SHA-512 hash. --- ChangeLog | 7 ++++++ library/rsa.c | 2 ++ tests/data_files/rsa512.key | 9 ++++++++ tests/data_files/rsa521.key | 9 ++++++++ tests/data_files/rsa522.key | 9 ++++++++ tests/data_files/rsa528.key | 9 ++++++++ tests/suites/test_suite_pkcs1_v21.data | 32 ++++++++++++++++++++++++++ 7 files changed, 77 insertions(+) create mode 100644 tests/data_files/rsa512.key create mode 100644 tests/data_files/rsa521.key create mode 100644 tests/data_files/rsa522.key create mode 100644 tests/data_files/rsa528.key diff --git a/ChangeLog b/ChangeLog index a3171d7eb..d2c5f6b36 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ mbed TLS ChangeLog (Sorted per branch, date) += mbed TLS 1.3.x released xxxx-xx-xx + +Security + * Fix buffer overflow in RSA-PSS verification when the hash is too + large for the key size. Found by Seth Terashima, Qualcomm Product + Security Initiative, Qualcomm Technologies Inc. + = mbed TLS 1.3.21 branch released 2017-08-10 Security diff --git a/library/rsa.c b/library/rsa.c index ca8f688e6..d531c2607 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -1368,6 +1368,8 @@ int rsa_rsassa_pss_verify_ext( rsa_context *ctx, return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); hlen = md_get_size( md_info ); + if( siglen < hlen + 2 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); slen = siglen - hlen - 1; /* Currently length of salt + padding */ memset( zeros, 0, 8 ); diff --git a/tests/data_files/rsa512.key b/tests/data_files/rsa512.key new file mode 100644 index 000000000..1fd7987c2 --- /dev/null +++ b/tests/data_files/rsa512.key @@ -0,0 +1,9 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIBOwIBAAJBALB20jJQgW+aqwIwfkUrl/DK51mDabQWJOivx5caWaE4kvZLB+qm +7JKMFgstbsj50N1bY8izrAdntPZciS9WwQ8CAwEAAQJAKYfNcIoB7II6PQmsrhrU +Z5dZW3fSKNANX7X/A1DwR0DlF8uZnpWsWbYcRoXX7QjvepZqc54wryhW55Wlm6yI +AQIhAOJIaLjSpbHjzzcJQ7mylxn2WGIlbJPPzJ9OaFZCZQvxAiEAx6OEAvl6JKa6 +6a+N2Wvhtcgb4qqR6UHQGJQYGJz5nP8CIAvgoR6ScAAWZRoOcm+c4DGMrLb6H+ji +T2tNQkzEz2kBAiEAmw34GStU36STpa6RGJ4+tyZN6jWakDVqf7x+HpfFE1cCIQDc +KzXIxec2taye4OeIa1v4W/MigMmYE9w93Uw/Qi3azA== +-----END RSA PRIVATE KEY----- diff --git a/tests/data_files/rsa521.key b/tests/data_files/rsa521.key new file mode 100644 index 000000000..0b940aa6e --- /dev/null +++ b/tests/data_files/rsa521.key @@ -0,0 +1,9 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIBPQIBAAJCATG2mGDzy5v4XqNY/fK9KZDxt3qA1qT9+BekPdiWvffdJq+KwCN/ +Um4NM7EFyXH9vU/6ns6Z/EafMez0Kej1YsHDAgMBAAECQCdoYjwdMSHp4kksL5Aa +0kDc58ni0chy9IgXo+FHjTVmR9DkaZANrwfVvYMJxqYCZo0im1Dw7ZJBUDJQNXnl +ZokCIRiSk66I24AWa7XGUFvatVwXWi2ACE4QEKqzWQe1mQ24/wIhDHD1TCKpqucA +XDI+1N7EHs+fN4CfTSWe8FPGiK6q3VM9AiESrKKLi/q011U4KeS8SfR2blDcL2cg +XFkuQWqxzzLoGOUCIQmgl5E0+Ypwe0zc7NYZFDarf4+ZjqxKQnXCvk0irMHcGQIh +EVPli6RQb3Gcx7vXJHltzSTno7NElzBDRMBVUlBmVxAJ +-----END RSA PRIVATE KEY----- diff --git a/tests/data_files/rsa522.key b/tests/data_files/rsa522.key new file mode 100644 index 000000000..18fbe70ca --- /dev/null +++ b/tests/data_files/rsa522.key @@ -0,0 +1,9 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIBPgIBAAJCAtMCdT492ij0L02fkshkdCDqb7yXwQ+EmLlmqVPzV2mNZYEGDf4y +yKuY20vFzirN8MHm5ASnWhMoJVDBqjfTzci/AgMBAAECQU05ffxf7uVg74yC9tKg +qCa746NpMh3OM+HZrUxiOXv0sJMRXNEPD5HNLtgcNY6MI5NYbUvkOXktnFZpxWYP +TH7BAiEeFJGs5Z6gRd2v/IbYLMFDHgjqho04INGTOvnyI7lGVKUCIRgJM7moFuoM +UrKTmJK1uOzauWEykCKgc6BGH6TGZoEWkwIhBzQn2v82qO1ydOYGKRk2w2sa+Yd1 +pH5/kkHqf+m8QjKdAiEQ9eVW+4J30wxD0JyX4b1E/S5UpN5KYNhWX0US+6D3NBsC +IRxePzdQlutZWg0Cnku3QE1tOLBCFlP7QVVl5FbKcY5H5w== +-----END RSA PRIVATE KEY----- diff --git a/tests/data_files/rsa528.key b/tests/data_files/rsa528.key new file mode 100644 index 000000000..fd463b54d --- /dev/null +++ b/tests/data_files/rsa528.key @@ -0,0 +1,9 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIBRQIBAAJDAOMcJG1GSFmEJh/RdMqz1DVzRGAuzXk8R9vlQlLTe7NQvGNDWbGV +FVQggORySktnIpG+V8dkj1Finq7yNOhH2ZzGXwIDAQABAkMAsWYyLglQSlwnS4NZ +L1z4zieTqW3lomWr2+BgxkHbxl2w0Rx4L+Ezp+YK6mhtIQWNkoytPvWJJMS7Jrkg +agMAHQJBAiIA+F1y5GO0Bv+igsNLXwwtbCqs8hAkavU9W8egt/oDbhzbAiIA6hds +PZp/s1X7n7dwfmebSs+3vLZFuQfifN8XZLw0CXHNAiEuEzgDQrPdMIN3er96zImI +rYoUBgabiQ9u/WPFfa4xOU0CIgDDYC089Tfjy72pPgcr2PkpZVhqro5esg/8PI5f +yxx7TXkCIgCYoE8Y5IxomtL1ub1AQzPe9UyyUGzQB1yWeiloJh6LjxA= +-----END RSA PRIVATE KEY----- diff --git a/tests/suites/test_suite_pkcs1_v21.data b/tests/suites/test_suite_pkcs1_v21.data index a5b382f05..5a66bda09 100644 --- a/tests/suites/test_suite_pkcs1_v21.data +++ b/tests/suites/test_suite_pkcs1_v21.data @@ -787,3 +787,35 @@ RSASSA-PSS Signature verify options #13 (MGF1 alg != MSG hash alg, arg wrong) depends_on:POLARSSL_SHA256_C pkcs1_rsassa_pss_verify_ext:1024:16:"00dd118a9f99bab068ca2aea3b6a6d5997ed4ec954e40deecea07da01eaae80ec2bb1340db8a128e891324a5c5f5fad8f590d7c8cacbc5fe931dafda1223735279461abaa0572b761631b3a8afe7389b088b63993a0a25ee45d21858bab9931aedd4589a631b37fcf714089f856549f359326dd1e0e86dde52ed66b4a90bda4095":16:"010001":POLARSSL_MD_NONE:POLARSSL_MD_SHA256:POLARSSL_MD_SHA1:RSA_SALT_LEN_ANY:"c0719e9a8d5d838d861dc6f675c899d2b309a3a65bb9fe6b11e5afcbf9a2c0b1":"7fc506d26ca3b22922a1ce39faaedd273161b82d9443c56f1a034f131ae4a18cae1474271cb4b66a17d9707ca58b0bdbd3c406b7e65bbcc9bbbce94dc45de807b4989b23b3e4db74ca29298137837eb90cc83d3219249bc7d480fceaf075203a86e54c4ecfa4e312e39f8f69d76534089a36ed9049ca9cfd5ab1db1fa75fe5c8":0:POLARSSL_ERR_RSA_INVALID_PADDING +RSASSA-PSS verify ext, 512-bit key, empty salt, good signature +depends_on:POLARSSL_SHA256_C +pkcs1_rsassa_pss_verify_ext:512:16:"00b076d23250816f9aab02307e452b97f0cae7598369b41624e8afc7971a59a13892f64b07eaa6ec928c160b2d6ec8f9d0dd5b63c8b3ac0767b4f65c892f56c10f":16:"010001":POLARSSL_MD_SHA256:POLARSSL_MD_SHA256:POLARSSL_MD_SHA256:0:"":"ace8b03347da1b9a7a5e94a0d76359bb39c819bb170bef38ea84995ed653446c0ae87ede434cdf9d0cb2d7bf164cf427892363e6855a1d24d0ce5dd72acaf246":0:0 + +RSASSA-PSS verify ext, 512-bit key, empty salt, bad signature +depends_on:POLARSSL_SHA256_C +pkcs1_rsassa_pss_verify_ext:512:16:"00b076d23250816f9aab02307e452b97f0cae7598369b41624e8afc7971a59a13892f64b07eaa6ec928c160b2d6ec8f9d0dd5b63c8b3ac0767b4f65c892f56c10f":16:"010001":POLARSSL_MD_SHA256:POLARSSL_MD_SHA256:POLARSSL_MD_SHA256:0:"":"ace8b03347da1b9a7a5e94a0d76359bb39c819bb170bef38ea84995ed653446c0ae87ede434cdf9d0cb2d7bf164cf427892363e6855a1d24d0ce5dd72acaf247":POLARSSL_ERR_RSA_INVALID_PADDING:POLARSSL_ERR_RSA_INVALID_PADDING + +RSASSA-PSS verify ext, 522-bit key, SHA-512, empty salt, good signature +depends_on:POLARSSL_SHA512_C +pkcs1_rsassa_pss_verify_ext:522:16:"02d302753e3dda28f42f4d9f92c8647420ea6fbc97c10f8498b966a953f357698d6581060dfe32c8ab98db4bc5ce2acdf0c1e6e404a75a13282550c1aa37d3cdc8bf":16:"010001":POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:0:"":"016752ae0b5dfbade6bbd3dd37868d48c8d741f92dca41c360aeda553204c2212a117b1a3d77e0d3f48723503c46e16c8a64de00f1dee3e37e478417452630859486":0:0 + +RSASSA-PSS verify ext, 528-bit key, SHA-512, saltlen=64, good signature with saltlen=0 +depends_on:POLARSSL_SHA512_C +pkcs1_rsassa_pss_verify_ext:528:16:"00e31c246d46485984261fd174cab3d4357344602ecd793c47dbe54252d37bb350bc634359b19515542080e4724a4b672291be57c7648f51629eaef234e847d99cc65f":16:"010001":POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:64:"":"a9ad7994ba3a1071124153486924448cc67a5af3a5d34e9261d53770782cc85f58e2edde5f7004652a645e3e9606530eb57de41df7298ae2be9dec69cc0d613ab629":0:POLARSSL_ERR_RSA_INVALID_PADDING + +RSASSA-PSS verify ext, 528-bit key, SHA-512, empty salt, good signature +depends_on:POLARSSL_SHA512_C +pkcs1_rsassa_pss_verify_ext:528:16:"00e31c246d46485984261fd174cab3d4357344602ecd793c47dbe54252d37bb350bc634359b19515542080e4724a4b672291be57c7648f51629eaef234e847d99cc65f":16:"010001":POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:0:"":"a9ad7994ba3a1071124153486924448cc67a5af3a5d34e9261d53770782cc85f58e2edde5f7004652a645e3e9606530eb57de41df7298ae2be9dec69cc0d613ab629":0:0 + +RSASSA-PSS verify ext, 528-bit key, SHA-512, saltlen=64, good signature with saltlen=0 +depends_on:POLARSSL_SHA512_C +pkcs1_rsassa_pss_verify_ext:528:16:"00e31c246d46485984261fd174cab3d4357344602ecd793c47dbe54252d37bb350bc634359b19515542080e4724a4b672291be57c7648f51629eaef234e847d99cc65f":16:"010001":POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:64:"":"a9ad7994ba3a1071124153486924448cc67a5af3a5d34e9261d53770782cc85f58e2edde5f7004652a645e3e9606530eb57de41df7298ae2be9dec69cc0d613ab629":0:POLARSSL_ERR_RSA_INVALID_PADDING + +RSASSA-PSS verify ext, 512-bit key, SHA-512 (hash too large) +depends_on:POLARSSL_SHA512_C +pkcs1_rsassa_pss_verify_ext:512:16:"00b076d23250816f9aab02307e452b97f0cae7598369b41624e8afc7971a59a13892f64b07eaa6ec928c160b2d6ec8f9d0dd5b63c8b3ac0767b4f65c892f56c10f":16:"010001":POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:0:"":"ace8b03347da1b9a7a5e94a0d76359bb39c819bb170bef38ea84995ed653446c0ae87ede434cdf9d0cb2d7bf164cf427892363e6855a1d24d0ce5dd72acaf246":POLARSSL_ERR_RSA_BAD_INPUT_DATA:POLARSSL_ERR_RSA_BAD_INPUT_DATA + +RSASSA-PSS verify ext, 521-bit key, SHA-512, empty salt, bad signature +depends_on:POLARSSL_SHA512_C +pkcs1_rsassa_pss_verify_ext:521:16:"0131b69860f3cb9bf85ea358fdf2bd2990f1b77a80d6a4fdf817a43dd896bdf7dd26af8ac0237f526e0d33b105c971fdbd4ffa9ece99fc469f31ecf429e8f562c1c3":16:"010001":POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:0:"":"00471794655837da498cbf27242807b40593a353c707eb22fd2cc5a3259e728ac4f1df676043eeec8e16c1175b3d9ac8cae72ec1d5772dd69de71c5677f19031568e":POLARSSL_ERR_RSA_INVALID_PADDING:POLARSSL_ERR_RSA_INVALID_PADDING + From 511bb84c609e1b39cc9e470f4f9132accb412591 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 17 Oct 2017 19:02:13 +0200 Subject: [PATCH 2/5] RSA: Fix another buffer overflow in PSS signature verification Fix buffer overflow in RSA-PSS signature verification when the masking operation results in an all-zero buffer. This could happen at any key size. --- ChangeLog | 2 ++ library/rsa.c | 21 +++++++++++---------- tests/suites/test_suite_pkcs1_v21.data | 4 ++++ 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index d2c5f6b36..9b3dc5c18 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,8 @@ Security * Fix buffer overflow in RSA-PSS verification when the hash is too large for the key size. Found by Seth Terashima, Qualcomm Product Security Initiative, Qualcomm Technologies Inc. + * Fix buffer overflow in RSA-PSS verification when the unmasked + data is all zeros. = mbed TLS 1.3.21 branch released 2017-08-10 diff --git a/library/rsa.c b/library/rsa.c index d531c2607..56fd7920f 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -1325,10 +1325,11 @@ int rsa_rsassa_pss_verify_ext( rsa_context *ctx, size_t siglen; unsigned char *p; unsigned char buf[POLARSSL_MPI_MAX_SIZE]; + unsigned char *hash_start; unsigned char result[POLARSSL_MD_MAX_SIZE]; unsigned char zeros[8]; unsigned int hlen; - size_t slen, msb; + size_t observed_salt_len, msb; const md_info_t *md_info; md_context_t md_ctx; @@ -1370,7 +1371,7 @@ int rsa_rsassa_pss_verify_ext( rsa_context *ctx, hlen = md_get_size( md_info ); if( siglen < hlen + 2 ) return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); - slen = siglen - hlen - 1; /* Currently length of salt + padding */ + hash_start = buf + siglen - hlen - 1; memset( zeros, 0, 8 ); @@ -1385,6 +1386,7 @@ int rsa_rsassa_pss_verify_ext( rsa_context *ctx, p++; siglen -= 1; } + else if( buf[0] >> ( 8 - siglen * 8 + msb ) ) return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); @@ -1395,25 +1397,24 @@ int rsa_rsassa_pss_verify_ext( rsa_context *ctx, return( ret ); } - mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx ); + mgf_mask( p, siglen - hlen - 1, hash_start, hlen, &md_ctx ); buf[0] &= 0xFF >> ( siglen * 8 - msb ); - while( p < buf + siglen && *p == 0 ) + while( p < hash_start - 1 && *p == 0 ) p++; - if( p == buf + siglen || + if( p == hash_start || *p++ != 0x01 ) { md_free( &md_ctx ); return( POLARSSL_ERR_RSA_INVALID_PADDING ); } - /* Actual salt len */ - slen -= p - buf; + observed_salt_len = hash_start - p; if( expected_salt_len != RSA_SALT_LEN_ANY && - slen != (size_t) expected_salt_len ) + observed_salt_len != (size_t) expected_salt_len ) { md_free( &md_ctx ); return( POLARSSL_ERR_RSA_INVALID_PADDING ); @@ -1424,12 +1425,12 @@ int rsa_rsassa_pss_verify_ext( rsa_context *ctx, md_starts( &md_ctx ); md_update( &md_ctx, zeros, 8 ); md_update( &md_ctx, hash, hashlen ); - md_update( &md_ctx, p, slen ); + md_update( &md_ctx, p, observed_salt_len ); md_finish( &md_ctx, result ); md_free( &md_ctx ); - if( memcmp( p + slen, result, hlen ) == 0 ) + if( memcmp( hash_start, result, hlen ) == 0 ) return( 0 ); else return( POLARSSL_ERR_RSA_VERIFY_FAILED ); diff --git a/tests/suites/test_suite_pkcs1_v21.data b/tests/suites/test_suite_pkcs1_v21.data index 5a66bda09..b396c642a 100644 --- a/tests/suites/test_suite_pkcs1_v21.data +++ b/tests/suites/test_suite_pkcs1_v21.data @@ -819,3 +819,7 @@ RSASSA-PSS verify ext, 521-bit key, SHA-512, empty salt, bad signature depends_on:POLARSSL_SHA512_C pkcs1_rsassa_pss_verify_ext:521:16:"0131b69860f3cb9bf85ea358fdf2bd2990f1b77a80d6a4fdf817a43dd896bdf7dd26af8ac0237f526e0d33b105c971fdbd4ffa9ece99fc469f31ecf429e8f562c1c3":16:"010001":POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:0:"":"00471794655837da498cbf27242807b40593a353c707eb22fd2cc5a3259e728ac4f1df676043eeec8e16c1175b3d9ac8cae72ec1d5772dd69de71c5677f19031568e":POLARSSL_ERR_RSA_INVALID_PADDING:POLARSSL_ERR_RSA_INVALID_PADDING +RSASSA-PSS verify ext, all-zero padding, automatic salt length +depends_on:POLARSSL_SHA256_C +pkcs1_rsassa_pss_verify_ext:512:16:"00b076d23250816f9aab02307e452b97f0cae7598369b41624e8afc7971a59a13892f64b07eaa6ec928c160b2d6ec8f9d0dd5b63c8b3ac0767b4f65c892f56c10f":16:"010001":POLARSSL_MD_NONE:POLARSSL_MD_SHA256:POLARSSL_MD_SHA256:RSA_SALT_LEN_ANY:"":"63a35294577c7e593170378175b7df27c293dae583ec2a971426eb2d66f2af483e897bfae5dc20300a9d61a3644e08c3aee61a463690a3498901563c46041056":POLARSSL_ERR_RSA_INVALID_PADDING:POLARSSL_ERR_RSA_INVALID_PADDING + From 7addb7f0a0c3f7b2294780022cf8c84990d9bca0 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 18 Oct 2017 19:03:42 +0200 Subject: [PATCH 3/5] RSA PSS: fix minimum length check for keys of size 8N+1 The check introduced by the previous security fix was off by one. It fixed the buffer overflow but was not compliant with the definition of PSS which technically led to accepting some invalid signatures (but not signatures made without the private key). --- library/rsa.c | 7 ++++--- tests/suites/test_suite_pkcs1_v21.data | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/library/rsa.c b/library/rsa.c index 56fd7920f..6b720a4f9 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -1369,9 +1369,6 @@ int rsa_rsassa_pss_verify_ext( rsa_context *ctx, return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); hlen = md_get_size( md_info ); - if( siglen < hlen + 2 ) - return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); - hash_start = buf + siglen - hlen - 1; memset( zeros, 0, 8 ); @@ -1390,6 +1387,10 @@ int rsa_rsassa_pss_verify_ext( rsa_context *ctx, if( buf[0] >> ( 8 - siglen * 8 + msb ) ) return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + if( siglen < hlen + 2 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + hash_start = p + siglen - hlen - 1; + md_init( &md_ctx ); if( ( ret = md_init_ctx( &md_ctx, md_info ) ) != 0 ) { diff --git a/tests/suites/test_suite_pkcs1_v21.data b/tests/suites/test_suite_pkcs1_v21.data index b396c642a..1c4113748 100644 --- a/tests/suites/test_suite_pkcs1_v21.data +++ b/tests/suites/test_suite_pkcs1_v21.data @@ -817,7 +817,7 @@ pkcs1_rsassa_pss_verify_ext:512:16:"00b076d23250816f9aab02307e452b97f0cae7598369 RSASSA-PSS verify ext, 521-bit key, SHA-512, empty salt, bad signature depends_on:POLARSSL_SHA512_C -pkcs1_rsassa_pss_verify_ext:521:16:"0131b69860f3cb9bf85ea358fdf2bd2990f1b77a80d6a4fdf817a43dd896bdf7dd26af8ac0237f526e0d33b105c971fdbd4ffa9ece99fc469f31ecf429e8f562c1c3":16:"010001":POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:0:"":"00471794655837da498cbf27242807b40593a353c707eb22fd2cc5a3259e728ac4f1df676043eeec8e16c1175b3d9ac8cae72ec1d5772dd69de71c5677f19031568e":POLARSSL_ERR_RSA_INVALID_PADDING:POLARSSL_ERR_RSA_INVALID_PADDING +pkcs1_rsassa_pss_verify_ext:521:16:"0131b69860f3cb9bf85ea358fdf2bd2990f1b77a80d6a4fdf817a43dd896bdf7dd26af8ac0237f526e0d33b105c971fdbd4ffa9ece99fc469f31ecf429e8f562c1c3":16:"010001":POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:0:"":"00471794655837da498cbf27242807b40593a353c707eb22fd2cc5a3259e728ac4f1df676043eeec8e16c1175b3d9ac8cae72ec1d5772dd69de71c5677f19031568e":POLARSSL_ERR_RSA_BAD_INPUT_DATA:POLARSSL_ERR_RSA_BAD_INPUT_DATA RSASSA-PSS verify ext, all-zero padding, automatic salt length depends_on:POLARSSL_SHA256_C From 5d9224e11cb76712f4416da71715fec09aef12e7 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 19 Oct 2017 15:23:49 +0200 Subject: [PATCH 4/5] RSA PSS: fix first byte check for keys of size 8N+1 For a key of size 8N+1, check that the first byte after applying the public key operation is 0 (it could have been 1 instead). The code was incorrectly doing a no-op check instead, which led to invalid signatures being accepted. Not a security flaw, since you would need the private key to craft such an invalid signature, but a bug nonetheless. --- library/rsa.c | 6 +++--- tests/suites/test_suite_pkcs1_v21.data | 8 ++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/library/rsa.c b/library/rsa.c index 6b720a4f9..923294f0b 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -1376,6 +1376,9 @@ int rsa_rsassa_pss_verify_ext( rsa_context *ctx, // msb = mpi_msb( &ctx->N ) - 1; + if( buf[0] >> ( 8 - siglen * 8 + msb ) ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + // Compensate for boundary condition when applying mask // if( msb % 8 == 0 ) @@ -1383,9 +1386,6 @@ int rsa_rsassa_pss_verify_ext( rsa_context *ctx, p++; siglen -= 1; } - else - if( buf[0] >> ( 8 - siglen * 8 + msb ) ) - return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); if( siglen < hlen + 2 ) return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); diff --git a/tests/suites/test_suite_pkcs1_v21.data b/tests/suites/test_suite_pkcs1_v21.data index 1c4113748..85fb6c0cb 100644 --- a/tests/suites/test_suite_pkcs1_v21.data +++ b/tests/suites/test_suite_pkcs1_v21.data @@ -819,6 +819,14 @@ RSASSA-PSS verify ext, 521-bit key, SHA-512, empty salt, bad signature depends_on:POLARSSL_SHA512_C pkcs1_rsassa_pss_verify_ext:521:16:"0131b69860f3cb9bf85ea358fdf2bd2990f1b77a80d6a4fdf817a43dd896bdf7dd26af8ac0237f526e0d33b105c971fdbd4ffa9ece99fc469f31ecf429e8f562c1c3":16:"010001":POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:0:"":"00471794655837da498cbf27242807b40593a353c707eb22fd2cc5a3259e728ac4f1df676043eeec8e16c1175b3d9ac8cae72ec1d5772dd69de71c5677f19031568e":POLARSSL_ERR_RSA_BAD_INPUT_DATA:POLARSSL_ERR_RSA_BAD_INPUT_DATA +RSASSA-PSS verify ext, 521-bit key, SHA-256, empty salt, good signature +depends_on:POLARSSL_SHA256_C +pkcs1_rsassa_pss_verify_ext:521:16:"0131b69860f3cb9bf85ea358fdf2bd2990f1b77a80d6a4fdf817a43dd896bdf7dd26af8ac0237f526e0d33b105c971fdbd4ffa9ece99fc469f31ecf429e8f562c1c3":16:"010001":POLARSSL_MD_SHA256:POLARSSL_MD_SHA256:POLARSSL_MD_SHA256:0:"41":"009c4941157fa36288e467310b198ab0c615c40963d611ffeef03000549ded809235955ecc57adba44782e9497c004f480ba2b3d58db8335fe0b391075c02c843a6d":0:0 + +RSASSA-PSS verify ext, 521-bit key, SHA-256, empty salt, flipped-highest-bit signature +depends_on:POLARSSL_SHA256_C +pkcs1_rsassa_pss_verify_ext:521:16:"0131b69860f3cb9bf85ea358fdf2bd2990f1b77a80d6a4fdf817a43dd896bdf7dd26af8ac0237f526e0d33b105c971fdbd4ffa9ece99fc469f31ecf429e8f562c1c3":16:"010001":POLARSSL_MD_SHA256:POLARSSL_MD_SHA256:POLARSSL_MD_SHA256:0:"41":"00e11a2403df681c44a1f73f014b6c9ad17847d0b673f7c2a801cee208d10ab5792c10cd0cd495a4b331aaa521409fca7cb1b0d978b3a84cd67e28078b98753e9466":POLARSSL_ERR_RSA_BAD_INPUT_DATA:POLARSSL_ERR_RSA_BAD_INPUT_DATA + RSASSA-PSS verify ext, all-zero padding, automatic salt length depends_on:POLARSSL_SHA256_C pkcs1_rsassa_pss_verify_ext:512:16:"00b076d23250816f9aab02307e452b97f0cae7598369b41624e8afc7971a59a13892f64b07eaa6ec928c160b2d6ec8f9d0dd5b63c8b3ac0767b4f65c892f56c10f":16:"010001":POLARSSL_MD_NONE:POLARSSL_MD_SHA256:POLARSSL_MD_SHA256:RSA_SALT_LEN_ANY:"":"63a35294577c7e593170378175b7df27c293dae583ec2a971426eb2d66f2af483e897bfae5dc20300a9d61a3644e08c3aee61a463690a3498901563c46041056":POLARSSL_ERR_RSA_INVALID_PADDING:POLARSSL_ERR_RSA_INVALID_PADDING From 28474f41a0b7eb34e4c0550c588d0aca7126fdfb Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 19 Oct 2017 17:46:14 +0200 Subject: [PATCH 5/5] RSA PSS: remove redundant check; changelog Remove a check introduced in the previous buffer overflow fix with keys of size 8N+1 which the subsequent fix for buffer start calculations made redundant. Added a changelog entry for the buffer start calculation fix. --- ChangeLog | 4 ++++ library/rsa.c | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9b3dc5c18..3de318419 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,10 @@ Security * Fix buffer overflow in RSA-PSS verification when the unmasked data is all zeros. +Bugfix + * Fix some invalid RSA-PSS signatures with keys of size 8N+1 that were + accepted. Generating these signatures required the private key. + = mbed TLS 1.3.21 branch released 2017-08-10 Security diff --git a/library/rsa.c b/library/rsa.c index 923294f0b..bbb028675 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -1405,8 +1405,7 @@ int rsa_rsassa_pss_verify_ext( rsa_context *ctx, while( p < hash_start - 1 && *p == 0 ) p++; - if( p == hash_start || - *p++ != 0x01 ) + if( *p++ != 0x01 ) { md_free( &md_ctx ); return( POLARSSL_ERR_RSA_INVALID_PADDING );