summaryrefslogtreecommitdiff
path: root/providers
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 /providers
parent0e1b7c816dcfa4655f443ae5dd8eea4fb42f3493 (diff)
downloadopenssl-new-a901b31e99442f087051ae7efdcbc9ad6e6a5b33.tar.gz
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)
Diffstat (limited to 'providers')
-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;
}