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

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

commit 223b2e693e98cb6c4c02bafdd881182a2196c47f
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]

Reply via email to