]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
auth/cephx: modify client + server challenges hashing
authorYehuda Sadeh <ysadehwe@ibm.com>
Thu, 27 Feb 2025 21:14:06 +0000 (16:14 -0500)
committerPatrick Donnelly <pdonnell@ibm.com>
Mon, 5 Jan 2026 21:23:26 +0000 (16:23 -0500)
This applies when using ciphers that are not the original
AES-128 one. Use the hmac-sha256 hash now. With AES256KRB5
the original method of encrypting the combined challenges
doesn't work as the confounder randomizes the result.

Signed-off-by: Yehuda Sadeh <ysadehwe@ibm.com>
src/auth/Crypto.cc
src/auth/Crypto.h
src/auth/cephx/CephxProtocol.cc
src/auth/cephx/CephxProtocol.h

index aedf1a2ed4a0690d25e17aa2e8ff40561ff496f7..b05473442fe24f36fd1fd82bf90ec4221f1803d6 100644 (file)
@@ -315,6 +315,7 @@ public:
   int encrypt(CephContext *cct, const ceph::bufferlist& in,
              ceph::bufferlist& out,
               std::string* /* unused */) const override {
+    ldout(cct, 20) << "CryptoAESKeyHandler::encrypt()" << dendl;
     // we need to take into account the PKCS#7 padding. There *always* will
     // be at least one byte of padding. This stays even to input aligned to
     // AES_BLOCK_LEN. Otherwise we would face ambiguities during decryption.
@@ -357,6 +358,7 @@ public:
   int decrypt(CephContext *cct, const ceph::bufferlist& in,
              ceph::bufferlist& out,
              std::string* /* unused */) const override {
+    ldout(cct, 20) << "CryptoAESKeyHandler::decrypt()" << dendl;
     // PKCS#7 padding enlarges even empty plain-text to take 16 bytes.
     if (in.length() < AES_BLOCK_LEN || in.length() % AES_BLOCK_LEN) {
       return -1;
@@ -746,6 +748,7 @@ public:
   int encrypt(CephContext *cct, const ceph::bufferlist& in,
              ceph::bufferlist& out,
               std::string* /* unused */) const override {
+    ldout(cct, 20) << "CryptoAES256KRB5KeyHandler::encrypt()" << dendl;
     // encrypted (confounder | data) | hash
     ceph::bufferptr out_tmp{static_cast<unsigned>(
       AES256KRB5_BLOCK_LEN + in.length() + AES256KRB5_HASH_LEN)};
@@ -795,6 +798,7 @@ public:
              ceph::bufferlist& out,
              std::string* /* unused */) const override {
 
+    ldout(cct, 20) << "CryptoAES256KRB5KeyHandler::decrypt()" << dendl;
     if (in.length() < AES256KRB5_BLOCK_LEN + AES256KRB5_HASH_LEN) { /* minimum size: confounder + hmac */
       return -EINVAL;
     }
@@ -862,7 +866,6 @@ public:
 
     return 0;
   }
-
 };
 
 
index 9281b37c799355e946bc48778d0e1855f3b51d71..c72fbdb131882cab25729eebe7e3a877293b2009 100644 (file)
@@ -188,7 +188,7 @@ public:
     return ckh->encrypt(cct, in, out);
   }
 
-  sha256_digest_t hmac_sha256(CephContext*, const ceph::buffer::list& in) {
+  sha256_digest_t hmac_sha256(CephContext*, const ceph::buffer::list& in) const {
     ceph_assert(ckh);
     return ckh->hmac_sha256(in);
   }
index ed7c1eb4dd9ba57ffeab50bece5ee2815b7893e2..797ff4dadcd366d0febfa43239046c5bf8c6f9b8 100644 (file)
@@ -40,8 +40,21 @@ void cephx_calc_client_server_challenge(CephContext *cct, CryptoKey& secret, uin
   b.client_challenge = client_challenge;
 
   bufferlist enc;
-  if (encode_encrypt(cct, b, secret, enc, error))
-    return;
+  switch (secret.get_type()) {
+    case CEPH_CRYPTO_AES:
+      if (encode_encrypt(cct, b, secret, enc, error))
+        return;
+      break;
+    default:
+      /*
+       * AES256KRB5 has a builtin confounder that randomizes the result,
+       * so just encode_encrypt() cannot be used. We should use
+       * a cryptographic has anyway, keeping the old behavior
+       * for AES for backward compatibility.
+       */
+      if (encode_hash(cct, b, secret, enc, error))
+        return;
+  };
 
   uint64_t k = 0;
   const ceph_le64 *p = (const ceph_le64 *)enc.c_str();
index f79558d7aca2737481c813a2919976471482dc78..914ed3aa336b974024ab6198d8c70dc611f8adce 100644 (file)
@@ -673,4 +673,17 @@ int encode_encrypt(CephContext *cct, const T& t, const CryptoKey& key,
   return 0;
 }
 
+template <typename T>
+int encode_hash(CephContext *cct, const T& t, const CryptoKey& key,
+                ceph::buffer::list& out, std::string &error)
+{
+  using ceph::encode;
+  ceph::buffer::list bl_enc;
+  /* simple encoding, we don't need to add any magic because this will not be decoded */
+  ::encode(t, bl_enc);
+  sha256_digest_t hash = key.hmac_sha256(cct, bl_enc);
+  out.append((const char *)&hash, sizeof(hash));
+  return 0;
+}
+
 #endif