class CryptoNoneKeyHandler : public CryptoKeyHandler {
public:
- void encrypt(const bufferlist& in,
- bufferlist& out, std::string &error) const {
+ int encrypt(const bufferlist& in,
+ bufferlist& out, std::string *error) const {
out = in;
+ return 0;
}
- void decrypt(const bufferlist& in,
- bufferlist& out, std::string &error) const {
+ int decrypt(const bufferlist& in,
+ bufferlist& out, std::string *error) const {
out = in;
+ return 0;
}
};
return 0;
}
- void encrypt(const bufferlist& in,
- bufferlist& out, std::string &error) const {
+ 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(
try {
stfEncryptor.MessageEnd();
} catch (CryptoPP::Exception& e) {
- ostringstream oss;
- oss << "encryptor.MessageEnd::Exception: " << e.GetWhat();
- error = oss.str();
- return;
+ 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;
}
- void decrypt(const bufferlist& in,
- bufferlist& out, std::string &error) const {
+ 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(
try {
stfDecryptor.MessageEnd();
} catch (CryptoPP::Exception& e) {
- ostringstream oss;
- oss << "decryptor.MessageEnd::Exception: " << e.GetWhat();
- error = oss.str();
- return;
+ 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;
}
};
# define AES_KEY_LEN 16
# define AES_BLOCK_LEN 16
-static void nss_aes_operation(CK_ATTRIBUTE_TYPE op,
- CK_MECHANISM_TYPE mechanism,
- PK11SymKey *key,
- SECItem *param,
- const bufferlist& in, bufferlist& out,
- std::string &error)
+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
in_buf, in.length());
if (ret != SECSuccess) {
PK11_DestroyContext(ectx, PR_TRUE);
- ostringstream oss;
- oss << "NSS AES failed: " << PR_GetError();
- error = oss.str();
- return;
+ if (error) {
+ ostringstream oss;
+ oss << "NSS AES failed: " << PR_GetError();
+ *error = oss.str();
+ }
+ return -1;
}
unsigned int written2;
PK11_DestroyContext(ectx, PR_TRUE);
if (ret != SECSuccess) {
PK11_DestroyContext(ectx, PR_TRUE);
- ostringstream oss;
- oss << "NSS AES final round failed: " << PR_GetError();
- error = oss.str();
- return;
+ 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 {
return 0;
}
- void encrypt(const bufferlist& in,
- bufferlist& out, std::string &error) const {
- nss_aes_operation(CKA_ENCRYPT, mechanism, key, param, in, out, error);
+ int encrypt(const bufferlist& in,
+ bufferlist& out, std::string *error) const {
+ return nss_aes_operation(CKA_ENCRYPT, mechanism, key, param, in, out, error);
}
- void decrypt(const bufferlist& in,
- bufferlist& out, std::string &error) const {
- nss_aes_operation(CKA_DECRYPT, mechanism, key, param, in, out, error);
+ int decrypt(const bufferlist& in,
+ bufferlist& out, std::string *error) const {
+ return nss_aes_operation(CKA_DECRYPT, mechanism, key, param, in, out, error);
}
};
virtual ~CryptoKeyHandler() {}
- virtual void encrypt(const bufferlist& in,
- bufferlist& out, std::string &error) const = 0;
- virtual void decrypt(const bufferlist& in,
- bufferlist& out, std::string &error) const = 0;
+ virtual int encrypt(const bufferlist& in,
+ bufferlist& out, std::string *error) const = 0;
+ virtual int decrypt(const bufferlist& in,
+ bufferlist& out, std::string *error) const = 0;
};
/*
// --
int create(CephContext *cct, int type);
- void encrypt(CephContext *cct, const bufferlist& in, bufferlist& out,
- std::string &error) const {
- ckh->encrypt(in, out, error);
+ int encrypt(CephContext *cct, const bufferlist& in, bufferlist& out,
+ std::string *error) const {
+ return ckh->encrypt(in, out, error);
}
- void decrypt(CephContext *cct, const bufferlist& in, bufferlist& out,
- std::string &error) const {
- ckh->decrypt(in, out, error);
+ int decrypt(CephContext *cct, const bufferlist& in, bufferlist& out,
+ std::string *error) const {
+ return ckh->decrypt(in, out, error);
}
void to_str(std::string& s) const;
uint64_t magic;
bufferlist bl;
- key.decrypt(cct, bl_enc, bl, error);
- if (!error.empty())
+ if (key.decrypt(cct, bl_enc, bl, &error) < 0)
return;
bufferlist::iterator iter2 = bl.begin();
::encode(magic, bl);
::encode(t, bl);
- key.encrypt(cct, bl, out, error);
+ key.encrypt(cct, bl, out, &error);
}
template <typename T>
{
const ceph_msg_header& header = m->get_header();
const ceph_msg_footer& footer = m->get_footer();
- std::string error;
// optimized signature calculation
// - avoid temporary allocated buffers from encode_encrypt[_enc_bl]
bl_plaintext.append(buffer::create_static(sizeof(sigblock), (char*)&sigblock));
bufferlist bl_ciphertext;
- key.encrypt(cct, bl_plaintext, bl_ciphertext, error);
+ if (key.encrypt(cct, bl_plaintext, bl_ciphertext, NULL) < 0) {
+ lderr(cct) << __func__ << " failed to encrypt signature block" << dendl;
+ return -1;
+ }
bufferlist::iterator ci = bl_ciphertext.begin();
::decode(*psig, ci);
bufferlist cipher;
std::string error;
CryptoKeyHandler *kh = h->get_key_handler(secret, error);
- kh->encrypt(plaintext, cipher, error);
+ int r = kh->encrypt(plaintext, cipher, &error);
+ ASSERT_EQ(r, 0);
ASSERT_EQ(error, "");
unsigned char want_cipher[] = {
std::string error;
bufferlist plaintext;
CryptoKeyHandler *kh = h->get_key_handler(secret, error);
- kh->decrypt(cipher, plaintext, error);
+ int r = kh->decrypt(cipher, plaintext, &error);
+ ASSERT_EQ(r, 0);
ASSERT_EQ(error, "");
ASSERT_EQ(sizeof(plaintext_s), plaintext.length());
std::string error;
CryptoKeyHandler *kh = h->get_key_handler(secret, error);
- kh->encrypt(plaintext, cipher, error);
+ int r = kh->encrypt(plaintext, cipher, &error);
+ ASSERT_EQ(r, 0);
ASSERT_EQ(error, "");
}
plaintext.clear();
CryptoHandler *h = g_ceph_context->get_crypto_handler(CEPH_CRYPTO_AES);
std::string error;
CryptoKeyHandler *ckh = h->get_key_handler(secret, error);
- ckh->decrypt(cipher, plaintext, error);
+ int r = ckh->decrypt(cipher, plaintext, &error);
+ ASSERT_EQ(r, 0);
ASSERT_EQ(error, "");
}
}
err = memcmp(plaintext_s, orig_plaintext_s, sizeof(orig_plaintext_s));
ASSERT_EQ(0, err);
}
+
+TEST(AES, LoopKey) {
+ bufferptr k(16);
+ get_random_bytes(k.c_str(), k.length());
+ CryptoKey key(CEPH_CRYPTO_AES, ceph_clock_now(NULL), k);
+
+ bufferlist data;
+ bufferptr r(128);
+ get_random_bytes(r.c_str(), r.length());
+ data.append(r);
+
+ utime_t start = ceph_clock_now(NULL);
+ int n = 100000;
+
+ for (int i=0; i<n; ++i) {
+ bufferlist encoded;
+ string error;
+ int r = key.encrypt(g_ceph_context, data, encoded, &error);
+ ASSERT_EQ(r, 0);
+ }
+
+ utime_t end = ceph_clock_now(NULL);
+ utime_t dur = end - start;
+ cout << n << " encoded in " << dur << std::endl;
+}
bufferlist enc_out;
std::string error;
if (key.encrypt(g_ceph_context, enc_in, enc_out, &error) < 0) {
- ASSERT_TRUE(!error.empty());
+ assert(!error.empty());
dout(0) << "couldn't encode! error " << error << dendl;
exit(1);
}
dec_in = enc_out;
if (key.decrypt(g_ceph_context, dec_in, dec_out, &error) < 0) {
- ASSERT_TRUE(!error.empty());
+ assert(!error.empty());
dout(0) << "couldn't decode! error " << error << dendl;
exit(1);
}