/*
- * Copyright 2016-2022 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)
return 1;
}
-/*
- * Use WPACKET to concat one or more OSSL_KDF_PARAM_INFO fields into a fixed
- * out buffer of size *outlen.
- * If out is NULL then outlen is used to return the required buffer size.
- */
-static int setinfo_fromparams(const OSSL_PARAM *p, unsigned char *out, size_t *outlen)
-{
- int ret = 0;
- WPACKET pkt;
-
- if (out == NULL) {
- if (!WPACKET_init_null(&pkt, 0))
- return 0;
- } else {
- if (!WPACKET_init_static_len(&pkt, out, *outlen, 0))
- return 0;
- }
-
- for (; p != NULL; p = OSSL_PARAM_locate_const(p + 1, OSSL_KDF_PARAM_INFO)) {
- if (p->data_type != OSSL_PARAM_OCTET_STRING)
- goto err;
- if (p->data != NULL
- && p->data_size != 0
- && !WPACKET_memcpy(&pkt, p->data, p->data_size))
- goto err;
- }
- if (!WPACKET_get_total_written(&pkt, outlen)
- || !WPACKET_finish(&pkt))
- goto err;
- ret = 1;
-err:
- WPACKET_cleanup(&pkt);
- return ret;
-}
-
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) {
- size_t sz = 0;
-
- /* calculate the total size */
- if (!setinfo_fromparams(p, NULL, &sz))
- return 0;
- if (sz > HKDF_MAXINFO)
- return 0;
+ if (ossl_param_get1_concat_octet_string(params, OSSL_KDF_PARAM_INFO,
+ &ctx->info, &ctx->info_len,
+ HKDF_MAXINFO) == 0)
+ return 0;
- OPENSSL_clear_free(ctx->info, ctx->info_len);
- ctx->info = NULL;
- if (sz == 0)
- return 1;
- /* Alloc the buffer */
- ctx->info = OPENSSL_malloc(sz);
- if (ctx->info == NULL)
- return 0;
- ctx->info_len = sz;
- /* Concat one or more OSSL_KDF_PARAM_INFO fields */
- if (!setinfo_fromparams(p, ctx->info, &sz))
- 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
};