]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
Introduced plugins for crypto and isal implementation.
authorAdam Kupczyk <akupczyk@mirantis.com>
Fri, 29 Jul 2016 14:09:02 +0000 (16:09 +0200)
committerAdam Kupczyk <akupczyk@mirantis.com>
Wed, 5 Apr 2017 16:31:17 +0000 (18:31 +0200)
Added submodule for isa-l_crypto
Fixed problem with uninitialised var.
Enable to use crypto plugin if available.
Now isal crypto plugin compiles only on intel.

Signed-off-by: Adam Kupczyk <akupczyk@mirantis.com>
12 files changed:
.gitmodules
src/CMakeLists.txt
src/isa-l_crypto [new submodule]
src/isa-l_crypto_plugin/CMakeLists.txt [new file with mode: 0644]
src/isa-l_crypto_plugin/crypto_accel.h [new file with mode: 0644]
src/isa-l_crypto_plugin/crypto_plugin.h [new file with mode: 0644]
src/isa-l_crypto_plugin/isal_crypto_accel.cc [new file with mode: 0644]
src/isa-l_crypto_plugin/isal_crypto_accel.h [new file with mode: 0644]
src/isa-l_crypto_plugin/isal_crypto_plugin.cc [new file with mode: 0644]
src/isa-l_crypto_plugin/isal_crypto_plugin.h [new file with mode: 0644]
src/os/CMakeLists.txt
src/rgw/rgw_crypt.cc

index 76658d1ecf4e0d335a1f701a5c8746a8808f8eb2..8290e69a40b8751a515a01a62b6a5d24807adf31 100644 (file)
@@ -19,7 +19,6 @@
 [submodule "ceph-erasure-code-corpus"]
        path = ceph-erasure-code-corpus
        url = https://github.com/ceph/ceph-erasure-code-corpus.git
-
 [submodule "src/googletest"]
        path = src/googletest
        url = https://github.com/ceph/googletest
@@ -50,3 +49,6 @@
 [submodule "src/zstd"]
        path = src/zstd
        url = https://github.com/facebook/zstd
+[submodule "src/isa-l_crypto"]
+       path = src/isa-l_crypto
+       url = https://github.com/01org/isa-l_crypto
index 69401efc062bffe7464f28e7a9bcf031e2fb403f..1f3e3e3b5f84c805a3c4cd482ad3de5f87f8ca9c 100644 (file)
@@ -834,9 +834,13 @@ add_subdirectory(test)
 endif(WITH_TESTS)
 
 add_subdirectory(compressor)
+
 add_subdirectory(tools)
 
+add_subdirectory(isa-l_crypto_plugin)
+
 if(WITH_TESTS)
+
 configure_file(${CMAKE_SOURCE_DIR}/src/ceph-coverage.in
   ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ceph-coverage @ONLY)
 
diff --git a/src/isa-l_crypto b/src/isa-l_crypto
new file mode 160000 (submodule)
index 0000000..7a7baca
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit 7a7baca8599811141b6c657c8d3c47c12a855066
diff --git a/src/isa-l_crypto_plugin/CMakeLists.txt b/src/isa-l_crypto_plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..7cf8369
--- /dev/null
@@ -0,0 +1,38 @@
+set(isal_dir ${CMAKE_SOURCE_DIR}/src/isa-l_crypto)
+
+set(isal_crypto_plugin_srcs
+  isal_crypto_accel.cc 
+  isal_crypto_plugin.cc
+  ${isal_dir}/aes/cbc_pre.c
+  ${isal_dir}/aes/cbc_multibinary.asm
+  ${isal_dir}/aes/keyexp_128.asm
+  ${isal_dir}/aes/keyexp_192.asm
+  ${isal_dir}/aes/keyexp_256.asm
+  ${isal_dir}/aes/keyexp_multibinary.asm
+  ${isal_dir}/aes/cbc_dec_128_x4_sse.asm
+  ${isal_dir}/aes/cbc_dec_128_x8_avx.asm
+  ${isal_dir}/aes/cbc_dec_192_x4_sse.asm
+  ${isal_dir}/aes/cbc_dec_192_x8_avx.asm
+  ${isal_dir}/aes/cbc_dec_256_x4_sse.asm
+  ${isal_dir}/aes/cbc_dec_256_x8_avx.asm
+  ${isal_dir}/aes/cbc_enc_128_x4_sb.asm
+  ${isal_dir}/aes/cbc_enc_128_x8_sb.asm
+  ${isal_dir}/aes/cbc_enc_192_x4_sb.asm
+  ${isal_dir}/aes/cbc_enc_192_x8_sb.asm
+  ${isal_dir}/aes/cbc_enc_256_x4_sb.asm
+  ${isal_dir}/aes/cbc_enc_256_x8_sb.asm)
+
+add_library(isal_crypto_plugin_objs OBJECT ${isal_crypto_plugin_srcs})
+target_include_directories(isal_crypto_plugin_objs PRIVATE ${isal_dir}/include)
+set(isal_crypto_plugin_dir ${CMAKE_INSTALL_PKGLIBDIR}/crypto)
+
+add_custom_target(crypto_plugins)
+if(HAVE_GOOD_YASM_ELF64)
+add_dependencies(crypto_plugins ceph_crypto_isal)
+endif(HAVE_GOOD_YASM_ELF64)
+
+add_library(ceph_crypto_isal SHARED ${isal_crypto_plugin_srcs})
+target_include_directories(ceph_crypto_isal PRIVATE ${isal_dir}/include)
+add_dependencies(ceph_crypto_isal ${CMAKE_SOURCE_DIR}/src/ceph_ver.h)
+set_target_properties(ceph_crypto_isal PROPERTIES VERSION 1.0.0 SOVERSION 1)
+install(TARGETS ceph_crypto_isal DESTINATION ${isal_crypto_plugin_dir})
diff --git a/src/isa-l_crypto_plugin/crypto_accel.h b/src/isa-l_crypto_plugin/crypto_accel.h
new file mode 100644 (file)
index 0000000..caefa38
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2016 Mirantis, Inc.
+ *
+ * Author: Adam Kupczyk <akupczyk@mirantis.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ */
+
+#ifndef CRYPTO_ACCEL_H
+#define CRYPTO_ACCEL_H
+#include <cstddef>
+#include "include/Context.h"
+
+class CryptoAccel;
+typedef ceph::shared_ptr<CryptoAccel> CryptoAccelRef;
+
+class CryptoAccel {
+ public:
+  CryptoAccel() {}
+  virtual ~CryptoAccel() {}
+
+  static const int AES_256_IVSIZE = 128/8;
+  static const int AES_256_KEYSIZE = 256/8;
+  virtual bool cbc_encrypt(unsigned char* out, const unsigned char* in, size_t size,
+                   const unsigned char (&iv)[AES_256_IVSIZE],
+                   const unsigned char (&key)[AES_256_KEYSIZE]) = 0;
+  virtual bool cbc_decrypt(unsigned char* out, const unsigned char* in, size_t size,
+                   const unsigned char (&iv)[AES_256_IVSIZE],
+                   const unsigned char (&key)[AES_256_KEYSIZE]) = 0;
+};
+#endif
diff --git a/src/isa-l_crypto_plugin/crypto_plugin.h b/src/isa-l_crypto_plugin/crypto_plugin.h
new file mode 100644 (file)
index 0000000..e941c9f
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2016 Mirantis, Inc.
+ *
+ * Author: Adam Kupczyk <akupczyk@mirantis.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ */
+
+#ifndef CRYPTO_PLUGIN_H
+#define CRYPTO_PLUGIN_H
+
+// -----------------------------------------------------------------------------
+#include "include/memory.h"
+#include "common/PluginRegistry.h"
+#include "ostream"
+
+#include "../isa-l_crypto_plugin/crypto_accel.h"
+// -----------------------------------------------------------------------------
+
+class CryptoPlugin : public Plugin {
+
+public:
+  explicit CryptoPlugin(CephContext* cct) : Plugin(cct)
+  {}
+  ~CryptoPlugin()
+  {}
+  virtual int factory(CryptoAccelRef *cs,
+                      std::ostream *ss) = 0;
+};
+#endif
diff --git a/src/isa-l_crypto_plugin/isal_crypto_accel.cc b/src/isa-l_crypto_plugin/isal_crypto_accel.cc
new file mode 100644 (file)
index 0000000..4d97415
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2016 Mirantis, Inc.
+ *
+ * Author: Adam Kupczyk <akupczyk@mirantis.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ */
+
+#include "../isa-l_crypto_plugin/isal_crypto_accel.h"
+
+#include <isa-l_crypto/include/aes_cbc.h>
+
+bool ISALCryptoAccel::cbc_encrypt(unsigned char* out, const unsigned char* in, size_t size,
+                             const unsigned char (&iv)[AES_256_IVSIZE],
+                             const unsigned char (&key)[AES_256_KEYSIZE])
+{
+  if ((size % AES_256_IVSIZE) != 0) {
+    return false;
+  }
+  struct cbc_key_data *keys_blk = (struct cbc_key_data*) memalign(16, sizeof(struct cbc_key_data));
+  aes_cbc_precomp(const_cast<unsigned char*>(&key[0]), AES_256_KEYSIZE, keys_blk);
+  aes_cbc_enc_256(const_cast<unsigned char*>(in),
+                  const_cast<unsigned char*>(&iv[0]), keys_blk->enc_keys, out, size);
+  free(keys_blk);
+  return true;
+}
+bool ISALCryptoAccel::cbc_decrypt(unsigned char* out, const unsigned char* in, size_t size,
+                             const unsigned char (&iv)[AES_256_IVSIZE],
+                             const unsigned char (&key)[AES_256_KEYSIZE])
+{
+  if ((size % AES_256_IVSIZE) != 0) {
+    return false;
+  }
+  struct cbc_key_data *keys_blk = (struct cbc_key_data*) memalign(16, sizeof(struct cbc_key_data));
+  aes_cbc_precomp(const_cast<unsigned char*>(&key[0]), AES_256_KEYSIZE, keys_blk);
+  aes_cbc_dec_256(const_cast<unsigned char*>(in), const_cast<unsigned char*>(&iv[0]), keys_blk->dec_keys, out, size);
+  free(keys_blk);
+  return true;
+}
diff --git a/src/isa-l_crypto_plugin/isal_crypto_accel.h b/src/isa-l_crypto_plugin/isal_crypto_accel.h
new file mode 100644 (file)
index 0000000..d7c68fa
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2016 Mirantis, Inc.
+ *
+ * Author: Adam Kupczyk <akupczyk@mirantis.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ */
+
+#ifndef ISAL_CRYPTO_ACCEL_H
+#define ISAL_CRYPTO_ACCEL_H
+#include "../isa-l_crypto_plugin/crypto_accel.h"
+
+
+class ISALCryptoAccel : public CryptoAccel {
+ public:
+  ISALCryptoAccel() {}
+  virtual ~ISALCryptoAccel() {}
+
+  bool cbc_encrypt(unsigned char* out, const unsigned char* in, size_t size,
+                   const unsigned char (&iv)[AES_256_IVSIZE],
+                   const unsigned char (&key)[AES_256_KEYSIZE]) override;
+  bool cbc_decrypt(unsigned char* out, const unsigned char* in, size_t size,
+                   const unsigned char (&iv)[AES_256_IVSIZE],
+                   const unsigned char (&key)[AES_256_KEYSIZE]) override;
+};
+#endif
diff --git a/src/isa-l_crypto_plugin/isal_crypto_plugin.cc b/src/isa-l_crypto_plugin/isal_crypto_plugin.cc
new file mode 100644 (file)
index 0000000..9ac0b88
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2016 Mirantis, Inc.
+ *
+ * Author: Adam Kupczyk <akupczykd@mirantis.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ */
+
+
+// -----------------------------------------------------------------------------
+#include "../isa-l_crypto_plugin/isal_crypto_plugin.h"
+
+#include "ceph_ver.h"
+// -----------------------------------------------------------------------------
+
+const char *__ceph_plugin_version()
+{
+  return CEPH_GIT_NICE_VER;
+}
+
+int __ceph_plugin_init(CephContext *cct,
+                       const std::string& type,
+                       const std::string& name)
+{
+  PluginRegistry *instance = cct->get_plugin_registry();
+
+  return instance->add(type, name, new ISALCryptoPlugin(cct));
+}
diff --git a/src/isa-l_crypto_plugin/isal_crypto_plugin.h b/src/isa-l_crypto_plugin/isal_crypto_plugin.h
new file mode 100644 (file)
index 0000000..af97ba9
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2016 Mirantis, Inc.
+ *
+ * Author: Adam Kupczyk <akupczyk@mirantis.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ */
+
+#ifndef ISAL_CRYPTO_PLUGIN_H
+#define ISAL_CRYPTO_PLUGIN_H
+// -----------------------------------------------------------------------------
+#include "../isa-l_crypto_plugin/crypto_plugin.h"
+#include "../isa-l_crypto_plugin/isal_crypto_accel.h"
+// -----------------------------------------------------------------------------
+
+
+class ISALCryptoPlugin : public CryptoPlugin {
+
+  CryptoAccelRef cryptoaccel;
+public:
+
+  explicit ISALCryptoPlugin(CephContext* cct) : CryptoPlugin(cct)
+  {}
+  ~ISALCryptoPlugin()
+  {}
+  virtual int factory(CryptoAccelRef *cs,
+                      ostream *ss)
+  {
+    if (cryptoaccel == nullptr)
+    {
+      cryptoaccel = CryptoAccelRef(new ISALCryptoAccel);
+    }
+    *cs = cryptoaccel;
+    return 0;
+  }
+};
+#endif
index 93255a3b045431997dd2bb771a23c991fb5cc328..1194c3f57c83da32bab385b9b87d594f6d9b6e9c 100644 (file)
@@ -83,6 +83,8 @@ endif()
 target_link_libraries(os kv)
 
 add_dependencies(os compressor_plugins)
