diff options
Diffstat (limited to 'src/common/cipher_openssl.c')
-rw-r--r-- | src/common/cipher_openssl.c | 268 |
1 files changed, 0 insertions, 268 deletions
diff --git a/src/common/cipher_openssl.c b/src/common/cipher_openssl.c deleted file mode 100644 index e7a1dc7ad9e..00000000000 --- a/src/common/cipher_openssl.c +++ /dev/null @@ -1,268 +0,0 @@ -/*------------------------------------------------------------------------- - * cipher_openssl.c - * Cryptographic function using OpenSSL - * - * This contains the common low-level functions needed in both frontend and - * backend, for implement the database encryption. - * - * Portions Copyright (c) 2020, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/common/cipher_openssl.c - * - *------------------------------------------------------------------------- - */ -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include "common/cipher.h" -#include <openssl/conf.h> -#include <openssl/err.h> -#include <openssl/evp.h> -#include <openssl/ssl.h> - -/* - * prototype for the EVP functions that return an algorithm, e.g. - * EVP_aes_128_gcm(). - */ -typedef const EVP_CIPHER *(*ossl_EVP_cipher_func) (void); - -static ossl_EVP_cipher_func get_evp_aes_gcm(int klen); -static EVP_CIPHER_CTX *ossl_cipher_ctx_create(int cipher, uint8 *key, int klen, - bool enc); - -/* - * Return a newly created cipher context. 'cipher' specifies cipher algorithm - * by identifer like PG_CIPHER_XXX. - */ -PgCipherCtx * -pg_cipher_ctx_create(int cipher, uint8 *key, int klen, bool enc) -{ - PgCipherCtx *ctx = NULL; - - if (cipher >= PG_MAX_CIPHER_ID) - return NULL; - - ctx = ossl_cipher_ctx_create(cipher, key, klen, enc); - - return ctx; -} - -void -pg_cipher_ctx_free(PgCipherCtx *ctx) -{ - EVP_CIPHER_CTX_free(ctx); -} - -/* - * Encryption routine to encrypt data provided. - * - * ctx is the encryption context which must have been created previously. - * - * plaintext is the data we are going to encrypt - * inlen is the length of the data to encrypt - * - * ciphertext is the encrypted result - * outlen is the encrypted length - * - * iv is the IV to use. - * ivlen is the IV length to use. - * - * outtag is the resulting tag. - * taglen is the length of the tag. - */ -bool -pg_cipher_encrypt(PgCipherCtx *ctx, - const unsigned char *plaintext, const int inlen, - unsigned char *ciphertext, int *outlen, - const unsigned char *iv, const int ivlen, - unsigned char *outtag, const int taglen) -{ - int len; - int enclen; - - Assert(ctx != NULL); - - /* - * Here we are setting the IV for the context which was passed - * in. Note that we signal to OpenSSL that we are configuring - * a new value for the context by passing in 'NULL' for the - * 2nd ('type') parameter. - */ - - /* Set the IV length first */ - if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, NULL)) - return false; - - /* Set the IV for this encryption. */ - if (!EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv)) - return false; - - /* - * This is the function which is actually performing the - * encryption for us. - */ - if (!EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, inlen)) - return false; - - enclen = len; - - /* Finalize the encryption, which could add more to output. */ - if (!EVP_EncryptFinal_ex(ctx, ciphertext + enclen, &len)) - return false; - - *outlen = enclen + len; - - /* - * Once all of the encryption has been completed we grab - * the tag. - */ - if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, taglen, outtag)) - return false; - - return true; -} -/* - * Decryption routine - * - * ctx is the encryption context which must have been created previously. - * - * ciphertext is the data we are going to decrypt - * inlen is the length of the data to decrypt - * - * plaintext is the decrypted result - * outlen is the decrypted length - * - * iv is the IV to use. - * ivlen is the length of the IV. - * - * intag is the tag to use to verify. - * taglen is the length of the tag. - */ -bool -pg_cipher_decrypt(PgCipherCtx *ctx, - const unsigned char *ciphertext, const int inlen, - unsigned char *plaintext, int *outlen, - const unsigned char *iv, const int ivlen, - unsigned char *intag, const int taglen) -{ - int declen; - int len; - - /* - * Here we are setting the IV for the context which was passed - * in. Note that we signal to OpenSSL that we are configuring - * a new value for the context by passing in 'NULL' for the - * 2nd ('type') parameter. - */ - - /* Set the IV length first */ - if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, NULL)) - return false; - - /* Set the IV for this decryption. */ - if (!EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv)) - return false; - - /* - * This is the function which is actually performing the - * decryption for us. - */ - if (!EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, inlen)) - return false; - - declen = len; - - /* Set the expected tag value. */ - if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, taglen, intag)) - return false; - - /* - * Finalize the decryption, which could add more to output, - * this is also the step which checks the tag and we MUST - * fail if this indicates an invalid tag! - */ - if (!EVP_DecryptFinal_ex(ctx, plaintext + declen, &len)) - return false; - - *outlen = declen + len; - - return true; -} - -/* - * Returns the correct cipher functions for OpenSSL based - * on the key length requested. - */ -static ossl_EVP_cipher_func -get_evp_aes_gcm(int klen) -{ - switch (klen) - { - case PG_AES128_KEY_LEN: - return EVP_aes_128_gcm; - case PG_AES192_KEY_LEN: - return EVP_aes_192_gcm; - case PG_AES256_KEY_LEN: - return EVP_aes_256_gcm; - default: - return NULL; - } -} - -/* - * Initialize and return an EVP_CIPHER_CTX. Returns NULL if the given - * cipher algorithm is not supported or on failure. - */ -static EVP_CIPHER_CTX * -ossl_cipher_ctx_create(int cipher, uint8 *key, int klen, bool enc) -{ - EVP_CIPHER_CTX *ctx; - ossl_EVP_cipher_func func; - int ret; - - ctx = EVP_CIPHER_CTX_new(); - - /* - * We currently only support AES GCM but others could be - * added in the future. - */ - switch (cipher) - { - case PG_CIPHER_AES_GCM: - func = get_evp_aes_gcm(klen); - if (!func) - goto failed; - break; - default: - goto failed; - } - - /* - * We create the context here based on the cipher requested and the provided - * key. Note that the IV will be provided in the actual encryption call - * through another EVP_EncryptInit_ex call- this is fine as long as 'type' - * is passed in as NULL! - */ - if (enc) - ret = EVP_EncryptInit_ex(ctx, (const EVP_CIPHER *) func(), NULL, key, NULL); - else - ret = EVP_DecryptInit_ex(ctx, (const EVP_CIPHER *) func(), NULL, key, NULL); - - if (!ret) - goto failed; - - /* Set the key length based on the key length requested. */ - if (!EVP_CIPHER_CTX_set_key_length(ctx, klen)) - goto failed; - - return ctx; - -failed: - EVP_CIPHER_CTX_free(ctx); - return NULL; -} - |