merge-cryptohash-ctx-and-state-structs.patch
text/x-patch
Filename: merge-cryptohash-ctx-and-state-structs.patch
Type: text/x-patch
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/common/cryptohash.c | 33 | 62 |
| src/common/cryptohash_openssl.c | 32 | 50 |
| src/include/common/cryptohash.h | 2 | 6 |
diff --git a/src/common/cryptohash.c b/src/common/cryptohash.c
index cf4588bad72..d3fa32888f0 100644
--- a/src/common/cryptohash.c
+++ b/src/common/cryptohash.c
@@ -39,6 +39,20 @@
#define FREE(ptr) free(ptr)
#endif
+struct pg_cryptohash_ctx
+{
+ pg_cryptohash_type type;
+
+ union
+ {
+ pg_md5_ctx md5;
+ pg_sha224_ctx sha224;
+ pg_sha256_ctx sha256;
+ pg_sha384_ctx sha384;
+ pg_sha512_ctx sha512;
+ } data;
+};
+
/*
* pg_cryptohash_create
*
@@ -50,38 +64,15 @@ pg_cryptohash_create(pg_cryptohash_type type)
{
pg_cryptohash_ctx *ctx;
+ /*
+ * FIXME: this always allocates enough space for the largest hash.
+ * A smaller allocation would be enough for md5, sha224 and sha256.
+ */
ctx = ALLOC(sizeof(pg_cryptohash_ctx));
if (ctx == NULL)
return NULL;
-
ctx->type = type;
- switch (type)
- {
- case PG_MD5:
- ctx->data = ALLOC(sizeof(pg_md5_ctx));
- break;
- case PG_SHA224:
- ctx->data = ALLOC(sizeof(pg_sha224_ctx));
- break;
- case PG_SHA256:
- ctx->data = ALLOC(sizeof(pg_sha256_ctx));
- break;
- case PG_SHA384:
- ctx->data = ALLOC(sizeof(pg_sha384_ctx));
- break;
- case PG_SHA512:
- ctx->data = ALLOC(sizeof(pg_sha512_ctx));
- break;
- }
-
- if (ctx->data == NULL)
- {
- explicit_bzero(ctx, sizeof(pg_cryptohash_ctx));
- FREE(ctx);
- return NULL;
- }
-
return ctx;
}
@@ -100,19 +91,19 @@ pg_cryptohash_init(pg_cryptohash_ctx *ctx)
switch (ctx->type)
{
case PG_MD5:
- pg_md5_init((pg_md5_ctx *) ctx->data);
+ pg_md5_init(&ctx->data.md5);
break;
case PG_SHA224:
- pg_sha224_init((pg_sha224_ctx *) ctx->data);
+ pg_sha224_init(&ctx->data.sha224);
break;
case PG_SHA256:
- pg_sha256_init((pg_sha256_ctx *) ctx->data);
+ pg_sha256_init(&ctx->data.sha256);
break;
case PG_SHA384:
- pg_sha384_init((pg_sha384_ctx *) ctx->data);
+ pg_sha384_init(&ctx->data.sha384);
break;
case PG_SHA512:
- pg_sha512_init((pg_sha512_ctx *) ctx->data);
+ pg_sha512_init(&ctx->data.sha512);
break;
}
@@ -134,19 +125,19 @@ pg_cryptohash_update(pg_cryptohash_ctx *ctx, const uint8 *data, size_t len)
switch (ctx->type)
{
case PG_MD5:
- pg_md5_update((pg_md5_ctx *) ctx->data, data, len);
+ pg_md5_update(&ctx->data.md5, data, len);
break;
case PG_SHA224:
- pg_sha224_update((pg_sha224_ctx *) ctx->data, data, len);
+ pg_sha224_update(&ctx->data.sha224, data, len);
break;
case PG_SHA256:
- pg_sha256_update((pg_sha256_ctx *) ctx->data, data, len);
+ pg_sha256_update(&ctx->data.sha256, data, len);
break;
case PG_SHA384:
- pg_sha384_update((pg_sha384_ctx *) ctx->data, data, len);
+ pg_sha384_update(&ctx->data.sha384, data, len);
break;
case PG_SHA512:
- pg_sha512_update((pg_sha512_ctx *) ctx->data, data, len);
+ pg_sha512_update(&ctx->data.sha512, data, len);
break;
}
@@ -168,19 +159,19 @@ pg_cryptohash_final(pg_cryptohash_ctx *ctx, uint8 *dest)
switch (ctx->type)
{
case PG_MD5:
- pg_md5_final((pg_md5_ctx *) ctx->data, dest);
+ pg_md5_final(&ctx->data.md5, dest);
break;
case PG_SHA224:
- pg_sha224_final((pg_sha224_ctx *) ctx->data, dest);
+ pg_sha224_final(&ctx->data.sha224, dest);
break;
case PG_SHA256:
- pg_sha256_final((pg_sha256_ctx *) ctx->data, dest);
+ pg_sha256_final(&ctx->data.sha256, dest);
break;
case PG_SHA384:
- pg_sha384_final((pg_sha384_ctx *) ctx->data, dest);
+ pg_sha384_final(&ctx->data.sha384, dest);
break;
case PG_SHA512:
- pg_sha512_final((pg_sha512_ctx *) ctx->data, dest);
+ pg_sha512_final(&ctx->data.sha512, dest);
break;
}
@@ -198,26 +189,6 @@ pg_cryptohash_free(pg_cryptohash_ctx *ctx)
if (ctx == NULL)
return;
- switch (ctx->type)
- {
- case PG_MD5:
- explicit_bzero(ctx->data, sizeof(pg_md5_ctx));
- break;
- case PG_SHA224:
- explicit_bzero(ctx->data, sizeof(pg_sha224_ctx));
- break;
- case PG_SHA256:
- explicit_bzero(ctx->data, sizeof(pg_sha256_ctx));
- break;
- case PG_SHA384:
- explicit_bzero(ctx->data, sizeof(pg_sha384_ctx));
- break;
- case PG_SHA512:
- explicit_bzero(ctx->data, sizeof(pg_sha512_ctx));
- break;
- }
-
- FREE(ctx->data);
explicit_bzero(ctx, sizeof(pg_cryptohash_ctx));
FREE(ctx);
}
diff --git a/src/common/cryptohash_openssl.c b/src/common/cryptohash_openssl.c
index 118651c4153..24b9636d1ca 100644
--- a/src/common/cryptohash_openssl.c
+++ b/src/common/cryptohash_openssl.c
@@ -35,7 +35,7 @@
* use malloc to be able to return a failure status back to the caller.
*/
#ifndef FRONTEND
-#define ALLOC(size) palloc(size)
+#define ALLOC(size) MemoryContextAllocExtended(TopMemoryContext, size, MCXT_ALLOC_NO_OOM)
#define FREE(ptr) pfree(ptr)
#else
#define ALLOC(size) malloc(size)
@@ -43,19 +43,21 @@
#endif
/*
- * Internal structure for pg_cryptohash_ctx->data.
+ * Internal pg_cryptohash_ctx structure.
*
* This tracks the resource owner associated to each EVP context data
* for the backend.
*/
-typedef struct pg_cryptohash_state
+struct pg_cryptohash_ctx
{
+ pg_cryptohash_type type;
+
EVP_MD_CTX *evpctx;
#ifndef FRONTEND
ResourceOwner resowner;
#endif
-} pg_cryptohash_state;
+};
/*
* pg_cryptohash_create
@@ -67,49 +69,41 @@ pg_cryptohash_ctx *
pg_cryptohash_create(pg_cryptohash_type type)
{
pg_cryptohash_ctx *ctx;
- pg_cryptohash_state *state;
+
+ /*
+ * Make sure that the resource owner has space to remember this
+ * reference. This can error out with "out of memory", so do this
+ * before any other allocation to avoid leaking.
+ */
+#ifndef FRONTEND
+ ResourceOwnerEnlargeCryptoHash(CurrentResourceOwner);
+#endif
ctx = ALLOC(sizeof(pg_cryptohash_ctx));
if (ctx == NULL)
return NULL;
-
- state = ALLOC(sizeof(pg_cryptohash_state));
- if (state == NULL)
- {
- explicit_bzero(ctx, sizeof(pg_cryptohash_ctx));
- FREE(ctx);
- return NULL;
- }
-
- ctx->data = state;
ctx->type = type;
-#ifndef FRONTEND
- ResourceOwnerEnlargeCryptoHash(CurrentResourceOwner);
-#endif
-
/*
* Initialization takes care of assigning the correct type for OpenSSL.
*/
- state->evpctx = EVP_MD_CTX_create();
+ ctx->evpctx = EVP_MD_CTX_create();
- if (state->evpctx == NULL)
+ if (ctx->evpctx == NULL)
{
- explicit_bzero(state, sizeof(pg_cryptohash_state));
explicit_bzero(ctx, sizeof(pg_cryptohash_ctx));
#ifndef FRONTEND
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
#else
- FREE(state);
FREE(ctx);
return NULL;
#endif
}
#ifndef FRONTEND
- state->resowner = CurrentResourceOwner;
+ ctx->resowner = CurrentResourceOwner;
ResourceOwnerRememberCryptoHash(CurrentResourceOwner,
PointerGetDatum(ctx));
#endif
@@ -126,33 +120,30 @@ int
pg_cryptohash_init(pg_cryptohash_ctx *ctx)
{
int status = 0;
- pg_cryptohash_state *state;
if (ctx == NULL)
return 0;
- state = (pg_cryptohash_state *) ctx->data;
-
switch (ctx->type)
{
case PG_MD5:
- status = EVP_DigestInit_ex(state->evpctx, EVP_md5(), NULL);
+ status = EVP_DigestInit_ex(ctx->evpctx, EVP_md5(), NULL);
break;
case PG_SHA224:
- status = EVP_DigestInit_ex(state->evpctx, EVP_sha224(), NULL);
+ status = EVP_DigestInit_ex(ctx->evpctx, EVP_sha224(), NULL);
break;
case PG_SHA256:
- status = EVP_DigestInit_ex(state->evpctx, EVP_sha256(), NULL);
+ status = EVP_DigestInit_ex(ctx->evpctx, EVP_sha256(), NULL);
break;
case PG_SHA384:
- status = EVP_DigestInit_ex(state->evpctx, EVP_sha384(), NULL);
+ status = EVP_DigestInit_ex(ctx->evpctx, EVP_sha384(), NULL);
break;
case PG_SHA512:
- status = EVP_DigestInit_ex(state->evpctx, EVP_sha512(), NULL);
+ status = EVP_DigestInit_ex(ctx->evpctx, EVP_sha512(), NULL);
break;
}
- /* OpenSSL internals return 1 on success, 0 on failure */
+ /* openssl internals return 1 on success, 0 on failure */
if (status <= 0)
return -1;
return 0;
@@ -161,21 +152,19 @@ pg_cryptohash_init(pg_cryptohash_ctx *ctx)
/*
* pg_cryptohash_update
*
- * Update a hash context. Returns 0 on success, and -1 on failure.
+ * update a hash context. returns 0 on success, and -1 on failure.
*/
int
pg_cryptohash_update(pg_cryptohash_ctx *ctx, const uint8 *data, size_t len)
{
int status = 0;
- pg_cryptohash_state *state;
if (ctx == NULL)
return 0;
- state = (pg_cryptohash_state *) ctx->data;
- status = EVP_DigestUpdate(state->evpctx, data, len);
+ status = EVP_DigestUpdate(ctx->evpctx, data, len);
- /* OpenSSL internals return 1 on success, 0 on failure */
+ /* openssl internals return 1 on success, 0 on failure */
if (status <= 0)
return -1;
return 0;
@@ -184,19 +173,17 @@ pg_cryptohash_update(pg_cryptohash_ctx *ctx, const uint8 *data, size_t len)
/*
* pg_cryptohash_final
*
- * Finalize a hash context. Returns 0 on success, and -1 on failure.
+ * finalize a hash context. returns 0 on success, and -1 on failure.
*/
int
pg_cryptohash_final(pg_cryptohash_ctx *ctx, uint8 *dest)
{
int status = 0;
- pg_cryptohash_state *state;
if (ctx == NULL)
return 0;
- state = (pg_cryptohash_state *) ctx->data;
- status = EVP_DigestFinal_ex(state->evpctx, dest, 0);
+ status = EVP_DigestFinal_ex(ctx->evpctx, dest, 0);
/* OpenSSL internals return 1 on success, 0 on failure */
if (status <= 0)
@@ -207,26 +194,21 @@ pg_cryptohash_final(pg_cryptohash_ctx *ctx, uint8 *dest)
/*
* pg_cryptohash_free
*
- * Free a hash context.
+ * free a hash context.
*/
void
pg_cryptohash_free(pg_cryptohash_ctx *ctx)
{
- pg_cryptohash_state *state;
-
if (ctx == NULL)
return;
- state = (pg_cryptohash_state *) ctx->data;
- EVP_MD_CTX_destroy(state->evpctx);
+ EVP_MD_CTX_destroy(ctx->evpctx);
#ifndef FRONTEND
- ResourceOwnerForgetCryptoHash(state->resowner,
+ ResourceOwnerForgetCryptoHash(ctx->resowner,
PointerGetDatum(ctx));
#endif
- explicit_bzero(state, sizeof(pg_cryptohash_state));
explicit_bzero(ctx, sizeof(pg_cryptohash_ctx));
- FREE(state);
FREE(ctx);
}
diff --git a/src/include/common/cryptohash.h b/src/include/common/cryptohash.h
index 6ead1cb8e5b..69e69532d44 100644
--- a/src/include/common/cryptohash.h
+++ b/src/include/common/cryptohash.h
@@ -25,12 +25,8 @@ typedef enum
PG_SHA512
} pg_cryptohash_type;
-typedef struct pg_cryptohash_ctx
-{
- pg_cryptohash_type type;
- /* private area used by each hash implementation */
- void *data;
-} pg_cryptohash_ctx;
+/* opaque context, private to the cryptohash implementation */
+typedef struct pg_cryptohash_ctx pg_cryptohash_ctx;
extern pg_cryptohash_ctx *pg_cryptohash_create(pg_cryptohash_type type);
extern int pg_cryptohash_init(pg_cryptohash_ctx *ctx);