summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomas Mraz <tomas@openssl.org>2023-03-17 16:13:35 +0100
committerPauli <pauli@openssl.org>2023-04-21 08:42:15 +1000
commita901b31e99442f087051ae7efdcbc9ad6e6a5b33 (patch)
tree9dafd264b76b25a6e033f489f75db55642909188
parent0e1b7c816dcfa4655f443ae5dd8eea4fb42f3493 (diff)
Minor refactoring of the Argon2 derive function
Cache the fetched MAC and MD implementation until propq changes. No need to keep the output stored in the context. Reviewed-by: Tom Cosgrove <tom.cosgrove@arm.com> Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/20534)
-rw-r--r--providers/implementations/kdfs/argon2.c78
1 files changed, 30 insertions, 48 deletions
diff --git a/providers/implementations/kdfs/argon2.c b/providers/implementations/kdfs/argon2.c
index 60c8fff1b8..6a4807b5c6 100644
--- a/providers/implementations/kdfs/argon2.c
+++ b/providers/implementations/kdfs/argon2.c
@@ -156,7 +156,6 @@ typedef struct {
typedef struct {
void *provctx;
- uint8_t *out;
uint32_t outlen;
uint8_t *pwd;
uint32_t pwdlen;
@@ -259,7 +258,7 @@ static ossl_inline int fill_memory_blocks(KDF_ARGON2 *ctx);
static void initial_hash(uint8_t *blockhash, KDF_ARGON2 *ctx);
static int initialize(KDF_ARGON2 *ctx);
-static void finalize(const KDF_ARGON2 *ctx);
+static void finalize(const KDF_ARGON2 *ctx, void *out);
static int blake2b(EVP_MD *md, EVP_MAC *mac, void *out, size_t outlen,
const void *in, size_t inlen, const void *key,
@@ -755,7 +754,7 @@ static int initialize(KDF_ARGON2 *ctx)
return 1;
}
-static void finalize(const KDF_ARGON2 *ctx)
+static void finalize(const KDF_ARGON2 *ctx, void *out)
{
BLOCK blockhash;
uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
@@ -775,7 +774,7 @@ static void finalize(const KDF_ARGON2 *ctx)
/* Hash the result */
store_block(blockhash_bytes, &blockhash);
- blake2b_long(ctx->md, ctx->mac, ctx->out, ctx->outlen, blockhash_bytes,
+ blake2b_long(ctx->md, ctx->mac, out, ctx->outlen, blockhash_bytes,
ARGON2_BLOCK_SIZE);
OPENSSL_cleanse(blockhash.v, ARGON2_BLOCK_SIZE);
OPENSSL_cleanse(blockhash_bytes, ARGON2_BLOCK_SIZE);
@@ -990,9 +989,6 @@ static void kdf_argon2_free(void *vctx)
if (ctx == NULL)
return;
- if (ctx->out != NULL)
- OPENSSL_clear_free(ctx->out, ctx->outlen);
-
if (ctx->pwd != NULL)
OPENSSL_clear_free(ctx->pwd, ctx->pwdlen);
@@ -1005,6 +1001,9 @@ static void kdf_argon2_free(void *vctx)
if (ctx->ad != NULL)
OPENSSL_clear_free(ctx->ad, ctx->adlen);
+ EVP_MD_free(ctx->md);
+ EVP_MAC_free(ctx->mac);
+
OPENSSL_free(ctx->propq);
memset(ctx, 0, sizeof(*ctx));
@@ -1023,16 +1022,17 @@ static int kdf_argon2_derive(void *vctx, unsigned char *out, size_t outlen,
if (!ossl_prov_is_running() || !kdf_argon2_set_ctx_params(vctx, params))
return 0;
- ctx->mac = EVP_MAC_fetch(ctx->libctx, "blake2bmac", ctx->propq);
+ if (ctx->mac == NULL)
+ ctx->mac = EVP_MAC_fetch(ctx->libctx, "blake2bmac", ctx->propq);
if (ctx->mac == NULL) {
ERR_raise_data(ERR_LIB_PROV, PROV_R_MISSING_MAC,
"cannot fetch blake2bmac");
return 0;
}
- ctx->md = EVP_MD_fetch(ctx->libctx, "blake2b512", ctx->propq);
+ if (ctx->md == NULL)
+ ctx->md = EVP_MD_fetch(ctx->libctx, "blake2b512", ctx->propq);
if (ctx->md == NULL) {
- EVP_MAC_free(ctx->mac);
ERR_raise_data(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST,
"canot fetch blake2b512");
return 0;
@@ -1040,15 +1040,16 @@ static int kdf_argon2_derive(void *vctx, unsigned char *out, size_t outlen,
if (ctx->salt == NULL || ctx->saltlen == 0) {
ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SALT);
- goto fail2;
+ return 0;
}
if (outlen != ctx->outlen) {
if (OSSL_PARAM_locate((OSSL_PARAM *)params, "size") != NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
- goto fail2;
+ return 0;
}
- kdf_argon2_ctx_set_out_length(ctx, (uint32_t) outlen);
+ if (!kdf_argon2_ctx_set_out_length(ctx, (uint32_t) outlen))
+ return 0;
}
switch (ctx->type) {
@@ -1058,7 +1059,7 @@ static int kdf_argon2_derive(void *vctx, unsigned char *out, size_t outlen,
break;
default:
ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_MODE, "invalid Argon2 type");
- goto fail2;
+ return 0;
}
if (ctx->threads > 1) {
@@ -1066,37 +1067,29 @@ static int kdf_argon2_derive(void *vctx, unsigned char *out, size_t outlen,
ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_THREAD_POOL_SIZE,
"requested %u threads, single-threaded mode supported only",
ctx->threads);
- goto fail2;
+ return 0;
# else
if (ctx->threads > ossl_get_avail_threads(ctx->libctx)) {
ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_THREAD_POOL_SIZE,
"requested %u threads, available: 1",
ossl_get_avail_threads(ctx->libctx));
- goto fail2;
+ return 0;
}
# endif
if (ctx->threads > ctx->lanes) {
ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_THREAD_POOL_SIZE,
"requested more threads (%u) than lanes (%u)",
ctx->threads, ctx->lanes);
- goto fail2;
+ return 0;
}
}
if (ctx->m_cost < 8 * ctx->lanes) {
ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_MEMORY_SIZE,
"m_cost must be greater or equal than 8 times the number of lanes");
- goto fail2;
+ return 0;
}
- if (ctx->type != ARGON2_D)
- ctx->out = OPENSSL_secure_zalloc(ctx->outlen + 1);
- else
- ctx->out = OPENSSL_zalloc(ctx->outlen + 1);
-
- if (ctx->out == NULL)
- goto fail2;
-
memory_blocks = ctx->m_cost;
if (memory_blocks < 2 * ARGON2_SYNC_POINTS * ctx->lanes)
memory_blocks = 2 * ARGON2_SYNC_POINTS * ctx->lanes;
@@ -1112,31 +1105,14 @@ static int kdf_argon2_derive(void *vctx, unsigned char *out, size_t outlen,
ctx->lane_length = segment_length * ARGON2_SYNC_POINTS;
if (initialize(ctx) != 1)
- goto fail3;
+ return 0;
if (fill_memory_blocks(ctx) != 1)
- goto fail3;
-
- finalize(ctx);
- memcpy(out, ctx->out, outlen);
+ return 0;
- EVP_MAC_free(ctx->mac);
- EVP_MD_free(ctx->md);
+ finalize(ctx, out);
return 1;
-
-fail3:
- if (ctx->type != ARGON2_D)
- OPENSSL_secure_clear_free(ctx->out, ctx->outlen + 1);
- else
- OPENSSL_clear_free(ctx->out, ctx->outlen + 1);
- ctx->out = NULL;
-
-fail2:
- EVP_MD_free(ctx->md);
- EVP_MAC_free(ctx->mac);
-
- return 0;
}
static void kdf_argon2_reset(void *vctx)
@@ -1149,8 +1125,10 @@ static void kdf_argon2_reset(void *vctx)
type = ctx->type;
libctx = ctx->libctx;
- if (ctx->out != NULL)
- OPENSSL_clear_free(ctx->out, ctx->outlen);
+ EVP_MD_free(ctx->md);
+ EVP_MAC_free(ctx->mac);
+
+ OPENSSL_free(ctx->propq);
if (ctx->pwd != NULL)
OPENSSL_clear_free(ctx->pwd, ctx->pwdlen);
@@ -1408,6 +1386,10 @@ static int set_property_query(KDF_ARGON2 *ctx, const char *propq)
if (ctx->propq == NULL)
return 0;
}
+ EVP_MD_free(ctx->md);
+ ctx->md = NULL;
+ EVP_MAC_free(ctx->mac);
+ ctx->mac = NULL;
return 1;
}