postgresql/src/backend/utils/adt/cryptohashes.c

170 lines
3.6 KiB
C

/*-------------------------------------------------------------------------
*
* cryptohashes.c
* Cryptographic hash functions
*
* Portions Copyright (c) 2018-2020, PostgreSQL Global Development Group
*
*
* IDENTIFICATION
* src/backend/utils/adt/cryptohashes.c
*
*-------------------------------------------------------------------------
*/
#include "postgres.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_sha224_ctx ctx;
unsigned char buf[PG_SHA224_DIGEST_LENGTH];
bytea *result;
len = VARSIZE_ANY_EXHDR(in);
data = (unsigned char *) VARDATA_ANY(in);
pg_sha224_init(&ctx);
pg_sha224_update(&ctx, data, len);
pg_sha224_final(&ctx, buf);
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_sha256_ctx ctx;
unsigned char buf[PG_SHA256_DIGEST_LENGTH];
bytea *result;
len = VARSIZE_ANY_EXHDR(in);
data = (unsigned char *) VARDATA_ANY(in);
pg_sha256_init(&ctx);
pg_sha256_update(&ctx, data, len);
pg_sha256_final(&ctx, buf);
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_sha384_ctx ctx;
unsigned char buf[PG_SHA384_DIGEST_LENGTH];
bytea *result;
len = VARSIZE_ANY_EXHDR(in);
data = (unsigned char *) VARDATA_ANY(in);
pg_sha384_init(&ctx);
pg_sha384_update(&ctx, data, len);
pg_sha384_final(&ctx, buf);
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_sha512_ctx ctx;
unsigned char buf[PG_SHA512_DIGEST_LENGTH];
bytea *result;
len = VARSIZE_ANY_EXHDR(in);
data = (unsigned char *) VARDATA_ANY(in);
pg_sha512_init(&ctx);
pg_sha512_update(&ctx, data, len);
pg_sha512_final(&ctx, buf);
result = palloc(sizeof(buf) + VARHDRSZ);
SET_VARSIZE(result, sizeof(buf) + VARHDRSZ);
memcpy(VARDATA(result), buf, sizeof(buf));
PG_RETURN_BYTEA_P(result);
}