summaryrefslogtreecommitdiff
path: root/contrib/pgcrypto
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2020-12-02 10:37:20 +0900
committerMichael Paquier <michael@paquier.xyz>2020-12-02 10:37:20 +0900
commit87ae9691d25379785f8c0f81b06a14818cfd8c56 (patch)
tree79d276dee0414a230eec82a1a9b98e4a7cabee5c /contrib/pgcrypto
parent888671a8cda5896d36d3ec523e201ab6a11e1855 (diff)
downloadpostgresql-87ae9691d25379785f8c0f81b06a14818cfd8c56.tar.gz
Move SHA2 routines to a new generic API layer for crypto hashes
Two new routines to allocate a hash context and to free it are created, as these become necessary for the goal behind this refactoring: switch the all cryptohash implementations for OpenSSL to use EVP (for FIPS and also because upstream does not recommend the use of low-level cryptohash functions for 20 years). Note that OpenSSL hides the internals of cryptohash contexts since 1.1.0, so it is necessary to leave the allocation to OpenSSL itself, explaining the need for those two new routines. This part is going to require more work to properly track hash contexts with resource owners, but this not introduced here. Still, this refactoring makes the move possible. This reduces the number of routines for all SHA2 implementations from twelve (SHA{224,256,386,512} with init, update and final calls) to five (create, free, init, update and final calls) by incorporating the hash type directly into the hash context data. The new cryptohash routines are moved to a new file, called cryptohash.c for the fallback implementations, with SHA2 specifics becoming a part internal to src/common/. OpenSSL specifics are part of cryptohash_openssl.c. This infrastructure is usable for more hash types, like MD5 or HMAC. Any code paths using the internal SHA2 routines are adapted to report correctly errors, which are most of the changes of this commit. The zones mostly impacted are checksum manifests, libpq and SCRAM. Note that e21cbb4 was a first attempt to switch SHA2 to EVP, but it lacked the refactoring needed for libpq, as done here. This patch has been tested on Linux and Windows, with and without OpenSSL, and down to 1.0.1, the oldest version supported on HEAD. Author: Michael Paquier Reviewed-by: Daniel Gustafsson Discussion: https://postgr.es/m/20200924025314.GE7405@paquier.xyz
Diffstat (limited to 'contrib/pgcrypto')
-rw-r--r--contrib/pgcrypto/internal-sha2.c188
1 files changed, 41 insertions, 147 deletions
diff --git a/contrib/pgcrypto/internal-sha2.c b/contrib/pgcrypto/internal-sha2.c
index 9fa940b5bb..0fe53e15af 100644
--- a/contrib/pgcrypto/internal-sha2.c
+++ b/contrib/pgcrypto/internal-sha2.c
@@ -33,6 +33,7 @@
#include <time.h>
+#include "common/cryptohash.h"
#include "common/sha2.h"
#include "px.h"
@@ -42,7 +43,6 @@ void init_sha384(PX_MD *h);
void init_sha512(PX_MD *h);
/* SHA224 */
-
static unsigned
int_sha224_len(PX_MD *h)
{
@@ -55,42 +55,7 @@ int_sha224_block_len(PX_MD *h)
return PG_SHA224_BLOCK_LENGTH;
}
-static void
-int_sha224_update(PX_MD *h, const uint8 *data, unsigned dlen)
-{
- pg_sha224_ctx *ctx = (pg_sha224_ctx *) h->p.ptr;
-
- pg_sha224_update(ctx, data, dlen);
-}
-
-static void
-int_sha224_reset(PX_MD *h)
-{
- pg_sha224_ctx *ctx = (pg_sha224_ctx *) h->p.ptr;
-
- pg_sha224_init(ctx);
-}
-
-static void
-int_sha224_finish(PX_MD *h, uint8 *dst)
-{
- pg_sha224_ctx *ctx = (pg_sha224_ctx *) h->p.ptr;
-
- pg_sha224_final(ctx, dst);
-}
-
-static void
-int_sha224_free(PX_MD *h)
-{
- pg_sha224_ctx *ctx = (pg_sha224_ctx *) h->p.ptr;
-
- px_memset(ctx, 0, sizeof(*ctx));
- pfree(ctx);
- pfree(h);
-}
-
/* SHA256 */
-
static unsigned
int_sha256_len(PX_MD *h)
{
@@ -103,42 +68,7 @@ int_sha256_block_len(PX_MD *h)
return PG_SHA256_BLOCK_LENGTH;
}
-static void
-int_sha256_update(PX_MD *h, const uint8 *data, unsigned dlen)
-{
- pg_sha256_ctx *ctx = (pg_sha256_ctx *) h->p.ptr;
-
- pg_sha256_update(ctx, data, dlen);
-}
-
-static void
-int_sha256_reset(PX_MD *h)
-{
- pg_sha256_ctx *ctx = (pg_sha256_ctx *) h->p.ptr;
-
- pg_sha256_init(ctx);
-}
-
-static void
-int_sha256_finish(PX_MD *h, uint8 *dst)
-{
- pg_sha256_ctx *ctx = (pg_sha256_ctx *) h->p.ptr;
-
- pg_sha256_final(ctx, dst);
-}
-
-static void
-int_sha256_free(PX_MD *h)
-{
- pg_sha256_ctx *ctx = (pg_sha256_ctx *) h->p.ptr;
-
- px_memset(ctx, 0, sizeof(*ctx));
- pfree(ctx);
- pfree(h);
-}
-
/* SHA384 */
-
static unsigned
int_sha384_len(PX_MD *h)
{
@@ -151,42 +81,7 @@ int_sha384_block_len(PX_MD *h)
return PG_SHA384_BLOCK_LENGTH;
}
-static void
-int_sha384_update(PX_MD *h, const uint8 *data, unsigned dlen)
-{
- pg_sha384_ctx *ctx = (pg_sha384_ctx *) h->p.ptr;
-
- pg_sha384_update(ctx, data, dlen);
-}
-
-static void
-int_sha384_reset(PX_MD *h)
-{
- pg_sha384_ctx *ctx = (pg_sha384_ctx *) h->p.ptr;
-
- pg_sha384_init(ctx);
-}
-
-static void
-int_sha384_finish(PX_MD *h, uint8 *dst)
-{
- pg_sha384_ctx *ctx = (pg_sha384_ctx *) h->p.ptr;
-
- pg_sha384_final(ctx, dst);
-}
-
-static void
-int_sha384_free(PX_MD *h)
-{
- pg_sha384_ctx *ctx = (pg_sha384_ctx *) h->p.ptr;
-
- px_memset(ctx, 0, sizeof(*ctx));
- pfree(ctx);
- pfree(h);
-}
-
/* SHA512 */
-
static unsigned
int_sha512_len(PX_MD *h)
{
@@ -199,37 +94,40 @@ int_sha512_block_len(PX_MD *h)
return PG_SHA512_BLOCK_LENGTH;
}
+/* Generic interface for all SHA2 methods */
static void
-int_sha512_update(PX_MD *h, const uint8 *data, unsigned dlen)
+int_sha2_update(PX_MD *h, const uint8 *data, unsigned dlen)
{
- pg_sha512_ctx *ctx = (pg_sha512_ctx *) h->p.ptr;
+ pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr;
- pg_sha512_update(ctx, data, dlen);
+ if (pg_cryptohash_update(ctx, data, dlen) < 0)
+ elog(ERROR, "could not update %s context", "SHA2");
}
static void
-int_sha512_reset(PX_MD *h)
+int_sha2_reset(PX_MD *h)
{
- pg_sha512_ctx *ctx = (pg_sha512_ctx *) h->p.ptr;
+ pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr;
- pg_sha512_init(ctx);
+ if (pg_cryptohash_init(ctx) < 0)
+ elog(ERROR, "could not initialize %s context", "SHA2");
}
static void
-int_sha512_finish(PX_MD *h, uint8 *dst)
+int_sha2_finish(PX_MD *h, uint8 *dst)
{
- pg_sha512_ctx *ctx = (pg_sha512_ctx *) h->p.ptr;
+ pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr;
- pg_sha512_final(ctx, dst);
+ if (pg_cryptohash_final(ctx, dst) < 0)
+ elog(ERROR, "could not finalize %s context", "SHA2");
}
static void
-int_sha512_free(PX_MD *h)
+int_sha2_free(PX_MD *h)
{
- pg_sha512_ctx *ctx = (pg_sha512_ctx *) h->p.ptr;
+ pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr;
- px_memset(ctx, 0, sizeof(*ctx));
- pfree(ctx);
+ pg_cryptohash_free(ctx);
pfree(h);
}
@@ -238,18 +136,17 @@ int_sha512_free(PX_MD *h)
void
init_sha224(PX_MD *md)
{
- pg_sha224_ctx *ctx;
-
- ctx = palloc0(sizeof(*ctx));
+ pg_cryptohash_ctx *ctx;
+ ctx = pg_cryptohash_create(PG_SHA224);
md->p.ptr = ctx;
md->result_size = int_sha224_len;
md->block_size = int_sha224_block_len;
- md->reset = int_sha224_reset;
- md->update = int_sha224_update;
- md->finish = int_sha224_finish;
- md->free = int_sha224_free;
+ md->reset = int_sha2_reset;
+ md->update = int_sha2_update;
+ md->finish = int_sha2_finish;
+ md->free = int_sha2_free;
md->reset(md);
}
@@ -257,18 +154,17 @@ init_sha224(PX_MD *md)
void
init_sha256(PX_MD *md)
{
- pg_sha256_ctx *ctx;
-
- ctx = palloc0(sizeof(*ctx));
+ pg_cryptohash_ctx *ctx;
+ ctx = pg_cryptohash_create(PG_SHA256);
md->p.ptr = ctx;
md->result_size = int_sha256_len;
md->block_size = int_sha256_block_len;
- md->reset = int_sha256_reset;
- md->update = int_sha256_update;
- md->finish = int_sha256_finish;
- md->free = int_sha256_free;
+ md->reset = int_sha2_reset;
+ md->update = int_sha2_update;
+ md->finish = int_sha2_finish;
+ md->free = int_sha2_free;
md->reset(md);
}
@@ -276,18 +172,17 @@ init_sha256(PX_MD *md)
void
init_sha384(PX_MD *md)
{
- pg_sha384_ctx *ctx;
-
- ctx = palloc0(sizeof(*ctx));
+ pg_cryptohash_ctx *ctx;
+ ctx = pg_cryptohash_create(PG_SHA384);
md->p.ptr = ctx;
md->result_size = int_sha384_len;
md->block_size = int_sha384_block_len;
- md->reset = int_sha384_reset;
- md->update = int_sha384_update;
- md->finish = int_sha384_finish;
- md->free = int_sha384_free;
+ md->reset = int_sha2_reset;
+ md->update = int_sha2_update;
+ md->finish = int_sha2_finish;
+ md->free = int_sha2_free;
md->reset(md);
}
@@ -295,18 +190,17 @@ init_sha384(PX_MD *md)
void
init_sha512(PX_MD *md)
{
- pg_sha512_ctx *ctx;
-
- ctx = palloc0(sizeof(*ctx));
+ pg_cryptohash_ctx *ctx;
+ ctx = pg_cryptohash_create(PG_SHA512);
md->p.ptr = ctx;
md->result_size = int_sha512_len;
md->block_size = int_sha512_block_len;
- md->reset = int_sha512_reset;
- md->update = int_sha512_update;
- md->finish = int_sha512_finish;
- md->free = int_sha512_free;
+ md->reset = int_sha2_reset;
+ md->update = int_sha2_update;
+ md->finish = int_sha2_finish;
+ md->free = int_sha2_free;
md->reset(md);
}