diff options
| author | Eric Biggers <ebiggers@kernel.org> | 2026-04-19 23:33:54 -0700 |
|---|---|---|
| committer | Herbert Xu <herbert@gondor.apana.org.au> | 2026-05-07 16:09:59 +0800 |
| commit | 262ec4782cf4ae3b661b30ff11d3af86f667c69c (patch) | |
| tree | 3b762ad0d5a7cc5d6a3525f3191fa61ed4e241ac /crypto | |
| parent | f4919bbca03c8d130a46eba99535b5730edd89a6 (diff) | |
| download | linux-next-history-262ec4782cf4ae3b661b30ff11d3af86f667c69c.tar.gz | |
crypto: drbg - Fold include/crypto/drbg.h into crypto/drbg.c
include/crypto/drbg.h no longer contains anything that is used
externally to crypto/drbg.c. Therefore, fold it into crypto/drbg.c.
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
| -rw-r--r-- | crypto/drbg.c | 132 | ||||
| -rw-r--r-- | crypto/testmgr.c | 3 |
2 files changed, 132 insertions, 3 deletions
diff --git a/crypto/drbg.c b/crypto/drbg.c index 66d7739469c67..fd1d75addaf78 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -92,14 +92,144 @@ * Just mix both scenarios above. */ -#include <crypto/drbg.h> #include <crypto/df_sp80090a.h> #include <crypto/internal/cipher.h> +#include <crypto/internal/drbg.h> +#include <crypto/internal/rng.h> +#include <crypto/hash.h> +#include <crypto/skcipher.h> +#include <linux/fips.h> #include <linux/kernel.h> #include <linux/jiffies.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/scatterlist.h> #include <linux/string_choices.h> #include <linux/unaligned.h> +struct drbg_state; +typedef uint32_t drbg_flag_t; + +struct drbg_core { + drbg_flag_t flags; /* flags for the cipher */ + __u8 statelen; /* maximum state length */ + __u8 blocklen_bytes; /* block size of output in bytes */ + char cra_name[CRYPTO_MAX_ALG_NAME]; /* mapping to kernel crypto API */ + /* kernel crypto API backend cipher name */ + char backend_cra_name[CRYPTO_MAX_ALG_NAME]; +}; + +struct drbg_state_ops { + int (*update)(struct drbg_state *drbg, struct list_head *seed, + int reseed); + int (*generate)(struct drbg_state *drbg, + unsigned char *buf, unsigned int buflen, + struct list_head *addtl); + int (*crypto_init)(struct drbg_state *drbg); + int (*crypto_fini)(struct drbg_state *drbg); + +}; + +enum drbg_seed_state { + DRBG_SEED_STATE_UNSEEDED, + DRBG_SEED_STATE_PARTIAL, /* Seeded with !rng_is_initialized() */ + DRBG_SEED_STATE_FULL, +}; + +struct drbg_state { + struct mutex drbg_mutex; /* lock around DRBG */ + unsigned char *V; /* internal state 10.1.1.1 1a) */ + unsigned char *Vbuf; + /* hash: static value 10.1.1.1 1b) hmac / ctr: key */ + unsigned char *C; + unsigned char *Cbuf; + /* Number of RNG requests since last reseed -- 10.1.1.1 1c) */ + size_t reseed_ctr; + size_t reseed_threshold; + /* some memory the DRBG can use for its operation */ + unsigned char *scratchpad; + unsigned char *scratchpadbuf; + void *priv_data; /* Cipher handle */ + + struct crypto_skcipher *ctr_handle; /* CTR mode cipher handle */ + struct skcipher_request *ctr_req; /* CTR mode request handle */ + __u8 *outscratchpadbuf; /* CTR mode output scratchpad */ + __u8 *outscratchpad; /* CTR mode aligned outbuf */ + struct crypto_wait ctr_wait; /* CTR mode async wait obj */ + struct scatterlist sg_in, sg_out; /* CTR mode SGLs */ + + enum drbg_seed_state seeded; /* DRBG fully seeded? */ + unsigned long last_seed_time; + bool pr; /* Prediction resistance enabled? */ + struct crypto_rng *jent; + const struct drbg_state_ops *d_ops; + const struct drbg_core *core; + struct drbg_string test_data; +}; + +static inline __u8 drbg_statelen(struct drbg_state *drbg) +{ + if (drbg && drbg->core) + return drbg->core->statelen; + return 0; +} + +static inline __u8 drbg_blocklen(struct drbg_state *drbg) +{ + if (drbg && drbg->core) + return drbg->core->blocklen_bytes; + return 0; +} + +static inline __u8 drbg_keylen(struct drbg_state *drbg) +{ + if (drbg && drbg->core) + return (drbg->core->statelen - drbg->core->blocklen_bytes); + return 0; +} + +static inline size_t drbg_max_request_bytes(struct drbg_state *drbg) +{ + /* SP800-90A requires the limit 2**19 bits, but we return bytes */ + return (1 << 16); +} + +/* + * SP800-90A allows implementations to support additional info / personalization + * strings of up to 2**35 bits. Implementations can have a smaller maximum. We + * use 2**35 - 16 bits == U32_MAX - 1 bytes so that the max + 1 always fits in a + * size_t, allowing drbg_healthcheck_sanity() to verify its enforcement. + */ +static inline size_t drbg_max_addtl(struct drbg_state *drbg) +{ + return U32_MAX - 1; +} + +static inline size_t drbg_max_requests(struct drbg_state *drbg) +{ + /* SP800-90A requires 2**48 maximum requests before reseeding */ + return (1<<20); +} + +/* DRBG type flags */ +#define DRBG_CTR ((drbg_flag_t)1<<0) +#define DRBG_HMAC ((drbg_flag_t)1<<1) +#define DRBG_HASH ((drbg_flag_t)1<<2) +#define DRBG_TYPE_MASK (DRBG_CTR | DRBG_HMAC | DRBG_HASH) +/* DRBG strength flags */ +#define DRBG_STRENGTH128 ((drbg_flag_t)1<<3) +#define DRBG_STRENGTH192 ((drbg_flag_t)1<<4) +#define DRBG_STRENGTH256 ((drbg_flag_t)1<<5) +#define DRBG_STRENGTH_MASK (DRBG_STRENGTH128 | DRBG_STRENGTH192 | \ + DRBG_STRENGTH256) + +enum drbg_prefixes { + DRBG_PREFIX0 = 0x00, + DRBG_PREFIX1, + DRBG_PREFIX2, + DRBG_PREFIX3 +}; + /*************************************************************** * Backend cipher definitions available to DRBG ***************************************************************/ diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 35ff2b50e3c2c..480368a41cc06 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -28,13 +28,12 @@ #include <linux/slab.h> #include <linux/string.h> #include <linux/uio.h> -#include <crypto/rng.h> -#include <crypto/drbg.h> #include <crypto/akcipher.h> #include <crypto/kpp.h> #include <crypto/acompress.h> #include <crypto/sig.h> #include <crypto/internal/cipher.h> +#include <crypto/internal/rng.h> #include <crypto/internal/simd.h> #include "internal.h" |
