/*
- * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
#include "prov/implementations.h"
#include "prov/provider_util.h"
#include "internal/e_os.h"
+#include "internal/params.h"
#define HKDF_MAXBUF 2048
+#define HKDF_MAXINFO (32*1024)
static OSSL_FUNC_kdf_newctx_fn kdf_hkdf_new;
static OSSL_FUNC_kdf_dupctx_fn kdf_hkdf_dup;
size_t label_len;
unsigned char *data;
size_t data_len;
- unsigned char info[HKDF_MAXBUF];
+ unsigned char *info;
size_t info_len;
} KDF_HKDF;
if (!ossl_prov_is_running())
return NULL;
- if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL)
- ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
- else
+ if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) != NULL)
ctx->provctx = provctx;
return ctx;
}
void *provctx = ctx->provctx;
ossl_prov_digest_reset(&ctx->digest);
+#ifdef FIPS_MODULE
+ OPENSSL_clear_free(ctx->salt, ctx->salt_len);
+#else
OPENSSL_free(ctx->salt);
+#endif
OPENSSL_free(ctx->prefix);
OPENSSL_free(ctx->label);
OPENSSL_clear_free(ctx->data, ctx->data_len);
OPENSSL_clear_free(ctx->key, ctx->key_len);
- OPENSSL_cleanse(ctx->info, ctx->info_len);
+ OPENSSL_clear_free(ctx->info, ctx->info_len);
memset(ctx, 0, sizeof(*ctx));
ctx->provctx = provctx;
}
&dest->label, &dest->label_len)
|| !ossl_prov_memdup(src->data, src->data_len,
&dest->data, &dest->data_len)
+ || !ossl_prov_memdup(src->info, src->info_len,
+ &dest->info, &dest->info_len)
|| !ossl_prov_digest_copy(&dest->digest, &src->digest))
goto err;
- memcpy(dest->info, src->info, sizeof(dest->info));
- dest->info_len = src->info_len;
dest->mode = src->mode;
}
return dest;
static int kdf_hkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
{
- const OSSL_PARAM *p;
KDF_HKDF *ctx = vctx;
if (params == NULL)
if (!hkdf_common_set_ctx_params(ctx, params))
return 0;
- /* The info fields concatenate, so process them all */
- if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_INFO)) != NULL) {
- ctx->info_len = 0;
- for (; p != NULL; p = OSSL_PARAM_locate_const(p + 1,
- OSSL_KDF_PARAM_INFO)) {
- const void *q = ctx->info + ctx->info_len;
- size_t sz = 0;
-
- if (p->data_size != 0
- && p->data != NULL
- && !OSSL_PARAM_get_octet_string(p, (void **)&q,
- HKDF_MAXBUF - ctx->info_len,
- &sz))
- return 0;
- ctx->info_len += sz;
- }
- }
+ if (ossl_param_get1_concat_octet_string(params, OSSL_KDF_PARAM_INFO,
+ &ctx->info, &ctx->info_len,
+ HKDF_MAXINFO) == 0)
+ return 0;
+
return 1;
}
return 0;
return OSSL_PARAM_set_size_t(p, sz);
}
+ if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_INFO)) != NULL) {
+ if (ctx->info == NULL || ctx->info_len == 0) {
+ p->return_size = 0;
+ return 1;
+ }
+ return OSSL_PARAM_set_octet_string(p, ctx->info, ctx->info_len);
+ }
return -2;
}
{
static const OSSL_PARAM known_gettable_ctx_params[] = {
OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
+ OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0),
OSSL_PARAM_END
};
return known_gettable_ctx_params;
{ OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
(void(*)(void))kdf_hkdf_gettable_ctx_params },
{ OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_hkdf_get_ctx_params },
- { 0, NULL }
+ OSSL_DISPATCH_END
};
/*
if (!HMAC_Final(hmac, prev, NULL))
goto err;
- copy_len = (done_len + dig_len > okm_len) ?
+ copy_len = (dig_len > okm_len - done_len) ?
okm_len - done_len :
dig_len;
}
if (prevsecret == NULL) {
prevsecret = default_zeros;
- prevsecretlen = 0;
+ prevsecretlen = mdlen;
} else {
EVP_MD_CTX *mctx = EVP_MD_CTX_new();
unsigned char hash[EVP_MAX_MD_SIZE];
{ OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
(void(*)(void))kdf_hkdf_gettable_ctx_params },
{ OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_hkdf_get_ctx_params },
- { 0, NULL }
+ OSSL_DISPATCH_END
};