]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
common: Use OpenSSL for cryptographic hashing 25773/head
authorJames P. Weaver <james.barrett@bbc.co.uk>
Thu, 3 Jan 2019 13:24:23 +0000 (13:24 +0000)
committerJames P. Weaver <james.barrett@bbc.co.uk>
Mon, 28 Jan 2019 13:46:02 +0000 (13:46 +0000)
The OpenSSL implementation of the hashing algorithms is faster than the NSS version, and
so should be preferred when available

Signed-off-by: James Weaver <james.barrett@bbc.co.uk>
src/common/ceph_crypto.cc
src/common/ceph_crypto.h

index 38b47826e7abe653165054178d4940bba69b6c6a..c5a7b9d5329cfda1b327957a35285f19a172c9c2 100644 (file)
 #include <secmod.h>
 #include <nspr.h>
 
+#endif /*USE_NSS*/
+
+#ifdef USE_OPENSSL
+#include <openssl/evp.h>
+#endif /*USE_OPENSSL*/
+
+#ifdef USE_NSS
+
 static pthread_mutex_t crypto_init_mutex = PTHREAD_MUTEX_INITIALIZER;
 static uint32_t crypto_refs = 0;
 static NSSInitContext *crypto_context = NULL;
@@ -51,13 +59,13 @@ void ceph::crypto::init(CephContext *cct)
                                      SECMOD_DB, &init_params, flags);
   }
   pthread_mutex_unlock(&crypto_init_mutex);
