]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
common: implement HMACs on top of OpenSSL. 26875/head
authorRadoslaw Zarzynski <rzarzyns@redhat.com>
Mon, 11 Mar 2019 22:09:37 +0000 (23:09 +0100)
committerRadoslaw Zarzynski <rzarzyns@redhat.com>
Wed, 13 Mar 2019 00:23:09 +0000 (01:23 +0100)
Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
src/common/ceph_crypto.cc
src/common/ceph_crypto.h
src/msg/async/ProtocolV2.cc

index c5a7b9d5329cfda1b327957a35285f19a172c9c2..c3e84e9a57b1b0ab65b1ca2dd9054ec6ee4fa50e 100644 (file)
@@ -77,7 +77,7 @@ void ceph::crypto::shutdown(bool shared)
   pthread_mutex_unlock(&crypto_init_mutex);
 }
 
-ceph::crypto::HMAC::~HMAC()
+ceph::crypto::nss::HMAC::~HMAC()
 {
   PK11_DestroyContext(ctx, PR_TRUE);
   PK11_FreeSymKey(symkey);
index e32bc718ce6cbe20ee1751c47238c922ccda91ce..1189ae54cbd8b363ee91ff5d347aafe0f0484505 100644 (file)
@@ -24,7 +24,9 @@
 #endif /*USE_NSS*/
 
 #ifdef USE_OPENSSL
+#include <openssl/evp.h>
 #include <openssl/ossl_typ.h>
+#include <openssl/hmac.h>
 
 extern "C" {
   const EVP_MD *EVP_md5(void);
@@ -135,30 +137,10 @@ namespace ceph {
 }
 #endif /*USE_OPENSSL*/
 
-#if defined(USE_OPENSSL)
-namespace ceph {
-  namespace crypto {
-    using ceph::crypto::ssl::SHA256;
-    using ceph::crypto::ssl::MD5;
-    using ceph::crypto::ssl::SHA1;
-  }
-}
-#elif defined(USE_NSS)
-namespace ceph {
-  namespace crypto {
-    using ceph::crypto::nss::SHA256;
-    using ceph::crypto::nss::MD5;
-    using ceph::crypto::nss::SHA1;
-  }
-}
-#else
-# error "No supported crypto implementation found."
-#endif
-
 
 #ifdef USE_NSS
 namespace ceph {
-  namespace crypto {
+  namespace crypto::nss {
     class HMAC {
     private:
       PK11SlotInfo *slot;
@@ -217,7 +199,114 @@ namespace ceph {
     };
   }
 }
+#endif
+
+#ifdef USE_OPENSSL
+namespace ceph::crypto::ssl {
+# if OPENSSL_VERSION_NUMBER < 0x10100000L
+  class HMAC {
+  private:
+    HMAC_CTX mContext;
+    const EVP_MD *mpType;
+
+  public:
+    HMAC (const EVP_MD *type, const unsigned char *key, size_t length)
+      : mpType(type) {
+      ::memset(&mContext, 0, sizeof(mContext));
+      const auto r = HMAC_Init_ex(&mContext, key, length, mpType, nullptr);
+      ceph_assert_always(r == 1);
+    }
+    ~HMAC () {
+      HMAC_CTX_cleanup(&mContext);
+    }
+
+    void Restart () {
+      const auto r = HMAC_Init_ex(&mContext, nullptr, 0, mpType, nullptr);
+      ceph_assert_always(r == 1);
+    }
+    void Update (const unsigned char *input, size_t length) {
+      if (length) {
+        const auto r = HMAC_Update(&mContext, input, length);
+        ceph_assert_always(r == 1);
+      }
+    }
+    void Final (unsigned char *digest) {
+      unsigned int s;
+      const auto r = HMAC_Final(&mContext, digest, &s);
+      ceph_assert_always(r == 1);
+    }
+  };
+# else
+  class HMAC {
+  private:
+    HMAC_CTX *mpContext;
 
+  public:
+    HMAC (const EVP_MD *type, const unsigned char *key, size_t length)
+      : mpContext(HMAC_CTX_new()) {
+      const auto r = HMAC_Init_ex(mpContext, key, length, type, nullptr);
+      ceph_assert_always(r == 1);
+    }
+    ~HMAC () {
+      HMAC_CTX_free(mpContext);
+    }
+
+    void Restart () {
+      const EVP_MD * const type = HMAC_CTX_get_md(mpContext);
+      const auto r = HMAC_Init_ex(mpContext, nullptr, 0, type, nullptr);
+      ceph_assert_always(r == 1);
+    }
+    void Update (const unsigned char *input, size_t length) {
+      if (length) {
+        const auto r = HMAC_Update(mpContext, input, length);
+        ceph_assert_always(r == 1);
+      }
+    }
+    void Final (unsigned char *digest) {
+      unsigned int s;
+      const auto r = HMAC_Final(mpContext, digest, &s);
+      ceph_assert_always(r == 1);
+    }
+  };
+# endif // OPENSSL_VERSION_NUMBER < 0x10100000L
+
+  struct HMACSHA1 : public HMAC {
+    HMACSHA1 (const unsigned char *key, size_t length)
+      : HMAC(EVP_sha1(), key, length) {
+    }
+  };
+
+  struct HMACSHA256 : public HMAC {
+    HMACSHA256 (const unsigned char *key, size_t length)
+      : HMAC(EVP_sha256(), key, length) {
+    }
+  };
+}
+#endif /*USE_OPENSSL*/
+
+
+#if defined(USE_OPENSSL)
+namespace ceph {
+  namespace crypto {
+    using ceph::crypto::ssl::SHA256;
+    using ceph::crypto::ssl::MD5;
+    using ceph::crypto::ssl::SHA1;
+
+    using ceph::crypto::ssl::HMACSHA256;
+    using ceph::crypto::ssl::HMACSHA1;
+  }
+}
+#elif defined(USE_NSS)
+namespace ceph {
+  namespace crypto {
+    using ceph::crypto::nss::SHA256;
+    using ceph::crypto::nss::MD5;
+    using ceph::crypto::nss::SHA1;
+
+    using ceph::crypto::nss::HMACSHA256;
+    using ceph::crypto::nss::HMACSHA1;
+  }
+}
 #else
 // cppcheck-suppress preprocessorErrorDirective
 # error "No supported crypto implementation found."
index b4c5e76985d00590ea5a02f7b127a8b6b5c03303..5078947533ca695912de4652501ad083385b4481 100644 (file)
@@ -94,7 +94,6 @@ ProtocolV2::ProtocolV2(AsyncConnection *connection)
       bannerExchangeCallback(nullptr),
       next_tag(static_cast<Tag>(0)),
       keepalive(false) {
-  ceph::crypto::init(cct);
 }
 
 ProtocolV2::~ProtocolV2() {