#include "pgsodium.h" PG_FUNCTION_INFO_V1 (pgsodium_crypto_pwhash_saltgen); Datum pgsodium_crypto_pwhash_saltgen (PG_FUNCTION_ARGS) { size_t result_size = VARHDRSZ + crypto_pwhash_SALTBYTES; bytea *result = _pgsodium_zalloc_bytea (result_size); randombytes_buf (VARDATA (result), crypto_pwhash_SALTBYTES); PG_RETURN_BYTEA_P (result); } PG_FUNCTION_INFO_V1 (pgsodium_crypto_pwhash); Datum pgsodium_crypto_pwhash (PG_FUNCTION_ARGS) { bytea *data; bytea *result; bytea *salt; int result_size = VARHDRSZ + crypto_box_SEEDBYTES; int success; data = PG_GETARG_BYTEA_P (0); salt = PG_GETARG_BYTEA_P (1); ERRORIF (VARSIZE_ANY_EXHDR (salt) != crypto_pwhash_SALTBYTES, "%s: invalid salt"); ERRORIF (VARSIZE_ANY_EXHDR (data) < crypto_pwhash_PASSWD_MIN || VARSIZE_ANY_EXHDR (data) > crypto_pwhash_PASSWD_MAX, "%s: invalid password"); result = _pgsodium_zalloc_bytea (result_size); success = crypto_pwhash (PGSODIUM_UCHARDATA (result), crypto_box_SEEDBYTES, VARDATA (data), VARSIZE_ANY_EXHDR (data), PGSODIUM_UCHARDATA (salt), crypto_pwhash_OPSLIMIT_MODERATE, crypto_pwhash_MEMLIMIT_MODERATE, crypto_pwhash_ALG_DEFAULT); ERRORIF (success != 0, "%s: invalid message"); PG_RETURN_BYTEA_P (result); } PG_FUNCTION_INFO_V1 (pgsodium_crypto_pwhash_str); Datum pgsodium_crypto_pwhash_str (PG_FUNCTION_ARGS) { int success; bytea *password = PG_GETARG_BYTEA_P (0); bytea *result = _pgsodium_zalloc_bytea (crypto_pwhash_STRBYTES + VARHDRSZ); success = crypto_pwhash_str (VARDATA (result), VARDATA (password), VARSIZE_ANY_EXHDR (password), crypto_pwhash_OPSLIMIT_MODERATE, crypto_pwhash_MEMLIMIT_MODERATE); ERRORIF (success != 0, "%s: out of memory in pwhash_str"); PG_RETURN_BYTEA_P (result); } PG_FUNCTION_INFO_V1 (pgsodium_crypto_pwhash_str_verify); Datum pgsodium_crypto_pwhash_str_verify (PG_FUNCTION_ARGS) { int success; bytea *hashed_password = PG_GETARG_BYTEA_P (0); bytea *password = PG_GETARG_BYTEA_P (1); success = crypto_pwhash_str_verify (VARDATA (hashed_password), VARDATA (password), VARSIZE_ANY_EXHDR (password)); PG_RETURN_BOOL (success == 0); }