auth/cephx/CephxSessionHandler: implement CEPHX_V2 calculation mode
authorSage Weil <sage@redhat.com>
Fri, 25 May 2018 14:32:13 +0000 (09:32 -0500)
committerSage Weil <sage@redhat.com>
Fri, 25 May 2018 14:32:13 +0000 (09:32 -0500)
Derive the signature from the entire buffer (both cipher blocks).

Signed-off-by: Sage Weil <sage@redhat.com>
(cherry picked from commit 8f396cf35a3826044b089141667a196454c0a587)

# Conflicts:
# src/auth/cephx/CephxSessionHandler.cc

- master and mimic use no_bl crypto interface, which doesn't exist here,
so fall back to using bufferlist-based calls into encrypt().

(cherry picked from commit a2b04cc337a6f6f7b7a8b02bf31a8f3448670645)

# Conflicts:
# src/auth/cephx/CephxSessionHandler.cc

- mswab differences

src/auth/cephx/CephxSessionHandler.cc

index 30ed852ba6fc3880c983ee9354ca8e645f620f00..d77c61cec59accc8188903cb239c62f11106b0e9 100644 (file)
@@ -29,33 +29,75 @@ int CephxSessionHandler::_calc_signature(Message *m, uint64_t *psig)
   const ceph_msg_header& header = m->get_header();
   const ceph_msg_footer& footer = m->get_footer();
 
-  // optimized signature calculation
-  // - avoid temporary allocated buffers from encode_encrypt[_enc_bl]
-  // - skip the leading 4 byte wrapper from encode_encrypt
-  struct {
-    __u8 v;
-    __le64 magic;
-    __le32 len;
-    __le32 header_crc;
-    __le32 front_crc;
-    __le32 middle_crc;
-    __le32 data_crc;
-  } __attribute__ ((packed)) sigblock = {
-    1, mswab64(AUTH_ENC_MAGIC), mswab32(4*4),
-    mswab32(header.crc), mswab32(footer.front_crc),
-    mswab32(footer.middle_crc), mswab32(footer.data_crc)
-  };
-  bufferlist bl_plaintext;
-  bl_plaintext.append(buffer::create_static(sizeof(sigblock), (char*)&sigblock));
-
-  bufferlist bl_ciphertext;
-  if (key.encrypt(cct, bl_plaintext, bl_ciphertext, NULL) < 0) {
-    lderr(cct) << __func__ << " failed to encrypt signature block" << dendl;
-    return -1;
-  }
+  if ((features & CEPH_FEATURE_CEPHX_V2) == 0) {
+    // legacy pre-mimic behavior for compatibility
+
+    // optimized signature calculation
+    // - avoid temporary allocated buffers from encode_encrypt[_enc_bl]
+    // - skip the leading 4 byte wrapper from encode_encrypt
+    struct {
+      __u8 v;
+      __le64 magic;
+      __le32 len;
+      __le32 header_crc;
+      __le32 front_crc;
+      __le32 middle_crc;
+      __le32 data_crc;
+    } __attribute__ ((packed)) sigblock = {
+      1, mswab64(AUTH_ENC_MAGIC), mswab32(4*4),
+      mswab32(header.crc), mswab32(footer.front_crc),
+      mswab32(footer.middle_crc), mswab32(footer.data_crc)
+    };
+
+    bufferlist bl_plaintext;
+    bl_plaintext.append(buffer::create_static(sizeof(sigblock),
+                                             (char*)&sigblock));
+
+    bufferlist bl_ciphertext;
+    if (key.encrypt(cct, bl_plaintext, bl_ciphertext, NULL) < 0) {
+      lderr(cct) << __func__ << " failed to encrypt signature block" << dendl;
+      return -1;
+    }
 
-  bufferlist::iterator ci = bl_ciphertext.begin();
-  ::decode(*psig, ci);
+    bufferlist::iterator ci = bl_ciphertext.begin();
+    ::decode(*psig, ci);
+  } else {
+    // newer mimic+ signatures
+    struct {
+      __le32 header_crc;
+      __le32 front_crc;
+      __le32 front_len;
+      __le32 middle_crc;
+      __le32 middle_len;
+      __le32 data_crc;
+      __le32 data_len;
+      __le32 seq_lower_word;
+    } __attribute__ ((packed)) sigblock = {
+      mswab32(header.crc),
+      mswab32(footer.front_crc),
+      mswab32(header.front_len),
+      mswab32(footer.middle_crc),
+      mswab32(header.middle_len),
+      mswab32(footer.data_crc),
+      mswab32(header.data_len),
+      mswab32((uint32_t)header.seq)
+    };
+
+    bufferlist bl_plaintext;
+    bl_plaintext.append(buffer::create_static(sizeof(sigblock),
+                                             (char*)&sigblock));
+
+    bufferlist bl_ciphertext;
+    if (key.encrypt(cct, bl_plaintext, bl_ciphertext, NULL) < 0) {
+      lderr(cct) << __func__ << " failed to encrypt signature block" << dendl;
+      return -1;
+    }
+
+    struct enc {
+      __le64 a, b, c, d;
+    } *penc = reinterpret_cast<enc*>(bl_ciphertext.c_str());
+    *psig = penc->a ^ penc->b ^ penc->c ^ penc->d;
+  }
 
   ldout(cct, 10) << __func__ << " seq " << m->get_seq()
                 << " front_crc_ = " << footer.front_crc