From ec906bbe68b69890f60531a9a080e867f8e6ba91 Mon Sep 17 00:00:00 2001 From: kongfanshen Date: Fri, 12 Apr 2024 14:15:19 +0800 Subject: [PATCH] Fix: make enough out data buffer when call EVP_DecryptUpdate (#479) If padding is enabled the decrypted data buffer out passed to EVP_DecryptUpdate() should have sufficient room for (inl + cipher_block_size) bytes. More detail information in https://www.openssl.org/docs/man3.1/man3/EVP_DecryptUpdate.html --- src/backend/crypto/kmgr.c | 6 +++--- src/common/kmgr_utils.c | 17 ++++++++++++++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/backend/crypto/kmgr.c b/src/backend/crypto/kmgr.c index 32f2366a9a5..0b6fce1304e 100644 --- a/src/backend/crypto/kmgr.c +++ b/src/backend/crypto/kmgr.c @@ -45,7 +45,7 @@ typedef struct KmgrShmemData { CryptoKey intlKeys[KMGR_NUM_DATA_KEYS]; } KmgrShmemData; -static KmgrShmemData *KmgrShmem; +static KmgrShmemData *KmgrShmem = NULL; /* GUC variables */ char *cluster_key_command = NULL; @@ -218,7 +218,7 @@ BootStrapKmgr(void) Size KmgrShmemSize(void) { - if (!FileEncryptionEnabled) + if (!tde_force_switch) return 0; return MAXALIGN(sizeof(KmgrShmemData)); @@ -230,7 +230,7 @@ KmgrShmemInit(void) { bool found; - if (!FileEncryptionEnabled) + if (!tde_force_switch) return; KmgrShmem = (KmgrShmemData *) ShmemInitStruct("File encryption key manager", diff --git a/src/common/kmgr_utils.c b/src/common/kmgr_utils.c index 1a6f281deb6..af668854b67 100644 --- a/src/common/kmgr_utils.c +++ b/src/common/kmgr_utils.c @@ -102,14 +102,29 @@ bool kmgr_unwrap_data_key(PgCipherCtx *ctx, unsigned char *in, int inlen, CryptoKey *out) { int outlen; + int out_buffer_len; + unsigned char *out_buffer; + + /* + * When call EVP_DecryptUpdate, + * We need to alloc enough buffer + * More detail info see + * https://www.openssl.org/docs/man3.1/man3/EVP_DecryptUpdate.html + */ + out_buffer_len = pg_cipher_blocksize(ctx) + inlen; + out_buffer = (unsigned char *)palloc0(out_buffer_len); Assert(ctx && in && out); - if (!pg_cipher_keyunwrap(ctx, in, inlen, (unsigned char *) out, &outlen)) + if (!pg_cipher_keyunwrap(ctx, in, inlen, (unsigned char *) out_buffer, &outlen)) return false; Assert(outlen == sizeof(CryptoKey)); + memcpy(out, out_buffer, sizeof(CryptoKey)); + + pfree(out_buffer); + return true; }