From a5df0cfcbe9b04832095f1f8ef0ce9f178888efd Mon Sep 17 00:00:00 2001 From: Mark Kogan Date: Tue, 12 Oct 2021 14:07:54 +0000 Subject: [PATCH] rgw: under fips, set flag to allow md5 in select rgw ops Fixes: https://tracker.ceph.com/issues/52900 Signed-off-by: Mark Kogan --- src/common/ceph_crypto.cc | 5 +++++ src/common/ceph_crypto.h | 1 + src/rgw/rgw_bucket.cc | 2 ++ src/rgw/rgw_etag_verifier.h | 10 ++++++++-- src/rgw/rgw_file.h | 2 ++ src/rgw/rgw_op.cc | 14 ++++++++++++++ src/rgw/rgw_putobj_processor.cc | 2 ++ src/rgw/rgw_rados.cc | 2 ++ src/rgw/rgw_rest_swift.cc | 2 ++ src/rgw/rgw_sal_rados.cc | 2 ++ src/rgw/rgw_tools.h | 7 ++++++- src/rgw/rgw_torrent.cc | 1 - src/rgw/rgw_zone.cc | 2 ++ src/rgw/services/svc_zone.cc | 2 ++ 14 files changed, 50 insertions(+), 4 deletions(-) diff --git a/src/common/ceph_crypto.cc b/src/common/ceph_crypto.cc index cbeb1b06df6..e1f8705c9e6 100644 --- a/src/common/ceph_crypto.cc +++ b/src/common/ceph_crypto.cc @@ -196,6 +196,11 @@ void ssl::OpenSSLDigest::Restart() { EVP_DigestInit_ex(mpContext, mpType, NULL); } +void ssl::OpenSSLDigest::SetFlags(int flags) { + EVP_MD_CTX_set_flags(mpContext, flags); + this->Restart(); +} + void ssl::OpenSSLDigest::Update(const unsigned char *input, size_t length) { if (length) { EVP_DigestUpdate(mpContext, const_cast(reinterpret_cast(input)), length); diff --git a/src/common/ceph_crypto.h b/src/common/ceph_crypto.h index 6bf344aa8f1..2feced03a99 100644 --- a/src/common/ceph_crypto.h +++ b/src/common/ceph_crypto.h @@ -52,6 +52,7 @@ namespace TOPNSPC::crypto { OpenSSLDigest (const EVP_MD *_type); ~OpenSSLDigest (); void Restart(); + void SetFlags(int flags); void Update (const unsigned char *input, size_t length); void Final (unsigned char *digest); }; diff --git a/src/rgw/rgw_bucket.cc b/src/rgw/rgw_bucket.cc index edc7f802731..21aa6ff419e 100644 --- a/src/rgw/rgw_bucket.cc +++ b/src/rgw/rgw_bucket.cc @@ -1909,6 +1909,8 @@ static void get_md5_digest(const RGWBucketEntryPoint *be, string& md5_digest) { f->flush(bl); MD5 hash; + // Allow use of MD5 digest in FIPS mode for non-cryptographic purposes + hash.SetFlags(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); hash.Update((const unsigned char *)bl.c_str(), bl.length()); hash.Final(m); diff --git a/src/rgw/rgw_etag_verifier.h b/src/rgw/rgw_etag_verifier.h index 75a0e3e4724..56a679ebddd 100644 --- a/src/rgw/rgw_etag_verifier.h +++ b/src/rgw/rgw_etag_verifier.h @@ -30,7 +30,10 @@ protected: public: ETagVerifier(CephContext* cct_, rgw::sal::DataProcessor *next) - : Pipe(next), cct(cct_) {} + : Pipe(next), cct(cct_) { + // Allow use of MD5 digest in FIPS mode for non-cryptographic purposes + hash.SetFlags(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + } virtual void calculate_etag() = 0; std::string get_calculated_etag() { return calculated_etag;} @@ -62,7 +65,10 @@ public: rgw::sal::DataProcessor *next) : ETagVerifier(cct, next), part_ofs(std::move(part_ofs)) - {} + { + // Allow use of MD5 digest in FIPS mode for non-cryptographic purposes + hash.SetFlags(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + } int process(bufferlist&& data, uint64_t logical_offset) override; void calculate_etag() override; diff --git a/src/rgw/rgw_file.h b/src/rgw/rgw_file.h index c05562881d6..b5ab94986dc 100644 --- a/src/rgw/rgw_file.h +++ b/src/rgw/rgw_file.h @@ -2517,6 +2517,8 @@ public: // invoking this classes's header_init() (void) RGWWriteRequest::header_init(); op = this; + // Allow use of MD5 digest in FIPS mode for non-cryptographic purposes + hash.SetFlags(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); } bool only_bucket() override { return true; } diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 25bf48daff9..a1f99507504 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -1674,6 +1674,8 @@ static int iterate_user_manifest_parts(const DoutPrefixProvider *dpp, rgw::sal::Bucket::ListResults results; MD5 etag_sum; + // Allow use of MD5 digest in FIPS mode for non-cryptographic purposes + etag_sum.SetFlags(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); do { static constexpr auto MAX_LIST_OBJS = 100u; int r = bucket->list(dpp, params, MAX_LIST_OBJS, results, y); @@ -1952,6 +1954,8 @@ int RGWGetObj::handle_slo_manifest(bufferlist& bl, optional_yield y) map slo_parts; MD5 etag_sum; + // Allow use of MD5 digest in FIPS mode for non-cryptographic purposes + etag_sum.SetFlags(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); total_len = 0; for (const auto& entry : slo_info.entries) { @@ -3829,6 +3833,8 @@ void RGWPutObj::execute(optional_yield y) char calc_md5[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 1]; unsigned char m[CEPH_CRYPTO_MD5_DIGESTSIZE]; MD5 hash; + // Allow use of MD5 digest in FIPS mode for non-cryptographic purposes + hash.SetFlags(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); bufferlist bl, aclbl, bs; int len; @@ -4300,6 +4306,8 @@ void RGWPostObj::execute(optional_yield y) char calc_md5[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 1]; unsigned char m[CEPH_CRYPTO_MD5_DIGESTSIZE]; MD5 hash; + // Allow use of MD5 digest in FIPS mode for non-cryptographic purposes + hash.SetFlags(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); ceph::buffer::list bl, aclbl; int len = 0; @@ -5769,6 +5777,8 @@ void RGWPutLC::execute(optional_yield y) ldpp_dout(this, 15) << "read len=" << data.length() << " data=" << (buf ? buf : "") << dendl; MD5 data_hash; + // Allow use of MD5 digest in FIPS mode for non-cryptographic purposes + data_hash.SetFlags(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); unsigned char data_hash_res[CEPH_CRYPTO_MD5_DIGESTSIZE]; data_hash.Update(reinterpret_cast(buf), data.length()); data_hash.Final(data_hash_res); @@ -6362,6 +6372,8 @@ bool RGWCompleteMultipart::check_previously_completed(const RGWMultiCompleteUplo string oetag = sattrs[RGW_ATTR_ETAG].to_str(); MD5 hash; + // Allow use of MD5 digest in FIPS mode for non-cryptographic purposes + hash.SetFlags(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); for (const auto& [index, part] : parts->parts) { std::string partetag = rgw_string_unquote(part); char petag[CEPH_CRYPTO_MD5_DIGESTSIZE]; @@ -7390,6 +7402,8 @@ int RGWBulkUploadOp::handle_file(const std::string_view path, ssize_t len = 0; size_t ofs = 0; MD5 hash; + // Allow use of MD5 digest in FIPS mode for non-cryptographic purposes + hash.SetFlags(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); do { ceph::bufferlist data; len = body.get_at_most(s->cct->_conf->rgw_max_chunk_size, data); diff --git a/src/rgw/rgw_putobj_processor.cc b/src/rgw/rgw_putobj_processor.cc index 58cff298028..3e95b984e14 100644 --- a/src/rgw/rgw_putobj_processor.cc +++ b/src/rgw/rgw_putobj_processor.cc @@ -639,6 +639,8 @@ int AppendObjectProcessor::complete(size_t accounted_size, const string &etag, c //calculate the etag if (!cur_etag.empty()) { MD5 hash; + // Allow use of MD5 digest in FIPS mode for non-cryptographic purposes + hash.SetFlags(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); char petag[CEPH_CRYPTO_MD5_DIGESTSIZE]; char final_etag[CEPH_CRYPTO_MD5_DIGESTSIZE]; char final_etag_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 16]; diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 9b4f77a8ca9..4574f4c3258 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -5316,6 +5316,8 @@ static void generate_fake_tag(const DoutPrefixProvider *dpp, rgw::sal::Store* st unsigned char md5[CEPH_CRYPTO_MD5_DIGESTSIZE]; char md5_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 1]; MD5 hash; + // Allow use of MD5 digest in FIPS mode for non-cryptographic purposes + hash.SetFlags(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); hash.Update((const unsigned char *)manifest_bl.c_str(), manifest_bl.length()); map::iterator iter = attrset.find(RGW_ATTR_ETAG); diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc index 124ce202f1d..0a651bbb96a 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -977,6 +977,8 @@ int RGWPutObj_ObjStore_SWIFT::get_params(optional_yield y) } MD5 etag_sum; + // Allow use of MD5 digest in FIPS mode for non-cryptographic purposes + etag_sum.SetFlags(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); uint64_t total_size = 0; for (auto& entry : slo_info->entries) { etag_sum.Update((const unsigned char *)entry.etag.c_str(), diff --git a/src/rgw/rgw_sal_rados.cc b/src/rgw/rgw_sal_rados.cc index 5ce3b2f0009..de3ade75588 100644 --- a/src/rgw/rgw_sal_rados.cc +++ b/src/rgw/rgw_sal_rados.cc @@ -2225,6 +2225,8 @@ int RadosMultipartUpload::complete(const DoutPrefixProvider *dpp, std::string etag; bufferlist etag_bl; MD5 hash; + // Allow use of MD5 digest in FIPS mode for non-cryptographic purposes + hash.SetFlags(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); bool truncated; int ret; diff --git a/src/rgw/rgw_tools.h b/src/rgw/rgw_tools.h index df17f3914df..b842916fd87 100644 --- a/src/rgw/rgw_tools.h +++ b/src/rgw/rgw_tools.h @@ -111,7 +111,12 @@ class RGWEtag H hash; public: - RGWEtag() {} + RGWEtag() { + if constexpr (std::is_same_v) { + // Allow use of MD5 digest in FIPS mode for non-cryptographic purposes + hash.SetFlags(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + } + } void update(const char *buf, size_t len) { hash.Update((const unsigned char *)buf, len); diff --git a/src/rgw/rgw_torrent.cc b/src/rgw/rgw_torrent.cc index 887b13a92b4..41a4a4d91a5 100644 --- a/src/rgw/rgw_torrent.cc +++ b/src/rgw/rgw_torrent.cc @@ -19,7 +19,6 @@ using namespace std; using namespace librados; using namespace boost; -using ceph::crypto::MD5; using ceph::crypto::SHA1; seed::seed() diff --git a/src/rgw/rgw_zone.cc b/src/rgw/rgw_zone.cc index 9dd98d43f5d..013793c7e63 100644 --- a/src/rgw/rgw_zone.cc +++ b/src/rgw/rgw_zone.cc @@ -1905,6 +1905,8 @@ static uint32_t gen_short_zone_id(const std::string zone_id) { unsigned char md5[CEPH_CRYPTO_MD5_DIGESTSIZE]; MD5 hash; + // Allow use of MD5 digest in FIPS mode for non-cryptographic purposes + hash.SetFlags(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); hash.Update((const unsigned char *)zone_id.c_str(), zone_id.size()); hash.Final(md5); diff --git a/src/rgw/services/svc_zone.cc b/src/rgw/services/svc_zone.cc index a3502b3b5ab..995abe60686 100644 --- a/src/rgw/services/svc_zone.cc +++ b/src/rgw/services/svc_zone.cc @@ -565,6 +565,8 @@ int RGWSI_Zone::replace_region_with_zonegroup(const DoutPrefixProvider *dpp, opt unsigned char md5[CEPH_CRYPTO_MD5_DIGESTSIZE]; char md5_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 1]; MD5 hash; + // Allow use of MD5 digest in FIPS mode for non-cryptographic purposes + hash.SetFlags(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); hash.Update((const unsigned char *)new_realm_name.c_str(), new_realm_name.length()); hash.Final(md5); buf_to_hex(md5, CEPH_CRYPTO_MD5_DIGESTSIZE, md5_str); -- 2.39.5