Skip to content

Commit 6a0ae39

Browse files
t8mmattcaswell
authored andcommitted
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 openssl#22488 Reviewed-by: Richard Levitte <[email protected]> Reviewed-by: Paul Dale <[email protected]> Reviewed-by: Tim Hudson <[email protected]> Reviewed-by: Matt Caswell <[email protected]> (Merged from openssl#22491)
1 parent c7ed5e4 commit 6a0ae39

File tree

9 files changed

+115
-24
lines changed

9 files changed

+115
-24
lines changed

crypto/evp/digest.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,15 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize)
454454
if (ctx->digest->prov == NULL)
455455
goto legacy;
456456

457+
if (ctx->digest->gettable_ctx_params != NULL) {
458+
OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
459+
460+
params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE,
461+
&mdsize);
462+
if (!EVP_MD_CTX_get_params(ctx, params))
463+
return 0;
464+
}
465+
457466
if (ctx->digest->dfinal == NULL) {
458467
ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR);
459468
return 0;

doc/man3/EVP_DigestInit.pod

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -282,9 +282,11 @@ data.
282282
Retrieves the digest value from I<ctx> and places it in I<md>. If the I<s>
283283
parameter is not NULL then the number of bytes of data written (i.e. the
284284
length of the digest) will be written to the integer at I<s>, at most
285-
B<EVP_MAX_MD_SIZE> bytes will be written. After calling EVP_DigestFinal_ex()
286-
no additional calls to EVP_DigestUpdate() can be made, but
287-
EVP_DigestInit_ex2() can be called to initialize a new digest operation.
285+
B<EVP_MAX_MD_SIZE> bytes will be written unless the digest implementation
286+
allows changing the digest size and it is set to a larger value by the
287+
application. After calling EVP_DigestFinal_ex() no additional calls to
288+
EVP_DigestUpdate() can be made, but EVP_DigestInit_ex2() can be called to
289+
initialize a new digest operation.
288290

289291
=item EVP_DigestFinalXOF()
290292

doc/man7/EVP_MD-BLAKE2.pod

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,21 @@ Known names are "BLAKE2B-512" and "BLAKE2b512".
3030
This implementation supports the common gettable parameters described
3131
in L<EVP_MD-common(7)>.
3232

33+
=head2 Settable Context Parameters
34+
35+
The BLAKE2B-512 implementation supports the following L<OSSL_PARAM(3)> entries,
36+
settable for an B<EVP_MD_CTX> with L<EVP_MD_CTX_set_params(3)>:
37+
38+
=over 4
39+
40+
=item "size" (B<OSSL_DIGEST_PARAM_SIZE>) <unsigned integer>
41+
42+
Sets a different digest length for the L<EVP_DigestFinal(3)> output.
43+
The value of the "size" parameter should not exceed 255 and it must be set
44+
during the L<EVP_DigestInit_ex2(3)> call.
45+
46+
=back
47+
3348
=head1 SEE ALSO
3449

3550
L<provider-digest(7)>, L<OSSL_PROVIDER-default(7)>

providers/implementations/digests/blake2_prov.c

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99

1010
#include <openssl/crypto.h>
11+
#include <openssl/proverr.h>
1112
#include "prov/blake2.h"
1213
#include "prov/digestcommon.h"
1314
#include "prov/implementations.h"
@@ -83,23 +84,32 @@ static int blake2b512_internal_final(void *ctx, unsigned char *out,
8384
size_t *outl, size_t outsz)
8485
{
8586
struct blake2b_md_data_st *b_ctx;
86-
87+
8788
b_ctx = (struct blake2b_md_data_st *)ctx;
88-
*outl = b_ctx->ctx.outlen;
8989

9090
if (!ossl_prov_is_running())
9191
return 0;
9292

93-
return (outsz > 0) ? ossl_blake2b_final(out, ctx) : 1;
93+
*outl = b_ctx->ctx.outlen;
94+
95+
if (outsz == 0)
96+
return 1;
97+
98+
if (outsz < *outl) {
99+
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_SIZE);
100+
return 0;
101+
}
102+
103+
return ossl_blake2b_final(out, ctx);
94104
}
95105

96106
static int blake2b512_get_params(OSSL_PARAM params[])
97107
{
98108
return ossl_digest_default_get_params(params, BLAKE2B_BLOCKBYTES, 64, 0);
99109
}
100110

101-
const OSSL_DISPATCH ossl_blake2b512_functions[] =
102-
{ {OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))blake2b512_newctx},
111+
const OSSL_DISPATCH ossl_blake2b512_functions[] = {
112+
{OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))blake2b512_newctx},
103113
{OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))ossl_blake2b_update},
104114
{OSSL_FUNC_DIGEST_FINAL, (void (*)(void))blake2b512_internal_final},
105115
{OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))blake2b512_freectx},
@@ -108,8 +118,13 @@ const OSSL_DISPATCH ossl_blake2b512_functions[] =
108118
{OSSL_FUNC_DIGEST_GETTABLE_PARAMS,
109119
(void (*)(void))ossl_digest_default_gettable_params},
110120
{OSSL_FUNC_DIGEST_INIT, (void (*)(void))blake2b512_internal_init},
121+
{OSSL_FUNC_DIGEST_GETTABLE_CTX_PARAMS,
122+
(void (*)(void))ossl_blake2b_gettable_ctx_params},
111123
{OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS,
112124
(void (*)(void))ossl_blake2b_settable_ctx_params},
125+
{OSSL_FUNC_DIGEST_GET_CTX_PARAMS,
126+
(void (*)(void))ossl_blake2b_get_ctx_params},
113127
{OSSL_FUNC_DIGEST_SET_CTX_PARAMS,
114-
(void (*)(void))ossl_blake2b_set_ctx_params}, {0, NULL} };
115-
128+
(void (*)(void))ossl_blake2b_set_ctx_params},
129+
{0, NULL}
130+
};

providers/implementations/digests/blake2b_prov.c

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,52 @@
2020
#include <openssl/core_names.h>
2121
#include <openssl/proverr.h>
2222
#include <openssl/err.h>
23+
#include "internal/numbers.h"
2324
#include "blake2_impl.h"
2425
#include "prov/blake2.h"
2526

26-
static const OSSL_PARAM known_blake2b_settable_ctx_params[] = {
27-
{OSSL_DIGEST_PARAM_XOFLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0},
27+
static const OSSL_PARAM known_blake2b_ctx_params[] = {
28+
{OSSL_DIGEST_PARAM_SIZE, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0},
2829
OSSL_PARAM_END
2930
};
3031

32+
const OSSL_PARAM *ossl_blake2b_gettable_ctx_params(ossl_unused void *ctx,
33+
ossl_unused void *pctx)
34+
{
35+
return known_blake2b_ctx_params;
36+
}
37+
3138
const OSSL_PARAM *ossl_blake2b_settable_ctx_params(ossl_unused void *ctx,
3239
ossl_unused void *pctx)
3340
{
34-
return known_blake2b_settable_ctx_params;
41+
return known_blake2b_ctx_params;
42+
}
43+
44+
int ossl_blake2b_get_ctx_params(void *vctx, OSSL_PARAM params[])
45+
{
46+
struct blake2b_md_data_st *mdctx = vctx;
47+
OSSL_PARAM *p;
48+
49+
BLAKE2B_CTX *ctx = &mdctx->ctx;
50+
51+
if (ctx == NULL)
52+
return 0;
53+
if (params == NULL)
54+
return 1;
55+
56+
p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_SIZE);
57+
if (p != NULL
58+
&& !OSSL_PARAM_set_uint(p, (unsigned int)mdctx->params.digest_length)) {
59+
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
60+
return 0;
61+
}
62+
63+
return 1;
3564
}
3665

3766
int ossl_blake2b_set_ctx_params(void *vctx, const OSSL_PARAM params[])
3867
{
39-
size_t xoflen;
68+
size_t size;
4069
struct blake2b_md_data_st *mdctx = vctx;
4170
const OSSL_PARAM *p;
4271

@@ -47,13 +76,17 @@ int ossl_blake2b_set_ctx_params(void *vctx, const OSSL_PARAM params[])
4776
if (params == NULL)
4877
return 1;
4978

50-
p = OSSL_PARAM_locate_const(params, OSSL_DIGEST_PARAM_XOFLEN);
79+
p = OSSL_PARAM_locate_const(params, OSSL_DIGEST_PARAM_SIZE);
5180
if (p != NULL) {
52-
if (!OSSL_PARAM_get_size_t(p, &xoflen)) {
81+
if (!OSSL_PARAM_get_size_t(p, &size)) {
5382
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
5483
return 0;
5584
}
56-
ossl_blake2b_param_set_digest_length(&mdctx->params, (uint8_t)xoflen);
85+
if (size < 1 || size > UINT8_MAX) {
86+
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_SIZE);
87+
return 0;
88+
}
89+
ossl_blake2b_param_set_digest_length(&mdctx->params, (uint8_t)size);
5790
}
5891

5992
return 1;

providers/implementations/include/prov/blake2.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,9 @@ int ossl_blake2b_init_key(BLAKE2B_CTX *c, const BLAKE2B_PARAM *P,
9494
int ossl_blake2b_update(BLAKE2B_CTX *c, const void *data, size_t datalen);
9595
int ossl_blake2b_final(unsigned char *md, BLAKE2B_CTX *c);
9696

97+
OSSL_FUNC_digest_get_ctx_params_fn ossl_blake2b_get_ctx_params;
9798
OSSL_FUNC_digest_set_ctx_params_fn ossl_blake2b_set_ctx_params;
99+
OSSL_FUNC_digest_gettable_ctx_params_fn ossl_blake2b_gettable_ctx_params;
98100
OSSL_FUNC_digest_settable_ctx_params_fn ossl_blake2b_settable_ctx_params;
99101

100102
/*

providers/implementations/kdfs/argon2.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -823,12 +823,12 @@ static int blake2b_md(EVP_MD *md, void *out, size_t outlen, const void *in,
823823
if ((ctx = EVP_MD_CTX_create()) == NULL)
824824
return 0;
825825

826-
par[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &outlen);
826+
par[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE, &outlen);
827827
par[1] = OSSL_PARAM_construct_end();
828828

829829
ret = EVP_DigestInit_ex2(ctx, md, par) == 1
830830
&& EVP_DigestUpdate(ctx, in, inlen) == 1
831-
&& EVP_DigestFinalXOF(ctx, out, outlen) == 1;
831+
&& EVP_DigestFinal_ex(ctx, out, NULL) == 1;
832832

833833
EVP_MD_CTX_free(ctx);
834834
return ret;
@@ -868,14 +868,14 @@ static int blake2b_long(EVP_MD *md, EVP_MAC *mac, unsigned char *out,
868868
return 0;
869869

870870
outlen_md = (outlen <= BLAKE2B_OUTBYTES) ? outlen : BLAKE2B_OUTBYTES;
871-
par[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &outlen_md);
871+
par[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE, &outlen_md);
872872
par[1] = OSSL_PARAM_construct_end();
873873

874874
ret = EVP_DigestInit_ex2(ctx, md, par) == 1
875875
&& EVP_DigestUpdate(ctx, outlen_bytes, sizeof(outlen_bytes)) == 1
876876
&& EVP_DigestUpdate(ctx, in, inlen) == 1
877-
&& EVP_DigestFinalXOF(ctx, (outlen > BLAKE2B_OUTBYTES) ? outbuf : out,
878-
outlen_md) == 1;
877+
&& EVP_DigestFinal_ex(ctx, (outlen > BLAKE2B_OUTBYTES) ? outbuf : out,
878+
NULL) == 1;
879879

880880
if (ret == 0)
881881
goto fail;

test/evp_test.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,8 @@ typedef struct digest_data_st {
355355
int pad_type;
356356
/* XOF mode? */
357357
int xof;
358+
/* Size for variable output length but non-XOF */
359+
size_t digest_size;
358360
} DIGEST_DATA;
359361

360362
static int digest_test_init(EVP_TEST *t, const char *alg)
@@ -410,6 +412,15 @@ static int digest_test_parse(EVP_TEST *t,
410412
return (mdata->pad_type = atoi(value)) > 0;
411413
if (strcmp(keyword, "XOF") == 0)
412414
return (mdata->xof = atoi(value)) > 0;
415+
if (strcmp(keyword, "OutputSize") == 0) {
416+
int sz;
417+
418+
sz = atoi(value);
419+
if (sz < 0)
420+
return -1;
421+
mdata->digest_size = sz;
422+
return 1;
423+
}
413424
return 0;
414425
}
415426

@@ -463,6 +474,10 @@ static int digest_test_run(EVP_TEST *t)
463474
*p++ = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN,
464475
&expected->output_len);
465476
}
477+
if (expected->digest_size > 0) {
478+
*p++ = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE,
479+
&expected->digest_size);
480+
}
466481
if (expected->pad_type > 0)
467482
*p++ = OSSL_PARAM_construct_int(OSSL_DIGEST_PARAM_PAD_TYPE,
468483
&expected->pad_type);

test/recipes/30-test_evp_data/evpmd_blake.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,10 @@ Output = DF0A9D0C212843A6A934E3902B2DD30D17FBA5F969D2030B12A546D8A6A45E80CF5635F
9292

9393
Digest = BLAKE2b512
9494
Input =
95-
XOF = 1
95+
OutputSize = 32
9696
Output = 0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8
9797

9898
Digest = BLAKE2b512
9999
Input = 61
100-
XOF = 1
100+
OutputSize = 32
101101
Output = 8928aae63c84d87ea098564d1e03ad813f107add474e56aedd286349c0c03ea4

0 commit comments

Comments
 (0)