From 7625d3dd03e3254dbe70ac72d8ec441696a5a9ad Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Thu, 15 Aug 2019 13:08:56 +0900 Subject: [PATCH 1/5] Introduce cryptographic functions for cluster encryption. --- configure | 15 +- src/backend/storage/Makefile | 3 +- src/backend/storage/encryption/Makefile | 21 ++ src/backend/storage/encryption/enc_cipher.c | 125 ++++++++ src/backend/storage/encryption/enc_openssl.c | 420 +++++++++++++++++++++++++++ src/include/pg_config.h.in | 6 + src/include/storage/enc_cipher.h | 37 +++ src/include/storage/enc_common.h | 32 ++ src/include/storage/enc_internal.h | 38 +++ src/include/storage/encryption.h | 49 ++++ 10 files changed, 744 insertions(+), 2 deletions(-) create mode 100644 src/backend/storage/encryption/Makefile create mode 100644 src/backend/storage/encryption/enc_cipher.c create mode 100644 src/backend/storage/encryption/enc_openssl.c create mode 100644 src/include/storage/enc_cipher.h create mode 100644 src/include/storage/enc_common.h create mode 100644 src/include/storage/enc_internal.h create mode 100644 src/include/storage/encryption.h diff --git a/configure b/configure index 2c98e80..4ac4c1b 100755 --- a/configure +++ b/configure @@ -12113,7 +12113,7 @@ done # defines OPENSSL_VERSION_NUMBER to claim version 2.0.0, even though it # doesn't have these OpenSSL 1.1.0 functions. So check for individual # functions. - for ac_func in OPENSSL_init_ssl BIO_get_data BIO_meth_new ASN1_STRING_get0_data + for ac_func in OPENSSL_init_ssl OPENSSL_init_crypto BIO_get_data BIO_meth_new ASN1_STRING_get0_data EVP_PKEY_derive do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -12827,6 +12827,19 @@ fi done +# check for +for ac_header in netinet/tcp.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "openssl/kdf.h" "ac_cv_header_openssl_kdf_h" "$ac_includes_default" +if test "x$ac_cv_header_openssl_kdf_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_OPENSSL_KDF 1 +_ACEOF + +fi + +done + if expr x"$pgac_cv_check_readline" : 'x-lreadline' >/dev/null ; then for ac_header in readline/readline.h diff --git a/src/backend/storage/Makefile b/src/backend/storage/Makefile index 8376cdf..2a6d2ab 100644 --- a/src/backend/storage/Makefile +++ b/src/backend/storage/Makefile @@ -8,6 +8,7 @@ subdir = src/backend/storage top_builddir = ../../.. include $(top_builddir)/src/Makefile.global -SUBDIRS = buffer file freespace ipc large_object lmgr page smgr sync +SUBDIRS = buffer file freespace ipc large_object lmgr page smgr sync \ + encryption include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/storage/encryption/Makefile b/src/backend/storage/encryption/Makefile new file mode 100644 index 0000000..50244c3 --- /dev/null +++ b/src/backend/storage/encryption/Makefile @@ -0,0 +1,21 @@ +#------------------------------------------------------------------------- +# +# Makefile-- +# Makefile for storage/encryption +# +# IDENTIFICATION +# src/backend/storage/encryption/Makefile +# +#------------------------------------------------------------------------- + +subdir = src/backend/storage/encryption/ +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global + +OBJS = kmgr.o bufenc.o walenc.o enc_cipher.o + +ifeq ($(with_openssl),yes) +OBJS += enc_openssl.o +endif + +include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/storage/encryption/enc_cipher.c b/src/backend/storage/encryption/enc_cipher.c new file mode 100644 index 0000000..7f63c22 --- /dev/null +++ b/src/backend/storage/encryption/enc_cipher.c @@ -0,0 +1,125 @@ +/*------------------------------------------------------------------------- + * + * enc_openssl.c + * This code handles encryption and decryption using OpenSSL + * + * Copyright (c) 2019, PostgreSQL Global Development Group + * + * + * IDENTIFICATION + * src/backend/storage/encryption/enc_openssl.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "storage/enc_cipher.h" +#include "storage/enc_common.h" +#include "storage/enc_internal.h" + +/* GUC parameter */ +int data_encryption_cipher; +int EncryptionKeySize; + +/* Data encryption */ +void +pg_encrypt(const char *input, char *output, int size, + const char *key, const char *iv) +{ +#ifdef USE_OPENSSL + ossl_encrypt_data(input, output, size, key, iv); +#endif +} + +/* Data decryption */ +void +pg_decrypt(const char *input, char *output, int size, + const char *key, const char *iv) +{ +#ifdef USE_OPENSSL + ossl_decrypt_data(input, output, size, key, iv); +#endif +} + +/* Password based key derivation */ +void +pg_derive_key_passphrase(const char *passphrase, int pass_size, + unsigned char *salt, int salt_size, + int iter_cnt, int derived_size, + unsigned char *derived_key) +{ +#ifdef USE_OPENSSL + ossl_derive_key_passphrase(passphrase, pass_size, salt, salt_size, + iter_cnt, derived_size, derived_key); +#endif +} + +/* Key derivation */ +void +pg_derive_key(const unsigned char *base_key, int base_size, unsigned char *info, + unsigned char *derived_key, Size derived_size) +{ +#ifdef USE_OPENSSL + ossl_derive_key(base_key, base_size, info, derived_key, derived_size); +#endif +} + +/* Compute HMAC */ +void +pg_compute_hmac(const unsigned char *hmac_key, int key_size, unsigned char *data, + int data_size, unsigned char *hmac) +{ +#ifdef USE_OPENSSL + ossl_compute_hmac(hmac_key, key_size, data, data_size, hmac); +#endif +} + +/* Key wrap */ +void +pg_wrap_key(const unsigned char *key, int key_size, unsigned char *in, + int in_size, unsigned char *out, int *out_size) +{ +#ifdef USE_OPENSSL + ossl_wrap_key(key, key_size, in, in_size, out, out_size); +#endif +} + +/* Key unwrap */ +void +pg_unwrap_key(const unsigned char *key, int key_size, unsigned char *in, + int in_size, unsigned char *out, int *out_size) +{ +#ifdef USE_OPENSSL + ossl_unwrap_key(key, key_size, in, in_size, out, out_size); +#endif +} + +/* Convert cipher name string to integer value */ +int +EncryptionCipherValue(const char *name) +{ + if (strcmp(name, "aes-128") == 0) + return TDE_ENCRYPTION_AES_128; + else if (strcmp(name, "aes-256") == 0) + return TDE_ENCRYPTION_AES_256; + else + return TDE_ENCRYPTION_OFF; +} + +/* Convert integer value to cipher name string */ +char * +EncryptionCipherString(int value) +{ + switch (value) + { + case TDE_ENCRYPTION_OFF : + return "off"; + case TDE_ENCRYPTION_AES_128: + return "aes-128"; + case TDE_ENCRYPTION_AES_256: + return "aes-256"; + } + + return "unknown"; +} diff --git a/src/backend/storage/encryption/enc_openssl.c b/src/backend/storage/encryption/enc_openssl.c new file mode 100644 index 0000000..11cdcfd --- /dev/null +++ b/src/backend/storage/encryption/enc_openssl.c @@ -0,0 +1,420 @@ +/*------------------------------------------------------------------------- + * + * enc_openssl.c + * This code handles encryption and decryption using OpenSSL + * + * Copyright (c) 2019, PostgreSQL Global Development Group + * + * + * IDENTIFICATION + * src/backend/storage/encryption/enc_openssl.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include + +#include "storage/enc_internal.h" +#include "storage/enc_common.h" +#include "utils/memutils.h" + +#include +#include +#include +#include +#ifdef HAVE_OPENSSL_KDF +#include +#endif + +/* + * prototype for the EVP functions that return an algorithm, e.g. + * EVP_aes_128_cbc(). + */ +typedef const EVP_CIPHER *(*ossl_EVP_cipher_func) (void); +typedef struct +{ + ossl_EVP_cipher_func cipher_func; + int key_len; +} cipher_info; + +/* + * Supported cipher function and its key size. The index of each cipher + * is (data_encryption_cipher - 1). + */ +cipher_info cipher_info_table[] = +{ + {EVP_aes_128_ctr, 16}, /* TDE_ENCRYPTION_AES_128 */ + {EVP_aes_256_ctr, 32} /* TDE_ENCRYPTION_AES_256 */ +}; + +typedef struct CipherCtx +{ + /* Encryption context */ + EVP_CIPHER_CTX *enc_ctx; + + /* Decryption context */ + EVP_CIPHER_CTX *dec_ctx; + + /* Key wrap context */ + EVP_CIPHER_CTX *wrap_ctx; + + /* Key unwrap context */ + EVP_CIPHER_CTX *unwrap_ctx; + + /* Key derivation context */ + EVP_PKEY_CTX *derive_ctx; +} CipherCtx; + +CipherCtx *MyCipherCtx = NULL; +MemoryContext EncMemoryCtx; + +static void createCipherContext(void); +static EVP_CIPHER_CTX *create_ossl_encryption_ctx(ossl_EVP_cipher_func func, + int klen, bool isenc, + bool iswrap); +static EVP_PKEY_CTX *create_ossl_derive_ctx(void); +static void setup_encryption_ossl(void); +static void setup_encryption(void) ; + +static void +createCipherContext(void) +{ + cipher_info *cipher = &cipher_info_table[data_encryption_cipher - 1]; + MemoryContext old_ctx; + CipherCtx *cctx; + + if (MyCipherCtx != NULL) + return; + + if (EncMemoryCtx == NULL) + EncMemoryCtx = AllocSetContextCreate(TopMemoryContext, + "db encryption context", + ALLOCSET_DEFAULT_SIZES); + + old_ctx = MemoryContextSwitchTo(EncMemoryCtx); + + cctx = (CipherCtx *) palloc(sizeof(CipherCtx)); + + /* Create encryption/decryption contexts */ + cctx->enc_ctx = create_ossl_encryption_ctx(cipher->cipher_func, + cipher->key_len, true, false); + cctx->dec_ctx = create_ossl_encryption_ctx(cipher->cipher_func, + cipher->key_len, false, false); + + /* Create key wrap/unwrap contexts */ + cctx->wrap_ctx = create_ossl_encryption_ctx(EVP_aes_256_wrap, + 32, true, true); + cctx->unwrap_ctx = create_ossl_encryption_ctx(EVP_aes_256_wrap, + 32, false, true); + + /* Create key derivation context */ + cctx->derive_ctx = create_ossl_derive_ctx(); + + /* Set my cipher context and key size */ + MyCipherCtx = cctx; + EncryptionKeySize = cipher->key_len; + + MemoryContextSwitchTo(old_ctx); +} + +/* Create openssl's key derivation context */ +static EVP_PKEY_CTX * +create_ossl_derive_ctx(void) +{ + EVP_PKEY_CTX *pctx = NULL; + +#ifdef HAVE_OPENSSL_KDF + pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL); + + if (EVP_PKEY_derive_init(pctx) <= 0) + ereport(ERROR, + (errmsg("openssl encountered error during initializing derive context"), + (errdetail("openssl error string: %s", + ERR_error_string(ERR_get_error(), NULL))))); + + if (EVP_PKEY_CTX_set_hkdf_md(pctx, EVP_sha256()) <= 0) + ereport(ERROR, + (errmsg("openssl encountered error during setting HKDF context"), + (errdetail("openssl error string: %s", + ERR_error_string(ERR_get_error(), NULL))))); +#endif + + return pctx; +} + +/* Create openssl's encryption context */ +static EVP_CIPHER_CTX * +create_ossl_encryption_ctx(ossl_EVP_cipher_func func, int klen, bool isenc, + bool iswrap) +{ + EVP_CIPHER_CTX *ctx; + int ret; + + /* Create new openssl cipher context */ + ctx = EVP_CIPHER_CTX_new(); + + /* Enable key wrap algorithm */ + if (iswrap) + EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); + + if (ctx == NULL) + ereport(ERROR, + (errmsg("openssl encountered error during creating context"), + (errdetail("openssl error string: %s", + ERR_error_string(ERR_get_error(), NULL))))); + + if (isenc) + ret = EVP_EncryptInit_ex(ctx, (const EVP_CIPHER *) func(), NULL, + NULL, NULL); + else + ret = EVP_DecryptInit_ex(ctx, (const EVP_CIPHER *) func(), NULL, + NULL, NULL); + + if (ret != 1) + ereport(ERROR, + (errmsg("openssl encountered error during initializing context"), + (errdetail("openssl error string: %s", + ERR_error_string(ERR_get_error(), NULL))))); + + if (!EVP_CIPHER_CTX_set_key_length(ctx, klen)) + ereport(ERROR, + (errmsg("openssl encountered error during setting key length"), + (errdetail("openssl error string: %s", + ERR_error_string(ERR_get_error(), NULL))))); + + return ctx; +} + +/* + * Initialize encryption subsystem for use. Must be called before any + * encryptable data is read from or written to data directory. + */ +static void +setup_encryption(void) +{ + setup_encryption_ossl(); + createCipherContext(); +} + +static void +setup_encryption_ossl(void) +{ +#ifndef HAVE_OPENSSL_KDF + /* + * We can initialize openssl even with openssl is 1.0.0 or older, but + * since AES key wrap algorithms have introduced in openssl 1.1.0 + * we require 1.1.0 or higher version for cluster encryption. + */ + ereport(ERROR, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + (errmsg("openssl 1.1.0 or higher is required for cluster encryption")))); +#endif + +#ifdef HAVE_OPENSSL_INIT_CRYPTO + /* Setup OpenSSL */ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); +#endif +} + +void +ossl_encrypt_data(const char *input, char *output, int size, + const char *key, const char *iv) +{ + int out_size; + EVP_CIPHER_CTX *ctx; + + /* Ensure encryption has setup */ + if (MyCipherCtx == NULL) + setup_encryption(); + + ctx = MyCipherCtx->enc_ctx; + + if (EVP_EncryptInit_ex(ctx, NULL, NULL, (unsigned char *) key, + (unsigned char *) iv) != 1) + ereport(ERROR, + (errmsg("openssl encountered initialization error during encryption"), + (errdetail("openssl error string: %s", + ERR_error_string(ERR_get_error(), NULL))))); + + if (EVP_EncryptUpdate(ctx, (unsigned char *) output, + &out_size, (unsigned char *) input, size) != 1) + ereport(ERROR, + (errmsg("openssl encountered error during encryption"), + (errdetail("openssl error string: %s", + ERR_error_string(ERR_get_error(), NULL))))); + + Assert(out_size == size); +} + +void +ossl_decrypt_data(const char *input, char *output, int size, + const char *key, const char *iv) +{ + int out_size; + EVP_CIPHER_CTX *ctx; + + /* Ensure encryption has setup */ + if (MyCipherCtx == NULL) + setup_encryption(); + + ctx = MyCipherCtx->dec_ctx; + + if (EVP_DecryptInit_ex(ctx, NULL, NULL, (unsigned char *) key, + (unsigned char *) iv) != 1) + ereport(ERROR, + (errmsg("openssl encountered initialization error during decryption"), + (errdetail("openssl error string: %s", + ERR_error_string(ERR_get_error(), NULL))))); + + if (EVP_DecryptUpdate(ctx, (unsigned char *) output, + &out_size, (unsigned char *) input, size) != 1) + ereport(ERROR, + (errmsg("openssl encountered error during decryption"), + (errdetail("openssl error string: %s", + ERR_error_string(ERR_get_error(), NULL))))); + + Assert(out_size == size); +} + +void +ossl_derive_key_passphrase(const char *passphrase, int pass_size, + unsigned char *salt, int salt_size, + int iter_cnt, int derived_size, + unsigned char *derived_key) +{ + int rc; + + /* Derive KEK from passphrase */ + rc = PKCS5_PBKDF2_HMAC(passphrase, pass_size, salt, salt_size, iter_cnt, + EVP_sha256(), derived_size, derived_key); + + if (rc != 1) + ereport(ERROR, + (errmsg("could not derive key from passphrase"), + (errdetail("openssl error string: %s", + ERR_error_string(ERR_get_error(), NULL))))); +} + +void +ossl_derive_key(const unsigned char *base_key, int base_size, unsigned char *info, + unsigned char *derived_key, Size derived_size) +{ +#ifdef HAVE_OPENSSL_KDF + EVP_PKEY_CTX *pctx; + + pctx = MyCipherCtx->derive_ctx; + + if (EVP_PKEY_CTX_set1_hkdf_key(pctx, base_key, base_size) != 1) + ereport(ERROR, + (errmsg("openssl encountered setting key error during key derivation"), + (errdetail("openssl error string: %s", + ERR_error_string(ERR_get_error(), NULL))))); + + /* + * we don't need to set salt since the input key is already present + * as cryptographically strong. + */ + + if (EVP_PKEY_CTX_add1_hkdf_info(pctx, (unsigned char *) info, + strlen((char *) info)) != 1) + ereport(ERROR, + (errmsg("openssl encountered setting info error during key derivation"), + (errdetail("openssl error string: %s", + ERR_error_string(ERR_get_error(), NULL))))); + + /* + * The 'derivedkey_size' should contain the length of the 'derivedkey' + * buffer, if the call got successful the derived key is written to + * 'derivedkey' and the amount of data written to 'derivedkey_size' + */ + if (EVP_PKEY_derive(pctx, derived_key, &derived_size) != 1) + ereport(ERROR, + (errmsg("openssl encountered error during key derivation"), + (errdetail("openssl error string: %s", + ERR_error_string(ERR_get_error(), NULL))))); +#endif +} + +void +ossl_compute_hmac(const unsigned char *hmac_key, int key_size, + unsigned char *data, int data_size, unsigned char *hmac) +{ + unsigned char *h; + uint32 hmac_size; + + Assert(hmac != NULL); + + h = HMAC(EVP_sha256(), hmac_key, key_size, data, data_size, hmac, &hmac_size); + + if (h == NULL) + ereport(ERROR, + (errmsg("could not compute HMAC"), + (errdetail("openssl error string: %s", + ERR_error_string(ERR_get_error(), NULL))))); + + memcpy(hmac, h, hmac_size); +} + +void +ossl_wrap_key(const unsigned char *key, int key_size, unsigned char *in, + int in_size, unsigned char *out, int *out_size) +{ + EVP_CIPHER_CTX *ctx; + + /* Ensure encryption has setup */ + if (MyCipherCtx == NULL) + setup_encryption(); + + ctx = MyCipherCtx->wrap_ctx; + + if (EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL) != 1) + ereport(ERROR, + (errmsg("openssl encountered initialization error during unwrapping key"), + (errdetail("openssl error string: %s", + ERR_error_string(ERR_get_error(), NULL))))); + + if (!EVP_CIPHER_CTX_set_key_length(ctx, key_size)) + ereport(ERROR, + (errmsg("openssl encountered setting key length error during wrapping key"), + (errdetail("openssl error string: %s", + ERR_error_string(ERR_get_error(), NULL))))); + + if (!EVP_EncryptUpdate(ctx, out, out_size, in, in_size)) + ereport(ERROR, + (errmsg("openssl encountered error during unwrapping key"), + (errdetail("openssl error string: %s", + ERR_error_string(ERR_get_error(), NULL))))); +} + +void +ossl_unwrap_key(const unsigned char *key, int key_size, unsigned char *in, + int in_size, unsigned char *out, int *out_size) +{ + EVP_CIPHER_CTX *ctx; + + /* Ensure encryption has setup */ + if (MyCipherCtx == NULL) + setup_encryption(); + + ctx = MyCipherCtx->unwrap_ctx; + + if (EVP_DecryptInit_ex(ctx, NULL, NULL, key, NULL) != 1) + ereport(ERROR, + (errmsg("openssl encountered initialization error during unwrapping key"), + (errdetail("openssl error string: %s", + ERR_error_string(ERR_get_error(), NULL))))); + + if (!EVP_CIPHER_CTX_set_key_length(ctx, key_size)) + ereport(ERROR, + (errmsg("openssl encountered setting key length error during unwrapping key"), + (errdetail("openssl error string: %s", + ERR_error_string(ERR_get_error(), NULL))))); + + if (EVP_DecryptUpdate(ctx, out, out_size, in, in_size) != 1) + ereport(ERROR, + (errmsg("openssl encountered error during unwrapping key"), + (errdetail("openssl error string: %s", + ERR_error_string(ERR_get_error(), NULL))))); +} diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 512213a..ac5334b 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -416,6 +416,12 @@ /* Define to 1 if you have the `OPENSSL_init_ssl' function. */ #undef HAVE_OPENSSL_INIT_SSL +/* Define to 1 if you have the `OPENSSL_init_crypto' function. */ +#undef HAVE_OPENSSL_INIT_CRYPTO + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_KDF + /* Define to 1 if you have the header file. */ #undef HAVE_OSSP_UUID_H diff --git a/src/include/storage/enc_cipher.h b/src/include/storage/enc_cipher.h new file mode 100644 index 0000000..3915047 --- /dev/null +++ b/src/include/storage/enc_cipher.h @@ -0,0 +1,37 @@ +/*------------------------------------------------------------------------- + * + * enc_cipher.h + * This file contains definitions for structures and externs for + * functions used by data encryption. + * + * Portions Copyright (c) 2019, PostgreSQL Global Development Group + * + * src/include/storage/enc_cipher.h + * + *------------------------------------------------------------------------- + */ +#ifndef ENC_CIPHER_H +#define ENC_CIPHER_H + +extern void pg_encrypt(const char *input, char *output, int size, + const char *key, const char *iv); +extern void pg_decrypt(const char *input, char *output, int size, + const char *key, const char *iv); +extern void pg_derive_key_passphrase(const char *passphrase, int pass_size, + unsigned char *salt, int salt_size, + int iter_cnt, int derived_size, + unsigned char *derived_key); +extern void pg_derive_key(const unsigned char *base_key, int base_size, + unsigned char *info, unsigned char *derived_key, + Size derived_size); +extern void pg_compute_hmac(const unsigned char *hmac_key, int key_size, + unsigned char *data, int data_size, + unsigned char *hmac); +extern void pg_wrap_key(const unsigned char *key, int key_size, + unsigned char *in, int in_size, unsigned char *out, + int *out_size); +extern void pg_unwrap_key(const unsigned char *key, int key_size, + unsigned char *in, int in_size, unsigned char *out, + int *out_size); + +#endif /* ENC_CIPHER_H */ diff --git a/src/include/storage/enc_common.h b/src/include/storage/enc_common.h new file mode 100644 index 0000000..bea5427 --- /dev/null +++ b/src/include/storage/enc_common.h @@ -0,0 +1,32 @@ +/*------------------------------------------------------------------------- + * + * enc_common.h + * This file contains common definitions for cluster encryption. + * + * Portions Copyright (c) 2019, PostgreSQL Global Development Group + * + * src/include/storage/enc_common.h + * + *------------------------------------------------------------------------- + */ +#ifndef ENC_COMMON_H +#define ENC_COMMON_H + +/* Value of data_encryption_cipher */ +enum database_encryption_cipher_kind +{ + TDE_ENCRYPTION_OFF = 0, + TDE_ENCRYPTION_AES_128, + TDE_ENCRYPTION_AES_256 +}; + +/* GUC parameter */ +extern int data_encryption_cipher; + +/* Encrypton keys (TDEK and WDEK) size */ +extern int EncryptionKeySize; + +extern char *EncryptionCipherString(int value); +extern int EncryptionCipherValue(const char *name); + +#endif /* ENC_COMMON_H */ diff --git a/src/include/storage/enc_internal.h b/src/include/storage/enc_internal.h new file mode 100644 index 0000000..7726fd6 --- /dev/null +++ b/src/include/storage/enc_internal.h @@ -0,0 +1,38 @@ +/*------------------------------------------------------------------------- + * + * enc_internal.h + * This file contains internal definitions of encryption cipher + * functions. + * + * Portions Copyright (c) 2019, PostgreSQL Global Development Group + * + * src/include/storage/enc_internal.h + * + *------------------------------------------------------------------------- + */ +#ifndef ENC_INTERNAL_H +#define ENC_INTERNAL_H + +/* enc_openssl.h */ +extern void ossl_encrypt_data(const char *input, char *output, int size, + const char *key, const char *iv); +extern void ossl_decrypt_data(const char *input, char *output, int size, + const char *key, const char *iv); +extern void ossl_derive_key_passphrase(const char *passphrase, int pass_size, + unsigned char *salt, int salt_size, + int iter_cnt, int derived_size, + unsigned char *derived_key); +extern void ossl_derive_key(const unsigned char *base_key, int base_size, + unsigned char *info, unsigned char *derived_key, + Size derived_size); +extern void ossl_compute_hmac(const unsigned char *hmac_key, int key_size, + unsigned char *data, int data_size, + unsigned char *hmac); +extern void ossl_wrap_key(const unsigned char *kek, int key_size, + unsigned char *in, int in_size, unsigned char *out, + int *out_size); +extern void ossl_unwrap_key(const unsigned char *key, int key_size, + unsigned char *in, int in_size, unsigned char *out, + int *out_size); + +#endif /* ENC_INTERNAL_H */ diff --git a/src/include/storage/encryption.h b/src/include/storage/encryption.h new file mode 100644 index 0000000..eaf17ab --- /dev/null +++ b/src/include/storage/encryption.h @@ -0,0 +1,49 @@ +/*------------------------------------------------------------------------- + * + * encryption.h + * Cluster encryption functions. + * + * Portions Copyright (c) 2019, PostgreSQL Global Development Group + * + * src/include/storage/encryption.h + * + *------------------------------------------------------------------------- + */ +#ifndef ENCRYPTION_H +#define ENCRYPTION_H + +#include "access/xlogdefs.h" +#include "storage/bufpage.h" +#include "storage/enc_cipher.h" +#include "storage/enc_common.h" + +#define DataEncryptionEnabled() \ + (data_encryption_cipher > 0) + +/* Cluster encryption doesn't encrypt VM and FSM */ +#define EncryptForkNum(forknum) \ + ((forknum) == MAIN_FORKNUM || (forknum) == INIT_FORKNUM) + +/* + * The encrypted data is a series of blocks of size ENCRYPTION_BLOCK. + * Initialization vector(IV) is the same size of cipher block. + */ +#define ENC_BLOCK_SIZE 16 +#define ENC_IV_SIZE (ENC_BLOCK_SIZE) + +/* + * Maximum encryption key size is used by AES-256. + */ +#define ENC_MAX_ENCRYPTION_KEY_SIZE 32 + +/* + * The size for counter of AES-CTR mode in nonce. + */ +#define ENC_WAL_AES_COUNTER_SIZE 32 +#define ENC_BUFFER_AES_COUNTER_SIZE 32 + +/* bufenc.c */ +extern void DecryptBufferBlock(BlockNumber blocknum, Page page); +extern void EncryptBufferBlock(BlockNumber blocknum, Page page); + +#endif /* ENCRYPTION_H */ -- 2.10.5