From: Adam Kupczyk Date: Fri, 29 Jul 2016 14:09:02 +0000 (+0200) Subject: Introduced plugins for crypto and isal implementation. X-Git-Tag: v12.0.2~34^2~28 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=dbbf052fa00ddf12731aac75b0570760e7564ea5;p=ceph.git Introduced plugins for crypto and isal implementation. 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 --- diff --git a/.gitmodules b/.gitmodules index 76658d1ecf4e..8290e69a40b8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -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 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 69401efc062b..1f3e3e3b5f84 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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 index 000000000000..7a7baca85998 --- /dev/null +++ b/src/isa-l_crypto @@ -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 index 000000000000..7cf8369b14ee --- /dev/null +++ b/src/isa-l_crypto_plugin/CMakeLists.txt @@ -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 index 000000000000..caefa38a366f --- /dev/null +++ b/src/isa-l_crypto_plugin/crypto_accel.h @@ -0,0 +1,37 @@ +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2016 Mirantis, Inc. + * + * Author: Adam Kupczyk + * + * 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 +#include "include/Context.h" + +class CryptoAccel; +typedef ceph::shared_ptr 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 index 000000000000..e941c9fd2b53 --- /dev/null +++ b/src/isa-l_crypto_plugin/crypto_plugin.h @@ -0,0 +1,36 @@ +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2016 Mirantis, Inc. + * + * Author: Adam Kupczyk + * + * 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 index 000000000000..4d974156aaa8 --- /dev/null +++ b/src/isa-l_crypto_plugin/isal_crypto_accel.cc @@ -0,0 +1,45 @@ +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2016 Mirantis, Inc. + * + * Author: Adam Kupczyk + * + * 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 + +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(&key[0]), AES_256_KEYSIZE, keys_blk); + aes_cbc_enc_256(const_cast(in), + const_cast(&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(&key[0]), AES_256_KEYSIZE, keys_blk); + aes_cbc_dec_256(const_cast(in), const_cast(&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 index 000000000000..d7c68fadde5a --- /dev/null +++ b/src/isa-l_crypto_plugin/isal_crypto_accel.h @@ -0,0 +1,32 @@ +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2016 Mirantis, Inc. + * + * Author: Adam Kupczyk + * + * 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 index 000000000000..9ac0b88cb5a1 --- /dev/null +++ b/src/isa-l_crypto_plugin/isal_crypto_plugin.cc @@ -0,0 +1,34 @@ +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2016 Mirantis, Inc. + * + * Author: Adam Kupczyk + * + * 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 index 000000000000..af97ba98a6a0 --- /dev/null +++ b/src/isa-l_crypto_plugin/isal_crypto_plugin.h @@ -0,0 +1,43 @@ +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2016 Mirantis, Inc. + * + * Author: Adam Kupczyk + * + * 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 diff --git a/src/os/CMakeLists.txt b/src/os/CMakeLists.txt index 93255a3b0454..1194c3f57c83 100644 --- a/src/os/CMakeLists.txt +++ b/src/os/CMakeLists.txt @@ -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 diff --git a/src/rgw/rgw_crypt.cc b/src/rgw/rgw_crypt.cc index beeea6bd100b..8c9da69d23ff 100644 --- a/src/rgw/rgw_crypt.cc +++ b/src/rgw/rgw_crypt.cc @@ -11,6 +11,8 @@ #include "include/assert.h" #include #include +#include "../isa-l_crypto_plugin/crypto_accel.h" +#include "../isa-l_crypto_plugin/crypto_plugin.h" #ifdef USE_NSS # include @@ -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(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(&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(buf.c_str()); unsigned char* input_raw = reinterpret_cast(input.c_str()); unsigned char iv[AES_256_IVSIZE]; - result = cbc_transform(buf_raw, input_raw + in_ofs, aligned_size,