summaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/cryptohashfuncs.c
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2020-12-04 12:58:44 +0900
committerMichael Paquier <michael@paquier.xyz>2020-12-04 12:58:44 +0900
commitbd94a9c04e04bb3b626e88981a50fcca2bd99d60 (patch)
treefc386a6cd043da9d074ac9818b36def2c719e7ee /src/backend/utils/adt/cryptohashfuncs.c
parent4f48a6fbe2b28d8281dbbfa2d334fa2ed8472734 (diff)
downloadpostgresql-bd94a9c04e04bb3b626e88981a50fcca2bd99d60.tar.gz
Rename cryptohashes.c to cryptohashfuncs.c
87ae969 has created two new files called cryptohash{_openssl}.c in src/common/, whose names overlap with the existing backend file called cryptohashes.c dedicated to the SQL wrappers for SHA2 and MD5. This file is renamed to cryptohashfuncs.c to be more consistent with the surroundings and reduce the confusion with the new cryptohash interface of src/common/. Author: Michael Paquier Reviewed-by: Daniel Gustafsson Discussion: https://postgr.es/m/X8hHhaQgbMbW+aGU@paquier.xyz
Diffstat (limited to 'src/backend/utils/adt/cryptohashfuncs.c')
-rw-r--r--src/backend/utils/adt/cryptohashfuncs.c190
1 files changed, 190 insertions, 0 deletions
diff --git a/src/backend/utils/adt/cryptohashfuncs.c b/src/backend/utils/adt/cryptohashfuncs.c
new file mode 100644
index 0000000000..47bc0b3482
--- /dev/null
+++ b/src/backend/utils/adt/cryptohashfuncs.c
@@ -0,0 +1,190 @@
+/*-------------------------------------------------------------------------
+ *
+ * cryptohashfuncs.c
+ * Cryptographic hash functions
+ *
+ * Portions Copyright (c) 2018-2020, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * src/backend/utils/adt/cryptohashfuncs.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "common/cryptohash.h"
+#include "common/md5.h"
+#include "common/sha2.h"
+#include "utils/builtins.h"
+
+
+/*
+ * MD5
+ */
+
+/* MD5 produces a 16 byte (128 bit) hash; double it for hex */
+#define MD5_HASH_LEN 32
+
+/*
+ * Create an MD5 hash of a text value and return it as hex string.
+ */
+Datum
+md5_text(PG_FUNCTION_ARGS)
+{
+ text *in_text = PG_GETARG_TEXT_PP(0);
+ size_t len;
+ char hexsum[MD5_HASH_LEN + 1];
+
+ /* Calculate the length of the buffer using varlena metadata */
+ len = VARSIZE_ANY_EXHDR(in_text);
+
+ /* get the hash result */
+ if (pg_md5_hash(VARDATA_ANY(in_text), len, hexsum) == false)
+ ereport(ERROR,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of memory")));
+
+ /* convert to text and return it */
+ PG_RETURN_TEXT_P(cstring_to_text(hexsum));
+}
+
+/*
+ * Create an MD5 hash of a bytea value and return it as a hex string.
+ */
+Datum
+md5_bytea(PG_FUNCTION_ARGS)
+{
+ bytea *in = PG_GETARG_BYTEA_PP(0);
+ size_t len;
+ char hexsum[MD5_HASH_LEN + 1];
+
+ len = VARSIZE_ANY_EXHDR(in);
+ if (pg_md5_hash(VARDATA_ANY(in), len, hexsum) == false)
+ ereport(ERROR,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of memory")));
+
+ PG_RETURN_TEXT_P(cstring_to_text(hexsum));
+}
+
+
+/*
+ * SHA-2 variants
+ */
+
+Datum
+sha224_bytea(PG_FUNCTION_ARGS)
+{
+ bytea *in = PG_GETARG_BYTEA_PP(0);
+ const uint8 *data;
+ size_t len;
+ pg_cryptohash_ctx *ctx;
+ unsigned char buf[PG_SHA224_DIGEST_LENGTH];
+ bytea *result;
+
+ len = VARSIZE_ANY_EXHDR(in);
+ data = (unsigned char *) VARDATA_ANY(in);
+
+ ctx = pg_cryptohash_create(PG_SHA224);
+ if (pg_cryptohash_init(ctx) < 0)
+ elog(ERROR, "could not initialize %s context", "SHA224");
+ if (pg_cryptohash_update(ctx, data, len) < 0)
+ elog(ERROR, "could not update %s context", "SHA224");
+ if (pg_cryptohash_final(ctx, buf) < 0)
+ elog(ERROR, "could not finalize %s context", "SHA224");
+ pg_cryptohash_free(ctx);
+
+ result = palloc(sizeof(buf) + VARHDRSZ);
+ SET_VARSIZE(result, sizeof(buf) + VARHDRSZ);
+ memcpy(VARDATA(result), buf, sizeof(buf));
+
+ PG_RETURN_BYTEA_P(result);
+}
+
+Datum
+sha256_bytea(PG_FUNCTION_ARGS)
+{
+ bytea *in = PG_GETARG_BYTEA_PP(0);
+ const uint8 *data;
+ size_t len;
+ pg_cryptohash_ctx *ctx;
+ unsigned char buf[PG_SHA256_DIGEST_LENGTH];
+ bytea *result;
+
+ len = VARSIZE_ANY_EXHDR(in);
+ data = (unsigned char *) VARDATA_ANY(in);
+
+ ctx = pg_cryptohash_create(PG_SHA256);
+ if (pg_cryptohash_init(ctx) < 0)
+ elog(ERROR, "could not initialize %s context", "SHA256");
+ if (pg_cryptohash_update(ctx, data, len) < 0)
+ elog(ERROR, "could not update %s context", "SHA256");
+ if (pg_cryptohash_final(ctx, buf) < 0)
+ elog(ERROR, "could not finalize %s context", "SHA256");
+ pg_cryptohash_free(ctx);
+
+ result = palloc(sizeof(buf) + VARHDRSZ);
+ SET_VARSIZE(result, sizeof(buf) + VARHDRSZ);
+ memcpy(VARDATA(result), buf, sizeof(buf));
+
+ PG_RETURN_BYTEA_P(result);
+}
+
+Datum
+sha384_bytea(PG_FUNCTION_ARGS)
+{
+ bytea *in = PG_GETARG_BYTEA_PP(0);
+ const uint8 *data;
+ size_t len;
+ pg_cryptohash_ctx *ctx;
+ unsigned char buf[PG_SHA384_DIGEST_LENGTH];
+ bytea *result;
+
+ len = VARSIZE_ANY_EXHDR(in);
+ data = (unsigned char *) VARDATA_ANY(in);
+
+ ctx = pg_cryptohash_create(PG_SHA384);
+ if (pg_cryptohash_init(ctx) < 0)
+ elog(ERROR, "could not initialize %s context", "SHA384");
+ if (pg_cryptohash_update(ctx, data, len) < 0)
+ elog(ERROR, "could not update %s context", "SHA384");
+ if (pg_cryptohash_final(ctx, buf) < 0)
+ elog(ERROR, "could not finalize %s context", "SHA384");
+ pg_cryptohash_free(ctx);
+
+ result = palloc(sizeof(buf) + VARHDRSZ);
+ SET_VARSIZE(result, sizeof(buf) + VARHDRSZ);
+ memcpy(VARDATA(result), buf, sizeof(buf));
+
+ PG_RETURN_BYTEA_P(result);
+}
+
+Datum
+sha512_bytea(PG_FUNCTION_ARGS)
+{
+ bytea *in = PG_GETARG_BYTEA_PP(0);
+ const uint8 *data;
+ size_t len;
+ pg_cryptohash_ctx *ctx;
+ unsigned char buf[PG_SHA512_DIGEST_LENGTH];
+ bytea *result;
+
+ len = VARSIZE_ANY_EXHDR(in);
+ data = (unsigned char *) VARDATA_ANY(in);
+
+ ctx = pg_cryptohash_create(PG_SHA512);
+ if (pg_cryptohash_init(ctx) < 0)
+ elog(ERROR, "could not initialize %s context", "SHA512");
+ if (pg_cryptohash_update(ctx, data, len) < 0)
+ elog(ERROR, "could not update %s context", "SHA512");
+ if (pg_cryptohash_final(ctx, buf) < 0)
+ elog(ERROR, "could not finalize %s context", "SHA512");
+ pg_cryptohash_free(ctx);
+
+ result = palloc(sizeof(buf) + VARHDRSZ);
+ SET_VARSIZE(result, sizeof(buf) + VARHDRSZ);
+ memcpy(VARDATA(result), buf, sizeof(buf));
+
+ PG_RETURN_BYTEA_P(result);
+}