This is an automated email from the ASF dual-hosted git repository.

reshke pushed a commit to branch REL_2_STABLE
in repository https://gitbox.apache.org/repos/asf/cloudberry.git

commit b85a3a9bf4d7aa1cc20e4c8b527cb376f06c6575
Author: Daniel Gustafsson <[email protected]>
AuthorDate: Mon Aug 10 06:38:37 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        | 202 +++++++++++++++++++++
 contrib/pgcrypto/expected/pgp-pubkey-decrypt_1.out |   2 +-
 contrib/pgcrypto/pgp-cfb.c                         |   9 +-
 4 files changed, 212 insertions(+), 3 deletions(-)

diff --git a/contrib/pgcrypto/expected/pgp-decrypt_1.out 
b/contrib/pgcrypto/expected/pgp-decrypt_1.out
index 63d5ab98654..1bad2c93261 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..743e7080033
--- /dev/null
+++ b/contrib/pgcrypto/expected/pgp-encrypt_1.out
@@ -0,0 +1,202 @@
+--
+-- PGP encrypt
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+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 pgp_sym_decrypt_bytea(pgp_sym_encrypt('Text', 'baz'), 'baz');
+ pgp_sym_decrypt_bytea 
+-----------------------
+ 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 encode(pgp_sym_decrypt_bytea(
+       pgp_sym_encrypt(E'1\n2\n3\r\n', 'key', 'convert-crlf=1'),
+       'key'), 'hex');
+        encode        
+----------------------
+ 310d0a320d0a330d0d0a
+(1 row)
+
+-- conversion should be lossless
+select encode(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'), 'hex') as result,
+  encode(digest(E'\r\n0\n1\r\r\n\n2\r', 'sha1'), 'hex') as expect;
+                  result                  |                  expect            
      
+------------------------------------------+------------------------------------------
+ 47bde5d88d6ef8770572b9cbb4278b402aa69966 | 
47bde5d88d6ef8770572b9cbb4278b402aa69966
+(1 row)
+
diff --git a/contrib/pgcrypto/expected/pgp-pubkey-decrypt_1.out 
b/contrib/pgcrypto/expected/pgp-pubkey-decrypt_1.out
index f41c6c9893a..34d3c28c48d 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 dafa562daa1..967ea50a4b7 100644
--- a/contrib/pgcrypto/pgp-cfb.c
+++ b/contrib/pgcrypto/pgp-cfb.c
@@ -220,7 +220,14 @@ cfb_process(PGP_CFB *ctx, const uint8 *data, int len, 
uint8 *dst,
 
        while (len > 0)
        {
-               px_cipher_encrypt(ctx->ciph, ctx->fr, ctx->block_size, 
ctx->fre);
+               int                     err;
+
+               err = px_cipher_encrypt(ctx->ciph, ctx->fr, ctx->block_size, 
ctx->fre);
+               if (err)
+                       ereport(ERROR,
+                                       
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
+                                        errmsg("encrypt error: %s", 
px_strerror(err))));
+
                if (ctx->block_no < 5)
                        ctx->block_no++;
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to