From bf723a274cbb00c7fba66c66312a77940af13d79 Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Mon, 3 Jul 2017 12:10:11 +0300
Subject: [PATCH] Forbid gen_random_uuid() with --disable-strong-random

Previously, gen_random_uuid() would fall back to a weak random number
generator, unlike gen_random_bytes() which would just fail. And this was
not made very clear in the docs. For consistency, also make
gen_random_uuid() fail outright, if compiled with --disable-strong-random.

Re-word the error message you get with --disable-strong-random. It is also
used by pgp functions that require random salts, and now also
gen_random_uuid().

Reported by Radek Slupik.

Discussion: https://www.postgresql.org/message-id/20170101232054.10135.50528@wrigleys.postgresql.org
---
 .../pgcrypto/expected/pgp-compression_1.out   |  8 ++--
 contrib/pgcrypto/expected/pgp-decrypt_1.out   |  4 +-
 contrib/pgcrypto/expected/pgp-encrypt_1.out   | 46 +++++++++----------
 .../expected/pgp-pubkey-encrypt_1.out         | 12 ++---
 contrib/pgcrypto/pgcrypto.c                   | 10 ++--
 contrib/pgcrypto/px.c                         |  2 +-
 6 files changed, 41 insertions(+), 41 deletions(-)

diff --git a/contrib/pgcrypto/expected/pgp-compression_1.out b/contrib/pgcrypto/expected/pgp-compression_1.out
index 25d5c35bf79..8a046d84964 100644
--- a/contrib/pgcrypto/expected/pgp-compression_1.out
+++ b/contrib/pgcrypto/expected/pgp-compression_1.out
@@ -17,19 +17,19 @@ DMcmR53SXfLoDJOv/M8uKj3QSq7oWNIp95pxfA==
 select pgp_sym_decrypt(
 	pgp_sym_encrypt('Secret message', 'key', 'compress-algo=0'),
 	'key', 'expect-compress-algo=0');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 select pgp_sym_decrypt(
 	pgp_sym_encrypt('Secret message', 'key', 'compress-algo=1'),
 	'key', 'expect-compress-algo=1');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 select pgp_sym_decrypt(
 	pgp_sym_encrypt('Secret message', 'key', 'compress-algo=2'),
 	'key', 'expect-compress-algo=2');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 -- level=0 should turn compression off
@@ -37,6 +37,6 @@ select pgp_sym_decrypt(
 	pgp_sym_encrypt('Secret message', 'key',
 			'compress-algo=2, compress-level=0'),
 	'key', 'expect-compress-algo=0');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
diff --git a/contrib/pgcrypto/expected/pgp-decrypt_1.out b/contrib/pgcrypto/expected/pgp-decrypt_1.out
index d9e1e386a25..431bac2b410 100644
--- a/contrib/pgcrypto/expected/pgp-decrypt_1.out
+++ b/contrib/pgcrypto/expected/pgp-decrypt_1.out
@@ -366,7 +366,7 @@ a3nsOzKTXUfS9VyaXo8IrncM6n7fdaXpwba/3tNsAhJG4lDv1k4g9v8Ix2dfv6Rs
 -- expected: 7efefcab38467f7484d6fa43dc86cf5281bd78e2
 -- check BUG #11905, problem with messages 6 less than a power of 2.
 select pgp_sym_decrypt(pgp_sym_encrypt(repeat('x',65530),'1'),'1') = repeat('x',65530);
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 -- expected: true
@@ -389,7 +389,7 @@ NOTICE:  dbg: mdcbuf_finish: bad MDC pkt hdr
 ERROR:  Wrong key or corrupt data
 -- Routine text/binary mismatch.
 select pgp_sym_decrypt(pgp_sym_encrypt_bytea('P', 'key'), 'key', 'debug=1');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 -- Decryption with a certain incorrect key yields an apparent BZip2-compressed
diff --git a/contrib/pgcrypto/expected/pgp-encrypt_1.out b/contrib/pgcrypto/expected/pgp-encrypt_1.out
index 2291e662ecd..48346e8e7e0 100644
--- a/contrib/pgcrypto/expected/pgp-encrypt_1.out
+++ b/contrib/pgcrypto/expected/pgp-encrypt_1.out
@@ -4,7 +4,7 @@
 -- 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');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 -- check whether the defaults are ok
@@ -16,7 +16,7 @@ select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'),
 		expect-s2k-digest-algo=sha1,
 		expect-compress-algo=0
 		');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 -- maybe the expect- stuff simply does not work
