diff --git a/contrib/pgcrypto/internal-sha2.c b/contrib/pgcrypto/internal-sha2.c
index 0fe53e15af..012203eea4 100644
--- a/contrib/pgcrypto/internal-sha2.c
+++ b/contrib/pgcrypto/internal-sha2.c
@@ -118,7 +118,7 @@ int_sha2_finish(PX_MD *h, uint8 *dst)
 {
 	pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr;
 
-	if (pg_cryptohash_final(ctx, dst) < 0)
+	if (pg_cryptohash_final(ctx, dst, PG_SHA256_DIGEST_LENGTH) < 0)
 		elog(ERROR, "could not finalize %s context", "SHA2");
 }
 
diff --git a/contrib/pgcrypto/internal.c b/contrib/pgcrypto/internal.c
index ef6ce2fb1e..955501b4d4 100644
--- a/contrib/pgcrypto/internal.c
+++ b/contrib/pgcrypto/internal.c
@@ -106,7 +106,7 @@ int_md5_finish(PX_MD *h, uint8 *dst)
 {
 	pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr;
 
-	if (pg_cryptohash_final(ctx, dst) < 0)
+	if (pg_cryptohash_final(ctx, dst, MD5_DIGEST_LENGTH) < 0)
 		elog(ERROR, "could not finalize %s context", "MD5");
 }
 
@@ -156,7 +156,7 @@ int_sha1_finish(PX_MD *h, uint8 *dst)
 {
 	pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr;
 
-	if (pg_cryptohash_final(ctx, dst) < 0)
+	if (pg_cryptohash_final(ctx, dst, SHA1_DIGEST_LENGTH) < 0)
 		elog(ERROR, "could not finalize %s context", "SHA1");
 }
 
diff --git a/src/backend/libpq/auth-scram.c b/src/backend/libpq/auth-scram.c
index 8d857f39df..736b1191e2 100644
--- a/src/backend/libpq/auth-scram.c
+++ b/src/backend/libpq/auth-scram.c
@@ -1120,7 +1120,7 @@ verify_client_proof(scram_state *state)
 		scram_HMAC_update(&ctx,
 						  state->client_final_message_without_proof,
 						  strlen(state->client_final_message_without_proof)) < 0 ||
-		scram_HMAC_final(ClientSignature, &ctx) < 0)
+		scram_HMAC_final(&ctx, ClientSignature, SCRAM_KEY_LEN) < 0)
 	{
 		elog(ERROR, "could not calculate client signature");
 	}
@@ -1130,7 +1130,7 @@ verify_client_proof(scram_state *state)
 		ClientKey[i] = state->ClientProof[i] ^ ClientSignature[i];
 
 	/* Hash it one more time, and compare with StoredKey */
-	if (scram_H(ClientKey, SCRAM_KEY_LEN, client_StoredKey) < 0)
+	if (scram_H(ClientKey, SCRAM_KEY_LEN, client_StoredKey, SCRAM_KEY_LEN) < 0)
 		elog(ERROR, "could not hash stored key");
 
 	if (memcmp(client_StoredKey, state->StoredKey, SCRAM_KEY_LEN) != 0)
@@ -1374,7 +1374,7 @@ build_server_final_message(scram_state *state)
 		scram_HMAC_update(&ctx,
 						  state->client_final_message_without_proof,
 						  strlen(state->client_final_message_without_proof)) < 0 ||
-		scram_HMAC_final(ServerSignature, &ctx) < 0)
+		scram_HMAC_final(&ctx, ServerSignature, SCRAM_KEY_LEN) < 0)
 	{
 		elog(ERROR, "could not calculate server signature");
 	}