+add_dependencies(os ceph_crypto_isal)
+
 
 if(HAVE_LIBAIO)
   add_executable(ceph-bluestore-tool
index beeea6bd100bd8495040f648a5bcda63d85dda55..8c9da69d23ff4b44883be73041cc743da1a74d71 100644 (file)
@@ -11,6 +11,8 @@
 #include "include/assert.h"
 #include <boost/utility/string_ref.hpp>
 #include <rgw/rgw_keystone.h>
+#include "../isa-l_crypto_plugin/crypto_accel.h"
+#include "../isa-l_crypto_plugin/crypto_plugin.h"
 
 #ifdef USE_NSS
 # include <nspr.h>
@@ -192,6 +194,26 @@ const uint8_t AES_256_CTR::IV[AES_256_CTR::AES_256_IVSIZE] =
     { 'a', 'e', 's', '2', '5', '6', 'i', 'v', '_', 'c', 't', 'r', '1', '3', '3', '7' };
 
 
+CryptoAccelRef get_crypto_accel(CephContext *cct)
+{
+  CryptoAccelRef ca_impl = nullptr;
+  stringstream ss;
+  PluginRegistry *reg = cct->get_plugin_registry();
+  string crypto_accel_type = cct->_conf->async_compressor_type; //fixme
+  crypto_accel_type = "crypto_isal";
+
+  CryptoPlugin *factory = dynamic_cast<CryptoPlugin*>(reg->get_with_load("cryptoaccel", crypto_accel_type));
+  if (factory == nullptr) {
+    lderr(cct) << __func__ << " cannot load crypto accelerator of type " << crypto_accel_type << dendl;
+    return nullptr;
+  }
+  int err = factory->factory(&ca_impl, &ss);
+  if (err)
+    lderr(cct) << __func__ << " factory return error " << err << dendl;
+  return ca_impl;
+}
+
+
 /**
  * Encryption in CBC mode. Chunked to 4K blocks. offset is used as IV for 4K block.
  */
@@ -223,8 +245,8 @@ public:
 #ifdef USE_CRYPTOPP
 
   bool cbc_transform(unsigned char* out, const unsigned char* in, size_t size,
-                     unsigned char iv[AES_256_IVSIZE],
-                     unsigned char key[AES_256_KEYSIZE],
+                     const unsigned char (&iv)[AES_256_IVSIZE],
+                     const unsigned char (&key)[AES_256_KEYSIZE],
                      bool encrypt) {
     if (encrypt) {
       CBC_Mode< AES >::Encryption e;
@@ -241,8 +263,8 @@ public:
 #elif defined(USE_NSS)
 
   bool cbc_transform(unsigned char* out, const unsigned char* in, size_t size,
-                   unsigned char iv[AES_256_IVSIZE],
-                   unsigned char key[AES_256_KEYSIZE],
+                   const unsigned char (&iv)[AES_256_IVSIZE],
+                   const unsigned char (&key)[AES_256_KEYSIZE],
                    bool encrypt) {
     bool result = false;
     PK11SlotInfo *slot;
@@ -258,7 +280,7 @@ public:
     slot = PK11_GetBestSlot(CKM_AES_CBC, NULL);
     if (slot) {
       keyItem.type = siBuffer;
-      keyItem.data = key;
+      keyItem.data = const_cast<unsigned char*>(&key[0]);
       keyItem.len = AES_256_KEYSIZE;
       symkey = PK11_ImportSymKey(slot, CKM_AES_CBC, PK11_OriginUnwrap, CKA_UNWRAP, &keyItem, NULL);
       if (symkey) {
@@ -295,17 +317,32 @@ public:
 #error Must define USE_CRYPTOPP or USE_NSS
 #endif
 
+
+
   bool cbc_transform(unsigned char* out, const unsigned char* in, size_t size,
                      off_t stream_offset,
-                     unsigned char key[AES_256_KEYSIZE],
+                     const unsigned char (&key)[AES_256_KEYSIZE],
                      bool encrypt) {
+    static CryptoAccelRef crypto_accel = get_crypto_accel(cct);
+    //compressor(Compressor::create(c, c->_conf->async_compressor_type))
     bool result = true;
     unsigned char iv[AES_256_IVSIZE];
     for (size_t offset = 0; result && (offset < size); offset += CHUNK_SIZE) {
+      size_t process_size = offset + CHUNK_SIZE <= size ? CHUNK_SIZE : size - offset;
       prepare_iv(iv, stream_offset + offset);
-      result = cbc_transform(
-          out + offset, in + offset, offset + CHUNK_SIZE <= size ? CHUNK_SIZE : size - offset,
-          iv, key, encrypt);
+      if (crypto_accel != nullptr) {
+        if (encrypt) {
+          result = crypto_accel->cbc_encrypt(out + offset, in + offset,
+                                             process_size, iv, key);
+        } else {
+          result = crypto_accel->cbc_decrypt(out + offset, in + offset,
+                                             process_size, iv, key);
+        }
+      } else {
+        result = cbc_transform(
+            out + offset, in + offset, process_size,
+            iv, key, encrypt);
+      }
     }
     return result;
   }
@@ -321,7 +358,6 @@ public:
     unsigned char* buf_raw = reinterpret_cast<unsigned char*>(buf.c_str());
     unsigned char* input_raw = reinterpret_cast<unsigned char*>(input.c_str());
     unsigned char iv[AES_256_IVSIZE];
-
     result = cbc_transform(buf_raw,
                            input_raw + in_ofs,
                            aligned_size,