PG-1416 Make assertions on length on encrypted data more local

This makes the code easier to follow by keeping things local. There
were already harmless misunderstandings of this API in the SMGR code.
pull/209/head
Andreas Karlsson 6 months ago committed by Andreas Karlsson
parent 9155b9e654
commit ac87addc37
  1. 6
      contrib/pg_tde/src/access/pg_tde_tdemap.c
  2. 33
      contrib/pg_tde/src/encryption/enc_aes.c
  3. 8
      contrib/pg_tde/src/encryption/enc_tde.c
  4. 4
      contrib/pg_tde/src/include/encryption/enc_aes.h
  5. 4
      contrib/pg_tde/src/include/encryption/enc_tde.h
  6. 9
      contrib/pg_tde/src/smgr/pg_tde_smgr.c

@ -276,9 +276,8 @@ static InternalKey *
tde_encrypt_rel_key(TDEPrincipalKey *principal_key, InternalKey *rel_key_data, Oid dbOid)
{
InternalKey *enc_rel_key_data;
size_t enc_key_bytes;
AesEncryptKey(principal_key, dbOid, rel_key_data, &enc_rel_key_data, &enc_key_bytes);
AesEncryptKey(principal_key, dbOid, rel_key_data, &enc_rel_key_data);
return enc_rel_key_data;
}
@ -925,9 +924,8 @@ static InternalKey *
tde_decrypt_rel_key(TDEPrincipalKey *principal_key, InternalKey *enc_rel_key_data, Oid dbOid)
{
InternalKey *rel_key_data = NULL;
size_t key_bytes;
AesDecryptKey(principal_key, dbOid, &rel_key_data, enc_rel_key_data, &key_bytes);
AesDecryptKey(principal_key, dbOid, &rel_key_data, enc_rel_key_data);
return rel_key_data;
}