@@ -1429,7 +1429,7 @@ scram_mock_salt(const char *username)
 	if (pg_cryptohash_init(ctx) < 0 ||
 		pg_cryptohash_update(ctx, (uint8 *) username, strlen(username)) < 0 ||
 		pg_cryptohash_update(ctx, (uint8 *) mock_auth_nonce, MOCK_AUTH_NONCE_LEN) < 0 ||
-		pg_cryptohash_final(ctx, sha_digest) < 0)
+		pg_cryptohash_final(ctx, sha_digest, PG_SHA256_DIGEST_LENGTH) < 0)
 	{
 		pg_cryptohash_free(ctx);
 		return NULL;
diff --git a/src/backend/replication/backup_manifest.c b/src/backend/replication/backup_manifest.c
index 0cefd181b5..b57e93ddbd 100644
--- a/src/backend/replication/backup_manifest.c
+++ b/src/backend/replication/backup_manifest.c
@@ -180,7 +180,7 @@ AddFileToBackupManifest(backup_manifest_info *manifest, const char *spcoid,
 		int			checksumlen;
 		uint64		dstlen;
 
-		checksumlen = pg_checksum_final(checksum_ctx, checksumbuf);
+		checksumlen = pg_checksum_final(checksum_ctx, checksumbuf, PG_CHECKSUM_MAX_LENGTH);
 		if (checksumlen < 0)
 			elog(ERROR, "could not finalize checksum of file \"%s\"",
 				 pathname);
@@ -330,7 +330,7 @@ SendBackupManifest(backup_manifest_info *manifest)
 	 * twice.
 	 */
 	manifest->still_checksumming = false;
-	if (pg_cryptohash_final(manifest->manifest_ctx, checksumbuf) < 0)
+	if (pg_cryptohash_final(manifest->manifest_ctx, checksumbuf, PG_SHA256_DIGEST_LENGTH) < 0)
 		elog(ERROR, "failed to finalize checksum of backup manifest");
 	AppendStringToManifest(manifest, "\"Manifest-Checksum\": \"");
 	dstlen = pg_hex_enc_len(PG_SHA256_DIGEST_LENGTH);
diff --git a/src/backend/utils/adt/cryptohashfuncs.c b/src/backend/utils/adt/cryptohashfuncs.c
index 152adcbfb4..c4915435ab 100644
--- a/src/backend/utils/adt/cryptohashfuncs.c
+++ b/src/backend/utils/adt/cryptohashfuncs.c
@@ -114,7 +114,7 @@ cryptohash_internal(pg_cryptohash_type type, bytea *input)
 		elog(ERROR, "could not initialize %s context", typestr);
 	if (pg_cryptohash_update(ctx, data, len) < 0)
 		elog(ERROR, "could not update %s context", typestr);
-	if (pg_cryptohash_final(ctx, (unsigned char *) VARDATA(result)) < 0)
+	if (pg_cryptohash_final(ctx, (unsigned char *) VARDATA(result), digest_len) < 0)
 		elog(ERROR, "could not finalize %s context", typestr);
 	pg_cryptohash_free(ctx);
 
diff --git a/src/bin/pg_verifybackup/parse_manifest.c b/src/bin/pg_verifybackup/parse_manifest.c
index db2fa90cfe..c138991be4 100644
--- a/src/bin/pg_verifybackup/parse_manifest.c
+++ b/src/bin/pg_verifybackup/parse_manifest.c
@@ -659,7 +659,7 @@ verify_manifest_checksum(JsonManifestParseState *parse, char *buffer,
 		context->error_cb(context, "could not initialize checksum of manifest");
 	if (pg_cryptohash_update(manifest_ctx, (uint8 *) buffer, penultimate_newline + 1) < 0)
 		context->error_cb(context, "could not update checksum of manifest");
-	if (pg_cryptohash_final(manifest_ctx, manifest_checksum_actual) < 0)
+	if (pg_cryptohash_final(manifest_ctx, manifest_checksum_actual, PG_SHA256_DIGEST_LENGTH) < 0)
 		context->error_cb(context, "could not finalize checksum of manifest");
 
 	/* Now verify it. */
diff --git a/src/bin/pg_verifybackup/pg_verifybackup.c b/src/bin/pg_verifybackup/pg_verifybackup.c
index bb3f2783d0..cec932b9fa 100644
--- a/src/bin/pg_verifybackup/pg_verifybackup.c
+++ b/src/bin/pg_verifybackup/pg_verifybackup.c
@@ -780,7 +780,7 @@ verify_file_checksum(verifier_context *context, manifest_file *m,
 	}
 
 	/* Get the final checksum. */
-	checksumlen = pg_checksum_final(&checksum_ctx, checksumbuf);
+	checksumlen = pg_checksum_final(&checksum_ctx, checksumbuf, PG_CHECKSUM_MAX_LENGTH);
 	if (checksumlen < 0)
 	{
 		report_backup_error(context,
diff --git a/src/common/checksum_helper.c b/src/common/checksum_helper.c
index 2881b2c178..6062c88321 100644
--- a/src/common/checksum_helper.c
+++ b/src/common/checksum_helper.c
@@ -173,7 +173,7 @@ pg_checksum_update(pg_checksum_context *context, const uint8 *input,
  * or -1 for a failure.
  */
 int
-pg_checksum_final(pg_checksum_context *context, uint8 *output)
+pg_checksum_final(pg_checksum_context *context, uint8 *output, size_t len)
 {
 	int			retval = 0;
 
@@ -198,25 +198,25 @@ pg_checksum_final(pg_checksum_context *context, uint8 *output)
 			memcpy(output, &context->raw_context.c_crc32c, retval);
 			break;
 		case CHECKSUM_TYPE_SHA224:
-			if (pg_cryptohash_final(context->raw_context.c_sha2, output) < 0)
+			if (pg_cryptohash_final(context->raw_context.c_sha2, output, len) < 0)
 				return -1;
 			pg_cryptohash_free(context->raw_context.c_sha2);
 			retval = PG_SHA224_DIGEST_LENGTH;
 			break;
 		case CHECKSUM_TYPE_SHA256:
-			if (pg_cryptohash_final(context->raw_context.c_sha2, output) < 0)
+			if (pg_cryptohash_final(context->raw_context.c_sha2, output, len) < 0)
 				return -1;
 			pg_cryptohash_free(context->raw_context.c_sha2);
 			retval = PG_SHA224_DIGEST_LENGTH;
 			break;
 		case CHECKSUM_TYPE_SHA384:
-			if (pg_cryptohash_final(context->raw_context.c_sha2, output) < 0)
+			if (pg_cryptohash_final(context->raw_context.c_sha2, output, len) < 0)
 				return -1;
 			pg_cryptohash_free(context->raw_context.c_sha2);
 			retval = PG_SHA384_DIGEST_LENGTH;
 			break;
 		case CHECKSUM_TYPE_SHA512:
-			if (pg_cryptohash_final(context->raw_context.c_sha2, output) < 0)
+			if (pg_cryptohash_final(context->raw_context.c_sha2, output, len) < 0)
 				return -1;
 			pg_cryptohash_free(context->raw_context.c_sha2);
 			retval = PG_SHA512_DIGEST_LENGTH;
diff --git a/src/common/cryptohash.c b/src/common/cryptohash.c
index 5b2c050d79..94e6a396e0 100644
--- a/src/common/cryptohash.c
+++ b/src/common/cryptohash.c
@@ -165,7 +165,7 @@ pg_cryptohash_update(pg_cryptohash_ctx *ctx, const uint8 *data, size_t len)
  * given a NULL context.
  */
 int
-pg_cryptohash_final(pg_cryptohash_ctx *ctx, uint8 *dest)
+pg_cryptohash_final(pg_cryptohash_ctx *ctx, uint8 *dest, size_t len)
 {
 	if (ctx == NULL)
 		return -1;
@@ -176,19 +176,19 @@ pg_cryptohash_final(pg_cryptohash_ctx *ctx, uint8 *dest)
 			pg_md5_final(&ctx->data.md5, dest);
 			break;
 		case PG_SHA1:
-			pg_sha1_final(&ctx->data.sha1, dest);
+			pg_sha1_final(&ctx->data.sha1, dest, len);
 			break;
 		case PG_SHA224:
-			pg_sha224_final(&ctx->data.sha224, dest);
+			pg_sha224_final(&ctx->data.sha224, dest, len);
 			break;
 		case PG_SHA256:
-			pg_sha256_final(&ctx->data.sha256, dest);
+			pg_sha256_final(&ctx->data.sha256, dest, len);
 			break;
 		case PG_SHA384:
-			pg_sha384_final(&ctx->data.sha384, dest);
+			pg_sha384_final(&ctx->data.sha384, dest, len);
 			break;
 		case PG_SHA512:
-			pg_sha512_final(&ctx->data.sha512, dest);
+			pg_sha512_final(&ctx->data.sha512, dest, len);
 			break;
 	}
 
diff --git a/src/common/md5_common.c b/src/common/md5_common.c
index b01c95ebb6..77e8708ffd 100644
--- a/src/common/md5_common.c
+++ b/src/common/md5_common.c
@@ -78,7 +78,7 @@ pg_md5_hash(const void *buff, size_t len, char *hexsum)
 
 	if (pg_cryptohash_init(ctx) < 0 ||
 		pg_cryptohash_update(ctx, buff, len) < 0 ||
-		pg_cryptohash_final(ctx, sum) < 0)
+		pg_cryptohash_final(ctx, sum, MD5_DIGEST_LENGTH) < 0)
 	{
 		pg_cryptohash_free(ctx);
 		return false;
@@ -100,7 +100,7 @@ pg_md5_binary(const void *buff, size_t len, void *outbuf)
 
 	if (pg_cryptohash_init(ctx) < 0 ||
 		pg_cryptohash_update(ctx, buff, len) < 0 ||
-		pg_cryptohash_final(ctx, outbuf) < 0)
+		pg_cryptohash_final(ctx, outbuf, MD5_DIGEST_LENGTH) < 0)
 	{
 		pg_cryptohash_free(ctx);
 		return false;
diff --git a/src/common/scram-common.c b/src/common/scram-common.c
index 3f406d4e4d..8f10c94137 100644
--- a/src/common/scram-common.c
+++ b/src/common/scram-common.c
@@ -51,7 +51,7 @@ scram_HMAC_init(scram_HMAC_ctx *ctx, const uint8 *key, int keylen)
 			return -1;
 		if (pg_cryptohash_init(sha256_ctx) < 0 ||
 			pg_cryptohash_update(sha256_ctx, key, keylen) < 0 ||
-			pg_cryptohash_final(sha256_ctx, keybuf) < 0)
+			pg_cryptohash_final(sha256_ctx, keybuf, SCRAM_KEY_LEN) < 0)
 		{
 			pg_cryptohash_free(sha256_ctx);
 			return -1;
@@ -106,13 +106,13 @@ scram_HMAC_update(scram_HMAC_ctx *ctx, const char *str, int slen)
  * The hash function used is SHA-256.  Returns 0 on success, -1 on failure.
  */
 int
-scram_HMAC_final(uint8 *result, scram_HMAC_ctx *ctx)
+scram_HMAC_final(scram_HMAC_ctx *ctx, uint8 *result, int rlen)
 {
 	uint8		h[SCRAM_KEY_LEN];
 
 	Assert(ctx->sha256ctx != NULL);
 
-	if (pg_cryptohash_final(ctx->sha256ctx, h) < 0)
+	if (pg_cryptohash_final(ctx->sha256ctx, h, SCRAM_KEY_LEN) < 0)
 	{
 		pg_cryptohash_free(ctx->sha256ctx);
 		return -1;
@@ -122,7 +122,7 @@ scram_HMAC_final(uint8 *result, scram_HMAC_ctx *ctx)
 	if (pg_cryptohash_init(ctx->sha256ctx) < 0 ||
 		pg_cryptohash_update(ctx->sha256ctx, ctx->k_opad, SHA256_HMAC_B) < 0 ||
 		pg_cryptohash_update(ctx->sha256ctx, h, SCRAM_KEY_LEN) < 0 ||
-		pg_cryptohash_final(ctx->sha256ctx, result) < 0)
+		pg_cryptohash_final(ctx->sha256ctx, result, rlen) < 0)
 	{
 		pg_cryptohash_free(ctx->sha256ctx);
 		return -1;
@@ -161,7 +161,7 @@ scram_SaltedPassword(const char *password,
 	if (scram_HMAC_init(&hmac_ctx, (uint8 *) password, password_len) < 0 ||
 		scram_HMAC_update(&hmac_ctx, salt, saltlen) < 0 ||
 		scram_HMAC_update(&hmac_ctx, (char *) &one, sizeof(uint32)) < 0 ||
-		scram_HMAC_final(Ui_prev, &hmac_ctx) < 0)
+		scram_HMAC_final(&hmac_ctx, Ui_prev, SCRAM_KEY_LEN) < 0)
 	{
 		return -1;
 	}
@@ -173,7 +173,7 @@ scram_SaltedPassword(const char *password,
 	{
 		if (scram_HMAC_init(&hmac_ctx, (uint8 *) password, password_len) < 0 ||
 			scram_HMAC_update(&hmac_ctx, (const char *) Ui_prev, SCRAM_KEY_LEN) < 0 ||
-			scram_HMAC_final(Ui, &hmac_ctx) < 0)
+			scram_HMAC_final(&hmac_ctx, Ui, SCRAM_KEY_LEN) < 0)
 		{
 			return -1;
 		}
@@ -192,7 +192,7 @@ scram_SaltedPassword(const char *password,
  * not included in the hash).  Returns 0 on success, -1 on failure.
  */
 int
-scram_H(const uint8 *input, int len, uint8 *result)
+scram_H(const uint8 *input, int len, uint8 *result, int rlen)
 {
 	pg_cryptohash_ctx *ctx;
 
@@ -202,7 +202,7 @@ scram_H(const uint8 *input, int len, uint8 *result)
 
 	if (pg_cryptohash_init(ctx) < 0 ||
 		pg_cryptohash_update(ctx, input, len) < 0 ||
-		pg_cryptohash_final(ctx, result) < 0)
+		pg_cryptohash_final(ctx, result, rlen) < 0)
 	{
 		pg_cryptohash_free(ctx);
 		return -1;
@@ -216,13 +216,13 @@ scram_H(const uint8 *input, int len, uint8 *result)
  * Calculate ClientKey.  Returns 0 on success, -1 on failure.
  */
 int
-scram_ClientKey(const uint8 *salted_password, uint8 *result)
+scram_ClientKey(const uint8 *salted_password, uint8 *result, int rlen)
 {
 	scram_HMAC_ctx ctx;
 
 	if (scram_HMAC_init(&ctx, salted_password, SCRAM_KEY_LEN) < 0 ||
 		scram_HMAC_update(&ctx, "Client Key", strlen("Client Key")) < 0 ||
-		scram_HMAC_final(result, &ctx) < 0)
+		scram_HMAC_final(&ctx, result, rlen) < 0)
 	{
 		return -1;
 	}
@@ -240,7 +240,7 @@ scram_ServerKey(const uint8 *salted_password, uint8 *result)
 
 	if (scram_HMAC_init(&ctx, salted_password, SCRAM_KEY_LEN) < 0 ||
 		scram_HMAC_update(&ctx, "Server Key", strlen("Server Key")) < 0 ||
-		scram_HMAC_final(result, &ctx) < 0)
+		scram_HMAC_final(&ctx, result, SCRAM_KEY_LEN) < 0)
 	{
 		return -1;
 	}
@@ -278,9 +278,9 @@ scram_build_secret(const char *salt, int saltlen, int iterations,
 	/* Calculate StoredKey and ServerKey */
 	if (scram_SaltedPassword(password, salt, saltlen, iterations,
 							 salted_password) < 0 ||
-		scram_ClientKey(salted_password, stored_key) < 0 ||
-		scram_H(stored_key, SCRAM_KEY_LEN, stored_key) < 0 ||
-		scram_ServerKey(salted_password, server_key) < 0)
+		scram_ClientKey(salted_password, stored_key, SCRAM_KEY_LEN) < 0 ||
+		scram_H(stored_key, SCRAM_KEY_LEN, stored_key, SCRAM_KEY_LEN) < 0 ||
+		scram_ServerKey(salted_password, server_key, SCRAM_KEY_LEN) < 0)
 	{
 #ifdef FRONTEND
 		return NULL;
diff --git a/src/common/sha2.c b/src/common/sha2.c
index ae4936b1a8..4654a5f71b 100644
--- a/src/common/sha2.c
+++ b/src/common/sha2.c
@@ -574,7 +574,7 @@ SHA256_Last(pg_sha256_ctx *context)
 }
 
 void
-pg_sha256_final(pg_sha256_ctx *context, uint8 *digest)
+pg_sha256_final(pg_sha256_ctx *context, uint8 *digest, size_t len)
 {
 	/* If no digest buffer is passed, we don't bother doing this: */
 	if (digest != NULL)
@@ -592,7 +592,7 @@ pg_sha256_final(pg_sha256_ctx *context, uint8 *digest)
 			}
 		}
 #endif
-		memcpy(digest, context->state, PG_SHA256_DIGEST_LENGTH);
+		memcpy(digest, context->state, len);
 	}
 
 	/* Clean up state data: */
@@ -902,7 +902,7 @@ SHA512_Last(pg_sha512_ctx *context)
 }
 
 void
-pg_sha512_final(pg_sha512_ctx *context, uint8 *digest)
+pg_sha512_final(pg_sha512_ctx *context, uint8 *digest, size_t len)
 {
 	/* If no digest buffer is passed, we don't bother doing this: */
 	if (digest != NULL)
@@ -921,7 +921,7 @@ pg_sha512_final(pg_sha512_ctx *context, uint8 *digest)
 			}
 		}
 #endif
-		memcpy(digest, context->state, PG_SHA512_DIGEST_LENGTH);
+		memcpy(digest, context->state, len);
 	}
 
 	/* Zero out state data */
@@ -947,7 +947,7 @@ pg_sha384_update(pg_sha384_ctx *context, const uint8 *data, size_t len)
 }
 
 void
-pg_sha384_final(pg_sha384_ctx *context, uint8 *digest)
+pg_sha384_final(pg_sha384_ctx *context, uint8 *digest, size_t len)
 {
 	/* If no digest buffer is passed, we don't bother doing this: */
 	if (digest != NULL)
@@ -966,7 +966,7 @@ pg_sha384_final(pg_sha384_ctx *context, uint8 *digest)
 			}
 		}
 #endif
-		memcpy(digest, context->state, PG_SHA384_DIGEST_LENGTH);
+		memcpy(digest, context->state, len);
 	}
 
 	/* Zero out state data */
@@ -991,7 +991,7 @@ pg_sha224_update(pg_sha224_ctx *context, const uint8 *data, size_t len)
 }
 
 void
-pg_sha224_final(pg_sha224_ctx *context, uint8 *digest)
+pg_sha224_final(pg_sha224_ctx *context, uint8 *digest, size_t len)
 {
 	/* If no digest buffer is passed, we don't bother doing this: */
 	if (digest != NULL)
@@ -1009,7 +1009,7 @@ pg_sha224_final(pg_sha224_ctx *context, uint8 *digest)
 			}
 		}
 #endif
