test-rand: return failure on not enough data, allow parent

The test-rand RNG was returning success when it had some but insufficient data.
Now, it returns failure and doesn't advance the data pointer.

The test-rand RNG was failing when a parent was specified.  This case is now
ignored.

Fixes #16785

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/16905)
This commit is contained in:
Pauli 2021-10-25 12:01:11 +10:00
parent e2e3f84fa5
commit d4dfd983e3
5 changed files with 68 additions and 16 deletions

View File

@ -52,9 +52,8 @@ they can all be set as well as read.
=item "test_entropy" (B<OSSL_RAND_PARAM_TEST_ENTROPY>) <octet string>
Sets the bytes returned when the test generator is sent an entropy request.
When entropy is requested, these bytes are treated as a cyclic buffer and they
are repeated as required. The current position is remembered across generate
calls.
The current position is remembered across generate calls.
If there are insufficient data present to satisfy a call, an error is returned.
=item "test_nonce" (B<OSSL_RAND_PARAM_TEST_NONCE>) <octet string>

View File

@ -52,9 +52,6 @@ static void *test_rng_new(void *provctx, void *parent,
{
PROV_TEST_RNG *t;
if (parent != NULL)
return NULL;
t = OPENSSL_zalloc(sizeof(*t));
if (t == NULL)
return NULL;
@ -107,16 +104,11 @@ static int test_rng_generate(void *vtest, unsigned char *out, size_t outlen,
const unsigned char *adin, size_t adin_len)
{
PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;
size_t i;
if (strength > t->strength)
if (strength > t->strength || t->entropy_len - t->entropy_pos < outlen)
return 0;
for (i = 0; i < outlen; i++) {
out[i] = t->entropy[t->entropy_pos++];
if (t->entropy_pos >= t->entropy_len)
break;
}
memcpy(out, t->entropy + t->entropy_pos, outlen);
t->entropy_pos += outlen;
return 1;
}

View File

@ -62,7 +62,7 @@ IF[{- !$disabled{tests} -}]
context_internal_test aesgcmtest params_test evp_pkey_dparams_test \
keymgmt_internal_test hexstr_test provider_status_test defltfips_test \
bio_readbuffer_test user_property_test pkcs7_test upcallstest \
provfetchtest prov_config_test
provfetchtest prov_config_test rand_test
IF[{- !$disabled{'deprecated-3.0'} -}]
PROGRAMS{noinst}=enginetest
@ -84,6 +84,10 @@ IF[{- !$disabled{tests} -}]
INCLUDE[sanitytest]=../include ../apps/include
DEPEND[sanitytest]=../libcrypto libtestutil.a
SOURCE[rand_test]=rand_test.c
INCLUDE[rand_test]=../include ../apps/include
DEPEND[rand_test]=../libcrypto libtestutil.a
SOURCE[rsa_complex]=rsa_complex.c
INCLUDE[rsa_complex]=../include ../apps/include

56
test/rand_test.c Normal file
View File

@ -0,0 +1,56 @@
/*
* Copyright 2021 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
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/bio.h>
#include <openssl/core_names.h>
#include "testutil.h"
static int test_rand(void)
{
EVP_RAND_CTX *privctx;
OSSL_PARAM params[2], *p = params;
unsigned char entropy1[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
unsigned char entropy2[] = { 0xff, 0xfe, 0xfd };
unsigned char outbuf[3];
if (!TEST_ptr(privctx = RAND_get0_private(NULL)))
return 0;
*p++ = OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY,
entropy1, sizeof(entropy1));
*p = OSSL_PARAM_construct_end();
if (!TEST_ptr(privctx = RAND_get0_private(NULL))
|| !TEST_true(EVP_RAND_CTX_set_params(privctx, params))
|| !TEST_int_gt(RAND_priv_bytes(outbuf, sizeof(outbuf)), 0)
|| !TEST_mem_eq(outbuf, sizeof(outbuf), entropy1, sizeof(outbuf))
|| !TEST_int_le(RAND_priv_bytes(outbuf, sizeof(outbuf) + 1), 0)
|| !TEST_int_gt(RAND_priv_bytes(outbuf, sizeof(outbuf)), 0)
|| !TEST_mem_eq(outbuf, sizeof(outbuf),
entropy1 + sizeof(outbuf), sizeof(outbuf)))
return 0;
*params = OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY,
entropy2, sizeof(entropy2));
if (!TEST_true(EVP_RAND_CTX_set_params(privctx, params))
|| !TEST_int_gt(RAND_priv_bytes(outbuf, sizeof(outbuf)), 0)
|| !TEST_mem_eq(outbuf, sizeof(outbuf), entropy2, sizeof(outbuf)))
return 0;
return 1;
}
int setup_tests(void)
{
if (!TEST_true(RAND_set_DRBG_type(NULL, "TEST-RAND", NULL, NULL, NULL)))
return 0;
ADD_TEST(test_rand);
return 1;
}

View File

@ -11,8 +11,9 @@ use warnings;
use OpenSSL::Test;
use OpenSSL::Test::Utils;
plan tests => 2;
plan tests => 3;
setup("test_rand");
ok(run(test(["rand_test"])));
ok(run(test(["drbgtest"])));
ok(run(test(["rand_status_test"])));