summaryrefslogtreecommitdiff
path: root/src/common/scram-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/scram-common.c')
-rw-r--r--src/common/scram-common.c175
1 files changed, 125 insertions, 50 deletions
diff --git a/src/common/scram-common.c b/src/common/scram-common.c
index 4971134b22a..caab68926d2 100644
--- a/src/common/scram-common.c
+++ b/src/common/scram-common.c
@@ -29,9 +29,9 @@
/*
* Calculate HMAC per RFC2104.
*
- * The hash function used is SHA-256.
+ * The hash function used is SHA-256. Returns 0 on success, -1 on failure.
*/
-void
+int
scram_HMAC_init(scram_HMAC_ctx *ctx, const uint8 *key, int keylen)
{
uint8 k_ipad[SHA256_HMAC_B];
@@ -44,13 +44,21 @@ scram_HMAC_init(scram_HMAC_ctx *ctx, const uint8 *key, int keylen)
*/
if (keylen > SHA256_HMAC_B)
{
- pg_sha256_ctx sha256_ctx;
-
- pg_sha256_init(&sha256_ctx);
- pg_sha256_update(&sha256_ctx, key, keylen);
- pg_sha256_final(&sha256_ctx, keybuf);
+ pg_cryptohash_ctx *sha256_ctx;
+
+ sha256_ctx = pg_cryptohash_create(PG_SHA256);
+ if (sha256_ctx == NULL)
+ 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_free(sha256_ctx);
+ return -1;
+ }
key = keybuf;
keylen = SCRAM_KEY_LEN;
+ pg_cryptohash_free(sha256_ctx);
}
memset(k_ipad, HMAC_IPAD, SHA256_HMAC_B);
@@ -62,45 +70,75 @@ scram_HMAC_init(scram_HMAC_ctx *ctx, const uint8 *key, int keylen)
ctx->k_opad[i] ^= key[i];
}
+ ctx->sha256ctx = pg_cryptohash_create(PG_SHA256);
+ if (ctx->sha256ctx == NULL)
+ return -1;
+
/* tmp = H(K XOR ipad, text) */
- pg_sha256_init(&ctx->sha256ctx);
- pg_sha256_update(&ctx->sha256ctx, k_ipad, SHA256_HMAC_B);
+ if (pg_cryptohash_init(ctx->sha256ctx) < 0 ||
+ pg_cryptohash_update(ctx->sha256ctx, k_ipad, SHA256_HMAC_B) < 0)
+ {
+ pg_cryptohash_free(ctx->sha256ctx);
+ return -1;
+ }
+
+ return 0;
}
/*
* Update HMAC calculation
- * The hash function used is SHA-256.
+ * The hash function used is SHA-256. Returns 0 on success, -1 on failure.
*/
-void
+int
scram_HMAC_update(scram_HMAC_ctx *ctx, const char *str, int slen)
{
- pg_sha256_update(&ctx->sha256ctx, (const uint8 *) str, slen);
+ Assert(ctx->sha256ctx != NULL);
+ if (pg_cryptohash_update(ctx->sha256ctx, (const uint8 *) str, slen) < 0)
+ {
+ pg_cryptohash_free(ctx->sha256ctx);
+ return -1;
+ }
+ return 0;
}
/*
* Finalize HMAC calculation.
- * The hash function used is SHA-256.
+ * The hash function used is SHA-256. Returns 0 on success, -1 on failure.
*/
-void
+int
scram_HMAC_final(uint8 *result, scram_HMAC_ctx *ctx)
{
uint8 h[SCRAM_KEY_LEN];
- pg_sha256_final(&ctx->sha256ctx, h);
+ Assert(ctx->sha256ctx != NULL);
+
+ if (pg_cryptohash_final(ctx->sha256ctx, h) < 0)
+ {
+ pg_cryptohash_free(ctx->sha256ctx);
+ return -1;
+ }
/* H(K XOR opad, tmp) */
- pg_sha256_init(&ctx->sha256ctx);
- pg_sha256_update(&ctx->sha256ctx, ctx->k_opad, SHA256_HMAC_B);
- pg_sha256_update(&ctx->sha256ctx, h, SCRAM_KEY_LEN);
- pg_sha256_final(&ctx->sha256ctx, result);
+ 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_free(ctx->sha256ctx);
+ return -1;
+ }
+
+ pg_cryptohash_free(ctx->sha256ctx);
+ return 0;
}
/*
* Calculate SaltedPassword.
*
- * The password should already be normalized by SASLprep.
+ * The password should already be normalized by SASLprep. Returns 0 on
+ * success, -1 on failure.
*/
-void
+int
scram_SaltedPassword(const char *password,
const char *salt, int saltlen, int iterations,
uint8 *result)
@@ -120,63 +158,94 @@ scram_SaltedPassword(const char *password,
*/
/* First iteration */
- scram_HMAC_init(&hmac_ctx, (uint8 *) password, password_len);
- scram_HMAC_update(&hmac_ctx, salt, saltlen);
- scram_HMAC_update(&hmac_ctx, (char *) &one, sizeof(uint32));
- scram_HMAC_final(Ui_prev, &hmac_ctx);
+ 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)
+ {
+ return -1;
+ }
+
memcpy(result, Ui_prev, SCRAM_KEY_LEN);
/* Subsequent iterations */
for (i = 2; i <= iterations; i++)
{
- scram_HMAC_init(&hmac_ctx, (uint8 *) password, password_len);
- scram_HMAC_update(&hmac_ctx, (const char *) Ui_prev, SCRAM_KEY_LEN);
- scram_HMAC_final(Ui, &hmac_ctx);
+ 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)
+ {
+ return -1;
+ }
+
for (j = 0; j < SCRAM_KEY_LEN; j++)
result[j] ^= Ui[j];
memcpy(Ui_prev, Ui, SCRAM_KEY_LEN);
}
+
+ return 0;
}
/*
* Calculate SHA-256 hash for a NULL-terminated string. (The NULL terminator is
- * not included in the hash).
+ * not included in the hash). Returns 0 on success, -1 on failure.
*/
-void
+int
scram_H(const uint8 *input, int len, uint8 *result)
{
- pg_sha256_ctx ctx;
+ pg_cryptohash_ctx *ctx;
- pg_sha256_init(&ctx);
- pg_sha256_update(&ctx, input, len);
- pg_sha256_final(&ctx, result);
+ ctx = pg_cryptohash_create(PG_SHA256);
+ if (ctx == NULL)
+ return -1;
+
+ if (pg_cryptohash_init(ctx) < 0 ||
+ pg_cryptohash_update(ctx, input, len) < 0 ||
+ pg_cryptohash_final(ctx, result) < 0)
+ {
+ pg_cryptohash_free(ctx);
+ return -1;
+ }
+
+ pg_cryptohash_free(ctx);
+ return 0;
}
/*
- * Calculate ClientKey.
+ * Calculate ClientKey. Returns 0 on success, -1 on failure.
*/
-void
+int
scram_ClientKey(const uint8 *salted_password, uint8 *result)
{
scram_HMAC_ctx ctx;
- scram_HMAC_init(&ctx, salted_password, SCRAM_KEY_LEN);
- scram_HMAC_update(&ctx, "Client Key", strlen("Client Key"));
- scram_HMAC_final(result, &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)
+ {
+ return -1;
+ }
+
+ return 0;
}
/*
- * Calculate ServerKey.
+ * Calculate ServerKey. Returns 0 on success, -1 on failure.
*/
-void
+int
scram_ServerKey(const uint8 *salted_password, uint8 *result)
{
scram_HMAC_ctx ctx;
- scram_HMAC_init(&ctx, salted_password, SCRAM_KEY_LEN);
- scram_HMAC_update(&ctx, "Server Key", strlen("Server Key"));
- scram_HMAC_final(result, &ctx);
+ 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)
+ {
+ return -1;
+ }
+
+ return 0;
}
@@ -207,12 +276,18 @@ scram_build_secret(const char *salt, int saltlen, int iterations,
iterations = SCRAM_DEFAULT_ITERATIONS;
/* Calculate StoredKey and ServerKey */
- scram_SaltedPassword(password, salt, saltlen, iterations,
- salted_password);
- scram_ClientKey(salted_password, stored_key);
- scram_H(stored_key, SCRAM_KEY_LEN, stored_key);
-
- scram_ServerKey(salted_password, server_key);
+ 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)
+ {
+#ifdef FRONTEND
+ return NULL;
+#else
+ elog(ERROR, "could not calculate stored key and server key");
+#endif
+ }
/*----------
* The format is: