/*-------------------------------------------------------------------------
 *
 * hmac_openssl.c
 *	  Implementation of HMAC with OpenSSL.
 *
 * This should only be used if code is compiled with OpenSSL support.
 *
 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *	  src/common/hmac_openssl.c
 *
 *-------------------------------------------------------------------------
 */

#ifndef FRONTEND
#include "postgres.h"
#else
#include "postgres_fe.h"
#endif


#include <openssl/err.h>
#include <openssl/hmac.h>

#include "common/hmac.h"
#include "common/md5.h"
#include "common/sha1.h"
#include "common/sha2.h"
#ifndef FRONTEND
#include "utils/memutils.h"
#include "utils/resowner.h"
#include "utils/resowner_private.h"
#endif

/*
 * In backend, use an allocation in TopMemoryContext to count for resowner
 * cleanup handling if necessary.  For versions of OpenSSL where HMAC_CTX is
 * known, just use palloc().  In frontend, use malloc to be able to return
 * a failure status back to the caller.
 */
#ifndef FRONTEND
#ifdef HAVE_HMAC_CTX_NEW
#define ALLOC(size) MemoryContextAlloc(TopMemoryContext, size)
#else
#define ALLOC(size) palloc(size)
#endif
#define FREE(ptr) pfree(ptr)
#else							/* FRONTEND */
#define ALLOC(size) malloc(size)
#define FREE(ptr) free(ptr)
#endif							/* FRONTEND */

/* Set of error states */
typedef enum pg_hmac_errno
{
	PG_HMAC_ERROR_NONE = 0,
	PG_HMAC_ERROR_DEST_LEN,
	PG_HMAC_ERROR_OPENSSL
} pg_hmac_errno;

/* Internal pg_hmac_ctx structure */
struct pg_hmac_ctx
{
	HMAC_CTX   *hmacctx;
	pg_cryptohash_type type;
	pg_hmac_errno error;
	const char *errreason;

#ifndef FRONTEND
	ResourceOwner resowner;
#endif
};

static const char *
SSLerrmessage(unsigned long ecode)
{
	if (ecode == 0)
		return NULL;

	/*
	 * This may return NULL, but we would fall back to a default error path if
	 * that were the case.
	 */
	return ERR_reason_error_string(ecode);
}

/*
 * pg_hmac_create
 *
 * Allocate a hash context.  Returns NULL on failure for an OOM.  The
 * backend issues an error, without returning.
 */
pg_hmac_ctx *
pg_hmac_create(pg_cryptohash_type type)
{
	pg_hmac_ctx *ctx;

	ctx = ALLOC(sizeof(pg_hmac_ctx));
	if (ctx == NULL)
		return NULL;
	memset(ctx, 0, sizeof(pg_hmac_ctx));

	ctx->type = type;
	ctx->error = PG_HMAC_ERROR_NONE;
	ctx->errreason = NULL;


	/*
	 * Initialization takes care of assigning the correct type for OpenSSL.
	 * Also ensure that there aren't any unconsumed errors in the queue from
	 * previous runs.
	 */
	ERR_clear_error();
#ifdef HAVE_HMAC_CTX_NEW
#ifndef FRONTEND
	ResourceOwnerEnlargeHMAC(CurrentResourceOwner);
#endif
	ctx->hmacctx = HMAC_CTX_new();
#else
	ctx->hmacctx = ALLOC(sizeof(HMAC_CTX));
#endif

	if (ctx->hmacctx == NULL)
	{
		explicit_bzero(ctx, sizeof(pg_hmac_ctx));
		FREE(ctx);
#ifndef FRONTEND
		ereport(ERROR,
				(errcode(ERRCODE_OUT_OF_MEMORY),
				 errmsg("out of memory")));
#endif
		return NULL;
	}

#ifdef HAVE_HMAC_CTX_NEW
#ifndef FRONTEND
	ctx->resowner = CurrentResourceOwner;
	ResourceOwnerRememberHMAC(CurrentResourceOwner, PointerGetDatum(ctx));
#endif
#else
	memset(ctx->hmacctx, 0, sizeof(HMAC_CTX));
#endif							/* HAVE_HMAC_CTX_NEW */

	return ctx;
}

/*
 * pg_hmac_init
 *
 * Initialize a HMAC context.  Returns 0 on success, -1 on failure.
 */
int
pg_hmac_init(pg_hmac_ctx *ctx, const uint8 *key, size_t len)
{
	int			status = 0;

	if (ctx == NULL)
		return -1;

	switch (ctx->type)
	{
		case PG_MD5:
			status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_md5(), NULL);
			break;
		case PG_SHA1:
			status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_sha1(), NULL);
			break;
		case PG_SHA224:
			status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_sha224(), NULL);
			break;
		case PG_SHA256:
			status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_sha256(), NULL);
			break;
		case PG_SHA384:
			status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_sha384(), NULL);
			break;
		case PG_SHA512:
			status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_sha512(), NULL);
			break;
		case PG_SM3:
			/* not support yet */
			return -1;
	}

	/* OpenSSL internals return 1 on success, 0 on failure */
	if (status <= 0)
	{
		ctx->errreason = SSLerrmessage(ERR_get_error());
		ctx->error = PG_HMAC_ERROR_OPENSSL;
		return -1;
	}

	return 0;
}

/*
 * pg_hmac_update
 *
 * Update a HMAC context.  Returns 0 on success, -1 on failure.
 */
int
pg_hmac_update(pg_hmac_ctx *ctx, const uint8 *data, size_t len)
{
	int			status = 0;

	if (ctx == NULL)
		return -1;

	status = HMAC_Update(ctx->hmacctx, data, len);

	/* OpenSSL internals return 1 on success, 0 on failure */
	if (status <= 0)
	{
		ctx->errreason = SSLerrmessage(ERR_get_error());
		ctx->error = PG_HMAC_ERROR_OPENSSL;
		return -1;
	}
	return 0;
}

/*
 * pg_hmac_final
 *
 * Finalize a HMAC context.  Returns 0 on success, -1 on failure.
 */
int
pg_hmac_final(pg_hmac_ctx *ctx, uint8 *dest, size_t len)
{
	int			status = 0;
	uint32		outlen;

	if (ctx == NULL)
		return -1;

	switch (ctx->type)
	{
		case PG_MD5:
			if (len < MD5_DIGEST_LENGTH)
			{
				ctx->error = PG_HMAC_ERROR_DEST_LEN;
				return -1;
			}
			break;
		case PG_SHA1:
			if (len < SHA1_DIGEST_LENGTH)
			{
				ctx->error = PG_HMAC_ERROR_DEST_LEN;
				return -1;
			}
			break;
		case PG_SHA224:
			if (len < PG_SHA224_DIGEST_LENGTH)
			{
				ctx->error = PG_HMAC_ERROR_DEST_LEN;
				return -1;
			}
			break;
		case PG_SHA256:
			if (len < PG_SHA256_DIGEST_LENGTH)
			{
				ctx->error = PG_HMAC_ERROR_DEST_LEN;
				return -1;
			}
			break;
		case PG_SHA384:
			if (len < PG_SHA384_DIGEST_LENGTH)
			{
				ctx->error = PG_HMAC_ERROR_DEST_LEN;
				return -1;
			}
			break;
		case PG_SHA512:
			if (len < PG_SHA512_DIGEST_LENGTH)
			{
				ctx->error = PG_HMAC_ERROR_DEST_LEN;
				return -1;
			}
			break;
		case PG_SM3:
			/* not support yet */
			return -1;
	}

	status = HMAC_Final(ctx->hmacctx, dest, &outlen);

	/* OpenSSL internals return 1 on success, 0 on failure */
	if (status <= 0)
	{
		ctx->errreason = SSLerrmessage(ERR_get_error());
		ctx->error = PG_HMAC_ERROR_OPENSSL;
		return -1;
	}
	return 0;
}

/*
 * pg_hmac_free
 *
 * Free a HMAC context.
 */
void
pg_hmac_free(pg_hmac_ctx *ctx)
{
	if (ctx == NULL)
		return;

#ifdef HAVE_HMAC_CTX_FREE
	HMAC_CTX_free(ctx->hmacctx);
#ifndef FRONTEND
	ResourceOwnerForgetHMAC(ctx->resowner, PointerGetDatum(ctx));
#endif
#else
	explicit_bzero(ctx->hmacctx, sizeof(HMAC_CTX));
	FREE(ctx->hmacctx);
#endif

	explicit_bzero(ctx, sizeof(pg_hmac_ctx));
	FREE(ctx);
}

/*
 * pg_hmac_error
 *
 * Returns a static string providing details about an error that happened
 * during a HMAC computation.
 */
const char *
pg_hmac_error(pg_hmac_ctx *ctx)
{
	if (ctx == NULL)
		return _("out of memory");

	/*
	 * If a reason is provided, rely on it, else fallback to any error code
	 * set.
	 */
	if (ctx->errreason)
		return ctx->errreason;

	switch (ctx->error)
	{
		case PG_HMAC_ERROR_NONE:
			return _("success");
		case PG_HMAC_ERROR_DEST_LEN:
			return _("destination buffer too small");
		case PG_HMAC_ERROR_OPENSSL:
			return _("OpenSSL failure");
	}

	Assert(false);				/* cannot be reached */
	return _("success");
}