@@ -28,127 +28,127 @@ select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'),
 		expect-s2k-digest-algo=md5,
 		expect-compress-algo=1
 		');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 -- bytea as text
 select pgp_sym_decrypt(pgp_sym_encrypt_bytea('Binary', 'baz'), 'baz');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 -- text as bytea
 select pgp_sym_decrypt_bytea(pgp_sym_encrypt('Text', 'baz'), 'baz');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 -- algorithm change
 select pgp_sym_decrypt(
 	pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=bf'),
 	'key', 'expect-cipher-algo=bf');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 select pgp_sym_decrypt(
 	pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=aes'),
 	'key', 'expect-cipher-algo=aes128');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 select pgp_sym_decrypt(
 	pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=aes192'),
 	'key', 'expect-cipher-algo=aes192');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 -- s2k change
 select pgp_sym_decrypt(
 	pgp_sym_encrypt('Secret.', 'key', 's2k-mode=0'),
 	'key', 'expect-s2k-mode=0');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 select pgp_sym_decrypt(
 	pgp_sym_encrypt('Secret.', 'key', 's2k-mode=1'),
 	'key', 'expect-s2k-mode=1');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 select pgp_sym_decrypt(
 	pgp_sym_encrypt('Secret.', 'key', 's2k-mode=3'),
 	'key', 'expect-s2k-mode=3');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 -- s2k count change
 select pgp_sym_decrypt(
 	pgp_sym_encrypt('Secret.', 'key', 's2k-count=1024'),
 	'key', 'expect-s2k-count=1024');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 -- s2k_count rounds up
 select pgp_sym_decrypt(
 	pgp_sym_encrypt('Secret.', 'key', 's2k-count=65000000'),
 	'key', 'expect-s2k-count=65000000');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 -- s2k digest change
 select pgp_sym_decrypt(
 	pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=md5'),
 	'key', 'expect-s2k-digest-algo=md5');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 select pgp_sym_decrypt(
 		pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=sha1'),
 	'key', 'expect-s2k-digest-algo=sha1');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 -- sess key
 select pgp_sym_decrypt(
 	pgp_sym_encrypt('Secret.', 'key', 'sess-key=0'),
 	'key', 'expect-sess-key=0');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 select pgp_sym_decrypt(
 	pgp_sym_encrypt('Secret.', 'key', 'sess-key=1'),
 	'key', 'expect-sess-key=1');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 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:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 select pgp_sym_decrypt(
 	pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=aes192'),
 	'key', 'expect-sess-key=1, expect-cipher-algo=aes192');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 select pgp_sym_decrypt(
 	pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=aes256'),
 	'key', 'expect-sess-key=1, expect-cipher-algo=aes256');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 -- no mdc
 select pgp_sym_decrypt(
 		pgp_sym_encrypt('Secret.', 'key', 'disable-mdc=1'),
 	'key', 'expect-disable-mdc=1');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 -- crlf
 select encode(pgp_sym_decrypt_bytea(
 	pgp_sym_encrypt(E'1\n2\n3\r\n', 'key', 'convert-crlf=1'),
 	'key'), 'hex');
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 -- conversion should be lossless
@@ -156,6 +156,6 @@ 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;
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
diff --git a/contrib/pgcrypto/expected/pgp-pubkey-encrypt_1.out b/contrib/pgcrypto/expected/pgp-pubkey-encrypt_1.out
index 3b1822ed916..41c54e47169 100644
--- a/contrib/pgcrypto/expected/pgp-pubkey-encrypt_1.out
+++ b/contrib/pgcrypto/expected/pgp-pubkey-encrypt_1.out
@@ -8,28 +8,28 @@ select pgp_pub_decrypt(
 	pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
 	dearmor(seckey))
 from keytbl where keytbl.id=1;
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 select pgp_pub_decrypt(
 		pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
 		dearmor(seckey))
 from keytbl where keytbl.id=2;
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 select pgp_pub_decrypt(
 		pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
 		dearmor(seckey))
 from keytbl where keytbl.id=3;
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 select pgp_pub_decrypt(
 		pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
 		dearmor(seckey))
 from keytbl where keytbl.id=6;
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 -- try with rsa-sign only
@@ -49,7 +49,7 @@ select pgp_pub_decrypt_bytea(
 		pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
 		dearmor(seckey))
 from keytbl where keytbl.id=1;
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
 -- and bytea-to-text?
@@ -57,6 +57,6 @@ select pgp_pub_decrypt(
 		pgp_pub_encrypt_bytea('Secret msg', dearmor(pubkey)),
 		dearmor(seckey))
 from keytbl where keytbl.id=1;
-ERROR:  pg_random_bytes() is not supported by this build
+ERROR:  generating random data is not supported by this build
 DETAIL:  This functionality requires a source of strong random numbers
 HINT:  You need to rebuild PostgreSQL using --enable-strong-random
diff --git a/contrib/pgcrypto/pgcrypto.c b/contrib/pgcrypto/pgcrypto.c
index 4e3516a86ad..e09f3378da6 100644
--- a/contrib/pgcrypto/pgcrypto.c
+++ b/contrib/pgcrypto/pgcrypto.c
@@ -451,13 +451,10 @@ PG_FUNCTION_INFO_V1(pg_random_uuid);
 Datum
 pg_random_uuid(PG_FUNCTION_ARGS)
 {
+#ifdef HAVE_STRONG_RANDOM
 	uint8	   *buf = (uint8 *) palloc(UUID_LEN);
 
-	/*
-	 * Generate random bits. pg_backend_random() will do here, we don't promis
-	 * UUIDs to be cryptographically random, when built with
-	 * --disable-strong-random.
-	 */
+	/* Generate random bits. */
 	if (!pg_backend_random((char *) buf, UUID_LEN))
 		px_THROW_ERROR(PXE_NO_RANDOM);
 
@@ -469,6 +466,9 @@ pg_random_uuid(PG_FUNCTION_ARGS)
 	buf[8] = (buf[8] & 0x3f) | 0x80;	/* "variant" field */
 
 	PG_RETURN_UUID_P((pg_uuid_t *) buf);
+#else
+	px_THROW_ERROR(PXE_NO_RANDOM);
+#endif
 }
 
 static void *
diff --git a/contrib/pgcrypto/px.c b/contrib/pgcrypto/px.c
index a5c02f3612d..8ec920224ad 100644
--- a/contrib/pgcrypto/px.c
+++ b/contrib/pgcrypto/px.c
@@ -104,7 +104,7 @@ px_THROW_ERROR(int err)
 #else
 		ereport(ERROR,
 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-				 errmsg("pg_random_bytes() is not supported by this build"),
+				 errmsg("generating random data is not supported by this build"),
 				 errdetail("This functionality requires a source of strong random numbers"),
 				 errhint("You need to rebuild PostgreSQL using --enable-strong-random")));
 #endif
-- 
GitLab