618 lines
18 KiB
C
618 lines
18 KiB
C
/*
|
|
* DRBG: Deterministic Random Bits Generator
|
|
* Implementation of the HMAC SHA-512 DRBG from NIST SP800-90A
|
|
*
|
|
* Copyright Stephan Mueller <smueller@chronox.de>, 2014
|
|
* Copyright 2026 Google LLC
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, and the entire permission notice in its entirety,
|
|
* including the disclaimer of warranties.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. The name of the author may not be used to endorse or promote
|
|
* products derived from this software without specific prior
|
|
* written permission.
|
|
*
|
|
* ALTERNATIVELY, this product may be distributed under the terms of
|
|
* the GNU General Public License, in which case the provisions of the GPL are
|
|
* required INSTEAD OF the above restrictions. (This clause is
|
|
* necessary due to a potential bad interaction between the GPL and
|
|
* the restrictions contained in a BSD-style copyright.)
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
|
|
* WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
|
* USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
|
|
* DAMAGE.
|
|
*
|
|
* DRBG Usage
|
|
* ==========
|
|
* The SP 800-90A DRBG allows the user to specify a personalization string
|
|
* for initialization as well as an additional information string for each
|
|
* random number request. The following code fragments show how a caller
|
|
* uses the kernel crypto API to use the full functionality of the DRBG.
|
|
*
|
|
* Usage without any additional data
|
|
* ---------------------------------
|
|
* struct crypto_rng *drng;
|
|
* int err;
|
|
* char data[DATALEN];
|
|
*
|
|
* drng = crypto_alloc_rng(drng_name, 0, 0);
|
|
* err = crypto_rng_get_bytes(drng, data, DATALEN);
|
|
* crypto_free_rng(drng);
|
|
*
|
|
*
|
|
* Usage with personalization string during initialization
|
|
* -------------------------------------------------------
|
|
* struct crypto_rng *drng;
|
|
* int err;
|
|
* char data[DATALEN];
|
|
* char personalization[11] = "some-string";
|
|
*
|
|
* drng = crypto_alloc_rng(drng_name, 0, 0);
|
|
* // The reset completely re-initializes the DRBG with the provided
|
|
* // personalization string
|
|
* err = crypto_rng_reset(drng, personalization, strlen(personalization));
|
|
* err = crypto_rng_get_bytes(drng, data, DATALEN);
|
|
* crypto_free_rng(drng);
|
|
*
|
|
*
|
|
* Usage with additional information string during random number request
|
|
* ---------------------------------------------------------------------
|
|
* struct crypto_rng *drng;
|
|
* int err;
|
|
* char data[DATALEN];
|
|
* char addtl_string[11] = "some-string";
|
|
*
|
|
* drng = crypto_alloc_rng(drng_name, 0, 0);
|
|
* err = crypto_rng_generate(drng, addtl_string, strlen(addtl_string),
|
|
data, DATALEN);
|
|
* crypto_free_rng(drng);
|
|
*
|
|
*
|
|
* Usage with personalization and additional information strings
|
|
* -------------------------------------------------------------
|
|
* Just mix both scenarios above.
|
|
*/
|
|
|
|
#include <crypto/internal/rng.h>
|
|
#include <crypto/sha2.h>
|
|
#include <linux/fips.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
#include <linux/mutex.h>
|
|
#include <linux/string_choices.h>
|
|
#include <linux/unaligned.h>
|
|
|
|
/* State length in bytes */
|
|
#define DRBG_STATE_LEN SHA512_DIGEST_SIZE
|
|
|
|
/* Security strength in bytes */
|
|
#define DRBG_SEC_STRENGTH (SHA512_DIGEST_SIZE / 2)
|
|
|
|
/*
|
|
* Maximum number of requests before reseeding is forced.
|
|
* SP800-90A allows this to be up to 2**48. We use a lower value.
|
|
*/
|
|
#define DRBG_MAX_REQUESTS 4096
|
|
|
|
/*
|
|
* Maximum number of random bytes that can be requested at once.
|
|
* SP800-90A allows up to 2**19 bits, which is 2**16 bytes.
|
|
*/
|
|
#define DRBG_MAX_REQUEST_BYTES (1 << 16)
|
|
|
|
/*
|
|
* Maximum length of additional info and personalization strings, in bytes.
|
|
* SP800-90A allows up to 2**35 bits, i.e. 2**32 bytes. We use 2**32 - 2 bytes
|
|
* so that the value never quite completely fills the range of a size_t,
|
|
* allowing the health check to verify that larger values are rejected.
|
|
*/
|
|
#define DRBG_MAX_ADDTL_BYTES (U32_MAX - 1)
|
|
|
|
struct drbg_state {
|
|
struct mutex drbg_mutex; /* lock around DRBG */
|
|
u8 V[DRBG_STATE_LEN]; /* internal state -- 10.1.2.1 1a */
|
|
struct hmac_sha512_key key; /* current key -- 10.1.2.1 1b */
|
|
/* Number of RNG requests since last reseed -- 10.1.2.1 1c */
|
|
size_t reseed_ctr;
|
|
bool instantiated;
|
|
struct crypto_rng *jent;
|
|
const u8 *test_entropy;
|
|
size_t test_entropylen;
|
|
};
|
|
|
|
/******************************************************************
|
|
* HMAC DRBG functions
|
|
******************************************************************/
|
|
|
|
/* update function of HMAC DRBG as defined in 10.1.2.2 */
|
|
static void drbg_hmac_update(struct drbg_state *drbg,
|
|
const u8 *data1, size_t data1_len,
|
|
const u8 *data2, size_t data2_len)
|
|
{
|
|
struct hmac_sha512_ctx hmac_ctx;
|
|
u8 new_key[DRBG_STATE_LEN];
|
|
|
|
for (u8 i = 0; i < 2; i++) {
|
|
/* 10.1.2.2 step 1 and 4 -- concatenation and HMAC for key */
|
|
hmac_sha512_init(&hmac_ctx, &drbg->key);
|
|
hmac_sha512_update(&hmac_ctx, drbg->V, DRBG_STATE_LEN);
|
|
hmac_sha512_update(&hmac_ctx, &i, 1);
|
|
hmac_sha512_update(&hmac_ctx, data1, data1_len);
|
|
hmac_sha512_update(&hmac_ctx, data2, data2_len);
|
|
hmac_sha512_final(&hmac_ctx, new_key);
|
|
hmac_sha512_preparekey(&drbg->key, new_key, DRBG_STATE_LEN);
|
|
|
|
/* 10.1.2.2 step 2 and 5 -- HMAC for V */
|
|
hmac_sha512(&drbg->key, drbg->V, DRBG_STATE_LEN, drbg->V);
|
|
|
|
/* 10.1.2.2 step 3 */
|
|
if (data1_len == 0 && data2_len == 0)
|
|
break;
|
|
}
|
|
memzero_explicit(new_key, sizeof(new_key));
|
|
}
|
|
|
|
/* generate function of HMAC DRBG as defined in 10.1.2.5 */
|
|
static void drbg_hmac_generate(struct drbg_state *drbg, u8 *out, size_t outlen,
|
|
const u8 *addtl1, size_t addtl1_len)
|
|
{
|
|
u8 addtl2[32];
|
|
size_t addtl2_len = 0;
|
|
|
|
/*
|
|
* Append some bytes from get_random_bytes() to the additional input
|
|
* string, except when in test mode (as it would break the tests).
|
|
* Using a nonempty additional input string works around the forward
|
|
* secrecy bug in HMAC_DRBG described by Woodage & Shumow (2018)
|
|
* (https://eprint.iacr.org/2018/349.pdf). Filling the string with
|
|
* get_random_bytes() rather than a fixed value is safer still, and in
|
|
* particular makes random.c reseeds be immediately reflected.
|
|
*
|
|
* Note that there's no need to pull bytes from jitterentropy here too,
|
|
* since FIPS doesn't require any entropy in the additional input.
|
|
*/
|
|
if (drbg->test_entropylen == 0) {
|
|
get_random_bytes(addtl2, sizeof(addtl2));
|
|
addtl2_len = sizeof(addtl2);
|
|
}
|
|
|
|
/* 10.1.2.5 step 2 */
|
|
if (addtl1_len || addtl2_len)
|
|
drbg_hmac_update(drbg, addtl1, addtl1_len, addtl2, addtl2_len);
|
|
|
|
while (outlen) {
|
|
size_t n = min(DRBG_STATE_LEN, outlen);
|
|
|
|
/* 10.1.2.5 step 4.1 */
|
|
hmac_sha512(&drbg->key, drbg->V, DRBG_STATE_LEN, drbg->V);
|
|
|
|
/* 10.1.2.5 step 4.2 */
|
|
memcpy(out, drbg->V, n);
|
|
out += n;
|
|
outlen -= n;
|
|
}
|
|
|
|
/* 10.1.2.5 step 6 */
|
|
drbg_hmac_update(drbg, addtl1, addtl1_len, addtl2, addtl2_len);
|
|
|
|
memzero_explicit(addtl2, sizeof(addtl2));
|
|
}
|
|
|
|
/*
|
|
* Seeding or reseeding of the DRBG
|
|
*
|
|
* @drbg: DRBG state struct
|
|
* @pers: personalization / additional information buffer
|
|
* @pers_len: length of @pers in bytes
|
|
* @reseed: false for initial seeding (instantiation), true for reseeding
|
|
*
|
|
* return:
|
|
* 0 on success
|
|
* error value otherwise
|
|
*/
|
|
static int drbg_seed(struct drbg_state *drbg, const u8 *pers, size_t pers_len,
|
|
bool reseed)
|
|
__must_hold(&drbg->drbg_mutex)
|
|
{
|
|
int ret;
|
|
u8 entropy_buf[(32 + 16) * 2];
|
|
size_t entropylen;
|
|
const u8 *entropy;
|
|
|
|
/* 9.1 / 9.2 / 9.3.1 step 3 */
|
|
if (pers_len > DRBG_MAX_ADDTL_BYTES) {
|
|
pr_devel("DRBG: personalization string too long %zu\n",
|
|
pers_len);
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (drbg->test_entropylen) {
|
|
entropy = drbg->test_entropy;
|
|
entropylen = drbg->test_entropylen;
|
|
pr_devel("DRBG: using test entropy\n");
|
|
} else {
|
|
/*
|
|
* Gather entropy equal to the security strength of the DRBG.
|
|
* With a derivation function, a nonce is required in addition
|
|
* to the entropy. A nonce must be at least 1/2 of the security
|
|
* strength of the DRBG in size. Thus, entropy + nonce is 3/2
|
|
* of the strength. The consideration of a nonce is only
|
|
* applicable during initial seeding.
|
|
*/
|
|
entropy = entropy_buf;
|
|
if (!reseed)
|
|
entropylen = ((DRBG_SEC_STRENGTH + 1) / 2) * 3;
|
|
else
|
|
entropylen = DRBG_SEC_STRENGTH;
|
|
BUG_ON(entropylen * 2 > sizeof(entropy_buf));
|
|
|
|
/* Get seed from in-kernel /dev/urandom */
|
|
get_random_bytes(entropy_buf, entropylen);
|
|
|
|
if (!drbg->jent) {
|
|
pr_devel("DRBG: (re)seeding with %zu bytes of entropy\n",
|
|
entropylen);
|
|
} else {
|
|
/*
|
|
* Get seed from Jitter RNG, failures are
|
|
* fatal only in FIPS mode.
|
|
*/
|
|
ret = crypto_rng_get_bytes(drbg->jent,
|
|
&entropy_buf[entropylen],
|
|
entropylen);
|
|
if (fips_enabled && ret) {
|
|
pr_devel("DRBG: jent failed with %d\n", ret);
|
|
|
|
/*
|
|
* Do not treat the transient failure of the
|
|
* Jitter RNG as an error that needs to be
|
|
* reported. The combined number of the
|
|
* maximum reseed threshold times the maximum
|
|
* number of Jitter RNG transient errors is
|
|
* less than the reseed threshold required by
|
|
* SP800-90A allowing us to treat the
|
|
* transient errors as such.
|
|
*
|
|
* However, we mandate that at least the first
|
|
* seeding operation must succeed with the
|
|
* Jitter RNG.
|
|
*/
|
|
if (!reseed || ret != -EAGAIN)
|
|
goto out;
|
|
}
|
|
|
|
entropylen *= 2;
|
|
pr_devel("DRBG: (re)seeding with %zu bytes of entropy\n",
|
|
entropylen);
|
|
}
|
|
}
|
|
|
|
if (pers_len)
|
|
pr_devel("DRBG: using personalization string\n");
|
|
|
|
drbg_hmac_update(drbg, entropy, entropylen, pers, pers_len);
|
|
drbg->reseed_ctr = 1;
|
|
ret = 0;
|
|
out:
|
|
memzero_explicit(entropy_buf, sizeof(entropy_buf));
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Generate random bytes from an SP800-90A DRBG.
|
|
*
|
|
* @drbg DRBG state handle
|
|
* @out Buffer where to store the random bytes
|
|
* @outlen Number of random bytes to generate
|
|
* @addtl Optional additional input that is mixed into state
|
|
* @addtl_len Length of @addtl in bytes, may be 0
|
|
*
|
|
* return: 0 when all bytes are generated; < 0 in case of an error
|
|
*/
|
|
static int drbg_generate(struct drbg_state *drbg, u8 *out, size_t outlen,
|
|
const u8 *addtl, size_t addtl_len)
|
|
__must_hold(&drbg->drbg_mutex)
|
|
{
|
|
int err;
|
|
|
|
if (!drbg->instantiated) {
|
|
pr_devel("DRBG: not yet instantiated\n");
|
|
return -EINVAL;
|
|
}
|
|
if (out == NULL || outlen == 0) {
|
|
pr_devel("DRBG: no output buffer provided\n");
|
|
return -EINVAL;
|
|
}
|
|
if (addtl == NULL && addtl_len != 0) {
|
|
pr_devel("DRBG: wrong format of additional information\n");
|
|
return -EINVAL;
|
|
}
|
|
|
|
/* 9.3.1 step 2 */
|
|
if (outlen > DRBG_MAX_REQUEST_BYTES) {
|
|
pr_devel("DRBG: request length is too long %zu\n", outlen);
|
|
return -EINVAL;
|
|
}
|
|
|
|
/* 9.3.1 step 3 is implicit with the chosen DRBG */
|
|
|
|
/* 9.3.1 step 4 */
|
|
if (addtl_len > DRBG_MAX_ADDTL_BYTES) {
|
|
pr_devel("DRBG: additional information string too long %zu\n",
|
|
addtl_len);
|
|
return -EINVAL;
|
|
}
|
|
/* 9.3.1 step 5 is implicit with the chosen DRBG */
|
|
|
|
/*
|
|
* 9.3.1 step 6 and 9 supplemented by 9.3.2 step c is implemented
|
|
* here. The spec is a bit convoluted here, we make it simpler.
|
|
*
|
|
* We no longer try to detect when random.c has reseeded itself and call
|
|
* drbg_seed() then too, since drbg_hmac_generate() adds bytes from
|
|
* random.c to the additional input, which is a de facto reseed anyway.
|
|
*/
|
|
if (drbg->reseed_ctr > DRBG_MAX_REQUESTS) {
|
|
pr_devel("DRBG: reseeding before generation\n");
|
|
/* 9.3.1 steps 7.1 through 7.3 */
|
|
err = drbg_seed(drbg, addtl, addtl_len, true);
|
|
if (err)
|
|
return err;
|
|
/* 9.3.1 step 7.4 */
|
|
addtl = NULL;
|
|
addtl_len = 0;
|
|
}
|
|
|
|
/* 9.3.1 step 8 and 10 */
|
|
drbg_hmac_generate(drbg, out, outlen, addtl, addtl_len);
|
|
|
|
/* 10.1.2.5 step 7 */
|
|
drbg->reseed_ctr++;
|
|
|
|
/*
|
|
* Section 11.3.3 requires to re-perform self tests after some
|
|
* generated random numbers. The chosen value after which self
|
|
* test is performed is arbitrary, but it should be reasonable.
|
|
* However, we do not perform the self tests because of the following
|
|
* reasons: it is mathematically impossible that the initial self tests
|
|
* were successfully and the following are not. If the initial would
|
|
* pass and the following would not, the kernel integrity is violated.
|
|
* In this case, the entire kernel operation is questionable and it
|
|
* is unlikely that the integrity violation only affects the
|
|
* correct operation of the DRBG.
|
|
*/
|
|
|
|
return 0;
|
|
}
|
|
|
|
/***************************************************************
|
|
* Kernel crypto API interface to DRBG
|
|
***************************************************************/
|
|
|
|
static int drbg_kcapi_init(struct crypto_tfm *tfm)
|
|
{
|
|
struct drbg_state *drbg = crypto_tfm_ctx(tfm);
|
|
|
|
mutex_init(&drbg->drbg_mutex);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Set test entropy in the DRBG. */
|
|
static void drbg_kcapi_set_entropy(struct crypto_rng *tfm,
|
|
const u8 *data, unsigned int len)
|
|
{
|
|
struct drbg_state *drbg = crypto_rng_ctx(tfm);
|
|
|
|
mutex_lock(&drbg->drbg_mutex);
|
|
drbg->test_entropy = data;
|
|
drbg->test_entropylen = len;
|
|
mutex_unlock(&drbg->drbg_mutex);
|
|
}
|
|
|
|
/* Seed (i.e. instantiate) or re-seed the DRBG. */
|
|
static int drbg_kcapi_seed(struct crypto_rng *tfm,
|
|
const u8 *pers, unsigned int pers_len)
|
|
{
|
|
static const u8 initial_key[DRBG_STATE_LEN]; /* all zeroes */
|
|
struct drbg_state *drbg = crypto_rng_ctx(tfm);
|
|
int ret;
|
|
|
|
pr_devel("DRBG: Initializing DRBG\n");
|
|
guard(mutex)(&drbg->drbg_mutex);
|
|
|
|
if (drbg->instantiated)
|
|
return drbg_seed(drbg, pers, pers_len, /* reseed= */ true);
|
|
|
|
/* 9.1 step 1 is implicit with the selected DRBG type */
|
|
|
|
/*
|
|
* 9.1 step 2 is implicit, as this implementation doesn't support
|
|
* prediction resistance
|
|
*/
|
|
|
|
/* 9.1 step 4 is implicit in DRBG_SEC_STRENGTH */
|
|
|
|
memset(drbg->V, 1, DRBG_STATE_LEN);
|
|
hmac_sha512_preparekey(&drbg->key, initial_key, DRBG_STATE_LEN);
|
|
|
|
/* Allocate jitterentropy_rng if not in test mode. */
|
|
if (drbg->test_entropylen == 0) {
|
|
drbg->jent = crypto_alloc_rng("jitterentropy_rng", 0, 0);
|
|
if (IS_ERR(drbg->jent)) {
|
|
ret = PTR_ERR(drbg->jent);
|
|
drbg->jent = NULL;
|
|
if (fips_enabled)
|
|
return ret;
|
|
pr_info("DRBG: Continuing without Jitter RNG\n");
|
|
}
|
|
}
|
|
|
|
ret = drbg_seed(drbg, pers, pers_len, /* reseed= */ false);
|
|
if (ret) {
|
|
crypto_free_rng(drbg->jent);
|
|
drbg->jent = NULL;
|
|
return ret;
|
|
}
|
|
drbg->instantiated = true;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Generate random numbers invoked by the kernel crypto API:
|
|
*
|
|
* src is additional input supplied to the RNG.
|
|
* slen is the length of src.
|
|
* dst is the output buffer where random data is to be stored.
|
|
* dlen is the length of dst.
|
|
*/
|
|
static int drbg_kcapi_generate(struct crypto_rng *tfm,
|
|
const u8 *src, unsigned int slen,
|
|
u8 *dst, unsigned int dlen)
|
|
{
|
|
struct drbg_state *drbg = crypto_rng_ctx(tfm);
|
|
|
|
/*
|
|
* Break the request into multiple requests if needed, to avoid
|
|
* exceeding the maximum request length of the core algorithm.
|
|
*/
|
|
do {
|
|
unsigned int n = min(dlen, DRBG_MAX_REQUEST_BYTES);
|
|
int err;
|
|
|
|
mutex_lock(&drbg->drbg_mutex);
|
|
err = drbg_generate(drbg, dst, n, src, slen);
|
|
mutex_unlock(&drbg->drbg_mutex);
|
|
if (err < 0)
|
|
return err;
|
|
dst += n;
|
|
dlen -= n;
|
|
} while (dlen);
|
|
return 0;
|
|
}
|
|
|
|
/* Uninstantiate the DRBG. */
|
|
static void drbg_kcapi_exit(struct crypto_tfm *tfm)
|
|
{
|
|
struct drbg_state *drbg = crypto_tfm_ctx(tfm);
|
|
|
|
crypto_free_rng(drbg->jent);
|
|
memzero_explicit(drbg, sizeof(*drbg));
|
|
}
|
|
|
|
/*
|
|
* Tests as defined in 11.3.2 in addition to the cipher tests: testing
|
|
* of the error handling.
|
|
*
|
|
* Note: testing of failing seed source as defined in 11.3.2 is not applicable
|
|
* as seed source of get_random_bytes does not fail.
|
|
*
|
|
* Note 2: There is no sensible way of testing the reseed counter
|
|
* enforcement, so skip it.
|
|
*/
|
|
static inline int __init drbg_healthcheck_sanity(void)
|
|
{
|
|
#define OUTBUFLEN 16
|
|
u8 buf[OUTBUFLEN];
|
|
struct drbg_state *drbg = NULL;
|
|
int ret;
|
|
|
|
/* only perform test in FIPS mode */
|
|
if (!fips_enabled)
|
|
return 0;
|
|
|
|
drbg = kzalloc_obj(struct drbg_state);
|
|
if (!drbg)
|
|
return -ENOMEM;
|
|
|
|
guard(mutex_init)(&drbg->drbg_mutex);
|
|
drbg->instantiated = true;
|
|
|
|
/*
|
|
* if the following tests fail, it is likely that there is a buffer
|
|
* overflow as buf is much smaller than the requested or provided
|
|
* string lengths -- in case the error handling does not succeed
|
|
* we may get an OOPS. And we want to get an OOPS as this is a
|
|
* grave bug.
|
|
*/
|
|
|
|
/* overflow addtllen with additional info string */
|
|
ret = drbg_generate(drbg, buf, OUTBUFLEN, buf,
|
|
DRBG_MAX_ADDTL_BYTES + 1);
|
|
BUG_ON(ret == 0);
|
|
/* overflow max_bits */
|
|
ret = drbg_generate(drbg, buf, DRBG_MAX_REQUEST_BYTES + 1, NULL, 0);
|
|
BUG_ON(ret == 0);
|
|
|
|
/* overflow max addtllen with personalization string */
|
|
ret = drbg_seed(drbg, buf, DRBG_MAX_ADDTL_BYTES + 1, false);
|
|
BUG_ON(ret == 0);
|
|
/* all tests passed */
|
|
|
|
pr_devel("DRBG: Sanity tests for failure code paths successfully "
|
|
"completed\n");
|
|
|
|
kfree(drbg);
|
|
return 0;
|
|
}
|
|
|
|
static struct rng_alg drbg_alg = {
|
|
.base.cra_name = "stdrng",
|
|
.base.cra_driver_name = "drbg_nopr_hmac_sha512",
|
|
.base.cra_priority = 201,
|
|
.base.cra_ctxsize = sizeof(struct drbg_state),
|
|
.base.cra_module = THIS_MODULE,
|
|
.base.cra_init = drbg_kcapi_init,
|
|
.set_ent = drbg_kcapi_set_entropy,
|
|
.seed = drbg_kcapi_seed,
|
|
.generate = drbg_kcapi_generate,
|
|
.base.cra_exit = drbg_kcapi_exit,
|
|
};
|
|
|
|
static int __init drbg_init(void)
|
|
{
|
|
int ret;
|
|
|
|
ret = drbg_healthcheck_sanity();
|
|
if (ret)
|
|
return ret;
|
|
|
|
/*
|
|
* In FIPS mode, boost the algorithm priority to ensure that when users
|
|
* request "stdrng", they really get the algorithm from here.
|
|
*/
|
|
if (fips_enabled)
|
|
drbg_alg.base.cra_priority += 2000;
|
|
|
|
return crypto_register_rng(&drbg_alg);
|
|
}
|
|
|
|
static void __exit drbg_exit(void)
|
|
{
|
|
crypto_unregister_rng(&drbg_alg);
|
|
}
|
|
|
|
module_init(drbg_init);
|
|
module_exit(drbg_exit);
|
|
MODULE_LICENSE("GPL");
|
|
MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>");
|
|
MODULE_DESCRIPTION("NIST SP800-90A Deterministic Random Bit Generator (DRBG)");
|
|
MODULE_ALIAS_CRYPTO("stdrng");
|
|
MODULE_ALIAS_CRYPTO("drbg_nopr_hmac_sha512");
|