diff --git a/crypto/pkcs7/pkcs7.c b/crypto/pkcs7/pkcs7.c index 0b22ea6ff4..3d26fac5a2 100644 --- a/crypto/pkcs7/pkcs7.c +++ b/crypto/pkcs7/pkcs7.c @@ -1159,8 +1159,10 @@ static int pkcs7_decrypt_rinfo(unsigned char **ek_out, PKCS7_RECIP_INFO *ri, // we still need to set |ek| to NULL to signal decryption failure to callers // so they can use random bytes as content encryption key for MMA defense. if (!ok) { +#if !defined(BORINGSSL_UNSAFE_FUZZER_MODE) OPENSSL_free(ek); ek = NULL; +#endif } ret = 1; @@ -1250,7 +1252,9 @@ static BIO *pkcs7_data_decode(PKCS7 *p7, EVP_PKEY *pkey, X509 *pcert) { if (!pkcs7_cmp_ri(ri, pcert)) { break; } +#if !defined(BORINGSSL_UNSAFE_FUZZER_MODE) ri = NULL; +#endif } if (ri == NULL) { OPENSSL_PUT_ERROR(PKCS7, PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); @@ -1290,14 +1294,16 @@ static BIO *pkcs7_data_decode(PKCS7 *p7, EVP_PKEY *pkey, X509 *pcert) { !EVP_CipherInit_ex(evp_ctx, cipher, NULL, NULL, NULL, 0)) { goto err; } - uint8_t iv[EVP_MAX_IV_LENGTH]; - OPENSSL_memcpy(iv, enc_alg->parameter->value.octet_string->data, - enc_alg->parameter->value.octet_string->length); const int expected_iv_len = EVP_CIPHER_CTX_iv_length(evp_ctx); - if (enc_alg->parameter->value.octet_string->length != expected_iv_len) { + if (enc_alg == NULL || enc_alg->parameter == NULL || + enc_alg->parameter->value.octet_string == NULL || + enc_alg->parameter->value.octet_string->length != expected_iv_len) { OPENSSL_PUT_ERROR(PKCS7, ERR_R_PKCS7_LIB); goto err; } + uint8_t iv[EVP_MAX_IV_LENGTH]; + OPENSSL_memcpy(iv, enc_alg->parameter->value.octet_string->data, + enc_alg->parameter->value.octet_string->length); if (!EVP_CipherInit_ex(evp_ctx, NULL, NULL, NULL, iv, 0)) { goto err; } @@ -1323,6 +1329,8 @@ static BIO *pkcs7_data_decode(PKCS7 *p7, EVP_PKEY *pkey, X509 *pcert) { OPENSSL_free(cek); OPENSSL_free(dummy_key); + cek = NULL; + dummy_key = NULL; out = cipher_bio; if (data_body && data_body->length > 0) { diff --git a/fuzz/CMakeLists.txt b/fuzz/CMakeLists.txt index f10022ad78..12e6bd54ef 100644 --- a/fuzz/CMakeLists.txt +++ b/fuzz/CMakeLists.txt @@ -29,6 +29,7 @@ fuzzer(ocsp) fuzzer(ocsp_http) fuzzer(ocsp_parse_url) fuzzer(pkcs12) +fuzzer(pkcs7_decrypt) fuzzer(pkcs8) fuzzer(pkcs8_v2) fuzzer(privkey) diff --git a/fuzz/pkcs7_decrypt.cc b/fuzz/pkcs7_decrypt.cc new file mode 100644 index 0000000000..2f31c47324 --- /dev/null +++ b/fuzz/pkcs7_decrypt.cc @@ -0,0 +1,99 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 OR ISC + +#include + +#include +#include +#include +#include +#include +#include + +// The corpus was created using the following key. +// If you change the key, the corpus should be augmented with inputs +// created using (or "seeded" from) PKCS7 values encrypted with +// the new key. +static const char kKey[] = R"( +-----BEGIN PRIVATE KEY----- +MIIJQQIBADANBgkqhkiG9w0BAQEFAASCCSswggknAgEAAoICAQC1+MOn+BopcEVR +4QMvjXdAxGkWFllXyQFDToL+qOiPRU1yN7C8KCtkbOAFttJIO4O/i0iZ7KqYbnmB +6YUA/ONAcakocnrdoESgRJcVMeAxDk/11OtMF5yIfeOOO/TUeVNmAUaT63gFbKy/ +adpqhzJtOv9BBl5VcYNGGSE+0wtbmjpmNsxunEQR1KLDc97fGYHeRfKoSyrCIEE8 +IaAEpKGR2Sku3v9Jwh7RpjupgiUAkH6pJk7VMZm5vl2wFjYvfysgjeN5ZtsxFDMa +PYZStpxMxpNd5C9DsO2Ljp5NMpGfNGmG4ZqiaQg8z2cIM6ESmN1zDJdUh5IXed1f +OxBZD/poUFH0wDRFWnvzlaPmjJEFrYLMK8svnE5nEQp9vu93ISFBx7cofs+niMaU +XPEqaRSqruifN2M1it3kOf/8YZl1vurs+VtHD6nOJo6bd11+37aBidIB/BaWnzLr +DmSTcPFa1tkTHwoLqc9+jThTq9jZ6w3lAMPpsoenyD19UmQB589+4kNp2SIO/Ttz +VQCGgQPXE2jDCl6G9aIPMkfvpPZK4THVil3WQRCFYnYdDO4HQXo2ZuC4RiqgY5yg +feoL+fa9k383lgxxAHQLS7xsbaVB40RmfdbdevgPYIwZNNO78ddRmMdSv6IknSW9 +gydGzY//btY+t1SWcBZWzn1Ewq8g2QIDAQABAoICAFQ/liZAIaypxA5ChP0RG/Mq +fBSzyC1ybFlDEjbg8LrUNST6T6LtXhmipp0+pWC33SljTPumrNzh2POir+djLbt6 +Y/zL88KEHwGsf95aNxe/Lpn8N+wEyn4O+rmxXIq6mTgSwyBc1jZ8uAXu9iZ37YrQ +07jBQA+C/GoJ3HB/uTRx1TPZjxBu3Lz8m1auYLMd1hiYfd4Y3vT9hfZXAwTjS8KA +riZ7K+p0K1yY/+pczNDUFTAvAjSGQEvUrP+HaRLYZ5ks1/IvArBYT8iIT5Yf4YFS +NowzxwYp9fC02OmYzf7Nf0XpUXR7+EpfI66SaLJ5f51yaOXD1olz7F/YsprpYN7+ +oQd7EKar1bY3ROM6naUZtsIoEblg6B0mkyHWQgZ9wZRbcN7Zmuc/tIpLat7se+MP +xQeAcH4Yhgnd2G6EELpmJBcyJ0Ss3atpI1eenU+ly++L4XbDQH9norKQ1PEDXYbV +XMAV5uIsplBL7hGIa6/u/cRMM5eN3TJchtzIHFhq9+ENMvjTOfo0bflcYR+tNxGD +6agWlD/Apedaapu/3Xp7ekyCiy/YTIwgT4U3rprYplzFM5HbzYtZ9ThxUm+CmnYj +ZSCKiLoaQq+11/M9zH1Je0uJP5aK0CxOii2LVRXZYaQfbDtiHNWUSM7uPIZMnDgE +IPTpl9CEfk7U3pgiUlg5AoIBAQDjUeikACPaRuewIjLqwTT2/j+ZO+/dCG4atFZa +W+gdZ1NVDCdowQPBZWg6bqejRr1MvORg2L83kqZDQjaT9y59qxsFhXCy26xKp7aP +Z4pEvUQmQnnf3RYHk3EBtOHyyMetTaghTGzL3MlPGo3uGbCiYtVoPKXZXGWeiOFN +s9RNDh/7m6harB2bmX2cK+QPdJ1roVBXQDLkjh2mvLnC5vrsw81GWSkbWQpYmnVi +YdLhytM+UTYjTrSugtrKk9e2KOFf2uR8PVaPeINEM4uubxW5YUy6gwF8ePtWYAtZ +Skw3kdBdShhGzHORSY3NsRTJZL6AUdkhHYFTl/rlfj1WXsdnAoIBAQDM7i0u2T+E +HmroTGiQAIRUEwUZQFDRkcEnM75jpkQT39jXF+zmhjzS1slJF2x0E0jUBV0juVWh +mz1kHjTMV0j3/mvCeVv0iTcdIbHYRtTwmOjzkwTsZGh6T7okYck3KexRjpyhPpcX +hOHOPJKS/muG0ZuaJjTEbJOzrSPU0rt0ppL7nOwd5jIOoGAciWiP17G1Lyyitrv4 +mKBK6mFQQWjAgEGy3jvBocbUo7Qo8Aucm6Y4eF1fUyC/X07RBzERHS4TuM+AQlDN +T+LgTgcwTjE+Nzow2WMwCIbhVQqFRScuWqcJ6NQ6S/dV0R+aGJ90Ey+DtiZ9N9uV +j0omAGvM8u2/AoIBADXF94FsIw8MfNw2itLrl2riJAtMmWYxC1K33EGNwi/KdHUG +5f+qwQerxGcmK/O81STk/iVGwJ0VzMzWSfDgpRfHNSIuOcWln3EdkVsFBDlUiF2A +ljH1q7NpFm9v6Y80HcAKQb52xLnI5boXrwFnBFi1hoQc7KKpb8R73sgxxQPhVoF/ +hejFFE/tlEAwRce+L0r5ovaw0hks4SjDNjI7z5nYi6ObjdTRUFg7WY9HUspk32m7 +blIV2Tn67GTFal7F9uJk9m3JWMOhn3OvudguoPX0ZWEtgll+iP4axDSAFd2DWcXn +tCxzStdQjgHdZOxrL4FNW06xGxm6Nvi4zyuySfsCggEAOuIpC3ATBxRyZYMm/FGZ +tEquyV2omz8FQA1nJFzu7MMCHHPcdzSVH4Pl3GGloQi1gW51H8GuMDxZ/H2NcDWY +WuG49u1GFdKjinRXFKztnKBjNzHEVWRYfOSRuMh8N6SNKbYPnWlNos1k0IypFSGT +pe5uhnF58gK8wgD67bkLce43B6NEWSb+tSMx2qFE8SfqAQSoD6zv//NjA4OrKJNS +1RVFS279vpqMdib/qk+nFn3G2i0Dr1NEcpihHgCyAZff2Hze6pyjeQr+RrNE74VY +MudNiiG8lV2t2+tClZ6ULoaPvpIvAP04+WiYav+uOX0VxwO8tXgqWSQOCzNNxlr7 +IwKCAQA7odNjE6Sc2qiecrOu13kEi3gT0heshIyZ0XhePrS1vgHfCouIRvNMw4FT +45ZZUFDSdOxhrew5GuMeLvo2YILBjmkX3UqTojQMbur7FcGH8/P0Sm0f20Vc06oS +sQF5Ji4LSyf6t9oQKePjFIGoIc6pf6BXJZYP4rBnzQzUQjH2yzDYDY3TuV7bFJJU +DcSTGM6nP0fRMmgBtB14o7A6Gsy6X/N2ElgbvWT8YhmUC6H8DIzmZwHRKaG6C6g5 +eEjuAYenYNM4jxeteC1neUDIdGxH/BA7JrAqcGaN9GT+R47YIfiS2WrEssD1Pi5h +hJTbHtjEDJ7BHLC/CNUhXbpyyu1y +-----END PRIVATE KEY----- +)"; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) { + PKCS7 *pkcs7 = nullptr; + EVP_PKEY *key = nullptr; + + pkcs7 = d2i_PKCS7(nullptr, &buf, len); + if (pkcs7 == nullptr) { + goto end; + } + + { + BIO *key_bio = BIO_new_mem_buf(const_cast(kKey), sizeof(kKey) - 1); + key = PEM_read_bio_PrivateKey(key_bio, nullptr, nullptr, nullptr); + BIO_free(key_bio); + } + { + BIO *data_bio = BIO_new(BIO_s_mem()); +OPENSSL_BEGIN_ALLOW_DEPRECATED + PKCS7_decrypt(pkcs7, key, NULL, data_bio, 0); +OPENSSL_END_ALLOW_DEPRECATED + BIO_free(data_bio); + } + + end: + EVP_PKEY_free(key); + PKCS7_free(pkcs7); + + return 0; +}