]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: under fips, set flag to allow md5 in select rgw ops
authorMark Kogan <mkogan@redhat.com>
Tue, 12 Oct 2021 14:07:54 +0000 (14:07 +0000)
committerMark Kogan <mkogan@redhat.com>
Tue, 25 Jan 2022 15:15:29 +0000 (17:15 +0200)
Fixes: https://tracker.ceph.com/issues/52900
Signed-off-by: Mark Kogan <mkogan@redhat.com>
(cherry picked from commit a5df0cfcbe9b04832095f1f8ef0ce9f178888efd)

Conflicts:
src/rgw/rgw_etag_verifier.h
src/rgw/rgw_op.cc
src/rgw/rgw_sal_rados.cc

12 files changed:
src/common/ceph_crypto.cc
src/common/ceph_crypto.h
src/rgw/rgw_bucket.cc
src/rgw/rgw_etag_verifier.h
src/rgw/rgw_file.h
src/rgw/rgw_op.cc
src/rgw/rgw_putobj_processor.cc
src/rgw/rgw_rados.cc
src/rgw/rgw_rest_swift.cc
src/rgw/rgw_tools.h
src/rgw/rgw_zone.cc
src/rgw/services/svc_zone.cc

index cbeb1b06df615f621e287a05d236ba174544eb1d..e1f8705c9e6545f3b2277d0b45c068115e8f4b91 100644 (file)
@@ -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<void *>(reinterpret_cast<const void *>(input)), length);
index 6bf344aa8f13f1d03b9ff256048bb3f1219123fa..2feced03a99a5a1391489b4eee118bca563a7065 100644 (file)
@@ -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);
     };
index 725df23a1400a9003a8f51d48923ab360c204799..26e30cc023c792cd317da8abaa920c0f6e762403 100644 (file)
@@ -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);
 
index 48007cf169984d614bc16c0befc8317b25281c38..563b1e8c78f8a0207b690d58a2a170c423393f80 100644 (file)
@@ -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;
index d716f533999762d27ef3ba6d07ef67dd6a8fb497..65f5ee8b2ac6e44f22f0dfb1cb5d2cec282ab9bf 100644 (file)
@@ -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; }
index 02ae8a93fd046c074b789ddd7c10440e66ac9470..1943b19c7cdf624a128da98e2fb9f8d967b90fbc 100644 (file)
@@ -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<RGWAccessControlPolicy>(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<uint64_t, rgw_slo_part> 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<const unsigned char*>(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);
index acfe1c1641298b62ba99e6b088c1eecf482dfc03..6be1cecda19036b7c8c6b3121dbf97aa857b9397 100644 (file)
@@ -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];
index 0ba0038d3171f2fb24d5b32c6451669dcb4a78b4..3c2bd4eb8a216c1f50604d6ec8da4aa0818a7aa6 100644 (file)
@@ -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<string, bufferlist>::iterator iter = attrset.find(RGW_ATTR_ETAG);
index 5ab5ab47709eabd8e427116c95bcbc3a688ff103..9daf1b17ea41dcf375d6b7953743e6aac1c93cd0 100644 (file)
@@ -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(),
index c1da97c890892b827cbb7ab95711b7388842bc72..90512ad98e9b53cdf97aae5395642d22c2a849b9 100644 (file)
@@ -111,7 +111,12 @@ class RGWEtag
   H hash;
 
 public:
-  RGWEtag() {}
+  RGWEtag() {
+    if constexpr (std::is_same_v<H, MD5>) {
+      // 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);
index 51bf3b3f8fc2a084a406526e920a187a51c320eb..80e7c75c199b310aa4dde1a3f292228afa90a6f2 100644 (file)
@@ -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);
 
index f98be61af2c652af49c27ed3eda8a376b2a87c02..c12db48004d6a529a980f2824e25ba6857da72eb 100644 (file)
@@ -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);