From: Mark Kogan Date: Tue, 12 Oct 2021 14:07:54 +0000 (+0000) Subject: rgw: under fips, set flag to allow md5 in select rgw ops X-Git-Tag: v16.2.8~123^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=07fe774e8947656662fa524567d42d5992552646;p=ceph.git rgw: under fips, set flag to allow md5 in select rgw ops Fixes: https://tracker.ceph.com/issues/52900 Signed-off-by: Mark Kogan (cherry picked from commit a5df0cfcbe9b04832095f1f8ef0ce9f178888efd) Conflicts: src/rgw/rgw_etag_verifier.h src/rgw/rgw_op.cc src/rgw/rgw_sal_rados.cc --- 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 725df23a140..26e30cc023c 100644 --- a/src/rgw/rgw_bucket.cc +++ b/src/rgw/rgw_bucket.cc @@ -2205,6 +2205,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 48007cf1699..563b1e8c78f 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::putobj::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; string get_calculated_etag() { return calculated_etag;} @@ -62,7 +65,10 @@ public: rgw::putobj::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 d716f533999..65f5ee8b2ac 100644 --- a/src/rgw/rgw_file.h +++ b/src/rgw/rgw_file.h @@ -2525,6 +2525,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 02ae8a93fd0..1943b19c7cd 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -414,7 +414,7 @@ static int get_multipart_info(const DoutPrefixProvider *dpp, struct req_state *s return get_multipart_info(dpp, s, meta_obj.get(), upload_info); } -static int read_bucket_policy(const DoutPrefixProvider *dpp, +static int read_bucket_policy(const DoutPrefixProvider *dpp, rgw::sal::RGWStore *store, struct req_state *s, RGWBucketInfo& bucket_info, @@ -742,7 +742,7 @@ int rgw_build_object_policies(const DoutPrefixProvider *dpp, rgw::sal::RGWRadosS s->object_acl = std::make_unique(s->cct); s->object->set_bucket(s->bucket.get()); - + s->object->set_atomic(s->obj_ctx); if (prefetch_data) { s->object->set_prefetch_data(s->obj_ctx); @@ -1628,6 +1628,8 @@ static int iterate_user_manifest_parts(const DoutPrefixProvider *dpp, rgw::sal::RGWBucket::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); @@ -1905,6 +1907,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) { @@ -3743,6 +3747,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; @@ -4215,6 +4221,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; @@ -5285,7 +5293,7 @@ void RGWCopyObj::execute(optional_yield y) // make reservation for notification if needed rgw::notify::reservation_t res(this, store, s, s->object.get()); - const auto event_type = rgw::notify::ObjectCreatedCopy; + const auto event_type = rgw::notify::ObjectCreatedCopy; op_ret = rgw::notify::publish_reserve(this, event_type, res, nullptr); if (op_ret < 0) { return; @@ -5664,6 +5672,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); @@ -6052,7 +6062,7 @@ void RGWInitMultipart::execute(optional_yield y) op_ret = obj_op->write_meta(this, bl.length(), 0, s->yield); } while (op_ret == -EEXIST); - + // send request to notification manager const auto ret = rgw::notify::publish_commit(s->object.get(), s->obj_size, ceph::real_clock::now(), attrs[RGW_ATTR_ETAG].to_str(), event_type, res, this); if (ret < 0) { @@ -6138,6 +6148,8 @@ void RGWCompleteMultipart::execute(optional_yield y) rgw::sal::RGWAttrs attrs; off_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); char final_etag[CEPH_CRYPTO_MD5_DIGESTSIZE]; char final_etag_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 16]; bufferlist etag_bl; @@ -6306,9 +6318,9 @@ void RGWCompleteMultipart::execute(optional_yield y) ldpp_dout(this, 0) << "ERROR: compression type was changed during multipart upload (" << cs_info.compression_type << ">>" << obj_part.cs_info.compression_type << ")" << dendl; op_ret = -ERR_INVALID_PART; - return; + return; } - + if (part_compressed) { int64_t new_ofs; // offset in compression data for new part if (cs_info.blocks.size() > 0) @@ -6322,7 +6334,7 @@ void RGWCompleteMultipart::execute(optional_yield y) cb.len = block.len; cs_info.blocks.push_back(cb); new_ofs = cb.new_ofs + cb.len; - } + } if (!compressed) cs_info.compression_type = obj_part.cs_info.compression_type; cs_info.orig_size += obj_part.cs_info.orig_size; @@ -6889,7 +6901,7 @@ void RGWDeleteMultiObj::execute(optional_yield y) // make reservation for notification if needed const auto versioned_object = s->bucket->versioning_enabled(); rgw::notify::reservation_t res(this, store, s, obj.get()); - const auto event_type = versioned_object && obj->get_instance().empty() ? + const auto event_type = versioned_object && obj->get_instance().empty() ? rgw::notify::ObjectRemovedDeleteMarkerCreated : rgw::notify::ObjectRemovedDelete; op_ret = rgw::notify::publish_reserve(this, event_type, res, nullptr); if (op_ret < 0) { @@ -7440,6 +7452,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 acfe1c16412..6be1cecda19 100644 --- a/src/rgw/rgw_putobj_processor.cc +++ b/src/rgw/rgw_putobj_processor.cc @@ -635,6 +635,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 0ba0038d317..3c2bd4eb8a2 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -5275,6 +5275,8 @@ static void generate_fake_tag(const DoutPrefixProvider *dpp, rgw::sal::RGWStore* 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 5ab5ab47709..9daf1b17ea4 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -985,6 +985,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_tools.h b/src/rgw/rgw_tools.h index c1da97c8908..90512ad98e9 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_zone.cc b/src/rgw/rgw_zone.cc index 51bf3b3f8fc..80e7c75c199 100644 --- a/src/rgw/rgw_zone.cc +++ b/src/rgw/rgw_zone.cc @@ -1834,6 +1834,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 f98be61af2c..c12db48004d 100644 --- a/src/rgw/services/svc_zone.cc +++ b/src/rgw/services/svc_zone.cc @@ -435,6 +435,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);