-		memcpy(digest, context->state, PG_SHA224_DIGEST_LENGTH);
+		memcpy(digest, context->state, len);
 	}
 
 	/* Clean up state data: */
diff --git a/src/include/common/checksum_helper.h b/src/include/common/checksum_helper.h
index cac7570ea1..20d939b4bc 100644
--- a/src/include/common/checksum_helper.h
+++ b/src/include/common/checksum_helper.h
@@ -67,6 +67,6 @@ extern char *pg_checksum_type_name(pg_checksum_type);
 extern int	pg_checksum_init(pg_checksum_context *, pg_checksum_type);
 extern int	pg_checksum_update(pg_checksum_context *, const uint8 *input,
 							   size_t len);
-extern int	pg_checksum_final(pg_checksum_context *, uint8 *output);
+extern int	pg_checksum_final(pg_checksum_context *, uint8 *output, size_t len);
 
 #endif
diff --git a/src/include/common/cryptohash.h b/src/include/common/cryptohash.h
index 32d7784ca5..541dc844c8 100644
--- a/src/include/common/cryptohash.h
+++ b/src/include/common/cryptohash.h
@@ -32,7 +32,7 @@ typedef struct pg_cryptohash_ctx pg_cryptohash_ctx;
 extern pg_cryptohash_ctx *pg_cryptohash_create(pg_cryptohash_type type);
 extern int	pg_cryptohash_init(pg_cryptohash_ctx *ctx);
 extern int	pg_cryptohash_update(pg_cryptohash_ctx *ctx, const uint8 *data, size_t len);
