X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fauth%2FCrypto.cc;fp=src%2Fceph%2Fsrc%2Fauth%2FCrypto.cc;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=0186b7b2255d670a218a8883751472164be403b9;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git diff --git a/src/ceph/src/auth/Crypto.cc b/src/ceph/src/auth/Crypto.cc deleted file mode 100644 index 0186b7b..0000000 --- a/src/ceph/src/auth/Crypto.cc +++ /dev/null @@ -1,492 +0,0 @@ -// vim: ts=8 sw=2 smarttab -/* - * Ceph - scalable distributed file system - * - * Copyright (C) 2004-2009 Sage Weil - * - * This is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software - * Foundation. See file COPYING. - * - */ - -#include -#include "Crypto.h" -#ifdef USE_CRYPTOPP -# include -# include -# include -#elif defined(USE_NSS) -# include -# include -# include -#endif - -#include "include/assert.h" -#include "common/Clock.h" -#include "common/armor.h" -#include "common/ceph_crypto.h" -#include "common/hex.h" -#include "common/safe_io.h" -#include "include/ceph_fs.h" -#include "include/compat.h" -#include "common/Formatter.h" -#include "common/debug.h" -#include - -int get_random_bytes(char *buf, int len) -{ - int fd = TEMP_FAILURE_RETRY(::open("/dev/urandom", O_RDONLY)); - if (fd < 0) - return -errno; - int ret = safe_read_exact(fd, buf, len); - VOID_TEMP_FAILURE_RETRY(::close(fd)); - return ret; -} - -static int get_random_bytes(int len, bufferlist& bl) -{ - char buf[len]; - get_random_bytes(buf, len); - bl.append(buf, len); - return 0; -} - -uint64_t get_random(uint64_t min_val, uint64_t max_val) -{ - uint64_t r; - get_random_bytes((char *)&r, sizeof(r)); - r = min_val + r % (max_val - min_val + 1); - return r; -} - - -// --------------------------------------------------- - -class CryptoNoneKeyHandler : public CryptoKeyHandler { -public: - int encrypt(const bufferlist& in, - bufferlist& out, std::string *error) const override { - out = in; - return 0; - } - int decrypt(const bufferlist& in, - bufferlist& out, std::string *error) const override { - out = in; - return 0; - } -}; - -class CryptoNone : public CryptoHandler { -public: - CryptoNone() { } - ~CryptoNone() override {} - int get_type() const override { - return CEPH_CRYPTO_NONE; - } - int create(bufferptr& secret) override { - return 0; - } - int validate_secret(const bufferptr& secret) override { - return 0; - } - CryptoKeyHandler *get_key_handler(const bufferptr& secret, string& error) override { - return new CryptoNoneKeyHandler; - } -}; - - -// --------------------------------------------------- - - -class CryptoAES : public CryptoHandler { -public: - CryptoAES() { } - ~CryptoAES() override {} - int get_type() const override { - return CEPH_CRYPTO_AES; - } - int create(bufferptr& secret) override; - int validate_secret(const bufferptr& secret) override; - CryptoKeyHandler *get_key_handler(const bufferptr& secret, string& error) override; -}; - -#ifdef USE_CRYPTOPP -# define AES_KEY_LEN ((size_t)CryptoPP::AES::DEFAULT_KEYLENGTH) -# define AES_BLOCK_LEN ((size_t)CryptoPP::AES::BLOCKSIZE) - -class CryptoAESKeyHandler : public CryptoKeyHandler { -public: - CryptoPP::AES::Encryption *enc_key; - CryptoPP::AES::Decryption *dec_key; - - CryptoAESKeyHandler() - : enc_key(NULL), - dec_key(NULL) {} - ~CryptoAESKeyHandler() { - delete enc_key; - delete dec_key; - } - - int init(const bufferptr& s, ostringstream& err) { - secret = s; - - enc_key = new CryptoPP::AES::Encryption( - (byte*)secret.c_str(), CryptoPP::AES::DEFAULT_KEYLENGTH); - dec_key = new CryptoPP::AES::Decryption( - (byte*)secret.c_str(), CryptoPP::AES::DEFAULT_KEYLENGTH); - - return 0; - } - - int encrypt(const bufferlist& in, - bufferlist& out, std::string *error) const { - string ciphertext; - CryptoPP::StringSink *sink = new CryptoPP::StringSink(ciphertext); - CryptoPP::CBC_Mode_ExternalCipher::Encryption cbc( - *enc_key, (const byte*)CEPH_AES_IV); - CryptoPP::StreamTransformationFilter stfEncryptor(cbc, sink); - - for (std::list::const_iterator it = in.buffers().begin(); - it != in.buffers().end(); ++it) { - const unsigned char *in_buf = (const unsigned char *)it->c_str(); - stfEncryptor.Put(in_buf, it->length()); - } - try { - stfEncryptor.MessageEnd(); - } catch (CryptoPP::Exception& e) { - if (error) { - ostringstream oss; - oss << "encryptor.MessageEnd::Exception: " << e.GetWhat(); - *error = oss.str(); - } - return -1; - } - out.append((const char *)ciphertext.c_str(), ciphertext.length()); - return 0; - } - - int decrypt(const bufferlist& in, - bufferlist& out, std::string *error) const { - string decryptedtext; - CryptoPP::StringSink *sink = new CryptoPP::StringSink(decryptedtext); - CryptoPP::CBC_Mode_ExternalCipher::Decryption cbc( - *dec_key, (const byte*)CEPH_AES_IV ); - CryptoPP::StreamTransformationFilter stfDecryptor(cbc, sink); - for (std::list::const_iterator it = in.buffers().begin(); - it != in.buffers().end(); ++it) { - const unsigned char *in_buf = (const unsigned char *)it->c_str(); - stfDecryptor.Put(in_buf, it->length()); - } - - try { - stfDecryptor.MessageEnd(); - } catch (CryptoPP::Exception& e) { - if (error) { - ostringstream oss; - oss << "decryptor.MessageEnd::Exception: " << e.GetWhat(); - *error = oss.str(); - } - return -1; - } - - out.append((const char *)decryptedtext.c_str(), decryptedtext.length()); - return 0; - } -}; - -#elif defined(USE_NSS) -// when we say AES, we mean AES-128 -# define AES_KEY_LEN 16 -# define AES_BLOCK_LEN 16 - -static int nss_aes_operation(CK_ATTRIBUTE_TYPE op, - CK_MECHANISM_TYPE mechanism, - PK11SymKey *key, - SECItem *param, - const bufferlist& in, bufferlist& out, - std::string *error) -{ - // sample source said this has to be at least size of input + 8, - // but i see 15 still fail with SEC_ERROR_OUTPUT_LEN - bufferptr out_tmp(in.length()+16); - bufferlist incopy; - - SECStatus ret; - int written; - unsigned char *in_buf; - - PK11Context *ectx; - ectx = PK11_CreateContextBySymKey(mechanism, op, key, param); - assert(ectx); - - incopy = in; // it's a shallow copy! - in_buf = (unsigned char*)incopy.c_str(); - ret = PK11_CipherOp(ectx, - (unsigned char*)out_tmp.c_str(), &written, out_tmp.length(), - in_buf, in.length()); - if (ret != SECSuccess) { - PK11_DestroyContext(ectx, PR_TRUE); - if (error) { - ostringstream oss; - oss << "NSS AES failed: " << PR_GetError(); - *error = oss.str(); - } - return -1; - } - - unsigned int written2; - ret = PK11_DigestFinal(ectx, - (unsigned char*)out_tmp.c_str()+written, &written2, - out_tmp.length()-written); - PK11_DestroyContext(ectx, PR_TRUE); - if (ret != SECSuccess) { - if (error) { - ostringstream oss; - oss << "NSS AES final round failed: " << PR_GetError(); - *error = oss.str(); - } - return -1; - } - - out_tmp.set_length(written + written2); - out.append(out_tmp); - return 0; -} - -class CryptoAESKeyHandler : public CryptoKeyHandler { - CK_MECHANISM_TYPE mechanism; - PK11SlotInfo *slot; - PK11SymKey *key; - SECItem *param; - -public: - CryptoAESKeyHandler() - : mechanism(CKM_AES_CBC_PAD), - slot(NULL), - key(NULL), - param(NULL) {} - ~CryptoAESKeyHandler() override { - SECITEM_FreeItem(param, PR_TRUE); - if (key) - PK11_FreeSymKey(key); - if (slot) - PK11_FreeSlot(slot); - } - - int init(const bufferptr& s, ostringstream& err) { - secret = s; - - slot = PK11_GetBestSlot(mechanism, NULL); - if (!slot) { - err << "cannot find NSS slot to use: " << PR_GetError(); - return -1; - } - - SECItem keyItem; - keyItem.type = siBuffer; - keyItem.data = (unsigned char*)secret.c_str(); - keyItem.len = secret.length(); - key = PK11_ImportSymKey(slot, mechanism, PK11_OriginUnwrap, CKA_ENCRYPT, - &keyItem, NULL); - if (!key) { - err << "cannot convert AES key for NSS: " << PR_GetError(); - return -1; - } - - SECItem ivItem; - ivItem.type = siBuffer; - // losing constness due to SECItem.data; IV should never be - // modified, regardless - ivItem.data = (unsigned char*)CEPH_AES_IV; - ivItem.len = sizeof(CEPH_AES_IV); - - param = PK11_ParamFromIV(mechanism, &ivItem); - if (!param) { - err << "cannot set NSS IV param: " << PR_GetError(); - return -1; - } - - return 0; - } - - int encrypt(const bufferlist& in, - bufferlist& out, std::string *error) const override { - return nss_aes_operation(CKA_ENCRYPT, mechanism, key, param, in, out, error); - } - int decrypt(const bufferlist& in, - bufferlist& out, std::string *error) const override { - return nss_aes_operation(CKA_DECRYPT, mechanism, key, param, in, out, error); - } -}; - -#else -# error "No supported crypto implementation found." -#endif - - - -// ------------------------------------------------------------ - -int CryptoAES::create(bufferptr& secret) -{ - bufferlist bl; - int r = get_random_bytes(AES_KEY_LEN, bl); - if (r < 0) - return r; - secret = buffer::ptr(bl.c_str(), bl.length()); - return 0; -} - -int CryptoAES::validate_secret(const bufferptr& secret) -{ - if (secret.length() < (size_t)AES_KEY_LEN) { - return -EINVAL; - } - - return 0; -} - -CryptoKeyHandler *CryptoAES::get_key_handler(const bufferptr& secret, - string& error) -{ - CryptoAESKeyHandler *ckh = new CryptoAESKeyHandler; - ostringstream oss; - if (ckh->init(secret, oss) < 0) { - error = oss.str(); - delete ckh; - return NULL; - } - return ckh; -} - - - - -// -- - - -// --------------------------------------------------- - - -void CryptoKey::encode(bufferlist& bl) const -{ - ::encode(type, bl); - ::encode(created, bl); - __u16 len = secret.length(); - ::encode(len, bl); - bl.append(secret); -} - -void CryptoKey::decode(bufferlist::iterator& bl) -{ - ::decode(type, bl); - ::decode(created, bl); - __u16 len; - ::decode(len, bl); - bufferptr tmp; - bl.copy_deep(len, tmp); - if (_set_secret(type, tmp) < 0) - throw buffer::malformed_input("malformed secret"); -} - -int CryptoKey::set_secret(int type, const bufferptr& s, utime_t c) -{ - int r = _set_secret(type, s); - if (r < 0) - return r; - this->created = c; - return 0; -} - -int CryptoKey::_set_secret(int t, const bufferptr& s) -{ - if (s.length() == 0) { - secret = s; - ckh.reset(); - return 0; - } - - CryptoHandler *ch = CryptoHandler::create(t); - if (ch) { - int ret = ch->validate_secret(s); - if (ret < 0) { - delete ch; - return ret; - } - string error; - ckh.reset(ch->get_key_handler(s, error)); - delete ch; - if (error.length()) { - return -EIO; - } - } else { - return -EOPNOTSUPP; - } - type = t; - secret = s; - return 0; -} - -int CryptoKey::create(CephContext *cct, int t) -{ - CryptoHandler *ch = CryptoHandler::create(t); - if (!ch) { - if (cct) - lderr(cct) << "ERROR: cct->get_crypto_handler(type=" << t << ") returned NULL" << dendl; - return -EOPNOTSUPP; - } - bufferptr s; - int r = ch->create(s); - delete ch; - if (r < 0) - return r; - - r = _set_secret(t, s); - if (r < 0) - return r; - created = ceph_clock_now(); - return r; -} - -void CryptoKey::print(std::ostream &out) const -{ - out << encode_base64(); -} - -void CryptoKey::to_str(std::string& s) const -{ - int len = secret.length() * 4; - char buf[len]; - hex2str(secret.c_str(), secret.length(), buf, len); - s = buf; -} - -void CryptoKey::encode_formatted(string label, Formatter *f, bufferlist &bl) -{ - f->open_object_section(label.c_str()); - f->dump_string("key", encode_base64()); - f->close_section(); - f->flush(bl); -} - -void CryptoKey::encode_plaintext(bufferlist &bl) -{ - bl.append(encode_base64()); -} - - -// ------------------ - -CryptoHandler *CryptoHandler::create(int type) -{ - switch (type) { - case CEPH_CRYPTO_NONE: - return new CryptoNone; - case CEPH_CRYPTO_AES: - return new CryptoAES; - default: - return NULL; - } -}