-  ceph_assert(crypto_context != NULL);
+  ceph_assert_always(crypto_context != NULL);
 }
 
 void ceph::crypto::shutdown(bool shared)
 {
   pthread_mutex_lock(&crypto_init_mutex);
-  ceph_assert(crypto_refs > 0);
+  ceph_assert_always(crypto_refs > 0);
   if (--crypto_refs == 0) {
     NSS_ShutdownContext(crypto_context);
     if (!shared) {
@@ -78,4 +86,32 @@ ceph::crypto::HMAC::~HMAC()
 
 #else
 # error "No supported crypto implementation found."
-#endif
+#endif /*USE_NSS*/
+
+#ifdef USE_OPENSSL
+
+ceph::crypto::ssl::OpenSSLDigest::OpenSSLDigest(const EVP_MD * _type)
+  : mpContext(EVP_MD_CTX_create())
+  , mpType(_type) {
+  this->Restart();
+}
+
+ceph::crypto::ssl::OpenSSLDigest::~OpenSSLDigest() {
+  EVP_MD_CTX_destroy(mpContext);
+}
+
+void ceph::crypto::ssl::OpenSSLDigest::Restart() {
+  EVP_DigestInit_ex(mpContext, mpType, NULL);
+}
+
+void ceph::crypto::ssl::OpenSSLDigest::Update(const unsigned char *input, size_t length) {
+  if (length) {
+    EVP_DigestUpdate(mpContext, const_cast<void *>(reinterpret_cast<const void *>(input)), length);
+  }
+}
+
+void ceph::crypto::ssl::OpenSSLDigest::Final(unsigned char *digest) {
+  unsigned int s;
+  EVP_DigestFinal_ex(mpContext, digest, &s);
+}
+#endif /*USE_OPENSSL*/
index 2234e9c05819e5721dd315f2706a80cb286eb7b8..e32bc718ce6cbe20ee1751c47238c922ccda91ce 100644 (file)
@@ -1,3 +1,4 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 #ifndef CEPH_CRYPTO_H
 #define CEPH_CRYPTO_H
 
 // with error checking, and just say these really should never fail.
 // This assert MUST NOT be compiled out, even on non-debug builds.
 # include "include/ceph_assert.h"
+#endif /*USE_NSS*/
+
+#ifdef USE_OPENSSL
+#include <openssl/ossl_typ.h>
+
+extern "C" {
+  const EVP_MD *EVP_md5(void);
+  const EVP_MD *EVP_sha1(void);
+  const EVP_MD *EVP_sha256(void);
+}
+#endif /*USE_OPENSSL*/
 
 namespace ceph {
   namespace crypto {
     void assert_init();
     void init(CephContext *cct);
     void shutdown(bool shared=true);
-    class Digest {
-    private:
-      PK11Context *ctx;
-      size_t digest_size;
-    public:
-      Digest (SECOidTag _type, size_t _digest_size) : digest_size(_digest_size) {
-       ctx = PK11_CreateDigestContext(_type);
-       ceph_assert_always(ctx);
-       Restart();
-      }
-      ~Digest () {
-       PK11_DestroyContext(ctx, PR_TRUE);
-      }
-      void Restart() {
-       SECStatus s;
-       s = PK11_DigestBegin(ctx);
-       ceph_assert_always(s == SECSuccess);
-      }
-      void Update (const unsigned char *input, size_t length) {
-        if (length) {
+  }
+}
+
+#ifdef USE_NSS
+namespace ceph {
+  namespace crypto {
+    namespace nss {
+      class NSSDigest {
+      private:
+        PK11Context *ctx;
+        size_t digest_size;
+      public:
+        NSSDigest (SECOidTag _type, size_t _digest_size)
+         : digest_size(_digest_size) {
+         ctx = PK11_CreateDigestContext(_type);
+         ceph_assert_always(ctx);
+         Restart();
+        }
+        ~NSSDigest () {
+         PK11_DestroyContext(ctx, PR_TRUE);
+       }
+       void Restart() {
          SECStatus s;
-         s = PK11_DigestOp(ctx, input, length);
+         s = PK11_DigestBegin(ctx);
          ceph_assert_always(s == SECSuccess);
-        }
-      }
-      void Final (unsigned char *digest) {
-       SECStatus s;
-       unsigned int dummy;
-       s = PK11_DigestFinal(ctx, digest, &dummy, digest_size);
-       ceph_assert_always(s == SECSuccess);
-       ceph_assert_always(dummy == digest_size);
-       Restart();
-      }
-    };
-    class MD5 : public Digest {
-    public:
-      MD5 () : Digest(SEC_OID_MD5, CEPH_CRYPTO_MD5_DIGESTSIZE) { }
-    };
+       }
+       void Update (const unsigned char *input, size_t length) {
+         if (length) {
+           SECStatus s;
+           s = PK11_DigestOp(ctx, input, length);
+           ceph_assert_always(s == SECSuccess);
+         }
+       }
+       void Final (unsigned char *digest) {
+         SECStatus s;
+         unsigned int dummy;
+         s = PK11_DigestFinal(ctx, digest, &dummy, digest_size);
+         ceph_assert_always(s == SECSuccess);
+         ceph_assert_always(dummy == digest_size);
+         Restart();
+       }
+      };
 
-    class SHA1 : public Digest {
-    public:
-      SHA1 () : Digest(SEC_OID_SHA1, CEPH_CRYPTO_SHA1_DIGESTSIZE) { }
-    };
+      class MD5 : public NSSDigest {
+      public:
+       MD5 () : NSSDigest(SEC_OID_MD5, CEPH_CRYPTO_MD5_DIGESTSIZE) { }
+      };
 
-    class SHA256 : public Digest {
-    public:
-      SHA256 () : Digest(SEC_OID_SHA256, CEPH_CRYPTO_SHA256_DIGESTSIZE) { }
-    };
+      class SHA1 : public NSSDigest {
+      public:
+        SHA1 () : NSSDigest(SEC_OID_SHA1, CEPH_CRYPTO_SHA1_DIGESTSIZE) { }
+      };
+
+      class SHA256 : public NSSDigest {
+      public:
+        SHA256 () : NSSDigest(SEC_OID_SHA256, CEPH_CRYPTO_SHA256_DIGESTSIZE) { }
+      };
+    }
+  }
+}
+#endif /*USE_NSS*/
+
+#ifdef USE_OPENSSL
+namespace ceph {
+  namespace crypto {
+    namespace ssl {
+      class OpenSSLDigest {
+      private:
+       EVP_MD_CTX *mpContext;
+       const EVP_MD *mpType;
+      public:
+       OpenSSLDigest (const EVP_MD *_type);
+       ~OpenSSLDigest ();
+       void Restart();
+       void Update (const unsigned char *input, size_t length);
+       void Final (unsigned char *digest);
+      };
+
+      class MD5 : public OpenSSLDigest {
+      public:
+       MD5 () : OpenSSLDigest(EVP_md5()) { }
+      };
+
+      class SHA1 : public OpenSSLDigest {
+      public:
+        SHA1 () : OpenSSLDigest(EVP_sha1()) { }
+      };
+
+      class SHA256 : public OpenSSLDigest {
+      public:
+        SHA256 () : OpenSSLDigest(EVP_sha256()) { }
+      };
+    }
+  }
+}
+#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 {
     class HMAC {
     private:
       PK11SlotInfo *slot;