18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * DRBG based on NIST SP800-90A 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright Stephan Mueller <smueller@chronox.de>, 2014 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 78c2ecf20Sopenharmony_ci * modification, are permitted provided that the following conditions 88c2ecf20Sopenharmony_ci * are met: 98c2ecf20Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright 108c2ecf20Sopenharmony_ci * notice, and the entire permission notice in its entirety, 118c2ecf20Sopenharmony_ci * including the disclaimer of warranties. 128c2ecf20Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright 138c2ecf20Sopenharmony_ci * notice, this list of conditions and the following disclaimer in the 148c2ecf20Sopenharmony_ci * documentation and/or other materials provided with the distribution. 158c2ecf20Sopenharmony_ci * 3. The name of the author may not be used to endorse or promote 168c2ecf20Sopenharmony_ci * products derived from this software without specific prior 178c2ecf20Sopenharmony_ci * written permission. 188c2ecf20Sopenharmony_ci * 198c2ecf20Sopenharmony_ci * ALTERNATIVELY, this product may be distributed under the terms of 208c2ecf20Sopenharmony_ci * the GNU General Public License, in which case the provisions of the GPL are 218c2ecf20Sopenharmony_ci * required INSTEAD OF the above restrictions. (This clause is 228c2ecf20Sopenharmony_ci * necessary due to a potential bad interaction between the GPL and 238c2ecf20Sopenharmony_ci * the restrictions contained in a BSD-style copyright.) 248c2ecf20Sopenharmony_ci * 258c2ecf20Sopenharmony_ci * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 268c2ecf20Sopenharmony_ci * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 278c2ecf20Sopenharmony_ci * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF 288c2ecf20Sopenharmony_ci * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 298c2ecf20Sopenharmony_ci * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 308c2ecf20Sopenharmony_ci * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 318c2ecf20Sopenharmony_ci * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 328c2ecf20Sopenharmony_ci * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 338c2ecf20Sopenharmony_ci * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 348c2ecf20Sopenharmony_ci * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 358c2ecf20Sopenharmony_ci * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH 368c2ecf20Sopenharmony_ci * DAMAGE. 378c2ecf20Sopenharmony_ci */ 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci#ifndef _DRBG_H 408c2ecf20Sopenharmony_ci#define _DRBG_H 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci#include <linux/random.h> 448c2ecf20Sopenharmony_ci#include <linux/scatterlist.h> 458c2ecf20Sopenharmony_ci#include <crypto/hash.h> 468c2ecf20Sopenharmony_ci#include <crypto/skcipher.h> 478c2ecf20Sopenharmony_ci#include <linux/module.h> 488c2ecf20Sopenharmony_ci#include <linux/crypto.h> 498c2ecf20Sopenharmony_ci#include <linux/slab.h> 508c2ecf20Sopenharmony_ci#include <crypto/internal/rng.h> 518c2ecf20Sopenharmony_ci#include <crypto/rng.h> 528c2ecf20Sopenharmony_ci#include <linux/fips.h> 538c2ecf20Sopenharmony_ci#include <linux/mutex.h> 548c2ecf20Sopenharmony_ci#include <linux/list.h> 558c2ecf20Sopenharmony_ci#include <linux/workqueue.h> 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci/* 588c2ecf20Sopenharmony_ci * Concatenation Helper and string operation helper 598c2ecf20Sopenharmony_ci * 608c2ecf20Sopenharmony_ci * SP800-90A requires the concatenation of different data. To avoid copying 618c2ecf20Sopenharmony_ci * buffers around or allocate additional memory, the following data structure 628c2ecf20Sopenharmony_ci * is used to point to the original memory with its size. In addition, it 638c2ecf20Sopenharmony_ci * is used to build a linked list. The linked list defines the concatenation 648c2ecf20Sopenharmony_ci * of individual buffers. The order of memory block referenced in that 658c2ecf20Sopenharmony_ci * linked list determines the order of concatenation. 668c2ecf20Sopenharmony_ci */ 678c2ecf20Sopenharmony_cistruct drbg_string { 688c2ecf20Sopenharmony_ci const unsigned char *buf; 698c2ecf20Sopenharmony_ci size_t len; 708c2ecf20Sopenharmony_ci struct list_head list; 718c2ecf20Sopenharmony_ci}; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_cistatic inline void drbg_string_fill(struct drbg_string *string, 748c2ecf20Sopenharmony_ci const unsigned char *buf, size_t len) 758c2ecf20Sopenharmony_ci{ 768c2ecf20Sopenharmony_ci string->buf = buf; 778c2ecf20Sopenharmony_ci string->len = len; 788c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&string->list); 798c2ecf20Sopenharmony_ci} 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_cistruct drbg_state; 828c2ecf20Sopenharmony_citypedef uint32_t drbg_flag_t; 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_cistruct drbg_core { 858c2ecf20Sopenharmony_ci drbg_flag_t flags; /* flags for the cipher */ 868c2ecf20Sopenharmony_ci __u8 statelen; /* maximum state length */ 878c2ecf20Sopenharmony_ci __u8 blocklen_bytes; /* block size of output in bytes */ 888c2ecf20Sopenharmony_ci char cra_name[CRYPTO_MAX_ALG_NAME]; /* mapping to kernel crypto API */ 898c2ecf20Sopenharmony_ci /* kernel crypto API backend cipher name */ 908c2ecf20Sopenharmony_ci char backend_cra_name[CRYPTO_MAX_ALG_NAME]; 918c2ecf20Sopenharmony_ci}; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_cistruct drbg_state_ops { 948c2ecf20Sopenharmony_ci int (*update)(struct drbg_state *drbg, struct list_head *seed, 958c2ecf20Sopenharmony_ci int reseed); 968c2ecf20Sopenharmony_ci int (*generate)(struct drbg_state *drbg, 978c2ecf20Sopenharmony_ci unsigned char *buf, unsigned int buflen, 988c2ecf20Sopenharmony_ci struct list_head *addtl); 998c2ecf20Sopenharmony_ci int (*crypto_init)(struct drbg_state *drbg); 1008c2ecf20Sopenharmony_ci int (*crypto_fini)(struct drbg_state *drbg); 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci}; 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_cistruct drbg_test_data { 1058c2ecf20Sopenharmony_ci struct drbg_string *testentropy; /* TEST PARAMETER: test entropy */ 1068c2ecf20Sopenharmony_ci}; 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_cienum drbg_seed_state { 1098c2ecf20Sopenharmony_ci DRBG_SEED_STATE_UNSEEDED, 1108c2ecf20Sopenharmony_ci DRBG_SEED_STATE_PARTIAL, /* Seeded with !rng_is_initialized() */ 1118c2ecf20Sopenharmony_ci DRBG_SEED_STATE_FULL, 1128c2ecf20Sopenharmony_ci}; 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_cistruct drbg_state { 1158c2ecf20Sopenharmony_ci struct mutex drbg_mutex; /* lock around DRBG */ 1168c2ecf20Sopenharmony_ci unsigned char *V; /* internal state 10.1.1.1 1a) */ 1178c2ecf20Sopenharmony_ci unsigned char *Vbuf; 1188c2ecf20Sopenharmony_ci /* hash: static value 10.1.1.1 1b) hmac / ctr: key */ 1198c2ecf20Sopenharmony_ci unsigned char *C; 1208c2ecf20Sopenharmony_ci unsigned char *Cbuf; 1218c2ecf20Sopenharmony_ci /* Number of RNG requests since last reseed -- 10.1.1.1 1c) */ 1228c2ecf20Sopenharmony_ci size_t reseed_ctr; 1238c2ecf20Sopenharmony_ci size_t reseed_threshold; 1248c2ecf20Sopenharmony_ci /* some memory the DRBG can use for its operation */ 1258c2ecf20Sopenharmony_ci unsigned char *scratchpad; 1268c2ecf20Sopenharmony_ci unsigned char *scratchpadbuf; 1278c2ecf20Sopenharmony_ci void *priv_data; /* Cipher handle */ 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci struct crypto_skcipher *ctr_handle; /* CTR mode cipher handle */ 1308c2ecf20Sopenharmony_ci struct skcipher_request *ctr_req; /* CTR mode request handle */ 1318c2ecf20Sopenharmony_ci __u8 *outscratchpadbuf; /* CTR mode output scratchpad */ 1328c2ecf20Sopenharmony_ci __u8 *outscratchpad; /* CTR mode aligned outbuf */ 1338c2ecf20Sopenharmony_ci struct crypto_wait ctr_wait; /* CTR mode async wait obj */ 1348c2ecf20Sopenharmony_ci struct scatterlist sg_in, sg_out; /* CTR mode SGLs */ 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci enum drbg_seed_state seeded; /* DRBG fully seeded? */ 1378c2ecf20Sopenharmony_ci bool pr; /* Prediction resistance enabled? */ 1388c2ecf20Sopenharmony_ci bool fips_primed; /* Continuous test primed? */ 1398c2ecf20Sopenharmony_ci unsigned char *prev; /* FIPS 140-2 continuous test value */ 1408c2ecf20Sopenharmony_ci struct crypto_rng *jent; 1418c2ecf20Sopenharmony_ci const struct drbg_state_ops *d_ops; 1428c2ecf20Sopenharmony_ci const struct drbg_core *core; 1438c2ecf20Sopenharmony_ci struct drbg_string test_data; 1448c2ecf20Sopenharmony_ci}; 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_cistatic inline __u8 drbg_statelen(struct drbg_state *drbg) 1478c2ecf20Sopenharmony_ci{ 1488c2ecf20Sopenharmony_ci if (drbg && drbg->core) 1498c2ecf20Sopenharmony_ci return drbg->core->statelen; 1508c2ecf20Sopenharmony_ci return 0; 1518c2ecf20Sopenharmony_ci} 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_cistatic inline __u8 drbg_blocklen(struct drbg_state *drbg) 1548c2ecf20Sopenharmony_ci{ 1558c2ecf20Sopenharmony_ci if (drbg && drbg->core) 1568c2ecf20Sopenharmony_ci return drbg->core->blocklen_bytes; 1578c2ecf20Sopenharmony_ci return 0; 1588c2ecf20Sopenharmony_ci} 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_cistatic inline __u8 drbg_keylen(struct drbg_state *drbg) 1618c2ecf20Sopenharmony_ci{ 1628c2ecf20Sopenharmony_ci if (drbg && drbg->core) 1638c2ecf20Sopenharmony_ci return (drbg->core->statelen - drbg->core->blocklen_bytes); 1648c2ecf20Sopenharmony_ci return 0; 1658c2ecf20Sopenharmony_ci} 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_cistatic inline size_t drbg_max_request_bytes(struct drbg_state *drbg) 1688c2ecf20Sopenharmony_ci{ 1698c2ecf20Sopenharmony_ci /* SP800-90A requires the limit 2**19 bits, but we return bytes */ 1708c2ecf20Sopenharmony_ci return (1 << 16); 1718c2ecf20Sopenharmony_ci} 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_cistatic inline size_t drbg_max_addtl(struct drbg_state *drbg) 1748c2ecf20Sopenharmony_ci{ 1758c2ecf20Sopenharmony_ci /* SP800-90A requires 2**35 bytes additional info str / pers str */ 1768c2ecf20Sopenharmony_ci#if (__BITS_PER_LONG == 32) 1778c2ecf20Sopenharmony_ci /* 1788c2ecf20Sopenharmony_ci * SP800-90A allows smaller maximum numbers to be returned -- we 1798c2ecf20Sopenharmony_ci * return SIZE_MAX - 1 to allow the verification of the enforcement 1808c2ecf20Sopenharmony_ci * of this value in drbg_healthcheck_sanity. 1818c2ecf20Sopenharmony_ci */ 1828c2ecf20Sopenharmony_ci return (SIZE_MAX - 1); 1838c2ecf20Sopenharmony_ci#else 1848c2ecf20Sopenharmony_ci return (1UL<<35); 1858c2ecf20Sopenharmony_ci#endif 1868c2ecf20Sopenharmony_ci} 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_cistatic inline size_t drbg_max_requests(struct drbg_state *drbg) 1898c2ecf20Sopenharmony_ci{ 1908c2ecf20Sopenharmony_ci /* SP800-90A requires 2**48 maximum requests before reseeding */ 1918c2ecf20Sopenharmony_ci return (1<<20); 1928c2ecf20Sopenharmony_ci} 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci/* 1958c2ecf20Sopenharmony_ci * This is a wrapper to the kernel crypto API function of 1968c2ecf20Sopenharmony_ci * crypto_rng_generate() to allow the caller to provide additional data. 1978c2ecf20Sopenharmony_ci * 1988c2ecf20Sopenharmony_ci * @drng DRBG handle -- see crypto_rng_get_bytes 1998c2ecf20Sopenharmony_ci * @outbuf output buffer -- see crypto_rng_get_bytes 2008c2ecf20Sopenharmony_ci * @outlen length of output buffer -- see crypto_rng_get_bytes 2018c2ecf20Sopenharmony_ci * @addtl_input additional information string input buffer 2028c2ecf20Sopenharmony_ci * @addtllen length of additional information string buffer 2038c2ecf20Sopenharmony_ci * 2048c2ecf20Sopenharmony_ci * return 2058c2ecf20Sopenharmony_ci * see crypto_rng_get_bytes 2068c2ecf20Sopenharmony_ci */ 2078c2ecf20Sopenharmony_cistatic inline int crypto_drbg_get_bytes_addtl(struct crypto_rng *drng, 2088c2ecf20Sopenharmony_ci unsigned char *outbuf, unsigned int outlen, 2098c2ecf20Sopenharmony_ci struct drbg_string *addtl) 2108c2ecf20Sopenharmony_ci{ 2118c2ecf20Sopenharmony_ci return crypto_rng_generate(drng, addtl->buf, addtl->len, 2128c2ecf20Sopenharmony_ci outbuf, outlen); 2138c2ecf20Sopenharmony_ci} 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci/* 2168c2ecf20Sopenharmony_ci * TEST code 2178c2ecf20Sopenharmony_ci * 2188c2ecf20Sopenharmony_ci * This is a wrapper to the kernel crypto API function of 2198c2ecf20Sopenharmony_ci * crypto_rng_generate() to allow the caller to provide additional data and 2208c2ecf20Sopenharmony_ci * allow furnishing of test_data 2218c2ecf20Sopenharmony_ci * 2228c2ecf20Sopenharmony_ci * @drng DRBG handle -- see crypto_rng_get_bytes 2238c2ecf20Sopenharmony_ci * @outbuf output buffer -- see crypto_rng_get_bytes 2248c2ecf20Sopenharmony_ci * @outlen length of output buffer -- see crypto_rng_get_bytes 2258c2ecf20Sopenharmony_ci * @addtl_input additional information string input buffer 2268c2ecf20Sopenharmony_ci * @addtllen length of additional information string buffer 2278c2ecf20Sopenharmony_ci * @test_data filled test data 2288c2ecf20Sopenharmony_ci * 2298c2ecf20Sopenharmony_ci * return 2308c2ecf20Sopenharmony_ci * see crypto_rng_get_bytes 2318c2ecf20Sopenharmony_ci */ 2328c2ecf20Sopenharmony_cistatic inline int crypto_drbg_get_bytes_addtl_test(struct crypto_rng *drng, 2338c2ecf20Sopenharmony_ci unsigned char *outbuf, unsigned int outlen, 2348c2ecf20Sopenharmony_ci struct drbg_string *addtl, 2358c2ecf20Sopenharmony_ci struct drbg_test_data *test_data) 2368c2ecf20Sopenharmony_ci{ 2378c2ecf20Sopenharmony_ci crypto_rng_set_entropy(drng, test_data->testentropy->buf, 2388c2ecf20Sopenharmony_ci test_data->testentropy->len); 2398c2ecf20Sopenharmony_ci return crypto_rng_generate(drng, addtl->buf, addtl->len, 2408c2ecf20Sopenharmony_ci outbuf, outlen); 2418c2ecf20Sopenharmony_ci} 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci/* 2448c2ecf20Sopenharmony_ci * TEST code 2458c2ecf20Sopenharmony_ci * 2468c2ecf20Sopenharmony_ci * This is a wrapper to the kernel crypto API function of 2478c2ecf20Sopenharmony_ci * crypto_rng_reset() to allow the caller to provide test_data 2488c2ecf20Sopenharmony_ci * 2498c2ecf20Sopenharmony_ci * @drng DRBG handle -- see crypto_rng_reset 2508c2ecf20Sopenharmony_ci * @pers personalization string input buffer 2518c2ecf20Sopenharmony_ci * @perslen length of additional information string buffer 2528c2ecf20Sopenharmony_ci * @test_data filled test data 2538c2ecf20Sopenharmony_ci * 2548c2ecf20Sopenharmony_ci * return 2558c2ecf20Sopenharmony_ci * see crypto_rng_reset 2568c2ecf20Sopenharmony_ci */ 2578c2ecf20Sopenharmony_cistatic inline int crypto_drbg_reset_test(struct crypto_rng *drng, 2588c2ecf20Sopenharmony_ci struct drbg_string *pers, 2598c2ecf20Sopenharmony_ci struct drbg_test_data *test_data) 2608c2ecf20Sopenharmony_ci{ 2618c2ecf20Sopenharmony_ci crypto_rng_set_entropy(drng, test_data->testentropy->buf, 2628c2ecf20Sopenharmony_ci test_data->testentropy->len); 2638c2ecf20Sopenharmony_ci return crypto_rng_reset(drng, pers->buf, pers->len); 2648c2ecf20Sopenharmony_ci} 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci/* DRBG type flags */ 2678c2ecf20Sopenharmony_ci#define DRBG_CTR ((drbg_flag_t)1<<0) 2688c2ecf20Sopenharmony_ci#define DRBG_HMAC ((drbg_flag_t)1<<1) 2698c2ecf20Sopenharmony_ci#define DRBG_HASH ((drbg_flag_t)1<<2) 2708c2ecf20Sopenharmony_ci#define DRBG_TYPE_MASK (DRBG_CTR | DRBG_HMAC | DRBG_HASH) 2718c2ecf20Sopenharmony_ci/* DRBG strength flags */ 2728c2ecf20Sopenharmony_ci#define DRBG_STRENGTH128 ((drbg_flag_t)1<<3) 2738c2ecf20Sopenharmony_ci#define DRBG_STRENGTH192 ((drbg_flag_t)1<<4) 2748c2ecf20Sopenharmony_ci#define DRBG_STRENGTH256 ((drbg_flag_t)1<<5) 2758c2ecf20Sopenharmony_ci#define DRBG_STRENGTH_MASK (DRBG_STRENGTH128 | DRBG_STRENGTH192 | \ 2768c2ecf20Sopenharmony_ci DRBG_STRENGTH256) 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_cienum drbg_prefixes { 2798c2ecf20Sopenharmony_ci DRBG_PREFIX0 = 0x00, 2808c2ecf20Sopenharmony_ci DRBG_PREFIX1, 2818c2ecf20Sopenharmony_ci DRBG_PREFIX2, 2828c2ecf20Sopenharmony_ci DRBG_PREFIX3 2838c2ecf20Sopenharmony_ci}; 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci#endif /* _DRBG_H */ 286