From: Yehuda Sadeh Date: Mon, 17 Mar 2025 11:44:30 +0000 (-0400) Subject: auth: test slice interface for aes256k X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e6fffbce445781a32fa253025d43f44b2ca184ce;p=ceph-ci.git auth: test slice interface for aes256k AES256KRB5 uses the default slice encryption implementation, testing that it works correctly. Signed-off-by: Yehuda Sadeh --- diff --git a/src/auth/Crypto.cc b/src/auth/Crypto.cc index cf8c318f89f..1c45ecb734d 100644 --- a/src/auth/Crypto.cc +++ b/src/auth/Crypto.cc @@ -156,18 +156,28 @@ int CryptoRandom::open_urandom() // fallback implementation of the bufferlist-free // interface. -std::size_t CryptoKeyHandler::encrypt( +std::size_t CryptoKeyHandler::encrypt_ext( CephContext *cct, const CryptoKeyHandler::in_slice_t& in, + const CryptoKeyHandler::in_slice_t *confounder, const CryptoKeyHandler::out_slice_t& out) const { + if (out.buf == nullptr) { + return enc_size(in, confounder); + } + ceph::bufferptr inptr(reinterpret_cast(in.buf), in.length); ceph::bufferlist plaintext; plaintext.append(std::move(inptr)); + ceph::bufferlist confounder_bl; + if (confounder) { + ceph::bufferptr cfp(reinterpret_cast(confounder->buf), confounder->length); + confounder_bl.append(std::move(cfp)); + } ceph::bufferlist ciphertext; std::string error; - const int ret = encrypt(cct, plaintext, ciphertext, &error); + const int ret = encrypt_ext(cct, plaintext, (confounder ? &confounder_bl : nullptr), ciphertext, &error); if (ret != 0 || !error.empty()) { throw std::runtime_error(std::move(error)); } @@ -228,11 +238,11 @@ public: : CryptoKeyHandler(CryptoKeyHandler::BLOCK_SIZE_0B()) { } - using CryptoKeyHandler::encrypt; + using CryptoKeyHandler::encrypt_ext; using CryptoKeyHandler::decrypt; - int encrypt(CephContext *cct, const bufferlist& in, - bufferlist& out, std::string *error) const override { + int encrypt_ext(CephContext *cct, const bufferlist& in, const bufferlist *confounder, + bufferlist& out, std::string *error) const override { out = in; return 0; } @@ -290,6 +300,9 @@ public: : CryptoKeyHandler(CryptoKeyHandler::BLOCK_SIZE_16B()) { } + using CryptoKeyHandler::encrypt; + using CryptoKeyHandler::encrypt_ext; + int init(const bufferptr& s, ostringstream& err) { secret = s; @@ -312,7 +325,8 @@ public: return 0; } - int encrypt(CephContext *cct, const ceph::bufferlist& in, + int encrypt_ext(CephContext *cct, const ceph::bufferlist& in, + const bufferlist *confounder /* ignored */, ceph::bufferlist& out, std::string* /* unused */) const override { ldout(cct, 20) << "CryptoAESKeyHandler::encrypt()" << dendl; @@ -388,12 +402,17 @@ public: return 0; } + std::size_t enc_size(const in_slice_t& in, + const in_slice_t *confounder) const override { + // 16 + p2align(10, 16) -> 16 + // 16 + p2align(16, 16) -> 32 + return AES_BLOCK_LEN + p2align(in.length, AES_BLOCK_LEN); + } + std::size_t encrypt(CephContext *cct, const in_slice_t& in, const out_slice_t& out) const override { if (out.buf == nullptr) { - // 16 + p2align(10, 16) -> 16 - // 16 + p2align(16, 16) -> 32 - return AES_BLOCK_LEN + p2align(in.length, AES_BLOCK_LEN); + return enc_size(in, nullptr); } // how many bytes of in.buf hang outside the alignment boundary and how @@ -716,8 +735,9 @@ public: CryptoAES256KRB5KeyHandler() : CryptoKeyHandler(CryptoKeyHandler::BLOCK_SIZE_16B()) { } - using CryptoKeyHandler::encrypt; + using CryptoKeyHandler::encrypt_ext; using CryptoKeyHandler::decrypt; + using CryptoKeyHandler::encrypt; int init(const ceph::bufferptr& s, uint32_t usage, ostringstream& err) { cipher = EVP_CIPHER_fetch(NULL, "AES-256-CBC-CTS", NULL); @@ -882,6 +902,11 @@ public: std::string* unused) const override { return encrypt_ext(cct, in, nullptr, out, unused); } + + std::size_t enc_size(const in_slice_t& in, + const in_slice_t *confounder) const override { + return 24 + (confounder ? confounder->length : 0 ) + in.length; + } }; diff --git a/src/auth/Crypto.h b/src/auth/Crypto.h index 7bd708d3597..3f7d7ebe491 100644 --- a/src/auth/Crypto.h +++ b/src/auth/Crypto.h @@ -72,23 +72,33 @@ public: virtual int encrypt(CephContext *cct, const ceph::buffer::list& in, - ceph::buffer::list& out, std::string *error) const = 0; + ceph::buffer::list& out, std::string *error) const { + return encrypt_ext(cct, in, nullptr, out, error); + } /* should either used internally, or for unitests. Confounder should be nullptr otherwise */ virtual int encrypt_ext(CephContext *cct, const ceph::buffer::list& in, const ceph::buffer::list *confounder, - ceph::buffer::list& out, std::string *error) const { - return -ENOTSUP; - } + ceph::buffer::list& out, std::string *error) const = 0; + virtual int decrypt(CephContext *cct, const ceph::buffer::list& in, ceph::buffer::list& out, std::string *error) const = 0; - // TODO: provide nullptr in the out::buf to get/estimate size requirements? - // Or maybe dedicated methods? + virtual std::size_t enc_size(const in_slice_t& in, + const in_slice_t *confounder) const { + return 0; + } + virtual std::size_t encrypt(CephContext *cct, const in_slice_t& in, + const out_slice_t& out) const { + return encrypt_ext(cct, in, nullptr, out); + } + virtual std::size_t encrypt_ext(CephContext *cct, + const in_slice_t& in, + const in_slice_t *confounder, const out_slice_t& out) const; virtual std::size_t decrypt(CephContext *cct, const in_slice_t& in, diff --git a/src/test/crypto.cc b/src/test/crypto.cc index 8ae35ec7c70..8e239a74ed6 100644 --- a/src/test/crypto.cc +++ b/src/test/crypto.cc @@ -406,6 +406,49 @@ TEST(AES256KRB5, Encrypt) { delete kh; } +TEST(AES256KRB5, EncryptNoBl) { + auto h = g_ceph_context->get_crypto_manager()->get_handler(CEPH_CRYPTO_AES256KRB5); + unsigned char secret_s[] = { + 0x6D, 0x40, 0x4D, 0x37, 0xFA, 0xF7, 0x9F, 0x9D, 0xF0, 0xD3, 0x35, 0x68, 0xD3, 0x20, 0x66, 0x98, + 0x00, 0xEB, 0x48, 0x36, 0x47, 0x2E, 0xA8, 0xA0, 0x26, 0xD1, 0x6B, 0x71, 0x82, 0x46, 0x0C, 0x52 }; + + bufferptr secret((char *)secret_s, sizeof(secret_s)); + + unsigned char confounder_data[] = { 0xB8, 0x0D, 0x32, 0x51, 0xC1, 0xF6, 0x47, 0x14, 0x94, 0x25, 0x6F, 0xFE, 0x71, 0x2D, 0x0B, 0x9A }; + const CryptoKey::in_slice_t confounder_slice { sizeof(confounder_data), confounder_data }; + + unsigned char plaintext_s[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; + + std::string error; + std::unique_ptr kh(h->get_key_handler_ext(secret, 2, error)); + + const CryptoKey::in_slice_t plain_slice { sizeof(plaintext_s), plaintext_s }; + + // we need to deduce size first + const CryptoKey::out_slice_t probe_slice { 0, nullptr }; + const auto needed = kh->encrypt_ext(g_ceph_context, plain_slice, &confounder_slice, probe_slice); + ASSERT_GE(needed, plain_slice.length); + + boost::container::small_vector< + // FIXME? + //unsigned char, sizeof(plaintext) + kh->get_block_size()> buf; + unsigned char, sizeof(plaintext_s) + 16> buf(needed); + const CryptoKey::out_slice_t cipher_slice { needed, buf.data() }; + const auto cipher_size = kh->encrypt_ext(g_ceph_context, plain_slice, &confounder_slice, cipher_slice); + ASSERT_EQ(cipher_size, needed); + + unsigned char want_cipher[] = { + 0x4E, 0xD7, 0xB3, 0x7C, 0x2B, 0xCA, 0xC8, 0xF7, 0x4F, 0x23, 0xC1, 0xCF, 0x07, 0xE6, 0x2B, 0xC7, + 0xB7, 0x5F, 0xB3, 0xF6, 0x37, 0xB9, 0xF5, 0x59, 0xC7, 0xF6, 0x64, 0xF6, 0x9E, 0xAB, 0x7B, 0x60, + 0x92, 0x23, 0x75, 0x26, 0xEA, 0x0D, 0x1F, 0x61, 0xCB, 0x20, 0xD6, 0x9D, 0x10, 0xF2 + }; + + ASSERT_EQ(sizeof(want_cipher), cipher_size); + + const int err = memcmp(buf.data(), want_cipher, sizeof(want_cipher)); + ASSERT_EQ(0, err); +} + TEST(AES256KRB5, Decrypt) { auto h = g_ceph_context->get_crypto_manager()->get_handler(CEPH_CRYPTO_AES256KRB5); unsigned char secret_s[] = {