提交 6a0ae393 编写于 作者: T Tomas Mraz 提交者: Matt Caswell

Blake2b: Use OSSL_DIGEST_PARAM_SIZE as settable instead of XOFLEN

BLAKE2 is not really an extensible output function unlike SHAKE
as the digest size must be set during the context initialization.
Thus it makes no sense to use OSSL_DIGEST_PARAM_XOFLEN.

We also need to adjust EVP_DigestFinal_ex() to query the
OSSL_DIGEST_PARAM_SIZE as gettable ctx param for the size.

Fixes #22488
Reviewed-by: NRichard Levitte <levitte@openssl.org>
Reviewed-by: NPaul Dale <pauli@openssl.org>
Reviewed-by: NTim Hudson <tjh@openssl.org>
Reviewed-by: NMatt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22491)
上级 c7ed5e46
......@@ -454,6 +454,15 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize)
if (ctx->digest->prov == NULL)
goto legacy;
if (ctx->digest->gettable_ctx_params != NULL) {
OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE,
&mdsize);
if (!EVP_MD_CTX_get_params(ctx, params))
return 0;
}
if (ctx->digest->dfinal == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR);
return 0;
......
......@@ -282,9 +282,11 @@ data.
Retrieves the digest value from I<ctx> and places it in I<md>. If the I<s>
parameter is not NULL then the number of bytes of data written (i.e. the
length of the digest) will be written to the integer at I<s>, at most
B<EVP_MAX_MD_SIZE> bytes will be written. After calling EVP_DigestFinal_ex()
no additional calls to EVP_DigestUpdate() can be made, but
EVP_DigestInit_ex2() can be called to initialize a new digest operation.
B<EVP_MAX_MD_SIZE> bytes will be written unless the digest implementation
allows changing the digest size and it is set to a larger value by the
application. After calling EVP_DigestFinal_ex() no additional calls to
EVP_DigestUpdate() can be made, but EVP_DigestInit_ex2() can be called to
initialize a new digest operation.
=item EVP_DigestFinalXOF()
......
......@@ -30,6 +30,21 @@ Known names are "BLAKE2B-512" and "BLAKE2b512".
This implementation supports the common gettable parameters described
in L<EVP_MD-common(7)>.
=head2 Settable Context Parameters
The BLAKE2B-512 implementation supports the following L<OSSL_PARAM(3)> entries,
settable for an B<EVP_MD_CTX> with L<EVP_MD_CTX_set_params(3)>:
=over 4
=item "size" (B<OSSL_DIGEST_PARAM_SIZE>) <unsigned integer>
Sets a different digest length for the L<EVP_DigestFinal(3)> output.
The value of the "size" parameter should not exceed 255 and it must be set
during the L<EVP_DigestInit_ex2(3)> call.
=back
=head1 SEE ALSO
L<provider-digest(7)>, L<OSSL_PROVIDER-default(7)>
......
......@@ -8,6 +8,7 @@
*/
#include <openssl/crypto.h>
#include <openssl/proverr.h>
#include "prov/blake2.h"
#include "prov/digestcommon.h"
#include "prov/implementations.h"
......@@ -83,14 +84,23 @@ static int blake2b512_internal_final(void *ctx, unsigned char *out,
size_t *outl, size_t outsz)
{
struct blake2b_md_data_st *b_ctx;
b_ctx = (struct blake2b_md_data_st *)ctx;
*outl = b_ctx->ctx.outlen;
if (!ossl_prov_is_running())
return 0;
return (outsz > 0) ? ossl_blake2b_final(out, ctx) : 1;
*outl = b_ctx->ctx.outlen;
if (outsz == 0)
return 1;
if (outsz < *outl) {
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_SIZE);
return 0;
}
return ossl_blake2b_final(out, ctx);
}
static int blake2b512_get_params(OSSL_PARAM params[])
......@@ -98,8 +108,8 @@ static int blake2b512_get_params(OSSL_PARAM params[])
return ossl_digest_default_get_params(params, BLAKE2B_BLOCKBYTES, 64, 0);
}
const OSSL_DISPATCH ossl_blake2b512_functions[] =
{ {OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))blake2b512_newctx},
const OSSL_DISPATCH ossl_blake2b512_functions[] = {
{OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))blake2b512_newctx},
{OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))ossl_blake2b_update},
{OSSL_FUNC_DIGEST_FINAL, (void (*)(void))blake2b512_internal_final},
{OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))blake2b512_freectx},
......@@ -108,8 +118,13 @@ const OSSL_DISPATCH ossl_blake2b512_functions[] =
{OSSL_FUNC_DIGEST_GETTABLE_PARAMS,
(void (*)(void))ossl_digest_default_gettable_params},
{OSSL_FUNC_DIGEST_INIT, (void (*)(void))blake2b512_internal_init},
{OSSL_FUNC_DIGEST_GETTABLE_CTX_PARAMS,
(void (*)(void))ossl_blake2b_gettable_ctx_params},
{OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS,
(void (*)(void))ossl_blake2b_settable_ctx_params},
{OSSL_FUNC_DIGEST_GET_CTX_PARAMS,
(void (*)(void))ossl_blake2b_get_ctx_params},
{OSSL_FUNC_DIGEST_SET_CTX_PARAMS,
(void (*)(void))ossl_blake2b_set_ctx_params}, {0, NULL} };
(void (*)(void))ossl_blake2b_set_ctx_params},
{0, NULL}
};
......@@ -20,23 +20,52 @@
#include <openssl/core_names.h>
#include <openssl/proverr.h>
#include <openssl/err.h>
#include "internal/numbers.h"
#include "blake2_impl.h"
#include "prov/blake2.h"
static const OSSL_PARAM known_blake2b_settable_ctx_params[] = {
{OSSL_DIGEST_PARAM_XOFLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0},
static const OSSL_PARAM known_blake2b_ctx_params[] = {
{OSSL_DIGEST_PARAM_SIZE, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0},
OSSL_PARAM_END
};
const OSSL_PARAM *ossl_blake2b_gettable_ctx_params(ossl_unused void *ctx,
ossl_unused void *pctx)
{
return known_blake2b_ctx_params;
}
const OSSL_PARAM *ossl_blake2b_settable_ctx_params(ossl_unused void *ctx,
ossl_unused void *pctx)
{
return known_blake2b_settable_ctx_params;
return known_blake2b_ctx_params;
}
int ossl_blake2b_get_ctx_params(void *vctx, OSSL_PARAM params[])
{
struct blake2b_md_data_st *mdctx = vctx;
OSSL_PARAM *p;
BLAKE2B_CTX *ctx = &mdctx->ctx;
if (ctx == NULL)
return 0;
if (params == NULL)
return 1;
p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_SIZE);
if (p != NULL
&& !OSSL_PARAM_set_uint(p, (unsigned int)mdctx->params.digest_length)) {
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return 0;
}
return 1;
}
int ossl_blake2b_set_ctx_params(void *vctx, const OSSL_PARAM params[])
{
size_t xoflen;
size_t size;
struct blake2b_md_data_st *mdctx = vctx;
const OSSL_PARAM *p;
......@@ -47,13 +76,17 @@ int ossl_blake2b_set_ctx_params(void *vctx, const OSSL_PARAM params[])
if (params == NULL)
return 1;
p = OSSL_PARAM_locate_const(params, OSSL_DIGEST_PARAM_XOFLEN);
p = OSSL_PARAM_locate_const(params, OSSL_DIGEST_PARAM_SIZE);
if (p != NULL) {
if (!OSSL_PARAM_get_size_t(p, &xoflen)) {
if (!OSSL_PARAM_get_size_t(p, &size)) {
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
return 0;
}
ossl_blake2b_param_set_digest_length(&mdctx->params, (uint8_t)xoflen);
if (size < 1 || size > UINT8_MAX) {
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_SIZE);
return 0;
}
ossl_blake2b_param_set_digest_length(&mdctx->params, (uint8_t)size);
}
return 1;
......
......@@ -94,7 +94,9 @@ int ossl_blake2b_init_key(BLAKE2B_CTX *c, const BLAKE2B_PARAM *P,
int ossl_blake2b_update(BLAKE2B_CTX *c, const void *data, size_t datalen);
int ossl_blake2b_final(unsigned char *md, BLAKE2B_CTX *c);
OSSL_FUNC_digest_get_ctx_params_fn ossl_blake2b_get_ctx_params;
OSSL_FUNC_digest_set_ctx_params_fn ossl_blake2b_set_ctx_params;
OSSL_FUNC_digest_gettable_ctx_params_fn ossl_blake2b_gettable_ctx_params;
OSSL_FUNC_digest_settable_ctx_params_fn ossl_blake2b_settable_ctx_params;
/*
......
......@@ -823,12 +823,12 @@ static int blake2b_md(EVP_MD *md, void *out, size_t outlen, const void *in,
if ((ctx = EVP_MD_CTX_create()) == NULL)
return 0;
par[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &outlen);
par[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE, &outlen);
par[1] = OSSL_PARAM_construct_end();
ret = EVP_DigestInit_ex2(ctx, md, par) == 1
&& EVP_DigestUpdate(ctx, in, inlen) == 1
&& EVP_DigestFinalXOF(ctx, out, outlen) == 1;
&& EVP_DigestFinal_ex(ctx, out, NULL) == 1;
EVP_MD_CTX_free(ctx);
return ret;
......@@ -868,14 +868,14 @@ static int blake2b_long(EVP_MD *md, EVP_MAC *mac, unsigned char *out,
return 0;
outlen_md = (outlen <= BLAKE2B_OUTBYTES) ? outlen : BLAKE2B_OUTBYTES;
par[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &outlen_md);
par[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE, &outlen_md);
par[1] = OSSL_PARAM_construct_end();
ret = EVP_DigestInit_ex2(ctx, md, par) == 1
&& EVP_DigestUpdate(ctx, outlen_bytes, sizeof(outlen_bytes)) == 1
&& EVP_DigestUpdate(ctx, in, inlen) == 1
&& EVP_DigestFinalXOF(ctx, (outlen > BLAKE2B_OUTBYTES) ? outbuf : out,
outlen_md) == 1;
&& EVP_DigestFinal_ex(ctx, (outlen > BLAKE2B_OUTBYTES) ? outbuf : out,
NULL) == 1;
if (ret == 0)
goto fail;
......
......@@ -355,6 +355,8 @@ typedef struct digest_data_st {
int pad_type;
/* XOF mode? */
int xof;
/* Size for variable output length but non-XOF */
size_t digest_size;
} DIGEST_DATA;
static int digest_test_init(EVP_TEST *t, const char *alg)
......@@ -410,6 +412,15 @@ static int digest_test_parse(EVP_TEST *t,
return (mdata->pad_type = atoi(value)) > 0;
if (strcmp(keyword, "XOF") == 0)
return (mdata->xof = atoi(value)) > 0;
if (strcmp(keyword, "OutputSize") == 0) {
int sz;
sz = atoi(value);
if (sz < 0)
return -1;
mdata->digest_size = sz;
return 1;
}
return 0;
}
......@@ -463,6 +474,10 @@ static int digest_test_run(EVP_TEST *t)
*p++ = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN,
&expected->output_len);
}
if (expected->digest_size > 0) {
*p++ = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE,
&expected->digest_size);
}
if (expected->pad_type > 0)
*p++ = OSSL_PARAM_construct_int(OSSL_DIGEST_PARAM_PAD_TYPE,
&expected->pad_type);
......
......@@ -92,10 +92,10 @@ Output = DF0A9D0C212843A6A934E3902B2DD30D17FBA5F969D2030B12A546D8A6A45E80CF5635F
Digest = BLAKE2b512
Input =
XOF = 1
OutputSize = 32
Output = 0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8
Digest = BLAKE2b512
Input = 61
XOF = 1
OutputSize = 32
Output = 8928aae63c84d87ea098564d1e03ad813f107add474e56aedd286349c0c03ea4
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册