mirror of https://github.com/postgres/postgres
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
191 lines
4.7 KiB
191 lines
4.7 KiB
![]()
8 years ago
|
/*-------------------------------------------------------------------------
|
||
|
*
|
||
![]()
5 years ago
|
* cryptohashfuncs.c
|
||
![]()
8 years ago
|
* Cryptographic hash functions
|
||
|
*
|
||
![]()
6 years ago
|
* Portions Copyright (c) 2018-2020, PostgreSQL Global Development Group
|
||
![]()
8 years ago
|
*
|
||
|
*
|
||
|
* IDENTIFICATION
|
||
![]()
5 years ago
|
* src/backend/utils/adt/cryptohashfuncs.c
|
||
![]()
8 years ago
|
*
|
||
|
*-------------------------------------------------------------------------
|
||
|
*/
|
||
|
#include "postgres.h"
|
||
|
|
||
![]()
5 years ago
|
#include "common/cryptohash.h"
|
||
![]()
8 years ago
|
#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;
|
||
![]()
5 years ago
|
pg_cryptohash_ctx *ctx;
|
||
![]()
8 years ago
|
unsigned char buf[PG_SHA224_DIGEST_LENGTH];
|
||
|
bytea *result;
|
||
|
|
||
|
len = VARSIZE_ANY_EXHDR(in);
|
||
|
data = (unsigned char *) VARDATA_ANY(in);
|
||
|
|
||
![]()
5 years ago
|
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);
|
||
![]()
8 years ago
|
|
||
|
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;
|
||
![]()
5 years ago
|
pg_cryptohash_ctx *ctx;
|
||
![]()
8 years ago
|
unsigned char buf[PG_SHA256_DIGEST_LENGTH];
|
||
|
bytea *result;
|
||
|
|
||
|
len = VARSIZE_ANY_EXHDR(in);
|
||
|
data = (unsigned char *) VARDATA_ANY(in);
|
||
|
|
||
![]()
5 years ago
|
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);
|
||
![]()
8 years ago
|
|
||
|
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;
|
||
![]()
5 years ago
|
pg_cryptohash_ctx *ctx;
|
||
![]()
8 years ago
|
unsigned char buf[PG_SHA384_DIGEST_LENGTH];
|
||
|
bytea *result;
|
||
|
|
||
|
len = VARSIZE_ANY_EXHDR(in);
|
||
|
data = (unsigned char *) VARDATA_ANY(in);
|
||
|
|
||
![]()
5 years ago
|
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);
|
||
![]()
8 years ago
|
|
||
|
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;
|
||
![]()
5 years ago
|
pg_cryptohash_ctx *ctx;
|
||
![]()
8 years ago
|
unsigned char buf[PG_SHA512_DIGEST_LENGTH];
|
||
|
bytea *result;
|
||
|
|
||
|
len = VARSIZE_ANY_EXHDR(in);
|
||
|
data = (unsigned char *) VARDATA_ANY(in);
|
||
|
|
||
![]()
5 years ago
|
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);
|
||
![]()
8 years ago
|
|
||
|
result = palloc(sizeof(buf) + VARHDRSZ);
|
||
|
SET_VARSIZE(result, sizeof(buf) + VARHDRSZ);
|
||
|
memcpy(VARDATA(result), buf, sizeof(buf));
|
||
|
|
||
|
PG_RETURN_BYTEA_P(result);
|
||
|
}
|