@ -63,8 +63,10 @@ AesInit(void)
/* TODO: a few things could be optimized in this. It's good enough for a prototype. */
static void
AesRunCtr(EVP_CIPHER_CTX **ctxPtr, int enc, const unsigned char *key, const unsigned char *iv, const unsigned char *in, int in_len, unsigned char *out, int *out_len)
AesRunCtr(EVP_CIPHER_CTX **ctxPtr, int enc, const unsigned char *key, const unsigned char *iv, const unsigned char *in, int in_len, unsigned char *out)
{
int out_len;
if (*ctxPtr == NULL)
{
*ctxPtr = EVP_CIPHER_CTX_new();
@ -77,15 +79,18 @@ AesRunCtr(EVP_CIPHER_CTX **ctxPtr, int enc, const unsigned char *key, const unsi
EVP_CIPHER_CTX_set_padding(*ctxPtr, 0);
}
if (EVP_CipherUpdate(*ctxPtr, out, out_len, in, in_len) == 0)
if (EVP_CipherUpdate(*ctxPtr, out, &out_len, in, in_len) == 0)
ereport(ERROR,
(errmsg("EVP_CipherUpdate failed. OpenSSL error: %s", ERR_error_string(ERR_get_error(), NULL))));
Assert(out_len == in_len);
}
static void
AesRunCbc(int enc, const unsigned char *key, const unsigned char *iv, const unsigned char *in, int in_len, unsigned char *out, int *out_len)
AesRunCbc(int enc, const unsigned char *key, const unsigned char *iv, const unsigned char *in, int in_len, unsigned char *out)
{
int out_len_final = 0;
int out_len;
int out_len_final;
EVP_CIPHER_CTX *ctx = NULL;
Assert(in_len % EVP_CIPHER_block_size(cipher_cbc) == 0);
@ -99,11 +104,11 @@ AesRunCbc(int enc, const unsigned char *key, const unsigned char *iv, const unsi
EVP_CIPHER_CTX_set_padding(ctx, 0);
if (EVP_CipherUpdate(ctx, out, out_len, in, in_len) == 0)
if (EVP_CipherUpdate(ctx, out, &out_len, in, in_len) == 0)
ereport(ERROR,
(errmsg("EVP_CipherUpdate failed. OpenSSL error: %s", ERR_error_string(ERR_get_error(), NULL))));
if (EVP_CipherFinal_ex(ctx, out + *out_len, &out_len_final) == 0)
if (EVP_CipherFinal_ex(ctx, out + out_len, &out_len_final) == 0)
ereport(ERROR,
(errmsg("EVP_CipherFinal_ex failed. OpenSSL error: %s", ERR_error_string(ERR_get_error(), NULL))));
@ -111,23 +116,23 @@ AesRunCbc(int enc, const unsigned char *key, const unsigned char *iv, const unsi
* We encrypt one block (16 bytes) Our expectation is that the result
* should also be 16 bytes, without any additional padding
*/
*out_len += out_len_final;
Assert(in_len == *out_len);
out_len += out_len_final;
Assert(in_len == out_len);
EVP_CIPHER_CTX_cleanup(ctx);
EVP_CIPHER_CTX_free(ctx);
}
void
AesEncrypt(const unsigned char *key, const unsigned char *iv, const unsigned char *in, int in_len, unsigned char *out, int *out_len)
AesEncrypt(const unsigned char *key, const unsigned char *iv, const unsigned char *in, int in_len, unsigned char *out)
{
AesRunCbc(1, key, iv, in, in_len, out, out_len);
AesRunCbc(1, key, iv, in, in_len, out);
}
void
AesDecrypt(const unsigned char *key, const unsigned char *iv, const unsigned char *in, int in_len, unsigned char *out, int *out_len)
AesDecrypt(const unsigned char *key, const unsigned char *iv, const unsigned char *in, int in_len, unsigned char *out)
{
AesRunCbc(0, key, iv, in, in_len, out, out_len);
AesRunCbc(0, key, iv, in, in_len, out);
}
/* This function assumes that the out buffer is big enough: at least (blockNumber2 - blockNumber1) * 16 bytes
@ -137,7 +142,6 @@ Aes128EncryptedZeroBlocks(void *ctxPtr, const unsigned char *key, const char *iv
{
const unsigned char iv[16] = {0,};
unsigned char *p;
int outLen;
Assert(blockNumber2 >= blockNumber1);
@ -157,6 +161,5 @@ Aes128EncryptedZeroBlocks(void *ctxPtr, const unsigned char *key, const char *iv
p += sizeof(j);
}
AesRunCtr(ctxPtr, 1, key, iv, out, p - out, out, &outLen);
Assert(outLen == p - out);
AesRunCtr(ctxPtr, 1, key, iv, out, p - out, out);
}

@ -162,7 +162,7 @@ pg_tde_crypt(const char *iv_prefix, uint32 start_offset, const char *data, uint3
* short lifespan until it is written to disk.
*/
void
AesEncryptKey(const TDEPrincipalKey *principal_key, Oid dbOid, InternalKey *rel_key_data, InternalKey **p_enc_rel_key_data, size_t *enc_key_bytes)
AesEncryptKey(const TDEPrincipalKey *principal_key, Oid dbOid, InternalKey *rel_key_data, InternalKey **p_enc_rel_key_data)
{
unsigned char iv[16] = {0,};
@ -174,7 +174,7 @@ AesEncryptKey(const TDEPrincipalKey *principal_key, Oid dbOid, InternalKey *rel_
*p_enc_rel_key_data = palloc_object(InternalKey);
**p_enc_rel_key_data = *rel_key_data;
AesEncrypt(principal_key->keyData, iv, (unsigned char *) rel_key_data, INTERNAL_KEY_LEN, (unsigned char *) *p_enc_rel_key_data, (int *) enc_key_bytes);
AesEncrypt(principal_key->keyData, iv, (unsigned char *) rel_key_data, INTERNAL_KEY_LEN, (unsigned char *) *p_enc_rel_key_data);
}
#endif /* FRONTEND */
@ -187,7 +187,7 @@ AesEncryptKey(const TDEPrincipalKey *principal_key, Oid dbOid, InternalKey *rel_
* to our key cache.
*/
void
AesDecryptKey(const TDEPrincipalKey *principal_key, Oid dbOid, InternalKey **p_rel_key_data, InternalKey *enc_rel_key_data, size_t *key_bytes)
AesDecryptKey(const TDEPrincipalKey *principal_key, Oid dbOid, InternalKey **p_rel_key_data, InternalKey *enc_rel_key_data)
{
unsigned char iv[16] = {0,};
@ -201,5 +201,5 @@ AesDecryptKey(const TDEPrincipalKey *principal_key, Oid dbOid, InternalKey **p_r
/* Fill in the structure */
**p_rel_key_data = *enc_rel_key_data;
AesDecrypt(principal_key->keyData, iv, (unsigned char *) enc_rel_key_data, INTERNAL_KEY_LEN, (unsigned char *) *p_rel_key_data, (int *) key_bytes);
AesDecrypt(principal_key->keyData, iv, (unsigned char *) enc_rel_key_data, INTERNAL_KEY_LEN, (unsigned char *) *p_rel_key_data);
}

@ -16,7 +16,7 @@ extern void AesInit(void);
extern void Aes128EncryptedZeroBlocks(void *ctxPtr, const unsigned char *key, const char *iv_prefix, uint64_t blockNumber1, uint64_t blockNumber2, unsigned char *out);
/* Only used for testing */
extern void AesEncrypt(const unsigned char *key, const unsigned char *iv, const unsigned char *in, int in_len, unsigned char *out, int *out_len);
extern void AesDecrypt(const unsigned char *key, const unsigned char *iv, const unsigned char *in, int in_len, unsigned char *out, int *out_len);
extern void AesEncrypt(const unsigned char *key, const unsigned char *iv, const unsigned char *in, int in_len, unsigned char *out);
extern void AesDecrypt(const unsigned char *key, const unsigned char *iv, const unsigned char *in, int in_len, unsigned char *out);
#endif /* ENC_AES_H */

@ -22,7 +22,7 @@ extern void pg_tde_crypt(const char *iv_prefix, uint32 start_offset, const char
#define PG_TDE_DECRYPT_DATA(_iv_prefix, _start_offset, _data, _data_len, _out, _key, _ctxptr) \
pg_tde_crypt(_iv_prefix, _start_offset, _data, _data_len, _out, _key, _ctxptr, "DECRYPT")
extern void AesEncryptKey(const TDEPrincipalKey *principal_key, Oid dbOid, InternalKey *rel_key_data, InternalKey **p_enc_rel_key_data, size_t *enc_key_bytes);
extern void AesDecryptKey(const TDEPrincipalKey *principal_key, Oid dbOid, InternalKey **p_rel_key_data, InternalKey *enc_rel_key_data, size_t *key_bytes);
extern void AesEncryptKey(const TDEPrincipalKey *principal_key, Oid dbOid, InternalKey *rel_key_data, InternalKey **p_enc_rel_key_data);
extern void AesDecryptKey(const TDEPrincipalKey *principal_key, Oid dbOid, InternalKey **p_rel_key_data, InternalKey *enc_rel_key_data);
#endif /* ENC_TDE_H */

@ -95,7 +95,6 @@ tde_mdwritev(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
for (int i = 0; i < nblocks; ++i)
{
int out_len = BLCKSZ;
BlockNumber bn = blocknum + i;
unsigned char iv[16] = {0,};
@ -104,7 +103,7 @@ tde_mdwritev(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
memcpy(iv + 4, &bn, sizeof(BlockNumber));
AesEncrypt(int_key->key, iv, ((unsigned char **) buffers)[i], BLCKSZ, local_buffers[i], &out_len);
AesEncrypt(int_key->key, iv, ((unsigned char **) buffers)[i], BLCKSZ, local_buffers[i]);
}
mdwritev(reln, forknum, blocknum,
@ -130,7 +129,6 @@ tde_mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
{
unsigned char *local_blocks = palloc(BLCKSZ * (1 + 1));
unsigned char *local_blocks_aligned = (unsigned char *) TYPEALIGN(PG_IO_ALIGN_SIZE, local_blocks);
int out_len = BLCKSZ;
unsigned char iv[16] = {
0,
};
@ -138,7 +136,7 @@ tde_mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
AesInit();
memcpy(iv + 4, &blocknum, sizeof(BlockNumber));
AesEncrypt(int_key->key, iv, ((unsigned char *) buffer), BLCKSZ, local_blocks_aligned, &out_len);
AesEncrypt(int_key->key, iv, ((unsigned char *) buffer), BLCKSZ, local_blocks_aligned);
mdextend(reln, forknum, blocknum, local_blocks_aligned, skipFsync);
@ -150,7 +148,6 @@ static void
tde_mdreadv(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
void **buffers, BlockNumber nblocks)
{
int out_len = BLCKSZ;
TDESMgrRelation tdereln = (TDESMgrRelation) reln;
InternalKey *int_key = &tdereln->relKey;
@ -194,7 +191,7 @@ tde_mdreadv(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
memcpy(iv + 4, &bn, sizeof(BlockNumber));
AesDecrypt(int_key->key, iv, ((unsigned char **) buffers)[i], BLCKSZ, ((unsigned char **) buffers)[i], &out_len);
AesDecrypt(int_key->key, iv, ((unsigned char **) buffers)[i], BLCKSZ, ((unsigned char **) buffers)[i]);
}
}

Loading…
Cancel
Save