This is an automated email from the ASF dual-hosted git repository. reshke pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/cloudberry.git
commit 359474ad38b7bb892c5ab36a11d3867b6d7ddcab Author: Daniel Gustafsson <[email protected]> AuthorDate: Mon Aug 10 06:38:25 2026 -0700 Fix errorhandling for PGP encryption PGP encryption was using px_cipher_encrypt without checking if any error was returned. When OpenSSL is running in FIPS mode, or when the legacy provider hasn't been loaded, not all ciphers which are supported by the PGP code are available and fail the init step in px_cipher_encrypt. Since the PGP encryption failed to notice this it XORed the non-encrypted block with the plaintext, effectively disabling the encryption. This was found due to a report of PGP encryption not respecting the pgcrypto.builtin_crypto_enabled flag and allowing Blowfish and DES. This however turned out to be a false positive, since the PGP code only use ciphers from OpenSSL and not the built in ciphers. Bug: #19457 Reported-by: Shishir Sharma <[email protected]> Reviewed-by: Jacob Champion <[email protected]> Discussion: https://postgr.es/m/[email protected] Security: CVE-2026-14663 Backpatch-through: 14 --- contrib/pgcrypto/expected/pgp-decrypt_1.out | 2 +- contrib/pgcrypto/expected/pgp-encrypt_1.out | 200 +++++++++++++++++++++ contrib/pgcrypto/expected/pgp-pubkey-decrypt_1.out | 2 +- contrib/pgcrypto/pgp-cfb.c | 8 +- 4 files changed, 209 insertions(+), 3 deletions(-) diff --git a/contrib/pgcrypto/expected/pgp-decrypt_1.out b/contrib/pgcrypto/expected/pgp-decrypt_1.out index d214e0bc0e0..ef2e27b8aa7 100644 --- a/contrib/pgcrypto/expected/pgp-decrypt_1.out +++ b/contrib/pgcrypto/expected/pgp-decrypt_1.out @@ -11,7 +11,7 @@ yA6Ce1QTMK3KdL2MPfamsTUSAML8huCJMwYQFfE= =JcP+ -----END PGP MESSAGE----- '), 'foobar'); -ERROR: Wrong key or corrupt data +ERROR: encrypt error: Cipher cannot be initialized select pgp_sym_decrypt(dearmor(' -----BEGIN PGP MESSAGE----- Comment: dat1.aes.sha1.mdc.s2k3.z0 diff --git a/contrib/pgcrypto/expected/pgp-encrypt_1.out b/contrib/pgcrypto/expected/pgp-encrypt_1.out new file mode 100644 index 00000000000..ad63df15707 --- /dev/null +++ b/contrib/pgcrypto/expected/pgp-encrypt_1.out @@ -0,0 +1,200 @@ +-- +-- PGP encrypt +-- +select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'), 'key'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +-- check whether the defaults are ok +select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'), + 'key', 'expect-cipher-algo=aes128, + expect-disable-mdc=0, + expect-sess-key=0, + expect-s2k-mode=3, + expect-s2k-digest-algo=sha1, + expect-compress-algo=0 + '); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +-- maybe the expect- stuff simply does not work +select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'), + 'key', 'expect-cipher-algo=bf, + expect-disable-mdc=1, + expect-sess-key=1, + expect-s2k-mode=0, + expect-s2k-digest-algo=md5, + expect-compress-algo=1 + '); +NOTICE: pgp_decrypt: unexpected cipher_algo: expected 4 got 7 +NOTICE: pgp_decrypt: unexpected s2k_mode: expected 0 got 3 +NOTICE: pgp_decrypt: unexpected s2k_digest_algo: expected 1 got 2 +NOTICE: pgp_decrypt: unexpected use_sess_key: expected 1 got 0 +NOTICE: pgp_decrypt: unexpected disable_mdc: expected 1 got 0 +NOTICE: pgp_decrypt: unexpected compress_algo: expected 1 got 0 + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +-- bytea as text +select pgp_sym_decrypt(pgp_sym_encrypt_bytea('Binary', 'baz'), 'baz'); +ERROR: Not text data +-- text as bytea +select encode(pgp_sym_decrypt_bytea(pgp_sym_encrypt('Text', 'baz'), 'baz'), 'escape'); + encode +-------- + Text +(1 row) + +-- algorithm change +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=bf'), + 'key', 'expect-cipher-algo=bf'); +ERROR: encrypt error: Cipher cannot be initialized +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=aes'), + 'key', 'expect-cipher-algo=aes128'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=aes192'), + 'key', 'expect-cipher-algo=aes192'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +-- s2k change +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 's2k-mode=0'), + 'key', 'expect-s2k-mode=0'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 's2k-mode=1'), + 'key', 'expect-s2k-mode=1'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 's2k-mode=3'), + 'key', 'expect-s2k-mode=3'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +-- s2k count change +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 's2k-count=1024'), + 'key', 'expect-s2k-count=1024'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +-- s2k_count rounds up +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 's2k-count=65000000'), + 'key', 'expect-s2k-count=65000000'); +NOTICE: pgp_decrypt: unexpected s2k_count: expected 65000000 got 65011712 + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +-- s2k digest change +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=md5'), + 'key', 'expect-s2k-digest-algo=md5'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=sha1'), + 'key', 'expect-s2k-digest-algo=sha1'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +-- sess key +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 'sess-key=0'), + 'key', 'expect-sess-key=0'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 'sess-key=1'), + 'key', 'expect-sess-key=1'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=bf'), + 'key', 'expect-sess-key=1, expect-cipher-algo=bf'); +ERROR: encrypt error: Cipher cannot be initialized +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=aes192'), + 'key', 'expect-sess-key=1, expect-cipher-algo=aes192'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=aes256'), + 'key', 'expect-sess-key=1, expect-cipher-algo=aes256'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +-- no mdc +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 'disable-mdc=1'), + 'key', 'expect-disable-mdc=1'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +-- crlf +select pgp_sym_decrypt_bytea( + pgp_sym_encrypt(E'1\n2\n3\r\n', 'key', 'convert-crlf=1'), + 'key'); + pgp_sym_decrypt_bytea +------------------------ + \x310d0a320d0a330d0d0a +(1 row) + +-- conversion should be lossless +select digest(pgp_sym_decrypt( + pgp_sym_encrypt(E'\r\n0\n1\r\r\n\n2\r', 'key', 'convert-crlf=1'), + 'key', 'convert-crlf=1'), 'sha1') as result, + digest(E'\r\n0\n1\r\r\n\n2\r', 'sha1') as expect; + result | expect +--------------------------------------------+-------------------------------------------- + \x47bde5d88d6ef8770572b9cbb4278b402aa69966 | \x47bde5d88d6ef8770572b9cbb4278b402aa69966 +(1 row) + diff --git a/contrib/pgcrypto/expected/pgp-pubkey-decrypt_1.out b/contrib/pgcrypto/expected/pgp-pubkey-decrypt_1.out index f41c6c9893a..7e2e1f98fca 100644 --- a/contrib/pgcrypto/expected/pgp-pubkey-decrypt_1.out +++ b/contrib/pgcrypto/expected/pgp-pubkey-decrypt_1.out @@ -595,7 +595,7 @@ from keytbl, encdata where keytbl.id=1 and encdata.id=1; select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) from keytbl, encdata where keytbl.id=2 and encdata.id=2; -ERROR: Wrong key or corrupt data +ERROR: encrypt error: Cipher cannot be initialized select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) from keytbl, encdata where keytbl.id=3 and encdata.id=3; pgp_pub_decrypt diff --git a/contrib/pgcrypto/pgp-cfb.c b/contrib/pgcrypto/pgp-cfb.c index de41e825b0c..e6ae3a49244 100644 --- a/contrib/pgcrypto/pgp-cfb.c +++ b/contrib/pgcrypto/pgp-cfb.c @@ -221,8 +221,14 @@ cfb_process(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst, while (len > 0) { unsigned rlen; + int err; + + err = px_cipher_encrypt(ctx->ciph, 0, ctx->fr, ctx->block_size, ctx->fre, &rlen); + if (err) + ereport(ERROR, + (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), + errmsg("encrypt error: %s", px_strerror(err)))); - px_cipher_encrypt(ctx->ciph, 0, ctx->fr, ctx->block_size, ctx->fre, &rlen); if (ctx->block_no < 5) ctx->block_no++; --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
