/* Copyright (c) 2021, 2024, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. This program is designed to work with certain software (including but not limited to OpenSSL) that is licensed under separate terms, as designated in a particular file or component or in included license documentation. The authors of MySQL hereby grant you an additional permission to link the program and your derivative works with the separately licensed software that they have either included with the program or referenced in the documentation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0, for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef KEYRING_AES_INCLUDED #define KEYRING_AES_INCLUDED #include /* clang-format off */ /** @defgroup group_keyring_component_services_inventory Keyring component services @ingroup group_components_services_inventory */ /* clang-format on */ /** @ingroup group_keyring_component_services_inventory Keyring aes encryption service provides APIs to perform AES encryption/decryption operation on given data. These methods make sure that key never leaves keyring component. @code my_service aes_encryption( "keyring_aes", m_reg_srv); if (!aes_encryption.is_valid()) { return true; } std::string mode("cbc"); size_t block_size = 256; const unsigned char plaintext[] = "Quick brown fox jumped over the lazy dog."; size_t plaintext_length = strlen(static_cast(plaintext)); size_t ciphertext_length = 0; if (aes_encryption->get_size(plaintext_length, block_size, mode.c_str, &ciphertext_length) == true) { return true; } std::unique_ptr ciphertext( new unsigned char[ciphertext_length]); if (ciphertext.get() == nullptr) { return true; } const unsigned char iv[] = "abcefgh12345678"; size_t out_length = 0; if (aes_encryption->encrypt( "my_aes_key_1", "testuser@localhost", mode.c_str(), block_size, iv, true, plaintext, plaintext_length, ciphertext.get(), ciphertext_length, &out_length) == true) { return true; } std::unique_ptr retrieved_plaintext( new unsigned char[plaintext_length]); if (retrieved_plaintext.get() == nullptr) { return true; } if (aes_encryption->decrypt( "my_aes_key_1", "testuser@localhost", mode.c_str(), block_size, iv, true, ciphertext.get(), out_length, retrieved_plaintext.get(), plaintext_length, &out_length) == true) { return true; } if (plaintext_length != out_length || memcmp(plaintext, retrieved_plaintext.get(), plaintext_length) != 0) { return true; } return false; @endcode */ BEGIN_SERVICE_DEFINITION(keyring_aes) /** Retrieve required out buffer length information Assumption: mode string is in lower case. @param [in] input_length Length of input text @param [in] mode AES mode. ASCII string. @param [in] block_size AES block size information @param [out] out_size Size of out buffer @returns Output buffer length or error @retval false Success @retval true Error processing given mode and/or block size */ DECLARE_BOOL_METHOD(get_size, (size_t input_length, const char *mode, size_t block_size, size_t *out_size)); /** Encrypt given piece of plaintext Block mode for operation (e.g. "ecb", "cbc", cfb1",...) Block size (e.g. 256) Length of out buffer should be sufficient to hold ciphertext data. See get_size() API. Encrypted data should be stored in out_buffer with out_length set to actual length of data. IV must be provided if block mode of operation requires it. It is caller's responsibility to supply same IV for encryption/decryption. @param [in] data_id Name of the key. Byte string. @param [in] auth_id Owner of the key. Byte string. @param [in] mode AES mode. ASCII string. @param [in] block_size AES block size information @param [in] iv Initialization vector @param [in] padding padding preference (0 implies no padding) @param [in] data_buffer Input buffer. Byte string. @param [in] data_buffer_length Input buffer length @param [out] out_buffer Output buffer. Byte string. @param [in] out_buffer_length Output buffer length @param [out] out_length Length of encrypted data @returns status of the operation @retval false Success @retval true Failure */ DECLARE_BOOL_METHOD(encrypt, (const char *data_id, const char *auth_id, const char *mode, size_t block_size, const unsigned char *iv, int padding, const unsigned char *data_buffer, size_t data_buffer_length, unsigned char *out_buffer, size_t out_buffer_length, size_t *out_length)); /** Decrypt given piece ciphertext Block mode for operation (e.g. "ecb", "cbc", cfb1",...) Block size (e.g. 256) Length of out buffer should be sufficient to hold ciphertext data. See get_size() API. If block mode requires IV, same should be provided by caller. This should same IV that was used for encryption operation. @param [in] data_id Name of the key. Byte string. @param [in] auth_id Owner of the key. Byte string. @param [in] mode AES mode. ASCII string. @param [in] block_size AES block size information @param [in] iv Initialization vector @param [in] padding padding preference (0 implies no padding) @param [in] data_buffer Input buffer. Byte string. @param [in] data_buffer_length Input buffer length @param [out] out_buffer Output buffer. Byte string. @param [in] out_buffer_length Output buffer length @param [out] out_length Length of decrypted data @returns status of the operation @retval false Success @retval true Failure */ DECLARE_BOOL_METHOD(decrypt, (const char *data_id, const char *auth_id, const char *mode, size_t block_size, const unsigned char *iv, int padding, const unsigned char *data_buffer, size_t data_buffer_length, unsigned char *out_buffer, size_t out_buffer_length, size_t *out_length)); END_SERVICE_DEFINITION(keyring_aes) #endif // KEYRING_AES_INCLUDED