-extern int	pg_cryptohash_final(pg_cryptohash_ctx *ctx, uint8 *dest);
+extern int	pg_cryptohash_final(pg_cryptohash_ctx *ctx, uint8 *dest, size_t len);
 extern void pg_cryptohash_free(pg_cryptohash_ctx *ctx);
 
 #endif							/* PG_CRYPTOHASH_H */
diff --git a/src/include/common/scram-common.h b/src/include/common/scram-common.h
index 9d684b41e8..d9f1537243 100644
--- a/src/include/common/scram-common.h
+++ b/src/include/common/scram-common.h
@@ -21,7 +21,7 @@
 #define SCRAM_SHA_256_PLUS_NAME "SCRAM-SHA-256-PLUS"	/* with channel binding */
 
 /* Length of SCRAM keys (client and server) */
-#define SCRAM_KEY_LEN				PG_SHA256_DIGEST_LENGTH
+#define SCRAM_KEY_LEN				PG_SHA512_DIGEST_LENGTH    /* make sure that have enough space */
 
 /* length of HMAC */
 #define SHA256_HMAC_B				PG_SHA256_BLOCK_LENGTH
@@ -57,11 +57,11 @@ typedef struct
 
 extern int	scram_HMAC_init(scram_HMAC_ctx *ctx, const uint8 *key, int keylen);
 extern int	scram_HMAC_update(scram_HMAC_ctx *ctx, const char *str, int slen);
