Commit f854c69a authored by Michael Paquier's avatar Michael Paquier

Refactor SQL functions of SHA-2 in cryptohashfuncs.c

The same code pattern was repeated four times when compiling a SHA-2
hash.  This refactoring has the advantage to issue a compilation warning
if a new value is added to pg_cryptohash_type, so as anybody doing an
addition in this area would need to consider if support for a new SQL
function is needed or not.

Author: Sehrope Sarkuni, Michael Paquier
Discussion: https://postgr.es/m/YA7DvLRn2xnTgsMc@paquier.xyz
parent e19594c5
...@@ -68,65 +68,77 @@ md5_bytea(PG_FUNCTION_ARGS) ...@@ -68,65 +68,77 @@ md5_bytea(PG_FUNCTION_ARGS)
PG_RETURN_TEXT_P(cstring_to_text(hexsum)); PG_RETURN_TEXT_P(cstring_to_text(hexsum));
} }
/* /*
* SHA-2 variants * Internal routine to compute a cryptohash with the given bytea input.
*/ */
static inline bytea *
Datum cryptohash_internal(pg_cryptohash_type type, bytea *input)
sha224_bytea(PG_FUNCTION_ARGS)
{ {
bytea *in = PG_GETARG_BYTEA_PP(0);
const uint8 *data; const uint8 *data;
const char *typestr = NULL;
int digest_len = 0;
size_t len; size_t len;
pg_cryptohash_ctx *ctx; pg_cryptohash_ctx *ctx;
unsigned char buf[PG_SHA224_DIGEST_LENGTH];
bytea *result; bytea *result;
len = VARSIZE_ANY_EXHDR(in); switch (type)
data = (unsigned char *) VARDATA_ANY(in); {
case PG_SHA224:
ctx = pg_cryptohash_create(PG_SHA224); typestr = "SHA224";
digest_len = PG_SHA224_DIGEST_LENGTH;
break;
case PG_SHA256:
typestr = "SHA256";
digest_len = PG_SHA256_DIGEST_LENGTH;
break;
case PG_SHA384:
typestr = "SHA384";
digest_len = PG_SHA384_DIGEST_LENGTH;
break;
case PG_SHA512:
typestr = "SHA512";
digest_len = PG_SHA512_DIGEST_LENGTH;
break;
case PG_MD5:
case PG_SHA1:
elog(ERROR, "unsupported cryptohash type %d", type);
break;
}
result = palloc0(digest_len + VARHDRSZ);
len = VARSIZE_ANY_EXHDR(input);
data = (unsigned char *) VARDATA_ANY(input);
ctx = pg_cryptohash_create(type);
if (pg_cryptohash_init(ctx) < 0) if (pg_cryptohash_init(ctx) < 0)
elog(ERROR, "could not initialize %s context", "SHA224"); elog(ERROR, "could not initialize %s context", typestr);
if (pg_cryptohash_update(ctx, data, len) < 0) if (pg_cryptohash_update(ctx, data, len) < 0)
elog(ERROR, "could not update %s context", "SHA224"); elog(ERROR, "could not update %s context", typestr);
if (pg_cryptohash_final(ctx, buf) < 0) if (pg_cryptohash_final(ctx, (unsigned char *) VARDATA(result)) < 0)
elog(ERROR, "could not finalize %s context", "SHA224"); elog(ERROR, "could not finalize %s context", typestr);
pg_cryptohash_free(ctx); pg_cryptohash_free(ctx);
result = palloc(sizeof(buf) + VARHDRSZ); SET_VARSIZE(result, digest_len + VARHDRSZ);
SET_VARSIZE(result, sizeof(buf) + VARHDRSZ);
memcpy(VARDATA(result), buf, sizeof(buf));
PG_RETURN_BYTEA_P(result); return result;
} }
/*
* SHA-2 variants
*/
Datum Datum
sha256_bytea(PG_FUNCTION_ARGS) sha224_bytea(PG_FUNCTION_ARGS)
{ {
bytea *in = PG_GETARG_BYTEA_PP(0); bytea *result = cryptohash_internal(PG_SHA224, 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); PG_RETURN_BYTEA_P(result);
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); Datum
SET_VARSIZE(result, sizeof(buf) + VARHDRSZ); sha256_bytea(PG_FUNCTION_ARGS)
memcpy(VARDATA(result), buf, sizeof(buf)); {
bytea *result = cryptohash_internal(PG_SHA256, PG_GETARG_BYTEA_PP(0));
PG_RETURN_BYTEA_P(result); PG_RETURN_BYTEA_P(result);
} }
...@@ -134,28 +146,7 @@ sha256_bytea(PG_FUNCTION_ARGS) ...@@ -134,28 +146,7 @@ sha256_bytea(PG_FUNCTION_ARGS)
Datum Datum
sha384_bytea(PG_FUNCTION_ARGS) sha384_bytea(PG_FUNCTION_ARGS)
{ {
bytea *in = PG_GETARG_BYTEA_PP(0); bytea *result = cryptohash_internal(PG_SHA384, 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); PG_RETURN_BYTEA_P(result);
} }
...@@ -163,28 +154,7 @@ sha384_bytea(PG_FUNCTION_ARGS) ...@@ -163,28 +154,7 @@ sha384_bytea(PG_FUNCTION_ARGS)
Datum Datum
sha512_bytea(PG_FUNCTION_ARGS) sha512_bytea(PG_FUNCTION_ARGS)
{ {
bytea *in = PG_GETARG_BYTEA_PP(0); bytea *result = cryptohash_internal(PG_SHA512, 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); PG_RETURN_BYTEA_P(result);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment