drbg: Implemented NIST SP-800-90A DRBG
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2013-2014 Tobias Brunner
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Copyright (C) 2016 Andreas Steffen
|
||||
* Copyright (C) 2016-2019 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -53,6 +53,7 @@ struct entry_t {
|
||||
hasher_constructor_t create_hasher;
|
||||
prf_constructor_t create_prf;
|
||||
xof_constructor_t create_xof;
|
||||
drbg_constructor_t create_drbg;
|
||||
rng_constructor_t create_rng;
|
||||
nonce_gen_constructor_t create_nonce_gen;
|
||||
dh_constructor_t create_dh;
|
||||
@@ -102,6 +103,11 @@ struct private_crypto_factory_t {
|
||||
*/
|
||||
linked_list_t *xofs;
|
||||
|
||||
/**
|
||||
* registered drbgs, as entry_t
|
||||
*/
|
||||
linked_list_t *drbgs;
|
||||
|
||||
/**
|
||||
* registered rngs, as entry_t
|
||||
*/
|
||||
@@ -342,6 +348,40 @@ METHOD(crypto_factory_t, create_xof, xof_t*,
|
||||
return xof;
|
||||
}
|
||||
|
||||
METHOD(crypto_factory_t, create_drbg, drbg_t*,
|
||||
private_crypto_factory_t *this, drbg_type_t type, uint32_t strength,
|
||||
rng_t *entropy, chunk_t personalization_str)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
entry_t *entry;
|
||||
drbg_t *drbg = NULL;
|
||||
|
||||
this->lock->read_lock(this->lock);
|
||||
enumerator = this->drbgs->create_enumerator(this->drbgs);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (entry->algo == type)
|
||||
{
|
||||
if (this->test_on_create &&
|
||||
!this->tester->test_drbg(this->tester, type,
|
||||
entry->create_drbg, NULL,
|
||||
default_plugin_name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
drbg = entry->create_drbg(type, strength, entropy,
|
||||
personalization_str);
|
||||
if (drbg)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->lock->unlock(this->lock);
|
||||
return drbg;
|
||||
}
|
||||
|
||||
METHOD(crypto_factory_t, create_rng, rng_t*,
|
||||
private_crypto_factory_t *this, rng_quality_t quality)
|
||||
{
|
||||
@@ -709,6 +749,43 @@ METHOD(crypto_factory_t, remove_xof, void,
|
||||
this->lock->unlock(this->lock);
|
||||
}
|
||||
|
||||
METHOD(crypto_factory_t, add_drbg, bool,
|
||||
private_crypto_factory_t *this, drbg_type_t type,
|
||||
const char *plugin_name, drbg_constructor_t create)
|
||||
{
|
||||
u_int speed = 0;
|
||||
|
||||
if (!this->test_on_add ||
|
||||
this->tester->test_drbg(this->tester, type, create,
|
||||
this->bench ? &speed : NULL, plugin_name))
|
||||
{
|
||||
add_entry(this, this->drbgs, type, plugin_name, speed, create);
|
||||
return TRUE;
|
||||
}
|
||||
this->test_failures++;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(crypto_factory_t, remove_drbg, void,
|
||||
private_crypto_factory_t *this, drbg_constructor_t create)
|
||||
{
|
||||
entry_t *entry;
|
||||
enumerator_t *enumerator;
|
||||
|
||||
this->lock->write_lock(this->lock);
|
||||
enumerator = this->drbgs->create_enumerator(this->drbgs);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (entry->create_drbg == create)
|
||||
{
|
||||
this->drbgs->remove_at(this->drbgs, enumerator);
|
||||
free(entry);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->lock->unlock(this->lock);
|
||||
}
|
||||
|
||||
METHOD(crypto_factory_t, add_rng, bool,
|
||||
private_crypto_factory_t *this, rng_quality_t quality,
|
||||
const char *plugin_name, rng_constructor_t create)
|
||||
@@ -981,6 +1058,30 @@ METHOD(crypto_factory_t, create_xof_enumerator, enumerator_t*,
|
||||
return create_enumerator(this, this->xofs, xof_filter);
|
||||
}
|
||||
|
||||
CALLBACK(drbg_filter, bool,
|
||||
void *n, enumerator_t *orig, va_list args)
|
||||
{
|
||||
entry_t *entry;
|
||||
drbg_type_t *type;
|
||||
const char **plugin_name;
|
||||
|
||||
VA_ARGS_VGET(args, type, plugin_name);
|
||||
|
||||
if (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*type = entry->algo;
|
||||
*plugin_name = entry->plugin_name;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(crypto_factory_t, create_drbg_enumerator, enumerator_t*,
|
||||
private_crypto_factory_t *this)
|
||||
{
|
||||
return create_enumerator(this, this->drbgs, drbg_filter);
|
||||
}
|
||||
|
||||
CALLBACK(dh_filter, bool,
|
||||
void *n, enumerator_t *orig, va_list args)
|
||||
{
|
||||
@@ -1068,6 +1169,8 @@ METHOD(crypto_factory_t, add_test_vector, void,
|
||||
return this->tester->add_prf_vector(this->tester, vector);
|
||||
case EXTENDED_OUTPUT_FUNCTION:
|
||||
return this->tester->add_xof_vector(this->tester, vector);
|
||||
case DETERMINISTIC_RANDOM_BIT_GENERATOR:
|
||||
return this->tester->add_drbg_vector(this->tester, vector);
|
||||
case RANDOM_NUMBER_GENERATOR:
|
||||
return this->tester->add_rng_vector(this->tester, vector);
|
||||
case DIFFIE_HELLMAN_GROUP:
|
||||
@@ -1129,6 +1232,10 @@ METHOD(enumerator_t, verify_enumerate, bool,
|
||||
*valid = this->tester->test_xof(this->tester, entry->algo,
|
||||
entry->create_xof, NULL, entry->plugin_name);
|
||||
break;
|
||||
case DETERMINISTIC_RANDOM_BIT_GENERATOR:
|
||||
*valid = this->tester->test_drbg(this->tester, entry->algo,
|
||||
entry->create_drbg, NULL, entry->plugin_name);
|
||||
break;
|
||||
case RANDOM_NUMBER_GENERATOR:
|
||||
*valid = this->tester->test_rng(this->tester, entry->algo,
|
||||
entry->create_rng, NULL, entry->plugin_name);
|
||||
@@ -1180,6 +1287,9 @@ METHOD(crypto_factory_t, create_verify_enumerator, enumerator_t*,
|
||||
case EXTENDED_OUTPUT_FUNCTION:
|
||||
inner = this->xofs->create_enumerator(this->xofs);
|
||||
break;
|
||||
case DETERMINISTIC_RANDOM_BIT_GENERATOR:
|
||||
inner = this->drbgs->create_enumerator(this->drbgs);
|
||||
break;
|
||||
case RANDOM_NUMBER_GENERATOR:
|
||||
inner = this->rngs->create_enumerator(this->rngs);
|
||||
break;
|
||||
@@ -1213,6 +1323,7 @@ METHOD(crypto_factory_t, destroy, void,
|
||||
this->hashers->destroy(this->hashers);
|
||||
this->prfs->destroy(this->prfs);
|
||||
this->xofs->destroy(this->xofs);
|
||||
this->drbgs->destroy(this->drbgs);
|
||||
this->rngs->destroy(this->rngs);
|
||||
this->nonce_gens->destroy(this->nonce_gens);
|
||||
this->dhs->destroy(this->dhs);
|
||||
@@ -1236,6 +1347,7 @@ crypto_factory_t *crypto_factory_create()
|
||||
.create_hasher = _create_hasher,
|
||||
.create_prf = _create_prf,
|
||||
.create_xof = _create_xof,
|
||||
.create_drbg = _create_drbg,
|
||||
.create_rng = _create_rng,
|
||||
.create_nonce_gen = _create_nonce_gen,
|
||||
.create_dh = _create_dh,
|
||||
@@ -1251,6 +1363,8 @@ crypto_factory_t *crypto_factory_create()
|
||||
.remove_prf = _remove_prf,
|
||||
.add_xof = _add_xof,
|
||||
.remove_xof = _remove_xof,
|
||||
.add_drbg = _add_drbg,
|
||||
.remove_drbg = _remove_drbg,
|
||||
.add_rng = _add_rng,
|
||||
.remove_rng = _remove_rng,
|
||||
.add_nonce_gen = _add_nonce_gen,
|
||||
@@ -1263,6 +1377,7 @@ crypto_factory_t *crypto_factory_create()
|
||||
.create_hasher_enumerator = _create_hasher_enumerator,
|
||||
.create_prf_enumerator = _create_prf_enumerator,
|
||||
.create_xof_enumerator = _create_xof_enumerator,
|
||||
.create_drbg_enumerator = _create_drbg_enumerator,
|
||||
.create_dh_enumerator = _create_dh_enumerator,
|
||||
.create_rng_enumerator = _create_rng_enumerator,
|
||||
.create_nonce_gen_enumerator = _create_nonce_gen_enumerator,
|
||||
@@ -1276,6 +1391,7 @@ crypto_factory_t *crypto_factory_create()
|
||||
.hashers = linked_list_create(),
|
||||
.prfs = linked_list_create(),
|
||||
.xofs = linked_list_create(),
|
||||
.drbgs = linked_list_create(),
|
||||
.rngs = linked_list_create(),
|
||||
.nonce_gens = linked_list_create(),
|
||||
.dhs = linked_list_create(),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Copyright (C) 2016 Andreas Steffen
|
||||
* Copyright (C) 2016-2019 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -33,6 +33,7 @@ typedef struct crypto_factory_t crypto_factory_t;
|
||||
#include <crypto/prfs/prf.h>
|
||||
#include <crypto/rngs/rng.h>
|
||||
#include <crypto/xofs/xof.h>
|
||||
#include <crypto/drbgs/drbg.h>
|
||||
#include <crypto/nonce_gen.h>
|
||||
#include <crypto/diffie_hellman.h>
|
||||
#include <crypto/transform.h>
|
||||
@@ -65,10 +66,16 @@ typedef hasher_t* (*hasher_constructor_t)(hash_algorithm_t algo);
|
||||
typedef prf_t* (*prf_constructor_t)(pseudo_random_function_t algo);
|
||||
|
||||
/**
|
||||
* Constructor function for pseudo random functions
|
||||
* Constructor function for extended output functions
|
||||
*/
|
||||
typedef xof_t* (*xof_constructor_t)(ext_out_function_t algo);
|
||||
|
||||
/**
|
||||
* Constructor function for deterministic random bit generators
|
||||
*/
|
||||
typedef drbg_t* (*drbg_constructor_t)(drbg_type_t type, uint32_t strength,
|
||||
rng_t *entropy, chunk_t personalization_str);
|
||||
|
||||
/**
|
||||
* Constructor function for source of randomness
|
||||
*/
|
||||
@@ -147,6 +154,19 @@ struct crypto_factory_t {
|
||||
*/
|
||||
xof_t* (*create_xof)(crypto_factory_t *this, ext_out_function_t algo);
|
||||
|
||||
/**
|
||||
* Create a deterministic random bit generator instance.
|
||||
*
|
||||
* @param type DRBG type to use
|
||||
* @param strength security strength in bits
|
||||
* @param entropy entropy source to be used
|
||||
* @param personalization_str optional personalization string
|
||||
* @return drbg_t instance, NULL if not supported
|
||||
*/
|
||||
drbg_t* (*create_drbg)(crypto_factory_t *this, drbg_type_t type,
|
||||
uint32_t strength, rng_t *entropy,
|
||||
chunk_t personalization_str);
|
||||
|
||||
/**
|
||||
* Create a source of randomness.
|
||||
*
|
||||
@@ -285,6 +305,24 @@ struct crypto_factory_t {
|
||||
*/
|
||||
void (*remove_xof)(crypto_factory_t *this, xof_constructor_t create);
|
||||
|
||||
/**
|
||||
* Register a drbg constructor.
|
||||
*
|
||||
* @param type type to constructor
|
||||
* @param plugin_name plugin that registered this algorithm
|
||||
* @param create constructor function for that algorithm
|
||||
* @return TRUE if registered, FALSE if test vector failed
|
||||
*/
|
||||
bool (*add_drbg)(crypto_factory_t *this, drbg_type_t type,
|
||||
const char *plugin_name, drbg_constructor_t create);
|
||||
|
||||
/**
|
||||
* Unregister a drbg constructor.
|
||||
*
|
||||
* @param create constructor function to unregister
|
||||
*/
|
||||
void (*remove_drbg)(crypto_factory_t *this, drbg_constructor_t create);
|
||||
|
||||
/**
|
||||
* Register a source of randomness.
|
||||
*
|
||||
@@ -381,6 +419,13 @@ struct crypto_factory_t {
|
||||
*/
|
||||
enumerator_t* (*create_xof_enumerator)(crypto_factory_t *this);
|
||||
|
||||
/**
|
||||
* Create an enumerator over all registered DRBGs.
|
||||
*
|
||||
* @return enumerator over drbg_type_t, plugin
|
||||
*/
|
||||
enumerator_t* (*create_drbg_enumerator)(crypto_factory_t *this);
|
||||
|
||||
/**
|
||||
* Create an enumerator over all registered diffie hellman groups.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2010 Martin Willi
|
||||
* Copyright (C) 2016-2019 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
* Copyright (C) 2010 revosec AG
|
||||
*
|
||||
@@ -24,6 +25,7 @@
|
||||
|
||||
#include <utils/debug.h>
|
||||
#include <collections/linked_list.h>
|
||||
#include <crypto/rngs/rng_tester.h>
|
||||
|
||||
typedef struct private_crypto_tester_t private_crypto_tester_t;
|
||||
|
||||
@@ -67,6 +69,11 @@ struct private_crypto_tester_t {
|
||||
*/
|
||||
linked_list_t *xof;
|
||||
|
||||
/**
|
||||
* List of DRBG test vectors
|
||||
*/
|
||||
linked_list_t *drbg;
|
||||
|
||||
/**
|
||||
* List of RNG test vectors
|
||||
*/
|
||||
@@ -1179,6 +1186,133 @@ failure:
|
||||
return !failed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Benchmark a DRBG
|
||||
*/
|
||||
static u_int bench_drbg(private_crypto_tester_t *this,
|
||||
drbg_type_t type, drbg_constructor_t create)
|
||||
{
|
||||
drbg_t *drbg;
|
||||
rng_t *entropy;
|
||||
uint32_t strength = 128;
|
||||
chunk_t seed = chunk_alloca(48);
|
||||
|
||||
memset(seed.ptr, 0x81, seed.len);
|
||||
entropy = rng_tester_create(seed);
|
||||
|
||||
drbg = create(type, strength, entropy, chunk_empty);
|
||||
if (drbg)
|
||||
{
|
||||
struct timespec start;
|
||||
u_int runs = 0;
|
||||
size_t out_len = 128;
|
||||
char out_buf[out_len];
|
||||
|
||||
start_timing(&start);
|
||||
while (end_timing(&start) < this->bench_time)
|
||||
{
|
||||
if (drbg->generate(drbg, out_len, out_buf))
|
||||
{
|
||||
runs++;
|
||||
}
|
||||
}
|
||||
drbg->destroy(drbg);
|
||||
|
||||
return runs;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
METHOD(crypto_tester_t, test_drbg, bool,
|
||||
private_crypto_tester_t *this, drbg_type_t type,
|
||||
drbg_constructor_t create, u_int *speed, const char *plugin_name)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
drbg_test_vector_t *vector;
|
||||
bool failed = FALSE;
|
||||
u_int tested = 0;
|
||||
|
||||
enumerator = this->drbg->create_enumerator(this->drbg);
|
||||
while (enumerator->enumerate(enumerator, &vector))
|
||||
{
|
||||
drbg_t *drbg;
|
||||
rng_t *entropy;
|
||||
chunk_t out = chunk_empty;
|
||||
|
||||
if (vector->type != type)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
tested++;
|
||||
failed = TRUE;
|
||||
|
||||
entropy = rng_tester_create(vector->entropy);
|
||||
out = chunk_alloc(vector->out.len);
|
||||
|
||||
drbg = create(type, vector->strength, entropy,
|
||||
vector->personalization_str);
|
||||
if (!drbg)
|
||||
{
|
||||
DBG1(DBG_LIB, "disabled %N[%s]: creating instance failed",
|
||||
drbg_type_names, type, plugin_name);
|
||||
entropy->destroy(entropy);
|
||||
chunk_free(&out);
|
||||
break;
|
||||
}
|
||||
if (!drbg->reseed(drbg))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
if (!drbg->generate(drbg, out.len, out.ptr))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
if (!drbg->generate(drbg, out.len, out.ptr))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
if (!chunk_equals(out, vector->out))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
failed = FALSE;
|
||||
|
||||
failure:
|
||||
drbg->destroy(drbg);
|
||||
entropy->destroy(entropy);
|
||||
chunk_free(&out);
|
||||
if (failed)
|
||||
{
|
||||
DBG1(DBG_LIB, "disabled %N[%s]: %s test vector failed",
|
||||
drbg_type_names, type, plugin_name, get_name(vector));
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
if (!tested)
|
||||
{
|
||||
DBG1(DBG_LIB, "%s %N[%s]: no test vectors found",
|
||||
this->required ? "disabled" : "enabled ",
|
||||
drbg_type_names, type, plugin_name);
|
||||
return !this->required;
|
||||
}
|
||||
if (!failed)
|
||||
{
|
||||
if (speed)
|
||||
{
|
||||
*speed = bench_drbg(this, type, create);
|
||||
DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors, %d points",
|
||||
drbg_type_names, type, plugin_name, tested, *speed);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors",
|
||||
drbg_type_names, type, plugin_name, tested);
|
||||
}
|
||||
}
|
||||
return !failed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Benchmark a RNG
|
||||
*/
|
||||
@@ -1489,6 +1623,12 @@ METHOD(crypto_tester_t, add_xof_vector, void,
|
||||
this->xof->insert_last(this->xof, vector);
|
||||
}
|
||||
|
||||
METHOD(crypto_tester_t, add_drbg_vector, void,
|
||||
private_crypto_tester_t *this, drbg_test_vector_t *vector)
|
||||
{
|
||||
this->drbg->insert_last(this->drbg, vector);
|
||||
}
|
||||
|
||||
METHOD(crypto_tester_t, add_rng_vector, void,
|
||||
private_crypto_tester_t *this, rng_test_vector_t *vector)
|
||||
{
|
||||
@@ -1510,6 +1650,7 @@ METHOD(crypto_tester_t, destroy, void,
|
||||
this->hasher->destroy(this->hasher);
|
||||
this->prf->destroy(this->prf);
|
||||
this->xof->destroy(this->xof);
|
||||
this->drbg->destroy(this->drbg);
|
||||
this->rng->destroy(this->rng);
|
||||
this->dh->destroy(this->dh);
|
||||
free(this);
|
||||
@@ -1530,6 +1671,7 @@ crypto_tester_t *crypto_tester_create()
|
||||
.test_hasher = _test_hasher,
|
||||
.test_prf = _test_prf,
|
||||
.test_xof = _test_xof,
|
||||
.test_drbg = _test_drbg,
|
||||
.test_rng = _test_rng,
|
||||
.test_dh = _test_dh,
|
||||
.add_crypter_vector = _add_crypter_vector,
|
||||
@@ -1538,6 +1680,7 @@ crypto_tester_t *crypto_tester_create()
|
||||
.add_hasher_vector = _add_hasher_vector,
|
||||
.add_prf_vector = _add_prf_vector,
|
||||
.add_xof_vector = _add_xof_vector,
|
||||
.add_drbg_vector = _add_drbg_vector,
|
||||
.add_rng_vector = _add_rng_vector,
|
||||
.add_dh_vector = _add_dh_vector,
|
||||
.destroy = _destroy,
|
||||
@@ -1548,6 +1691,7 @@ crypto_tester_t *crypto_tester_create()
|
||||
.hasher = linked_list_create(),
|
||||
.prf = linked_list_create(),
|
||||
.xof = linked_list_create(),
|
||||
.drbg = linked_list_create(),
|
||||
.rng = linked_list_create(),
|
||||
.dh = linked_list_create(),
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2009 Martin Willi
|
||||
* Copyright (C) 2016-2019 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -31,6 +32,7 @@ typedef struct signer_test_vector_t signer_test_vector_t;
|
||||
typedef struct hasher_test_vector_t hasher_test_vector_t;
|
||||
typedef struct prf_test_vector_t prf_test_vector_t;
|
||||
typedef struct xof_test_vector_t xof_test_vector_t;
|
||||
typedef struct drbg_test_vector_t drbg_test_vector_t;
|
||||
typedef struct rng_test_vector_t rng_test_vector_t;
|
||||
typedef struct dh_test_vector_t dh_test_vector_t;
|
||||
|
||||
@@ -128,6 +130,19 @@ struct xof_test_vector_t {
|
||||
u_char *out;
|
||||
};
|
||||
|
||||
struct drbg_test_vector_t {
|
||||
/** drbg type this test vector tests */
|
||||
drbg_type_t type;
|
||||
/** security strength in bits */
|
||||
uint32_t strength;
|
||||
/** optional personalization string */
|
||||
chunk_t personalization_str;
|
||||
/** entropy_input | nonce | entropy_input_reseed */
|
||||
chunk_t entropy;
|
||||
/** returned output bits */
|
||||
chunk_t out;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test vector for a RNG.
|
||||
*
|
||||
@@ -241,6 +256,17 @@ struct crypto_tester_t {
|
||||
bool (*test_xof)(crypto_tester_t *this, ext_out_function_t alg,
|
||||
xof_constructor_t create,
|
||||
u_int *speed, const char *plugin_name);
|
||||
/**
|
||||
* Test a DRBG type.
|
||||
*
|
||||
* @param type DRBG type to test
|
||||
* @param create constructor function for the DRBG
|
||||
* @param speed speed test result, NULL to omit
|
||||
* @return TRUE if test passed
|
||||
*/
|
||||
bool (*test_drbg)(crypto_tester_t *this, drbg_type_t type,
|
||||
drbg_constructor_t create,
|
||||
u_int *speed, const char *plugin_name);
|
||||
/**
|
||||
* Test a RNG implementation.
|
||||
*
|
||||
@@ -306,6 +332,13 @@ struct crypto_tester_t {
|
||||
*/
|
||||
void (*add_xof_vector)(crypto_tester_t *this, xof_test_vector_t *vector);
|
||||
|
||||
/**
|
||||
* Add a test vector to test a DRBG.
|
||||
*
|
||||
* @param vector pointer to test vector
|
||||
*/
|
||||
void (*add_drbg_vector)(crypto_tester_t *this, drbg_test_vector_t *vector);
|
||||
|
||||
/**
|
||||
* Add a test vector to test a RNG.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the "GNU General Public License as published by the
|
||||
* Free Software Foundatio"n; either version 2 of the License, or (at your
|
||||
* option) any later version". See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
**/
|
||||
|
||||
#include "drbg.h"
|
||||
|
||||
ENUM(drbg_type_names, DRBG_UNDEFINED, DRBG_CTR_AES256,
|
||||
"DRBG_UNDEFINED",
|
||||
"DRBG_HMAC_SHA1",
|
||||
"DRBG_HMAC_SHA256",
|
||||
"DRBG_HMAC_SHA384",
|
||||
"DRBG_HMAC_SHA512",
|
||||
"DRBG_CTR_AES128",
|
||||
"DRBG_CTR_AES192",
|
||||
"DRBG_CTR_AES256",
|
||||
);
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup drbg drbg
|
||||
* @{ @ingroup crypto
|
||||
*/
|
||||
|
||||
#ifndef DRBG_H_
|
||||
#define DRBG_H_
|
||||
|
||||
typedef enum drbg_type_t drbg_type_t;
|
||||
typedef struct drbg_t drbg_t;
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* Deterministic Random Bit Generator.(DRBG) Type
|
||||
*/
|
||||
enum drbg_type_t {
|
||||
DRBG_UNDEFINED,
|
||||
DRBG_HMAC_SHA1,
|
||||
DRBG_HMAC_SHA256,
|
||||
DRBG_HMAC_SHA384,
|
||||
DRBG_HMAC_SHA512,
|
||||
DRBG_CTR_AES128,
|
||||
DRBG_CTR_AES192,
|
||||
DRBG_CTR_AES256,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum name for drbg_type_t.
|
||||
*/
|
||||
extern enum_name_t *drbg_type_names;
|
||||
|
||||
/**
|
||||
* Interface for a Deterministic Random Bit Generator (DRBG)
|
||||
* compliant with NIST SP 800-90A
|
||||
*/
|
||||
struct drbg_t {
|
||||
|
||||
/**
|
||||
* Return the type of the DRBG
|
||||
*
|
||||
* @return DRBG type
|
||||
*/
|
||||
drbg_type_t (*get_type)(drbg_t *this);
|
||||
|
||||
/**
|
||||
* Return the security strength of the DRBG
|
||||
*
|
||||
* @return configured security strength in bits
|
||||
*/
|
||||
uint32_t (*get_strength)(drbg_t *this);
|
||||
|
||||
/**
|
||||
* Reseed the instantiated DRBG
|
||||
*
|
||||
* @return TRUE if successful
|
||||
*/
|
||||
bool (*reseed)(drbg_t *this);
|
||||
|
||||
/**
|
||||
* Generate pseudorandom bytes.
|
||||
* If the maximum number of requests has been reached, reseeding occurs
|
||||
*
|
||||
* @param len number of octets to generate
|
||||
* @param out address of output buffer
|
||||
* @return TRUE if successful
|
||||
*/
|
||||
bool (*generate)(drbg_t *this, uint32_t len, uint8_t *out);
|
||||
|
||||
/**
|
||||
* Get a reference on an drbg_t object increasing the count by one
|
||||
*
|
||||
* @return reference to the drbg_t object
|
||||
*/
|
||||
drbg_t* (*get_ref)(drbg_t *this);
|
||||
|
||||
/**
|
||||
* Uninstantiate and destroy the DRBG object
|
||||
*/
|
||||
void (*destroy)(drbg_t *this);
|
||||
|
||||
};
|
||||
|
||||
#endif /** DRBG_H_ @}*/
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "rng_tester.h"
|
||||
|
||||
typedef struct private_rng_t private_rng_t;
|
||||
|
||||
/**
|
||||
* Private data.
|
||||
*/
|
||||
struct private_rng_t {
|
||||
|
||||
/**
|
||||
* Public interface.
|
||||
*/
|
||||
rng_t public;
|
||||
|
||||
/**
|
||||
* Entropy string.
|
||||
*/
|
||||
chunk_t entropy;
|
||||
};
|
||||
|
||||
METHOD(rng_t, get_bytes, bool,
|
||||
private_rng_t *this, size_t bytes, uint8_t *buffer)
|
||||
{
|
||||
if (bytes > this->entropy.len)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
memcpy(buffer, this->entropy.ptr, bytes);
|
||||
this->entropy = chunk_skip(this->entropy, bytes);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(rng_t, allocate_bytes, bool,
|
||||
private_rng_t *this, size_t bytes, chunk_t *chunk)
|
||||
{
|
||||
if (bytes > this->entropy.len)
|
||||
{
|
||||
*chunk = chunk_empty;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*chunk = chunk_alloc(bytes);
|
||||
memcpy(chunk->ptr, this->entropy.ptr, bytes);
|
||||
this->entropy = chunk_skip(this->entropy, bytes);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(rng_t, destroy, void,
|
||||
private_rng_t *this)
|
||||
{
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
rng_t *rng_tester_create(chunk_t entropy)
|
||||
{
|
||||
private_rng_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.get_bytes = _get_bytes,
|
||||
.allocate_bytes = _allocate_bytes,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.entropy = entropy,
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2013-2019 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* rng_t providing deterministic output (DO NOT USE IN PRODUCTIVE SYSTEMS!!!)
|
||||
*
|
||||
* @defgroup rng_tester rng_tester
|
||||
* @{ @ingroup crypto
|
||||
*/
|
||||
|
||||
#ifndef RNG_TESTER_H_
|
||||
#define RNG_TESTER_H_
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* Creates a rng_tester_t instance.
|
||||
*
|
||||
* @param entropy deterministic output
|
||||
* @return created rng_tester_t
|
||||
*/
|
||||
rng_t *rng_tester_create(chunk_t entropy);
|
||||
|
||||
#endif /** RNG_TESTER_H_ @} */
|
||||
@@ -23,14 +23,15 @@ ENUM_BEGIN(transform_type_names, ENCRYPTION_ALGORITHM, EXTENDED_SEQUENCE_NUMBERS
|
||||
"INTEGRITY_ALGORITHM",
|
||||
"DIFFIE_HELLMAN_GROUP",
|
||||
"EXTENDED_SEQUENCE_NUMBERS");
|
||||
ENUM_NEXT(transform_type_names, HASH_ALGORITHM, EXTENDED_OUTPUT_FUNCTION,
|
||||
ENUM_NEXT(transform_type_names, HASH_ALGORITHM, DETERMINISTIC_RANDOM_BIT_GENERATOR,
|
||||
EXTENDED_SEQUENCE_NUMBERS,
|
||||
"HASH_ALGORITHM",
|
||||
"RANDOM_NUMBER_GENERATOR",
|
||||
"AEAD_ALGORITHM",
|
||||
"COMPRESSION_ALGORITHM",
|
||||
"EXTENDED OUTPUT FUNCTION");
|
||||
ENUM_END(transform_type_names, EXTENDED_OUTPUT_FUNCTION);
|
||||
"EXTENDED OUTPUT FUNCTION",
|
||||
"DETERMINISTIC RANDOM BIT GENERATOR");
|
||||
ENUM_END(transform_type_names, DETERMINISTIC_RANDOM_BIT_GENERATOR);
|
||||
|
||||
|
||||
ENUM(extended_sequence_numbers_names, NO_EXT_SEQ_NUMBERS, EXT_SEQ_NUMBERS,
|
||||
@@ -38,7 +39,6 @@ ENUM(extended_sequence_numbers_names, NO_EXT_SEQ_NUMBERS, EXT_SEQ_NUMBERS,
|
||||
"EXT_SEQ",
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
@@ -63,6 +63,8 @@ enum_name_t* transform_get_enum_names(transform_type_t type)
|
||||
return extended_sequence_numbers_names;
|
||||
case EXTENDED_OUTPUT_FUNCTION:
|
||||
return ext_out_function_names;
|
||||
case DETERMINISTIC_RANDOM_BIT_GENERATOR:
|
||||
return drbg_type_names;
|
||||
case COMPRESSION_ALGORITHM:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ enum transform_type_t {
|
||||
AEAD_ALGORITHM = 258,
|
||||
COMPRESSION_ALGORITHM = 259,
|
||||
EXTENDED_OUTPUT_FUNCTION = 260,
|
||||
DETERMINISTIC_RANDOM_BIT_GENERATOR = 261,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user