-extern int	scram_HMAC_final(uint8 *result, scram_HMAC_ctx *ctx);
+extern int	scram_HMAC_final(scram_HMAC_ctx *ctx, uint8 *result, int rlen);
 
 extern int	scram_SaltedPassword(const char *password, const char *salt,
 								 int saltlen, int iterations, uint8 *result);
-extern int	scram_H(const uint8 *str, int len, uint8 *result);
+extern int	scram_H(const uint8 *str, int len, uint8 *result, int rlen);
 extern int	scram_ClientKey(const uint8 *salted_password, uint8 *result);
 extern int	scram_ServerKey(const uint8 *salted_password, uint8 *result);
 
diff --git a/src/interfaces/libpq/fe-auth-scram.c b/src/interfaces/libpq/fe-auth-scram.c
index 002469540a..38a5741a80 100644
--- a/src/interfaces/libpq/fe-auth-scram.c
+++ b/src/interfaces/libpq/fe-auth-scram.c
@@ -785,7 +785,7 @@ calculate_client_proof(fe_scram_state *state,
 	if (scram_SaltedPassword(state->password, state->salt, state->saltlen,
 							 state->iterations, state->SaltedPassword) < 0 ||
 		scram_ClientKey(state->SaltedPassword, ClientKey) < 0 ||
-		scram_H(ClientKey, SCRAM_KEY_LEN, StoredKey) < 0 ||
+		scram_H(ClientKey, SCRAM_KEY_LEN, StoredKey, SCRAM_KEY_LEN) < 0 ||
 		scram_HMAC_init(&ctx, StoredKey, SCRAM_KEY_LEN) < 0 ||
 		scram_HMAC_update(&ctx,
 						  state->client_first_message_bare,
@@ -798,7 +798,7 @@ calculate_client_proof(fe_scram_state *state,
 		scram_HMAC_update(&ctx,
 						  client_final_message_without_proof,
 						  strlen(client_final_message_without_proof)) < 0 ||
-		scram_HMAC_final(ClientSignature, &ctx) < 0)
+		scram_HMAC_final(&ctx, ClientSignature, SCRAM_KEY_LEN) < 0)
 	{
 		return false;
 	}
@@ -836,7 +836,7 @@ verify_server_signature(fe_scram_state *state, bool *match)
 		scram_HMAC_update(&ctx,
 						  state->client_final_message_without_proof,
 						  strlen(state->client_final_message_without_proof)) < 0 ||
-		scram_HMAC_final(expected_ServerSignature, &ctx) < 0)
+		scram_HMAC_final(&ctx, expected_ServerSignature, SCRAM_KEY_LEN) < 0)
 	{
 		return false;
 	}
