162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * DRBG: Deterministic Random Bits Generator 362306a36Sopenharmony_ci * Based on NIST Recommended DRBG from NIST SP800-90A with the following 462306a36Sopenharmony_ci * properties: 562306a36Sopenharmony_ci * * CTR DRBG with DF with AES-128, AES-192, AES-256 cores 662306a36Sopenharmony_ci * * Hash DRBG with DF with SHA-1, SHA-256, SHA-384, SHA-512 cores 762306a36Sopenharmony_ci * * HMAC DRBG with DF with SHA-1, SHA-256, SHA-384, SHA-512 cores 862306a36Sopenharmony_ci * * with and without prediction resistance 962306a36Sopenharmony_ci * 1062306a36Sopenharmony_ci * Copyright Stephan Mueller <smueller@chronox.de>, 2014 1162306a36Sopenharmony_ci * 1262306a36Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 1362306a36Sopenharmony_ci * modification, are permitted provided that the following conditions 1462306a36Sopenharmony_ci * are met: 1562306a36Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright 1662306a36Sopenharmony_ci * notice, and the entire permission notice in its entirety, 1762306a36Sopenharmony_ci * including the disclaimer of warranties. 1862306a36Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright 1962306a36Sopenharmony_ci * notice, this list of conditions and the following disclaimer in the 2062306a36Sopenharmony_ci * documentation and/or other materials provided with the distribution. 2162306a36Sopenharmony_ci * 3. The name of the author may not be used to endorse or promote 2262306a36Sopenharmony_ci * products derived from this software without specific prior 2362306a36Sopenharmony_ci * written permission. 2462306a36Sopenharmony_ci * 2562306a36Sopenharmony_ci * ALTERNATIVELY, this product may be distributed under the terms of 2662306a36Sopenharmony_ci * the GNU General Public License, in which case the provisions of the GPL are 2762306a36Sopenharmony_ci * required INSTEAD OF the above restrictions. (This clause is 2862306a36Sopenharmony_ci * necessary due to a potential bad interaction between the GPL and 2962306a36Sopenharmony_ci * the restrictions contained in a BSD-style copyright.) 3062306a36Sopenharmony_ci * 3162306a36Sopenharmony_ci * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 3262306a36Sopenharmony_ci * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 3362306a36Sopenharmony_ci * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF 3462306a36Sopenharmony_ci * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 3562306a36Sopenharmony_ci * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 3662306a36Sopenharmony_ci * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 3762306a36Sopenharmony_ci * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 3862306a36Sopenharmony_ci * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 3962306a36Sopenharmony_ci * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 4062306a36Sopenharmony_ci * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 4162306a36Sopenharmony_ci * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH 4262306a36Sopenharmony_ci * DAMAGE. 4362306a36Sopenharmony_ci * 4462306a36Sopenharmony_ci * DRBG Usage 4562306a36Sopenharmony_ci * ========== 4662306a36Sopenharmony_ci * The SP 800-90A DRBG allows the user to specify a personalization string 4762306a36Sopenharmony_ci * for initialization as well as an additional information string for each 4862306a36Sopenharmony_ci * random number request. The following code fragments show how a caller 4962306a36Sopenharmony_ci * uses the kernel crypto API to use the full functionality of the DRBG. 5062306a36Sopenharmony_ci * 5162306a36Sopenharmony_ci * Usage without any additional data 5262306a36Sopenharmony_ci * --------------------------------- 5362306a36Sopenharmony_ci * struct crypto_rng *drng; 5462306a36Sopenharmony_ci * int err; 5562306a36Sopenharmony_ci * char data[DATALEN]; 5662306a36Sopenharmony_ci * 5762306a36Sopenharmony_ci * drng = crypto_alloc_rng(drng_name, 0, 0); 5862306a36Sopenharmony_ci * err = crypto_rng_get_bytes(drng, &data, DATALEN); 5962306a36Sopenharmony_ci * crypto_free_rng(drng); 6062306a36Sopenharmony_ci * 6162306a36Sopenharmony_ci * 6262306a36Sopenharmony_ci * Usage with personalization string during initialization 6362306a36Sopenharmony_ci * ------------------------------------------------------- 6462306a36Sopenharmony_ci * struct crypto_rng *drng; 6562306a36Sopenharmony_ci * int err; 6662306a36Sopenharmony_ci * char data[DATALEN]; 6762306a36Sopenharmony_ci * struct drbg_string pers; 6862306a36Sopenharmony_ci * char personalization[11] = "some-string"; 6962306a36Sopenharmony_ci * 7062306a36Sopenharmony_ci * drbg_string_fill(&pers, personalization, strlen(personalization)); 7162306a36Sopenharmony_ci * drng = crypto_alloc_rng(drng_name, 0, 0); 7262306a36Sopenharmony_ci * // The reset completely re-initializes the DRBG with the provided 7362306a36Sopenharmony_ci * // personalization string 7462306a36Sopenharmony_ci * err = crypto_rng_reset(drng, &personalization, strlen(personalization)); 7562306a36Sopenharmony_ci * err = crypto_rng_get_bytes(drng, &data, DATALEN); 7662306a36Sopenharmony_ci * crypto_free_rng(drng); 7762306a36Sopenharmony_ci * 7862306a36Sopenharmony_ci * 7962306a36Sopenharmony_ci * Usage with additional information string during random number request 8062306a36Sopenharmony_ci * --------------------------------------------------------------------- 8162306a36Sopenharmony_ci * struct crypto_rng *drng; 8262306a36Sopenharmony_ci * int err; 8362306a36Sopenharmony_ci * char data[DATALEN]; 8462306a36Sopenharmony_ci * char addtl_string[11] = "some-string"; 8562306a36Sopenharmony_ci * string drbg_string addtl; 8662306a36Sopenharmony_ci * 8762306a36Sopenharmony_ci * drbg_string_fill(&addtl, addtl_string, strlen(addtl_string)); 8862306a36Sopenharmony_ci * drng = crypto_alloc_rng(drng_name, 0, 0); 8962306a36Sopenharmony_ci * // The following call is a wrapper to crypto_rng_get_bytes() and returns 9062306a36Sopenharmony_ci * // the same error codes. 9162306a36Sopenharmony_ci * err = crypto_drbg_get_bytes_addtl(drng, &data, DATALEN, &addtl); 9262306a36Sopenharmony_ci * crypto_free_rng(drng); 9362306a36Sopenharmony_ci * 9462306a36Sopenharmony_ci * 9562306a36Sopenharmony_ci * Usage with personalization and additional information strings 9662306a36Sopenharmony_ci * ------------------------------------------------------------- 9762306a36Sopenharmony_ci * Just mix both scenarios above. 9862306a36Sopenharmony_ci */ 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci#include <crypto/drbg.h> 10162306a36Sopenharmony_ci#include <crypto/internal/cipher.h> 10262306a36Sopenharmony_ci#include <linux/kernel.h> 10362306a36Sopenharmony_ci#include <linux/jiffies.h> 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci/*************************************************************** 10662306a36Sopenharmony_ci * Backend cipher definitions available to DRBG 10762306a36Sopenharmony_ci ***************************************************************/ 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci/* 11062306a36Sopenharmony_ci * The order of the DRBG definitions here matter: every DRBG is registered 11162306a36Sopenharmony_ci * as stdrng. Each DRBG receives an increasing cra_priority values the later 11262306a36Sopenharmony_ci * they are defined in this array (see drbg_fill_array). 11362306a36Sopenharmony_ci * 11462306a36Sopenharmony_ci * HMAC DRBGs are favored over Hash DRBGs over CTR DRBGs, and 11562306a36Sopenharmony_ci * the SHA256 / AES 256 over other ciphers. Thus, the favored 11662306a36Sopenharmony_ci * DRBGs are the latest entries in this array. 11762306a36Sopenharmony_ci */ 11862306a36Sopenharmony_cistatic const struct drbg_core drbg_cores[] = { 11962306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_DRBG_CTR 12062306a36Sopenharmony_ci { 12162306a36Sopenharmony_ci .flags = DRBG_CTR | DRBG_STRENGTH128, 12262306a36Sopenharmony_ci .statelen = 32, /* 256 bits as defined in 10.2.1 */ 12362306a36Sopenharmony_ci .blocklen_bytes = 16, 12462306a36Sopenharmony_ci .cra_name = "ctr_aes128", 12562306a36Sopenharmony_ci .backend_cra_name = "aes", 12662306a36Sopenharmony_ci }, { 12762306a36Sopenharmony_ci .flags = DRBG_CTR | DRBG_STRENGTH192, 12862306a36Sopenharmony_ci .statelen = 40, /* 320 bits as defined in 10.2.1 */ 12962306a36Sopenharmony_ci .blocklen_bytes = 16, 13062306a36Sopenharmony_ci .cra_name = "ctr_aes192", 13162306a36Sopenharmony_ci .backend_cra_name = "aes", 13262306a36Sopenharmony_ci }, { 13362306a36Sopenharmony_ci .flags = DRBG_CTR | DRBG_STRENGTH256, 13462306a36Sopenharmony_ci .statelen = 48, /* 384 bits as defined in 10.2.1 */ 13562306a36Sopenharmony_ci .blocklen_bytes = 16, 13662306a36Sopenharmony_ci .cra_name = "ctr_aes256", 13762306a36Sopenharmony_ci .backend_cra_name = "aes", 13862306a36Sopenharmony_ci }, 13962306a36Sopenharmony_ci#endif /* CONFIG_CRYPTO_DRBG_CTR */ 14062306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_DRBG_HASH 14162306a36Sopenharmony_ci { 14262306a36Sopenharmony_ci .flags = DRBG_HASH | DRBG_STRENGTH128, 14362306a36Sopenharmony_ci .statelen = 55, /* 440 bits */ 14462306a36Sopenharmony_ci .blocklen_bytes = 20, 14562306a36Sopenharmony_ci .cra_name = "sha1", 14662306a36Sopenharmony_ci .backend_cra_name = "sha1", 14762306a36Sopenharmony_ci }, { 14862306a36Sopenharmony_ci .flags = DRBG_HASH | DRBG_STRENGTH256, 14962306a36Sopenharmony_ci .statelen = 111, /* 888 bits */ 15062306a36Sopenharmony_ci .blocklen_bytes = 48, 15162306a36Sopenharmony_ci .cra_name = "sha384", 15262306a36Sopenharmony_ci .backend_cra_name = "sha384", 15362306a36Sopenharmony_ci }, { 15462306a36Sopenharmony_ci .flags = DRBG_HASH | DRBG_STRENGTH256, 15562306a36Sopenharmony_ci .statelen = 111, /* 888 bits */ 15662306a36Sopenharmony_ci .blocklen_bytes = 64, 15762306a36Sopenharmony_ci .cra_name = "sha512", 15862306a36Sopenharmony_ci .backend_cra_name = "sha512", 15962306a36Sopenharmony_ci }, { 16062306a36Sopenharmony_ci .flags = DRBG_HASH | DRBG_STRENGTH256, 16162306a36Sopenharmony_ci .statelen = 55, /* 440 bits */ 16262306a36Sopenharmony_ci .blocklen_bytes = 32, 16362306a36Sopenharmony_ci .cra_name = "sha256", 16462306a36Sopenharmony_ci .backend_cra_name = "sha256", 16562306a36Sopenharmony_ci }, 16662306a36Sopenharmony_ci#endif /* CONFIG_CRYPTO_DRBG_HASH */ 16762306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_DRBG_HMAC 16862306a36Sopenharmony_ci { 16962306a36Sopenharmony_ci .flags = DRBG_HMAC | DRBG_STRENGTH128, 17062306a36Sopenharmony_ci .statelen = 20, /* block length of cipher */ 17162306a36Sopenharmony_ci .blocklen_bytes = 20, 17262306a36Sopenharmony_ci .cra_name = "hmac_sha1", 17362306a36Sopenharmony_ci .backend_cra_name = "hmac(sha1)", 17462306a36Sopenharmony_ci }, { 17562306a36Sopenharmony_ci .flags = DRBG_HMAC | DRBG_STRENGTH256, 17662306a36Sopenharmony_ci .statelen = 48, /* block length of cipher */ 17762306a36Sopenharmony_ci .blocklen_bytes = 48, 17862306a36Sopenharmony_ci .cra_name = "hmac_sha384", 17962306a36Sopenharmony_ci .backend_cra_name = "hmac(sha384)", 18062306a36Sopenharmony_ci }, { 18162306a36Sopenharmony_ci .flags = DRBG_HMAC | DRBG_STRENGTH256, 18262306a36Sopenharmony_ci .statelen = 32, /* block length of cipher */ 18362306a36Sopenharmony_ci .blocklen_bytes = 32, 18462306a36Sopenharmony_ci .cra_name = "hmac_sha256", 18562306a36Sopenharmony_ci .backend_cra_name = "hmac(sha256)", 18662306a36Sopenharmony_ci }, { 18762306a36Sopenharmony_ci .flags = DRBG_HMAC | DRBG_STRENGTH256, 18862306a36Sopenharmony_ci .statelen = 64, /* block length of cipher */ 18962306a36Sopenharmony_ci .blocklen_bytes = 64, 19062306a36Sopenharmony_ci .cra_name = "hmac_sha512", 19162306a36Sopenharmony_ci .backend_cra_name = "hmac(sha512)", 19262306a36Sopenharmony_ci }, 19362306a36Sopenharmony_ci#endif /* CONFIG_CRYPTO_DRBG_HMAC */ 19462306a36Sopenharmony_ci}; 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_cistatic int drbg_uninstantiate(struct drbg_state *drbg); 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci/****************************************************************** 19962306a36Sopenharmony_ci * Generic helper functions 20062306a36Sopenharmony_ci ******************************************************************/ 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci/* 20362306a36Sopenharmony_ci * Return strength of DRBG according to SP800-90A section 8.4 20462306a36Sopenharmony_ci * 20562306a36Sopenharmony_ci * @flags DRBG flags reference 20662306a36Sopenharmony_ci * 20762306a36Sopenharmony_ci * Return: normalized strength in *bytes* value or 32 as default 20862306a36Sopenharmony_ci * to counter programming errors 20962306a36Sopenharmony_ci */ 21062306a36Sopenharmony_cistatic inline unsigned short drbg_sec_strength(drbg_flag_t flags) 21162306a36Sopenharmony_ci{ 21262306a36Sopenharmony_ci switch (flags & DRBG_STRENGTH_MASK) { 21362306a36Sopenharmony_ci case DRBG_STRENGTH128: 21462306a36Sopenharmony_ci return 16; 21562306a36Sopenharmony_ci case DRBG_STRENGTH192: 21662306a36Sopenharmony_ci return 24; 21762306a36Sopenharmony_ci case DRBG_STRENGTH256: 21862306a36Sopenharmony_ci return 32; 21962306a36Sopenharmony_ci default: 22062306a36Sopenharmony_ci return 32; 22162306a36Sopenharmony_ci } 22262306a36Sopenharmony_ci} 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci/* 22562306a36Sopenharmony_ci * FIPS 140-2 continuous self test for the noise source 22662306a36Sopenharmony_ci * The test is performed on the noise source input data. Thus, the function 22762306a36Sopenharmony_ci * implicitly knows the size of the buffer to be equal to the security 22862306a36Sopenharmony_ci * strength. 22962306a36Sopenharmony_ci * 23062306a36Sopenharmony_ci * Note, this function disregards the nonce trailing the entropy data during 23162306a36Sopenharmony_ci * initial seeding. 23262306a36Sopenharmony_ci * 23362306a36Sopenharmony_ci * drbg->drbg_mutex must have been taken. 23462306a36Sopenharmony_ci * 23562306a36Sopenharmony_ci * @drbg DRBG handle 23662306a36Sopenharmony_ci * @entropy buffer of seed data to be checked 23762306a36Sopenharmony_ci * 23862306a36Sopenharmony_ci * return: 23962306a36Sopenharmony_ci * 0 on success 24062306a36Sopenharmony_ci * -EAGAIN on when the CTRNG is not yet primed 24162306a36Sopenharmony_ci * < 0 on error 24262306a36Sopenharmony_ci */ 24362306a36Sopenharmony_cistatic int drbg_fips_continuous_test(struct drbg_state *drbg, 24462306a36Sopenharmony_ci const unsigned char *entropy) 24562306a36Sopenharmony_ci{ 24662306a36Sopenharmony_ci unsigned short entropylen = drbg_sec_strength(drbg->core->flags); 24762306a36Sopenharmony_ci int ret = 0; 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci if (!IS_ENABLED(CONFIG_CRYPTO_FIPS)) 25062306a36Sopenharmony_ci return 0; 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci /* skip test if we test the overall system */ 25362306a36Sopenharmony_ci if (list_empty(&drbg->test_data.list)) 25462306a36Sopenharmony_ci return 0; 25562306a36Sopenharmony_ci /* only perform test in FIPS mode */ 25662306a36Sopenharmony_ci if (!fips_enabled) 25762306a36Sopenharmony_ci return 0; 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci if (!drbg->fips_primed) { 26062306a36Sopenharmony_ci /* Priming of FIPS test */ 26162306a36Sopenharmony_ci memcpy(drbg->prev, entropy, entropylen); 26262306a36Sopenharmony_ci drbg->fips_primed = true; 26362306a36Sopenharmony_ci /* priming: another round is needed */ 26462306a36Sopenharmony_ci return -EAGAIN; 26562306a36Sopenharmony_ci } 26662306a36Sopenharmony_ci ret = memcmp(drbg->prev, entropy, entropylen); 26762306a36Sopenharmony_ci if (!ret) 26862306a36Sopenharmony_ci panic("DRBG continuous self test failed\n"); 26962306a36Sopenharmony_ci memcpy(drbg->prev, entropy, entropylen); 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci /* the test shall pass when the two values are not equal */ 27262306a36Sopenharmony_ci return 0; 27362306a36Sopenharmony_ci} 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci/* 27662306a36Sopenharmony_ci * Convert an integer into a byte representation of this integer. 27762306a36Sopenharmony_ci * The byte representation is big-endian 27862306a36Sopenharmony_ci * 27962306a36Sopenharmony_ci * @val value to be converted 28062306a36Sopenharmony_ci * @buf buffer holding the converted integer -- caller must ensure that 28162306a36Sopenharmony_ci * buffer size is at least 32 bit 28262306a36Sopenharmony_ci */ 28362306a36Sopenharmony_ci#if (defined(CONFIG_CRYPTO_DRBG_HASH) || defined(CONFIG_CRYPTO_DRBG_CTR)) 28462306a36Sopenharmony_cistatic inline void drbg_cpu_to_be32(__u32 val, unsigned char *buf) 28562306a36Sopenharmony_ci{ 28662306a36Sopenharmony_ci struct s { 28762306a36Sopenharmony_ci __be32 conv; 28862306a36Sopenharmony_ci }; 28962306a36Sopenharmony_ci struct s *conversion = (struct s *) buf; 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci conversion->conv = cpu_to_be32(val); 29262306a36Sopenharmony_ci} 29362306a36Sopenharmony_ci#endif /* defined(CONFIG_CRYPTO_DRBG_HASH) || defined(CONFIG_CRYPTO_DRBG_CTR) */ 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci/****************************************************************** 29662306a36Sopenharmony_ci * CTR DRBG callback functions 29762306a36Sopenharmony_ci ******************************************************************/ 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_DRBG_CTR 30062306a36Sopenharmony_ci#define CRYPTO_DRBG_CTR_STRING "CTR " 30162306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("drbg_pr_ctr_aes256"); 30262306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("drbg_nopr_ctr_aes256"); 30362306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("drbg_pr_ctr_aes192"); 30462306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("drbg_nopr_ctr_aes192"); 30562306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("drbg_pr_ctr_aes128"); 30662306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("drbg_nopr_ctr_aes128"); 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_cistatic void drbg_kcapi_symsetkey(struct drbg_state *drbg, 30962306a36Sopenharmony_ci const unsigned char *key); 31062306a36Sopenharmony_cistatic int drbg_kcapi_sym(struct drbg_state *drbg, unsigned char *outval, 31162306a36Sopenharmony_ci const struct drbg_string *in); 31262306a36Sopenharmony_cistatic int drbg_init_sym_kernel(struct drbg_state *drbg); 31362306a36Sopenharmony_cistatic int drbg_fini_sym_kernel(struct drbg_state *drbg); 31462306a36Sopenharmony_cistatic int drbg_kcapi_sym_ctr(struct drbg_state *drbg, 31562306a36Sopenharmony_ci u8 *inbuf, u32 inbuflen, 31662306a36Sopenharmony_ci u8 *outbuf, u32 outlen); 31762306a36Sopenharmony_ci#define DRBG_OUTSCRATCHLEN 256 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci/* BCC function for CTR DRBG as defined in 10.4.3 */ 32062306a36Sopenharmony_cistatic int drbg_ctr_bcc(struct drbg_state *drbg, 32162306a36Sopenharmony_ci unsigned char *out, const unsigned char *key, 32262306a36Sopenharmony_ci struct list_head *in) 32362306a36Sopenharmony_ci{ 32462306a36Sopenharmony_ci int ret = 0; 32562306a36Sopenharmony_ci struct drbg_string *curr = NULL; 32662306a36Sopenharmony_ci struct drbg_string data; 32762306a36Sopenharmony_ci short cnt = 0; 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci drbg_string_fill(&data, out, drbg_blocklen(drbg)); 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci /* 10.4.3 step 2 / 4 */ 33262306a36Sopenharmony_ci drbg_kcapi_symsetkey(drbg, key); 33362306a36Sopenharmony_ci list_for_each_entry(curr, in, list) { 33462306a36Sopenharmony_ci const unsigned char *pos = curr->buf; 33562306a36Sopenharmony_ci size_t len = curr->len; 33662306a36Sopenharmony_ci /* 10.4.3 step 4.1 */ 33762306a36Sopenharmony_ci while (len) { 33862306a36Sopenharmony_ci /* 10.4.3 step 4.2 */ 33962306a36Sopenharmony_ci if (drbg_blocklen(drbg) == cnt) { 34062306a36Sopenharmony_ci cnt = 0; 34162306a36Sopenharmony_ci ret = drbg_kcapi_sym(drbg, out, &data); 34262306a36Sopenharmony_ci if (ret) 34362306a36Sopenharmony_ci return ret; 34462306a36Sopenharmony_ci } 34562306a36Sopenharmony_ci out[cnt] ^= *pos; 34662306a36Sopenharmony_ci pos++; 34762306a36Sopenharmony_ci cnt++; 34862306a36Sopenharmony_ci len--; 34962306a36Sopenharmony_ci } 35062306a36Sopenharmony_ci } 35162306a36Sopenharmony_ci /* 10.4.3 step 4.2 for last block */ 35262306a36Sopenharmony_ci if (cnt) 35362306a36Sopenharmony_ci ret = drbg_kcapi_sym(drbg, out, &data); 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_ci return ret; 35662306a36Sopenharmony_ci} 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci/* 35962306a36Sopenharmony_ci * scratchpad usage: drbg_ctr_update is interlinked with drbg_ctr_df 36062306a36Sopenharmony_ci * (and drbg_ctr_bcc, but this function does not need any temporary buffers), 36162306a36Sopenharmony_ci * the scratchpad is used as follows: 36262306a36Sopenharmony_ci * drbg_ctr_update: 36362306a36Sopenharmony_ci * temp 36462306a36Sopenharmony_ci * start: drbg->scratchpad 36562306a36Sopenharmony_ci * length: drbg_statelen(drbg) + drbg_blocklen(drbg) 36662306a36Sopenharmony_ci * note: the cipher writing into this variable works 36762306a36Sopenharmony_ci * blocklen-wise. Now, when the statelen is not a multiple 36862306a36Sopenharmony_ci * of blocklen, the generateion loop below "spills over" 36962306a36Sopenharmony_ci * by at most blocklen. Thus, we need to give sufficient 37062306a36Sopenharmony_ci * memory. 37162306a36Sopenharmony_ci * df_data 37262306a36Sopenharmony_ci * start: drbg->scratchpad + 37362306a36Sopenharmony_ci * drbg_statelen(drbg) + drbg_blocklen(drbg) 37462306a36Sopenharmony_ci * length: drbg_statelen(drbg) 37562306a36Sopenharmony_ci * 37662306a36Sopenharmony_ci * drbg_ctr_df: 37762306a36Sopenharmony_ci * pad 37862306a36Sopenharmony_ci * start: df_data + drbg_statelen(drbg) 37962306a36Sopenharmony_ci * length: drbg_blocklen(drbg) 38062306a36Sopenharmony_ci * iv 38162306a36Sopenharmony_ci * start: pad + drbg_blocklen(drbg) 38262306a36Sopenharmony_ci * length: drbg_blocklen(drbg) 38362306a36Sopenharmony_ci * temp 38462306a36Sopenharmony_ci * start: iv + drbg_blocklen(drbg) 38562306a36Sopenharmony_ci * length: drbg_satelen(drbg) + drbg_blocklen(drbg) 38662306a36Sopenharmony_ci * note: temp is the buffer that the BCC function operates 38762306a36Sopenharmony_ci * on. BCC operates blockwise. drbg_statelen(drbg) 38862306a36Sopenharmony_ci * is sufficient when the DRBG state length is a multiple 38962306a36Sopenharmony_ci * of the block size. For AES192 (and maybe other ciphers) 39062306a36Sopenharmony_ci * this is not correct and the length for temp is 39162306a36Sopenharmony_ci * insufficient (yes, that also means for such ciphers, 39262306a36Sopenharmony_ci * the final output of all BCC rounds are truncated). 39362306a36Sopenharmony_ci * Therefore, add drbg_blocklen(drbg) to cover all 39462306a36Sopenharmony_ci * possibilities. 39562306a36Sopenharmony_ci */ 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_ci/* Derivation Function for CTR DRBG as defined in 10.4.2 */ 39862306a36Sopenharmony_cistatic int drbg_ctr_df(struct drbg_state *drbg, 39962306a36Sopenharmony_ci unsigned char *df_data, size_t bytes_to_return, 40062306a36Sopenharmony_ci struct list_head *seedlist) 40162306a36Sopenharmony_ci{ 40262306a36Sopenharmony_ci int ret = -EFAULT; 40362306a36Sopenharmony_ci unsigned char L_N[8]; 40462306a36Sopenharmony_ci /* S3 is input */ 40562306a36Sopenharmony_ci struct drbg_string S1, S2, S4, cipherin; 40662306a36Sopenharmony_ci LIST_HEAD(bcc_list); 40762306a36Sopenharmony_ci unsigned char *pad = df_data + drbg_statelen(drbg); 40862306a36Sopenharmony_ci unsigned char *iv = pad + drbg_blocklen(drbg); 40962306a36Sopenharmony_ci unsigned char *temp = iv + drbg_blocklen(drbg); 41062306a36Sopenharmony_ci size_t padlen = 0; 41162306a36Sopenharmony_ci unsigned int templen = 0; 41262306a36Sopenharmony_ci /* 10.4.2 step 7 */ 41362306a36Sopenharmony_ci unsigned int i = 0; 41462306a36Sopenharmony_ci /* 10.4.2 step 8 */ 41562306a36Sopenharmony_ci const unsigned char *K = (unsigned char *) 41662306a36Sopenharmony_ci "\x00\x01\x02\x03\x04\x05\x06\x07" 41762306a36Sopenharmony_ci "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" 41862306a36Sopenharmony_ci "\x10\x11\x12\x13\x14\x15\x16\x17" 41962306a36Sopenharmony_ci "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"; 42062306a36Sopenharmony_ci unsigned char *X; 42162306a36Sopenharmony_ci size_t generated_len = 0; 42262306a36Sopenharmony_ci size_t inputlen = 0; 42362306a36Sopenharmony_ci struct drbg_string *seed = NULL; 42462306a36Sopenharmony_ci 42562306a36Sopenharmony_ci memset(pad, 0, drbg_blocklen(drbg)); 42662306a36Sopenharmony_ci memset(iv, 0, drbg_blocklen(drbg)); 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_ci /* 10.4.2 step 1 is implicit as we work byte-wise */ 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci /* 10.4.2 step 2 */ 43162306a36Sopenharmony_ci if ((512/8) < bytes_to_return) 43262306a36Sopenharmony_ci return -EINVAL; 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_ci /* 10.4.2 step 2 -- calculate the entire length of all input data */ 43562306a36Sopenharmony_ci list_for_each_entry(seed, seedlist, list) 43662306a36Sopenharmony_ci inputlen += seed->len; 43762306a36Sopenharmony_ci drbg_cpu_to_be32(inputlen, &L_N[0]); 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_ci /* 10.4.2 step 3 */ 44062306a36Sopenharmony_ci drbg_cpu_to_be32(bytes_to_return, &L_N[4]); 44162306a36Sopenharmony_ci 44262306a36Sopenharmony_ci /* 10.4.2 step 5: length is L_N, input_string, one byte, padding */ 44362306a36Sopenharmony_ci padlen = (inputlen + sizeof(L_N) + 1) % (drbg_blocklen(drbg)); 44462306a36Sopenharmony_ci /* wrap the padlen appropriately */ 44562306a36Sopenharmony_ci if (padlen) 44662306a36Sopenharmony_ci padlen = drbg_blocklen(drbg) - padlen; 44762306a36Sopenharmony_ci /* 44862306a36Sopenharmony_ci * pad / padlen contains the 0x80 byte and the following zero bytes. 44962306a36Sopenharmony_ci * As the calculated padlen value only covers the number of zero 45062306a36Sopenharmony_ci * bytes, this value has to be incremented by one for the 0x80 byte. 45162306a36Sopenharmony_ci */ 45262306a36Sopenharmony_ci padlen++; 45362306a36Sopenharmony_ci pad[0] = 0x80; 45462306a36Sopenharmony_ci 45562306a36Sopenharmony_ci /* 10.4.2 step 4 -- first fill the linked list and then order it */ 45662306a36Sopenharmony_ci drbg_string_fill(&S1, iv, drbg_blocklen(drbg)); 45762306a36Sopenharmony_ci list_add_tail(&S1.list, &bcc_list); 45862306a36Sopenharmony_ci drbg_string_fill(&S2, L_N, sizeof(L_N)); 45962306a36Sopenharmony_ci list_add_tail(&S2.list, &bcc_list); 46062306a36Sopenharmony_ci list_splice_tail(seedlist, &bcc_list); 46162306a36Sopenharmony_ci drbg_string_fill(&S4, pad, padlen); 46262306a36Sopenharmony_ci list_add_tail(&S4.list, &bcc_list); 46362306a36Sopenharmony_ci 46462306a36Sopenharmony_ci /* 10.4.2 step 9 */ 46562306a36Sopenharmony_ci while (templen < (drbg_keylen(drbg) + (drbg_blocklen(drbg)))) { 46662306a36Sopenharmony_ci /* 46762306a36Sopenharmony_ci * 10.4.2 step 9.1 - the padding is implicit as the buffer 46862306a36Sopenharmony_ci * holds zeros after allocation -- even the increment of i 46962306a36Sopenharmony_ci * is irrelevant as the increment remains within length of i 47062306a36Sopenharmony_ci */ 47162306a36Sopenharmony_ci drbg_cpu_to_be32(i, iv); 47262306a36Sopenharmony_ci /* 10.4.2 step 9.2 -- BCC and concatenation with temp */ 47362306a36Sopenharmony_ci ret = drbg_ctr_bcc(drbg, temp + templen, K, &bcc_list); 47462306a36Sopenharmony_ci if (ret) 47562306a36Sopenharmony_ci goto out; 47662306a36Sopenharmony_ci /* 10.4.2 step 9.3 */ 47762306a36Sopenharmony_ci i++; 47862306a36Sopenharmony_ci templen += drbg_blocklen(drbg); 47962306a36Sopenharmony_ci } 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_ci /* 10.4.2 step 11 */ 48262306a36Sopenharmony_ci X = temp + (drbg_keylen(drbg)); 48362306a36Sopenharmony_ci drbg_string_fill(&cipherin, X, drbg_blocklen(drbg)); 48462306a36Sopenharmony_ci 48562306a36Sopenharmony_ci /* 10.4.2 step 12: overwriting of outval is implemented in next step */ 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_ci /* 10.4.2 step 13 */ 48862306a36Sopenharmony_ci drbg_kcapi_symsetkey(drbg, temp); 48962306a36Sopenharmony_ci while (generated_len < bytes_to_return) { 49062306a36Sopenharmony_ci short blocklen = 0; 49162306a36Sopenharmony_ci /* 49262306a36Sopenharmony_ci * 10.4.2 step 13.1: the truncation of the key length is 49362306a36Sopenharmony_ci * implicit as the key is only drbg_blocklen in size based on 49462306a36Sopenharmony_ci * the implementation of the cipher function callback 49562306a36Sopenharmony_ci */ 49662306a36Sopenharmony_ci ret = drbg_kcapi_sym(drbg, X, &cipherin); 49762306a36Sopenharmony_ci if (ret) 49862306a36Sopenharmony_ci goto out; 49962306a36Sopenharmony_ci blocklen = (drbg_blocklen(drbg) < 50062306a36Sopenharmony_ci (bytes_to_return - generated_len)) ? 50162306a36Sopenharmony_ci drbg_blocklen(drbg) : 50262306a36Sopenharmony_ci (bytes_to_return - generated_len); 50362306a36Sopenharmony_ci /* 10.4.2 step 13.2 and 14 */ 50462306a36Sopenharmony_ci memcpy(df_data + generated_len, X, blocklen); 50562306a36Sopenharmony_ci generated_len += blocklen; 50662306a36Sopenharmony_ci } 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci ret = 0; 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_ciout: 51162306a36Sopenharmony_ci memset(iv, 0, drbg_blocklen(drbg)); 51262306a36Sopenharmony_ci memset(temp, 0, drbg_statelen(drbg) + drbg_blocklen(drbg)); 51362306a36Sopenharmony_ci memset(pad, 0, drbg_blocklen(drbg)); 51462306a36Sopenharmony_ci return ret; 51562306a36Sopenharmony_ci} 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ci/* 51862306a36Sopenharmony_ci * update function of CTR DRBG as defined in 10.2.1.2 51962306a36Sopenharmony_ci * 52062306a36Sopenharmony_ci * The reseed variable has an enhanced meaning compared to the update 52162306a36Sopenharmony_ci * functions of the other DRBGs as follows: 52262306a36Sopenharmony_ci * 0 => initial seed from initialization 52362306a36Sopenharmony_ci * 1 => reseed via drbg_seed 52462306a36Sopenharmony_ci * 2 => first invocation from drbg_ctr_update when addtl is present. In 52562306a36Sopenharmony_ci * this case, the df_data scratchpad is not deleted so that it is 52662306a36Sopenharmony_ci * available for another calls to prevent calling the DF function 52762306a36Sopenharmony_ci * again. 52862306a36Sopenharmony_ci * 3 => second invocation from drbg_ctr_update. When the update function 52962306a36Sopenharmony_ci * was called with addtl, the df_data memory already contains the 53062306a36Sopenharmony_ci * DFed addtl information and we do not need to call DF again. 53162306a36Sopenharmony_ci */ 53262306a36Sopenharmony_cistatic int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed, 53362306a36Sopenharmony_ci int reseed) 53462306a36Sopenharmony_ci{ 53562306a36Sopenharmony_ci int ret = -EFAULT; 53662306a36Sopenharmony_ci /* 10.2.1.2 step 1 */ 53762306a36Sopenharmony_ci unsigned char *temp = drbg->scratchpad; 53862306a36Sopenharmony_ci unsigned char *df_data = drbg->scratchpad + drbg_statelen(drbg) + 53962306a36Sopenharmony_ci drbg_blocklen(drbg); 54062306a36Sopenharmony_ci 54162306a36Sopenharmony_ci if (3 > reseed) 54262306a36Sopenharmony_ci memset(df_data, 0, drbg_statelen(drbg)); 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_ci if (!reseed) { 54562306a36Sopenharmony_ci /* 54662306a36Sopenharmony_ci * The DRBG uses the CTR mode of the underlying AES cipher. The 54762306a36Sopenharmony_ci * CTR mode increments the counter value after the AES operation 54862306a36Sopenharmony_ci * but SP800-90A requires that the counter is incremented before 54962306a36Sopenharmony_ci * the AES operation. Hence, we increment it at the time we set 55062306a36Sopenharmony_ci * it by one. 55162306a36Sopenharmony_ci */ 55262306a36Sopenharmony_ci crypto_inc(drbg->V, drbg_blocklen(drbg)); 55362306a36Sopenharmony_ci 55462306a36Sopenharmony_ci ret = crypto_skcipher_setkey(drbg->ctr_handle, drbg->C, 55562306a36Sopenharmony_ci drbg_keylen(drbg)); 55662306a36Sopenharmony_ci if (ret) 55762306a36Sopenharmony_ci goto out; 55862306a36Sopenharmony_ci } 55962306a36Sopenharmony_ci 56062306a36Sopenharmony_ci /* 10.2.1.3.2 step 2 and 10.2.1.4.2 step 2 */ 56162306a36Sopenharmony_ci if (seed) { 56262306a36Sopenharmony_ci ret = drbg_ctr_df(drbg, df_data, drbg_statelen(drbg), seed); 56362306a36Sopenharmony_ci if (ret) 56462306a36Sopenharmony_ci goto out; 56562306a36Sopenharmony_ci } 56662306a36Sopenharmony_ci 56762306a36Sopenharmony_ci ret = drbg_kcapi_sym_ctr(drbg, df_data, drbg_statelen(drbg), 56862306a36Sopenharmony_ci temp, drbg_statelen(drbg)); 56962306a36Sopenharmony_ci if (ret) 57062306a36Sopenharmony_ci return ret; 57162306a36Sopenharmony_ci 57262306a36Sopenharmony_ci /* 10.2.1.2 step 5 */ 57362306a36Sopenharmony_ci ret = crypto_skcipher_setkey(drbg->ctr_handle, temp, 57462306a36Sopenharmony_ci drbg_keylen(drbg)); 57562306a36Sopenharmony_ci if (ret) 57662306a36Sopenharmony_ci goto out; 57762306a36Sopenharmony_ci /* 10.2.1.2 step 6 */ 57862306a36Sopenharmony_ci memcpy(drbg->V, temp + drbg_keylen(drbg), drbg_blocklen(drbg)); 57962306a36Sopenharmony_ci /* See above: increment counter by one to compensate timing of CTR op */ 58062306a36Sopenharmony_ci crypto_inc(drbg->V, drbg_blocklen(drbg)); 58162306a36Sopenharmony_ci ret = 0; 58262306a36Sopenharmony_ci 58362306a36Sopenharmony_ciout: 58462306a36Sopenharmony_ci memset(temp, 0, drbg_statelen(drbg) + drbg_blocklen(drbg)); 58562306a36Sopenharmony_ci if (2 != reseed) 58662306a36Sopenharmony_ci memset(df_data, 0, drbg_statelen(drbg)); 58762306a36Sopenharmony_ci return ret; 58862306a36Sopenharmony_ci} 58962306a36Sopenharmony_ci 59062306a36Sopenharmony_ci/* 59162306a36Sopenharmony_ci * scratchpad use: drbg_ctr_update is called independently from 59262306a36Sopenharmony_ci * drbg_ctr_extract_bytes. Therefore, the scratchpad is reused 59362306a36Sopenharmony_ci */ 59462306a36Sopenharmony_ci/* Generate function of CTR DRBG as defined in 10.2.1.5.2 */ 59562306a36Sopenharmony_cistatic int drbg_ctr_generate(struct drbg_state *drbg, 59662306a36Sopenharmony_ci unsigned char *buf, unsigned int buflen, 59762306a36Sopenharmony_ci struct list_head *addtl) 59862306a36Sopenharmony_ci{ 59962306a36Sopenharmony_ci int ret; 60062306a36Sopenharmony_ci int len = min_t(int, buflen, INT_MAX); 60162306a36Sopenharmony_ci 60262306a36Sopenharmony_ci /* 10.2.1.5.2 step 2 */ 60362306a36Sopenharmony_ci if (addtl && !list_empty(addtl)) { 60462306a36Sopenharmony_ci ret = drbg_ctr_update(drbg, addtl, 2); 60562306a36Sopenharmony_ci if (ret) 60662306a36Sopenharmony_ci return 0; 60762306a36Sopenharmony_ci } 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_ci /* 10.2.1.5.2 step 4.1 */ 61062306a36Sopenharmony_ci ret = drbg_kcapi_sym_ctr(drbg, NULL, 0, buf, len); 61162306a36Sopenharmony_ci if (ret) 61262306a36Sopenharmony_ci return ret; 61362306a36Sopenharmony_ci 61462306a36Sopenharmony_ci /* 10.2.1.5.2 step 6 */ 61562306a36Sopenharmony_ci ret = drbg_ctr_update(drbg, NULL, 3); 61662306a36Sopenharmony_ci if (ret) 61762306a36Sopenharmony_ci len = ret; 61862306a36Sopenharmony_ci 61962306a36Sopenharmony_ci return len; 62062306a36Sopenharmony_ci} 62162306a36Sopenharmony_ci 62262306a36Sopenharmony_cistatic const struct drbg_state_ops drbg_ctr_ops = { 62362306a36Sopenharmony_ci .update = drbg_ctr_update, 62462306a36Sopenharmony_ci .generate = drbg_ctr_generate, 62562306a36Sopenharmony_ci .crypto_init = drbg_init_sym_kernel, 62662306a36Sopenharmony_ci .crypto_fini = drbg_fini_sym_kernel, 62762306a36Sopenharmony_ci}; 62862306a36Sopenharmony_ci#endif /* CONFIG_CRYPTO_DRBG_CTR */ 62962306a36Sopenharmony_ci 63062306a36Sopenharmony_ci/****************************************************************** 63162306a36Sopenharmony_ci * HMAC DRBG callback functions 63262306a36Sopenharmony_ci ******************************************************************/ 63362306a36Sopenharmony_ci 63462306a36Sopenharmony_ci#if defined(CONFIG_CRYPTO_DRBG_HASH) || defined(CONFIG_CRYPTO_DRBG_HMAC) 63562306a36Sopenharmony_cistatic int drbg_kcapi_hash(struct drbg_state *drbg, unsigned char *outval, 63662306a36Sopenharmony_ci const struct list_head *in); 63762306a36Sopenharmony_cistatic void drbg_kcapi_hmacsetkey(struct drbg_state *drbg, 63862306a36Sopenharmony_ci const unsigned char *key); 63962306a36Sopenharmony_cistatic int drbg_init_hash_kernel(struct drbg_state *drbg); 64062306a36Sopenharmony_cistatic int drbg_fini_hash_kernel(struct drbg_state *drbg); 64162306a36Sopenharmony_ci#endif /* (CONFIG_CRYPTO_DRBG_HASH || CONFIG_CRYPTO_DRBG_HMAC) */ 64262306a36Sopenharmony_ci 64362306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_DRBG_HMAC 64462306a36Sopenharmony_ci#define CRYPTO_DRBG_HMAC_STRING "HMAC " 64562306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("drbg_pr_hmac_sha512"); 64662306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("drbg_nopr_hmac_sha512"); 64762306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("drbg_pr_hmac_sha384"); 64862306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("drbg_nopr_hmac_sha384"); 64962306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("drbg_pr_hmac_sha256"); 65062306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("drbg_nopr_hmac_sha256"); 65162306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("drbg_pr_hmac_sha1"); 65262306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("drbg_nopr_hmac_sha1"); 65362306a36Sopenharmony_ci 65462306a36Sopenharmony_ci/* update function of HMAC DRBG as defined in 10.1.2.2 */ 65562306a36Sopenharmony_cistatic int drbg_hmac_update(struct drbg_state *drbg, struct list_head *seed, 65662306a36Sopenharmony_ci int reseed) 65762306a36Sopenharmony_ci{ 65862306a36Sopenharmony_ci int ret = -EFAULT; 65962306a36Sopenharmony_ci int i = 0; 66062306a36Sopenharmony_ci struct drbg_string seed1, seed2, vdata; 66162306a36Sopenharmony_ci LIST_HEAD(seedlist); 66262306a36Sopenharmony_ci LIST_HEAD(vdatalist); 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_ci if (!reseed) { 66562306a36Sopenharmony_ci /* 10.1.2.3 step 2 -- memset(0) of C is implicit with kzalloc */ 66662306a36Sopenharmony_ci memset(drbg->V, 1, drbg_statelen(drbg)); 66762306a36Sopenharmony_ci drbg_kcapi_hmacsetkey(drbg, drbg->C); 66862306a36Sopenharmony_ci } 66962306a36Sopenharmony_ci 67062306a36Sopenharmony_ci drbg_string_fill(&seed1, drbg->V, drbg_statelen(drbg)); 67162306a36Sopenharmony_ci list_add_tail(&seed1.list, &seedlist); 67262306a36Sopenharmony_ci /* buffer of seed2 will be filled in for loop below with one byte */ 67362306a36Sopenharmony_ci drbg_string_fill(&seed2, NULL, 1); 67462306a36Sopenharmony_ci list_add_tail(&seed2.list, &seedlist); 67562306a36Sopenharmony_ci /* input data of seed is allowed to be NULL at this point */ 67662306a36Sopenharmony_ci if (seed) 67762306a36Sopenharmony_ci list_splice_tail(seed, &seedlist); 67862306a36Sopenharmony_ci 67962306a36Sopenharmony_ci drbg_string_fill(&vdata, drbg->V, drbg_statelen(drbg)); 68062306a36Sopenharmony_ci list_add_tail(&vdata.list, &vdatalist); 68162306a36Sopenharmony_ci for (i = 2; 0 < i; i--) { 68262306a36Sopenharmony_ci /* first round uses 0x0, second 0x1 */ 68362306a36Sopenharmony_ci unsigned char prefix = DRBG_PREFIX0; 68462306a36Sopenharmony_ci if (1 == i) 68562306a36Sopenharmony_ci prefix = DRBG_PREFIX1; 68662306a36Sopenharmony_ci /* 10.1.2.2 step 1 and 4 -- concatenation and HMAC for key */ 68762306a36Sopenharmony_ci seed2.buf = &prefix; 68862306a36Sopenharmony_ci ret = drbg_kcapi_hash(drbg, drbg->C, &seedlist); 68962306a36Sopenharmony_ci if (ret) 69062306a36Sopenharmony_ci return ret; 69162306a36Sopenharmony_ci drbg_kcapi_hmacsetkey(drbg, drbg->C); 69262306a36Sopenharmony_ci 69362306a36Sopenharmony_ci /* 10.1.2.2 step 2 and 5 -- HMAC for V */ 69462306a36Sopenharmony_ci ret = drbg_kcapi_hash(drbg, drbg->V, &vdatalist); 69562306a36Sopenharmony_ci if (ret) 69662306a36Sopenharmony_ci return ret; 69762306a36Sopenharmony_ci 69862306a36Sopenharmony_ci /* 10.1.2.2 step 3 */ 69962306a36Sopenharmony_ci if (!seed) 70062306a36Sopenharmony_ci return ret; 70162306a36Sopenharmony_ci } 70262306a36Sopenharmony_ci 70362306a36Sopenharmony_ci return 0; 70462306a36Sopenharmony_ci} 70562306a36Sopenharmony_ci 70662306a36Sopenharmony_ci/* generate function of HMAC DRBG as defined in 10.1.2.5 */ 70762306a36Sopenharmony_cistatic int drbg_hmac_generate(struct drbg_state *drbg, 70862306a36Sopenharmony_ci unsigned char *buf, 70962306a36Sopenharmony_ci unsigned int buflen, 71062306a36Sopenharmony_ci struct list_head *addtl) 71162306a36Sopenharmony_ci{ 71262306a36Sopenharmony_ci int len = 0; 71362306a36Sopenharmony_ci int ret = 0; 71462306a36Sopenharmony_ci struct drbg_string data; 71562306a36Sopenharmony_ci LIST_HEAD(datalist); 71662306a36Sopenharmony_ci 71762306a36Sopenharmony_ci /* 10.1.2.5 step 2 */ 71862306a36Sopenharmony_ci if (addtl && !list_empty(addtl)) { 71962306a36Sopenharmony_ci ret = drbg_hmac_update(drbg, addtl, 1); 72062306a36Sopenharmony_ci if (ret) 72162306a36Sopenharmony_ci return ret; 72262306a36Sopenharmony_ci } 72362306a36Sopenharmony_ci 72462306a36Sopenharmony_ci drbg_string_fill(&data, drbg->V, drbg_statelen(drbg)); 72562306a36Sopenharmony_ci list_add_tail(&data.list, &datalist); 72662306a36Sopenharmony_ci while (len < buflen) { 72762306a36Sopenharmony_ci unsigned int outlen = 0; 72862306a36Sopenharmony_ci /* 10.1.2.5 step 4.1 */ 72962306a36Sopenharmony_ci ret = drbg_kcapi_hash(drbg, drbg->V, &datalist); 73062306a36Sopenharmony_ci if (ret) 73162306a36Sopenharmony_ci return ret; 73262306a36Sopenharmony_ci outlen = (drbg_blocklen(drbg) < (buflen - len)) ? 73362306a36Sopenharmony_ci drbg_blocklen(drbg) : (buflen - len); 73462306a36Sopenharmony_ci 73562306a36Sopenharmony_ci /* 10.1.2.5 step 4.2 */ 73662306a36Sopenharmony_ci memcpy(buf + len, drbg->V, outlen); 73762306a36Sopenharmony_ci len += outlen; 73862306a36Sopenharmony_ci } 73962306a36Sopenharmony_ci 74062306a36Sopenharmony_ci /* 10.1.2.5 step 6 */ 74162306a36Sopenharmony_ci if (addtl && !list_empty(addtl)) 74262306a36Sopenharmony_ci ret = drbg_hmac_update(drbg, addtl, 1); 74362306a36Sopenharmony_ci else 74462306a36Sopenharmony_ci ret = drbg_hmac_update(drbg, NULL, 1); 74562306a36Sopenharmony_ci if (ret) 74662306a36Sopenharmony_ci return ret; 74762306a36Sopenharmony_ci 74862306a36Sopenharmony_ci return len; 74962306a36Sopenharmony_ci} 75062306a36Sopenharmony_ci 75162306a36Sopenharmony_cistatic const struct drbg_state_ops drbg_hmac_ops = { 75262306a36Sopenharmony_ci .update = drbg_hmac_update, 75362306a36Sopenharmony_ci .generate = drbg_hmac_generate, 75462306a36Sopenharmony_ci .crypto_init = drbg_init_hash_kernel, 75562306a36Sopenharmony_ci .crypto_fini = drbg_fini_hash_kernel, 75662306a36Sopenharmony_ci}; 75762306a36Sopenharmony_ci#endif /* CONFIG_CRYPTO_DRBG_HMAC */ 75862306a36Sopenharmony_ci 75962306a36Sopenharmony_ci/****************************************************************** 76062306a36Sopenharmony_ci * Hash DRBG callback functions 76162306a36Sopenharmony_ci ******************************************************************/ 76262306a36Sopenharmony_ci 76362306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_DRBG_HASH 76462306a36Sopenharmony_ci#define CRYPTO_DRBG_HASH_STRING "HASH " 76562306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("drbg_pr_sha512"); 76662306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("drbg_nopr_sha512"); 76762306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("drbg_pr_sha384"); 76862306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("drbg_nopr_sha384"); 76962306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("drbg_pr_sha256"); 77062306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("drbg_nopr_sha256"); 77162306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("drbg_pr_sha1"); 77262306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("drbg_nopr_sha1"); 77362306a36Sopenharmony_ci 77462306a36Sopenharmony_ci/* 77562306a36Sopenharmony_ci * Increment buffer 77662306a36Sopenharmony_ci * 77762306a36Sopenharmony_ci * @dst buffer to increment 77862306a36Sopenharmony_ci * @add value to add 77962306a36Sopenharmony_ci */ 78062306a36Sopenharmony_cistatic inline void drbg_add_buf(unsigned char *dst, size_t dstlen, 78162306a36Sopenharmony_ci const unsigned char *add, size_t addlen) 78262306a36Sopenharmony_ci{ 78362306a36Sopenharmony_ci /* implied: dstlen > addlen */ 78462306a36Sopenharmony_ci unsigned char *dstptr; 78562306a36Sopenharmony_ci const unsigned char *addptr; 78662306a36Sopenharmony_ci unsigned int remainder = 0; 78762306a36Sopenharmony_ci size_t len = addlen; 78862306a36Sopenharmony_ci 78962306a36Sopenharmony_ci dstptr = dst + (dstlen-1); 79062306a36Sopenharmony_ci addptr = add + (addlen-1); 79162306a36Sopenharmony_ci while (len) { 79262306a36Sopenharmony_ci remainder += *dstptr + *addptr; 79362306a36Sopenharmony_ci *dstptr = remainder & 0xff; 79462306a36Sopenharmony_ci remainder >>= 8; 79562306a36Sopenharmony_ci len--; dstptr--; addptr--; 79662306a36Sopenharmony_ci } 79762306a36Sopenharmony_ci len = dstlen - addlen; 79862306a36Sopenharmony_ci while (len && remainder > 0) { 79962306a36Sopenharmony_ci remainder = *dstptr + 1; 80062306a36Sopenharmony_ci *dstptr = remainder & 0xff; 80162306a36Sopenharmony_ci remainder >>= 8; 80262306a36Sopenharmony_ci len--; dstptr--; 80362306a36Sopenharmony_ci } 80462306a36Sopenharmony_ci} 80562306a36Sopenharmony_ci 80662306a36Sopenharmony_ci/* 80762306a36Sopenharmony_ci * scratchpad usage: as drbg_hash_update and drbg_hash_df are used 80862306a36Sopenharmony_ci * interlinked, the scratchpad is used as follows: 80962306a36Sopenharmony_ci * drbg_hash_update 81062306a36Sopenharmony_ci * start: drbg->scratchpad 81162306a36Sopenharmony_ci * length: drbg_statelen(drbg) 81262306a36Sopenharmony_ci * drbg_hash_df: 81362306a36Sopenharmony_ci * start: drbg->scratchpad + drbg_statelen(drbg) 81462306a36Sopenharmony_ci * length: drbg_blocklen(drbg) 81562306a36Sopenharmony_ci * 81662306a36Sopenharmony_ci * drbg_hash_process_addtl uses the scratchpad, but fully completes 81762306a36Sopenharmony_ci * before either of the functions mentioned before are invoked. Therefore, 81862306a36Sopenharmony_ci * drbg_hash_process_addtl does not need to be specifically considered. 81962306a36Sopenharmony_ci */ 82062306a36Sopenharmony_ci 82162306a36Sopenharmony_ci/* Derivation Function for Hash DRBG as defined in 10.4.1 */ 82262306a36Sopenharmony_cistatic int drbg_hash_df(struct drbg_state *drbg, 82362306a36Sopenharmony_ci unsigned char *outval, size_t outlen, 82462306a36Sopenharmony_ci struct list_head *entropylist) 82562306a36Sopenharmony_ci{ 82662306a36Sopenharmony_ci int ret = 0; 82762306a36Sopenharmony_ci size_t len = 0; 82862306a36Sopenharmony_ci unsigned char input[5]; 82962306a36Sopenharmony_ci unsigned char *tmp = drbg->scratchpad + drbg_statelen(drbg); 83062306a36Sopenharmony_ci struct drbg_string data; 83162306a36Sopenharmony_ci 83262306a36Sopenharmony_ci /* 10.4.1 step 3 */ 83362306a36Sopenharmony_ci input[0] = 1; 83462306a36Sopenharmony_ci drbg_cpu_to_be32((outlen * 8), &input[1]); 83562306a36Sopenharmony_ci 83662306a36Sopenharmony_ci /* 10.4.1 step 4.1 -- concatenation of data for input into hash */ 83762306a36Sopenharmony_ci drbg_string_fill(&data, input, 5); 83862306a36Sopenharmony_ci list_add(&data.list, entropylist); 83962306a36Sopenharmony_ci 84062306a36Sopenharmony_ci /* 10.4.1 step 4 */ 84162306a36Sopenharmony_ci while (len < outlen) { 84262306a36Sopenharmony_ci short blocklen = 0; 84362306a36Sopenharmony_ci /* 10.4.1 step 4.1 */ 84462306a36Sopenharmony_ci ret = drbg_kcapi_hash(drbg, tmp, entropylist); 84562306a36Sopenharmony_ci if (ret) 84662306a36Sopenharmony_ci goto out; 84762306a36Sopenharmony_ci /* 10.4.1 step 4.2 */ 84862306a36Sopenharmony_ci input[0]++; 84962306a36Sopenharmony_ci blocklen = (drbg_blocklen(drbg) < (outlen - len)) ? 85062306a36Sopenharmony_ci drbg_blocklen(drbg) : (outlen - len); 85162306a36Sopenharmony_ci memcpy(outval + len, tmp, blocklen); 85262306a36Sopenharmony_ci len += blocklen; 85362306a36Sopenharmony_ci } 85462306a36Sopenharmony_ci 85562306a36Sopenharmony_ciout: 85662306a36Sopenharmony_ci memset(tmp, 0, drbg_blocklen(drbg)); 85762306a36Sopenharmony_ci return ret; 85862306a36Sopenharmony_ci} 85962306a36Sopenharmony_ci 86062306a36Sopenharmony_ci/* update function for Hash DRBG as defined in 10.1.1.2 / 10.1.1.3 */ 86162306a36Sopenharmony_cistatic int drbg_hash_update(struct drbg_state *drbg, struct list_head *seed, 86262306a36Sopenharmony_ci int reseed) 86362306a36Sopenharmony_ci{ 86462306a36Sopenharmony_ci int ret = 0; 86562306a36Sopenharmony_ci struct drbg_string data1, data2; 86662306a36Sopenharmony_ci LIST_HEAD(datalist); 86762306a36Sopenharmony_ci LIST_HEAD(datalist2); 86862306a36Sopenharmony_ci unsigned char *V = drbg->scratchpad; 86962306a36Sopenharmony_ci unsigned char prefix = DRBG_PREFIX1; 87062306a36Sopenharmony_ci 87162306a36Sopenharmony_ci if (!seed) 87262306a36Sopenharmony_ci return -EINVAL; 87362306a36Sopenharmony_ci 87462306a36Sopenharmony_ci if (reseed) { 87562306a36Sopenharmony_ci /* 10.1.1.3 step 1 */ 87662306a36Sopenharmony_ci memcpy(V, drbg->V, drbg_statelen(drbg)); 87762306a36Sopenharmony_ci drbg_string_fill(&data1, &prefix, 1); 87862306a36Sopenharmony_ci list_add_tail(&data1.list, &datalist); 87962306a36Sopenharmony_ci drbg_string_fill(&data2, V, drbg_statelen(drbg)); 88062306a36Sopenharmony_ci list_add_tail(&data2.list, &datalist); 88162306a36Sopenharmony_ci } 88262306a36Sopenharmony_ci list_splice_tail(seed, &datalist); 88362306a36Sopenharmony_ci 88462306a36Sopenharmony_ci /* 10.1.1.2 / 10.1.1.3 step 2 and 3 */ 88562306a36Sopenharmony_ci ret = drbg_hash_df(drbg, drbg->V, drbg_statelen(drbg), &datalist); 88662306a36Sopenharmony_ci if (ret) 88762306a36Sopenharmony_ci goto out; 88862306a36Sopenharmony_ci 88962306a36Sopenharmony_ci /* 10.1.1.2 / 10.1.1.3 step 4 */ 89062306a36Sopenharmony_ci prefix = DRBG_PREFIX0; 89162306a36Sopenharmony_ci drbg_string_fill(&data1, &prefix, 1); 89262306a36Sopenharmony_ci list_add_tail(&data1.list, &datalist2); 89362306a36Sopenharmony_ci drbg_string_fill(&data2, drbg->V, drbg_statelen(drbg)); 89462306a36Sopenharmony_ci list_add_tail(&data2.list, &datalist2); 89562306a36Sopenharmony_ci /* 10.1.1.2 / 10.1.1.3 step 4 */ 89662306a36Sopenharmony_ci ret = drbg_hash_df(drbg, drbg->C, drbg_statelen(drbg), &datalist2); 89762306a36Sopenharmony_ci 89862306a36Sopenharmony_ciout: 89962306a36Sopenharmony_ci memset(drbg->scratchpad, 0, drbg_statelen(drbg)); 90062306a36Sopenharmony_ci return ret; 90162306a36Sopenharmony_ci} 90262306a36Sopenharmony_ci 90362306a36Sopenharmony_ci/* processing of additional information string for Hash DRBG */ 90462306a36Sopenharmony_cistatic int drbg_hash_process_addtl(struct drbg_state *drbg, 90562306a36Sopenharmony_ci struct list_head *addtl) 90662306a36Sopenharmony_ci{ 90762306a36Sopenharmony_ci int ret = 0; 90862306a36Sopenharmony_ci struct drbg_string data1, data2; 90962306a36Sopenharmony_ci LIST_HEAD(datalist); 91062306a36Sopenharmony_ci unsigned char prefix = DRBG_PREFIX2; 91162306a36Sopenharmony_ci 91262306a36Sopenharmony_ci /* 10.1.1.4 step 2 */ 91362306a36Sopenharmony_ci if (!addtl || list_empty(addtl)) 91462306a36Sopenharmony_ci return 0; 91562306a36Sopenharmony_ci 91662306a36Sopenharmony_ci /* 10.1.1.4 step 2a */ 91762306a36Sopenharmony_ci drbg_string_fill(&data1, &prefix, 1); 91862306a36Sopenharmony_ci drbg_string_fill(&data2, drbg->V, drbg_statelen(drbg)); 91962306a36Sopenharmony_ci list_add_tail(&data1.list, &datalist); 92062306a36Sopenharmony_ci list_add_tail(&data2.list, &datalist); 92162306a36Sopenharmony_ci list_splice_tail(addtl, &datalist); 92262306a36Sopenharmony_ci ret = drbg_kcapi_hash(drbg, drbg->scratchpad, &datalist); 92362306a36Sopenharmony_ci if (ret) 92462306a36Sopenharmony_ci goto out; 92562306a36Sopenharmony_ci 92662306a36Sopenharmony_ci /* 10.1.1.4 step 2b */ 92762306a36Sopenharmony_ci drbg_add_buf(drbg->V, drbg_statelen(drbg), 92862306a36Sopenharmony_ci drbg->scratchpad, drbg_blocklen(drbg)); 92962306a36Sopenharmony_ci 93062306a36Sopenharmony_ciout: 93162306a36Sopenharmony_ci memset(drbg->scratchpad, 0, drbg_blocklen(drbg)); 93262306a36Sopenharmony_ci return ret; 93362306a36Sopenharmony_ci} 93462306a36Sopenharmony_ci 93562306a36Sopenharmony_ci/* Hashgen defined in 10.1.1.4 */ 93662306a36Sopenharmony_cistatic int drbg_hash_hashgen(struct drbg_state *drbg, 93762306a36Sopenharmony_ci unsigned char *buf, 93862306a36Sopenharmony_ci unsigned int buflen) 93962306a36Sopenharmony_ci{ 94062306a36Sopenharmony_ci int len = 0; 94162306a36Sopenharmony_ci int ret = 0; 94262306a36Sopenharmony_ci unsigned char *src = drbg->scratchpad; 94362306a36Sopenharmony_ci unsigned char *dst = drbg->scratchpad + drbg_statelen(drbg); 94462306a36Sopenharmony_ci struct drbg_string data; 94562306a36Sopenharmony_ci LIST_HEAD(datalist); 94662306a36Sopenharmony_ci 94762306a36Sopenharmony_ci /* 10.1.1.4 step hashgen 2 */ 94862306a36Sopenharmony_ci memcpy(src, drbg->V, drbg_statelen(drbg)); 94962306a36Sopenharmony_ci 95062306a36Sopenharmony_ci drbg_string_fill(&data, src, drbg_statelen(drbg)); 95162306a36Sopenharmony_ci list_add_tail(&data.list, &datalist); 95262306a36Sopenharmony_ci while (len < buflen) { 95362306a36Sopenharmony_ci unsigned int outlen = 0; 95462306a36Sopenharmony_ci /* 10.1.1.4 step hashgen 4.1 */ 95562306a36Sopenharmony_ci ret = drbg_kcapi_hash(drbg, dst, &datalist); 95662306a36Sopenharmony_ci if (ret) { 95762306a36Sopenharmony_ci len = ret; 95862306a36Sopenharmony_ci goto out; 95962306a36Sopenharmony_ci } 96062306a36Sopenharmony_ci outlen = (drbg_blocklen(drbg) < (buflen - len)) ? 96162306a36Sopenharmony_ci drbg_blocklen(drbg) : (buflen - len); 96262306a36Sopenharmony_ci /* 10.1.1.4 step hashgen 4.2 */ 96362306a36Sopenharmony_ci memcpy(buf + len, dst, outlen); 96462306a36Sopenharmony_ci len += outlen; 96562306a36Sopenharmony_ci /* 10.1.1.4 hashgen step 4.3 */ 96662306a36Sopenharmony_ci if (len < buflen) 96762306a36Sopenharmony_ci crypto_inc(src, drbg_statelen(drbg)); 96862306a36Sopenharmony_ci } 96962306a36Sopenharmony_ci 97062306a36Sopenharmony_ciout: 97162306a36Sopenharmony_ci memset(drbg->scratchpad, 0, 97262306a36Sopenharmony_ci (drbg_statelen(drbg) + drbg_blocklen(drbg))); 97362306a36Sopenharmony_ci return len; 97462306a36Sopenharmony_ci} 97562306a36Sopenharmony_ci 97662306a36Sopenharmony_ci/* generate function for Hash DRBG as defined in 10.1.1.4 */ 97762306a36Sopenharmony_cistatic int drbg_hash_generate(struct drbg_state *drbg, 97862306a36Sopenharmony_ci unsigned char *buf, unsigned int buflen, 97962306a36Sopenharmony_ci struct list_head *addtl) 98062306a36Sopenharmony_ci{ 98162306a36Sopenharmony_ci int len = 0; 98262306a36Sopenharmony_ci int ret = 0; 98362306a36Sopenharmony_ci union { 98462306a36Sopenharmony_ci unsigned char req[8]; 98562306a36Sopenharmony_ci __be64 req_int; 98662306a36Sopenharmony_ci } u; 98762306a36Sopenharmony_ci unsigned char prefix = DRBG_PREFIX3; 98862306a36Sopenharmony_ci struct drbg_string data1, data2; 98962306a36Sopenharmony_ci LIST_HEAD(datalist); 99062306a36Sopenharmony_ci 99162306a36Sopenharmony_ci /* 10.1.1.4 step 2 */ 99262306a36Sopenharmony_ci ret = drbg_hash_process_addtl(drbg, addtl); 99362306a36Sopenharmony_ci if (ret) 99462306a36Sopenharmony_ci return ret; 99562306a36Sopenharmony_ci /* 10.1.1.4 step 3 */ 99662306a36Sopenharmony_ci len = drbg_hash_hashgen(drbg, buf, buflen); 99762306a36Sopenharmony_ci 99862306a36Sopenharmony_ci /* this is the value H as documented in 10.1.1.4 */ 99962306a36Sopenharmony_ci /* 10.1.1.4 step 4 */ 100062306a36Sopenharmony_ci drbg_string_fill(&data1, &prefix, 1); 100162306a36Sopenharmony_ci list_add_tail(&data1.list, &datalist); 100262306a36Sopenharmony_ci drbg_string_fill(&data2, drbg->V, drbg_statelen(drbg)); 100362306a36Sopenharmony_ci list_add_tail(&data2.list, &datalist); 100462306a36Sopenharmony_ci ret = drbg_kcapi_hash(drbg, drbg->scratchpad, &datalist); 100562306a36Sopenharmony_ci if (ret) { 100662306a36Sopenharmony_ci len = ret; 100762306a36Sopenharmony_ci goto out; 100862306a36Sopenharmony_ci } 100962306a36Sopenharmony_ci 101062306a36Sopenharmony_ci /* 10.1.1.4 step 5 */ 101162306a36Sopenharmony_ci drbg_add_buf(drbg->V, drbg_statelen(drbg), 101262306a36Sopenharmony_ci drbg->scratchpad, drbg_blocklen(drbg)); 101362306a36Sopenharmony_ci drbg_add_buf(drbg->V, drbg_statelen(drbg), 101462306a36Sopenharmony_ci drbg->C, drbg_statelen(drbg)); 101562306a36Sopenharmony_ci u.req_int = cpu_to_be64(drbg->reseed_ctr); 101662306a36Sopenharmony_ci drbg_add_buf(drbg->V, drbg_statelen(drbg), u.req, 8); 101762306a36Sopenharmony_ci 101862306a36Sopenharmony_ciout: 101962306a36Sopenharmony_ci memset(drbg->scratchpad, 0, drbg_blocklen(drbg)); 102062306a36Sopenharmony_ci return len; 102162306a36Sopenharmony_ci} 102262306a36Sopenharmony_ci 102362306a36Sopenharmony_ci/* 102462306a36Sopenharmony_ci * scratchpad usage: as update and generate are used isolated, both 102562306a36Sopenharmony_ci * can use the scratchpad 102662306a36Sopenharmony_ci */ 102762306a36Sopenharmony_cistatic const struct drbg_state_ops drbg_hash_ops = { 102862306a36Sopenharmony_ci .update = drbg_hash_update, 102962306a36Sopenharmony_ci .generate = drbg_hash_generate, 103062306a36Sopenharmony_ci .crypto_init = drbg_init_hash_kernel, 103162306a36Sopenharmony_ci .crypto_fini = drbg_fini_hash_kernel, 103262306a36Sopenharmony_ci}; 103362306a36Sopenharmony_ci#endif /* CONFIG_CRYPTO_DRBG_HASH */ 103462306a36Sopenharmony_ci 103562306a36Sopenharmony_ci/****************************************************************** 103662306a36Sopenharmony_ci * Functions common for DRBG implementations 103762306a36Sopenharmony_ci ******************************************************************/ 103862306a36Sopenharmony_ci 103962306a36Sopenharmony_cistatic inline int __drbg_seed(struct drbg_state *drbg, struct list_head *seed, 104062306a36Sopenharmony_ci int reseed, enum drbg_seed_state new_seed_state) 104162306a36Sopenharmony_ci{ 104262306a36Sopenharmony_ci int ret = drbg->d_ops->update(drbg, seed, reseed); 104362306a36Sopenharmony_ci 104462306a36Sopenharmony_ci if (ret) 104562306a36Sopenharmony_ci return ret; 104662306a36Sopenharmony_ci 104762306a36Sopenharmony_ci drbg->seeded = new_seed_state; 104862306a36Sopenharmony_ci drbg->last_seed_time = jiffies; 104962306a36Sopenharmony_ci /* 10.1.1.2 / 10.1.1.3 step 5 */ 105062306a36Sopenharmony_ci drbg->reseed_ctr = 1; 105162306a36Sopenharmony_ci 105262306a36Sopenharmony_ci switch (drbg->seeded) { 105362306a36Sopenharmony_ci case DRBG_SEED_STATE_UNSEEDED: 105462306a36Sopenharmony_ci /* Impossible, but handle it to silence compiler warnings. */ 105562306a36Sopenharmony_ci fallthrough; 105662306a36Sopenharmony_ci case DRBG_SEED_STATE_PARTIAL: 105762306a36Sopenharmony_ci /* 105862306a36Sopenharmony_ci * Require frequent reseeds until the seed source is 105962306a36Sopenharmony_ci * fully initialized. 106062306a36Sopenharmony_ci */ 106162306a36Sopenharmony_ci drbg->reseed_threshold = 50; 106262306a36Sopenharmony_ci break; 106362306a36Sopenharmony_ci 106462306a36Sopenharmony_ci case DRBG_SEED_STATE_FULL: 106562306a36Sopenharmony_ci /* 106662306a36Sopenharmony_ci * Seed source has become fully initialized, frequent 106762306a36Sopenharmony_ci * reseeds no longer required. 106862306a36Sopenharmony_ci */ 106962306a36Sopenharmony_ci drbg->reseed_threshold = drbg_max_requests(drbg); 107062306a36Sopenharmony_ci break; 107162306a36Sopenharmony_ci } 107262306a36Sopenharmony_ci 107362306a36Sopenharmony_ci return ret; 107462306a36Sopenharmony_ci} 107562306a36Sopenharmony_ci 107662306a36Sopenharmony_cistatic inline int drbg_get_random_bytes(struct drbg_state *drbg, 107762306a36Sopenharmony_ci unsigned char *entropy, 107862306a36Sopenharmony_ci unsigned int entropylen) 107962306a36Sopenharmony_ci{ 108062306a36Sopenharmony_ci int ret; 108162306a36Sopenharmony_ci 108262306a36Sopenharmony_ci do { 108362306a36Sopenharmony_ci get_random_bytes(entropy, entropylen); 108462306a36Sopenharmony_ci ret = drbg_fips_continuous_test(drbg, entropy); 108562306a36Sopenharmony_ci if (ret && ret != -EAGAIN) 108662306a36Sopenharmony_ci return ret; 108762306a36Sopenharmony_ci } while (ret); 108862306a36Sopenharmony_ci 108962306a36Sopenharmony_ci return 0; 109062306a36Sopenharmony_ci} 109162306a36Sopenharmony_ci 109262306a36Sopenharmony_cistatic int drbg_seed_from_random(struct drbg_state *drbg) 109362306a36Sopenharmony_ci{ 109462306a36Sopenharmony_ci struct drbg_string data; 109562306a36Sopenharmony_ci LIST_HEAD(seedlist); 109662306a36Sopenharmony_ci unsigned int entropylen = drbg_sec_strength(drbg->core->flags); 109762306a36Sopenharmony_ci unsigned char entropy[32]; 109862306a36Sopenharmony_ci int ret; 109962306a36Sopenharmony_ci 110062306a36Sopenharmony_ci BUG_ON(!entropylen); 110162306a36Sopenharmony_ci BUG_ON(entropylen > sizeof(entropy)); 110262306a36Sopenharmony_ci 110362306a36Sopenharmony_ci drbg_string_fill(&data, entropy, entropylen); 110462306a36Sopenharmony_ci list_add_tail(&data.list, &seedlist); 110562306a36Sopenharmony_ci 110662306a36Sopenharmony_ci ret = drbg_get_random_bytes(drbg, entropy, entropylen); 110762306a36Sopenharmony_ci if (ret) 110862306a36Sopenharmony_ci goto out; 110962306a36Sopenharmony_ci 111062306a36Sopenharmony_ci ret = __drbg_seed(drbg, &seedlist, true, DRBG_SEED_STATE_FULL); 111162306a36Sopenharmony_ci 111262306a36Sopenharmony_ciout: 111362306a36Sopenharmony_ci memzero_explicit(entropy, entropylen); 111462306a36Sopenharmony_ci return ret; 111562306a36Sopenharmony_ci} 111662306a36Sopenharmony_ci 111762306a36Sopenharmony_cistatic bool drbg_nopr_reseed_interval_elapsed(struct drbg_state *drbg) 111862306a36Sopenharmony_ci{ 111962306a36Sopenharmony_ci unsigned long next_reseed; 112062306a36Sopenharmony_ci 112162306a36Sopenharmony_ci /* Don't ever reseed from get_random_bytes() in test mode. */ 112262306a36Sopenharmony_ci if (list_empty(&drbg->test_data.list)) 112362306a36Sopenharmony_ci return false; 112462306a36Sopenharmony_ci 112562306a36Sopenharmony_ci /* 112662306a36Sopenharmony_ci * Obtain fresh entropy for the nopr DRBGs after 300s have 112762306a36Sopenharmony_ci * elapsed in order to still achieve sort of partial 112862306a36Sopenharmony_ci * prediction resistance over the time domain at least. Note 112962306a36Sopenharmony_ci * that the period of 300s has been chosen to match the 113062306a36Sopenharmony_ci * CRNG_RESEED_INTERVAL of the get_random_bytes()' chacha 113162306a36Sopenharmony_ci * rngs. 113262306a36Sopenharmony_ci */ 113362306a36Sopenharmony_ci next_reseed = drbg->last_seed_time + 300 * HZ; 113462306a36Sopenharmony_ci return time_after(jiffies, next_reseed); 113562306a36Sopenharmony_ci} 113662306a36Sopenharmony_ci 113762306a36Sopenharmony_ci/* 113862306a36Sopenharmony_ci * Seeding or reseeding of the DRBG 113962306a36Sopenharmony_ci * 114062306a36Sopenharmony_ci * @drbg: DRBG state struct 114162306a36Sopenharmony_ci * @pers: personalization / additional information buffer 114262306a36Sopenharmony_ci * @reseed: 0 for initial seed process, 1 for reseeding 114362306a36Sopenharmony_ci * 114462306a36Sopenharmony_ci * return: 114562306a36Sopenharmony_ci * 0 on success 114662306a36Sopenharmony_ci * error value otherwise 114762306a36Sopenharmony_ci */ 114862306a36Sopenharmony_cistatic int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers, 114962306a36Sopenharmony_ci bool reseed) 115062306a36Sopenharmony_ci{ 115162306a36Sopenharmony_ci int ret; 115262306a36Sopenharmony_ci unsigned char entropy[((32 + 16) * 2)]; 115362306a36Sopenharmony_ci unsigned int entropylen = drbg_sec_strength(drbg->core->flags); 115462306a36Sopenharmony_ci struct drbg_string data1; 115562306a36Sopenharmony_ci LIST_HEAD(seedlist); 115662306a36Sopenharmony_ci enum drbg_seed_state new_seed_state = DRBG_SEED_STATE_FULL; 115762306a36Sopenharmony_ci 115862306a36Sopenharmony_ci /* 9.1 / 9.2 / 9.3.1 step 3 */ 115962306a36Sopenharmony_ci if (pers && pers->len > (drbg_max_addtl(drbg))) { 116062306a36Sopenharmony_ci pr_devel("DRBG: personalization string too long %zu\n", 116162306a36Sopenharmony_ci pers->len); 116262306a36Sopenharmony_ci return -EINVAL; 116362306a36Sopenharmony_ci } 116462306a36Sopenharmony_ci 116562306a36Sopenharmony_ci if (list_empty(&drbg->test_data.list)) { 116662306a36Sopenharmony_ci drbg_string_fill(&data1, drbg->test_data.buf, 116762306a36Sopenharmony_ci drbg->test_data.len); 116862306a36Sopenharmony_ci pr_devel("DRBG: using test entropy\n"); 116962306a36Sopenharmony_ci } else { 117062306a36Sopenharmony_ci /* 117162306a36Sopenharmony_ci * Gather entropy equal to the security strength of the DRBG. 117262306a36Sopenharmony_ci * With a derivation function, a nonce is required in addition 117362306a36Sopenharmony_ci * to the entropy. A nonce must be at least 1/2 of the security 117462306a36Sopenharmony_ci * strength of the DRBG in size. Thus, entropy + nonce is 3/2 117562306a36Sopenharmony_ci * of the strength. The consideration of a nonce is only 117662306a36Sopenharmony_ci * applicable during initial seeding. 117762306a36Sopenharmony_ci */ 117862306a36Sopenharmony_ci BUG_ON(!entropylen); 117962306a36Sopenharmony_ci if (!reseed) 118062306a36Sopenharmony_ci entropylen = ((entropylen + 1) / 2) * 3; 118162306a36Sopenharmony_ci BUG_ON((entropylen * 2) > sizeof(entropy)); 118262306a36Sopenharmony_ci 118362306a36Sopenharmony_ci /* Get seed from in-kernel /dev/urandom */ 118462306a36Sopenharmony_ci if (!rng_is_initialized()) 118562306a36Sopenharmony_ci new_seed_state = DRBG_SEED_STATE_PARTIAL; 118662306a36Sopenharmony_ci 118762306a36Sopenharmony_ci ret = drbg_get_random_bytes(drbg, entropy, entropylen); 118862306a36Sopenharmony_ci if (ret) 118962306a36Sopenharmony_ci goto out; 119062306a36Sopenharmony_ci 119162306a36Sopenharmony_ci if (!drbg->jent) { 119262306a36Sopenharmony_ci drbg_string_fill(&data1, entropy, entropylen); 119362306a36Sopenharmony_ci pr_devel("DRBG: (re)seeding with %u bytes of entropy\n", 119462306a36Sopenharmony_ci entropylen); 119562306a36Sopenharmony_ci } else { 119662306a36Sopenharmony_ci /* 119762306a36Sopenharmony_ci * Get seed from Jitter RNG, failures are 119862306a36Sopenharmony_ci * fatal only in FIPS mode. 119962306a36Sopenharmony_ci */ 120062306a36Sopenharmony_ci ret = crypto_rng_get_bytes(drbg->jent, 120162306a36Sopenharmony_ci entropy + entropylen, 120262306a36Sopenharmony_ci entropylen); 120362306a36Sopenharmony_ci if (fips_enabled && ret) { 120462306a36Sopenharmony_ci pr_devel("DRBG: jent failed with %d\n", ret); 120562306a36Sopenharmony_ci 120662306a36Sopenharmony_ci /* 120762306a36Sopenharmony_ci * Do not treat the transient failure of the 120862306a36Sopenharmony_ci * Jitter RNG as an error that needs to be 120962306a36Sopenharmony_ci * reported. The combined number of the 121062306a36Sopenharmony_ci * maximum reseed threshold times the maximum 121162306a36Sopenharmony_ci * number of Jitter RNG transient errors is 121262306a36Sopenharmony_ci * less than the reseed threshold required by 121362306a36Sopenharmony_ci * SP800-90A allowing us to treat the 121462306a36Sopenharmony_ci * transient errors as such. 121562306a36Sopenharmony_ci * 121662306a36Sopenharmony_ci * However, we mandate that at least the first 121762306a36Sopenharmony_ci * seeding operation must succeed with the 121862306a36Sopenharmony_ci * Jitter RNG. 121962306a36Sopenharmony_ci */ 122062306a36Sopenharmony_ci if (!reseed || ret != -EAGAIN) 122162306a36Sopenharmony_ci goto out; 122262306a36Sopenharmony_ci } 122362306a36Sopenharmony_ci 122462306a36Sopenharmony_ci drbg_string_fill(&data1, entropy, entropylen * 2); 122562306a36Sopenharmony_ci pr_devel("DRBG: (re)seeding with %u bytes of entropy\n", 122662306a36Sopenharmony_ci entropylen * 2); 122762306a36Sopenharmony_ci } 122862306a36Sopenharmony_ci } 122962306a36Sopenharmony_ci list_add_tail(&data1.list, &seedlist); 123062306a36Sopenharmony_ci 123162306a36Sopenharmony_ci /* 123262306a36Sopenharmony_ci * concatenation of entropy with personalization str / addtl input) 123362306a36Sopenharmony_ci * the variable pers is directly handed in by the caller, so check its 123462306a36Sopenharmony_ci * contents whether it is appropriate 123562306a36Sopenharmony_ci */ 123662306a36Sopenharmony_ci if (pers && pers->buf && 0 < pers->len) { 123762306a36Sopenharmony_ci list_add_tail(&pers->list, &seedlist); 123862306a36Sopenharmony_ci pr_devel("DRBG: using personalization string\n"); 123962306a36Sopenharmony_ci } 124062306a36Sopenharmony_ci 124162306a36Sopenharmony_ci if (!reseed) { 124262306a36Sopenharmony_ci memset(drbg->V, 0, drbg_statelen(drbg)); 124362306a36Sopenharmony_ci memset(drbg->C, 0, drbg_statelen(drbg)); 124462306a36Sopenharmony_ci } 124562306a36Sopenharmony_ci 124662306a36Sopenharmony_ci ret = __drbg_seed(drbg, &seedlist, reseed, new_seed_state); 124762306a36Sopenharmony_ci 124862306a36Sopenharmony_ciout: 124962306a36Sopenharmony_ci memzero_explicit(entropy, entropylen * 2); 125062306a36Sopenharmony_ci 125162306a36Sopenharmony_ci return ret; 125262306a36Sopenharmony_ci} 125362306a36Sopenharmony_ci 125462306a36Sopenharmony_ci/* Free all substructures in a DRBG state without the DRBG state structure */ 125562306a36Sopenharmony_cistatic inline void drbg_dealloc_state(struct drbg_state *drbg) 125662306a36Sopenharmony_ci{ 125762306a36Sopenharmony_ci if (!drbg) 125862306a36Sopenharmony_ci return; 125962306a36Sopenharmony_ci kfree_sensitive(drbg->Vbuf); 126062306a36Sopenharmony_ci drbg->Vbuf = NULL; 126162306a36Sopenharmony_ci drbg->V = NULL; 126262306a36Sopenharmony_ci kfree_sensitive(drbg->Cbuf); 126362306a36Sopenharmony_ci drbg->Cbuf = NULL; 126462306a36Sopenharmony_ci drbg->C = NULL; 126562306a36Sopenharmony_ci kfree_sensitive(drbg->scratchpadbuf); 126662306a36Sopenharmony_ci drbg->scratchpadbuf = NULL; 126762306a36Sopenharmony_ci drbg->reseed_ctr = 0; 126862306a36Sopenharmony_ci drbg->d_ops = NULL; 126962306a36Sopenharmony_ci drbg->core = NULL; 127062306a36Sopenharmony_ci if (IS_ENABLED(CONFIG_CRYPTO_FIPS)) { 127162306a36Sopenharmony_ci kfree_sensitive(drbg->prev); 127262306a36Sopenharmony_ci drbg->prev = NULL; 127362306a36Sopenharmony_ci drbg->fips_primed = false; 127462306a36Sopenharmony_ci } 127562306a36Sopenharmony_ci} 127662306a36Sopenharmony_ci 127762306a36Sopenharmony_ci/* 127862306a36Sopenharmony_ci * Allocate all sub-structures for a DRBG state. 127962306a36Sopenharmony_ci * The DRBG state structure must already be allocated. 128062306a36Sopenharmony_ci */ 128162306a36Sopenharmony_cistatic inline int drbg_alloc_state(struct drbg_state *drbg) 128262306a36Sopenharmony_ci{ 128362306a36Sopenharmony_ci int ret = -ENOMEM; 128462306a36Sopenharmony_ci unsigned int sb_size = 0; 128562306a36Sopenharmony_ci 128662306a36Sopenharmony_ci switch (drbg->core->flags & DRBG_TYPE_MASK) { 128762306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_DRBG_HMAC 128862306a36Sopenharmony_ci case DRBG_HMAC: 128962306a36Sopenharmony_ci drbg->d_ops = &drbg_hmac_ops; 129062306a36Sopenharmony_ci break; 129162306a36Sopenharmony_ci#endif /* CONFIG_CRYPTO_DRBG_HMAC */ 129262306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_DRBG_HASH 129362306a36Sopenharmony_ci case DRBG_HASH: 129462306a36Sopenharmony_ci drbg->d_ops = &drbg_hash_ops; 129562306a36Sopenharmony_ci break; 129662306a36Sopenharmony_ci#endif /* CONFIG_CRYPTO_DRBG_HASH */ 129762306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_DRBG_CTR 129862306a36Sopenharmony_ci case DRBG_CTR: 129962306a36Sopenharmony_ci drbg->d_ops = &drbg_ctr_ops; 130062306a36Sopenharmony_ci break; 130162306a36Sopenharmony_ci#endif /* CONFIG_CRYPTO_DRBG_CTR */ 130262306a36Sopenharmony_ci default: 130362306a36Sopenharmony_ci ret = -EOPNOTSUPP; 130462306a36Sopenharmony_ci goto err; 130562306a36Sopenharmony_ci } 130662306a36Sopenharmony_ci 130762306a36Sopenharmony_ci ret = drbg->d_ops->crypto_init(drbg); 130862306a36Sopenharmony_ci if (ret < 0) 130962306a36Sopenharmony_ci goto err; 131062306a36Sopenharmony_ci 131162306a36Sopenharmony_ci drbg->Vbuf = kmalloc(drbg_statelen(drbg) + ret, GFP_KERNEL); 131262306a36Sopenharmony_ci if (!drbg->Vbuf) { 131362306a36Sopenharmony_ci ret = -ENOMEM; 131462306a36Sopenharmony_ci goto fini; 131562306a36Sopenharmony_ci } 131662306a36Sopenharmony_ci drbg->V = PTR_ALIGN(drbg->Vbuf, ret + 1); 131762306a36Sopenharmony_ci drbg->Cbuf = kmalloc(drbg_statelen(drbg) + ret, GFP_KERNEL); 131862306a36Sopenharmony_ci if (!drbg->Cbuf) { 131962306a36Sopenharmony_ci ret = -ENOMEM; 132062306a36Sopenharmony_ci goto fini; 132162306a36Sopenharmony_ci } 132262306a36Sopenharmony_ci drbg->C = PTR_ALIGN(drbg->Cbuf, ret + 1); 132362306a36Sopenharmony_ci /* scratchpad is only generated for CTR and Hash */ 132462306a36Sopenharmony_ci if (drbg->core->flags & DRBG_HMAC) 132562306a36Sopenharmony_ci sb_size = 0; 132662306a36Sopenharmony_ci else if (drbg->core->flags & DRBG_CTR) 132762306a36Sopenharmony_ci sb_size = drbg_statelen(drbg) + drbg_blocklen(drbg) + /* temp */ 132862306a36Sopenharmony_ci drbg_statelen(drbg) + /* df_data */ 132962306a36Sopenharmony_ci drbg_blocklen(drbg) + /* pad */ 133062306a36Sopenharmony_ci drbg_blocklen(drbg) + /* iv */ 133162306a36Sopenharmony_ci drbg_statelen(drbg) + drbg_blocklen(drbg); /* temp */ 133262306a36Sopenharmony_ci else 133362306a36Sopenharmony_ci sb_size = drbg_statelen(drbg) + drbg_blocklen(drbg); 133462306a36Sopenharmony_ci 133562306a36Sopenharmony_ci if (0 < sb_size) { 133662306a36Sopenharmony_ci drbg->scratchpadbuf = kzalloc(sb_size + ret, GFP_KERNEL); 133762306a36Sopenharmony_ci if (!drbg->scratchpadbuf) { 133862306a36Sopenharmony_ci ret = -ENOMEM; 133962306a36Sopenharmony_ci goto fini; 134062306a36Sopenharmony_ci } 134162306a36Sopenharmony_ci drbg->scratchpad = PTR_ALIGN(drbg->scratchpadbuf, ret + 1); 134262306a36Sopenharmony_ci } 134362306a36Sopenharmony_ci 134462306a36Sopenharmony_ci if (IS_ENABLED(CONFIG_CRYPTO_FIPS)) { 134562306a36Sopenharmony_ci drbg->prev = kzalloc(drbg_sec_strength(drbg->core->flags), 134662306a36Sopenharmony_ci GFP_KERNEL); 134762306a36Sopenharmony_ci if (!drbg->prev) { 134862306a36Sopenharmony_ci ret = -ENOMEM; 134962306a36Sopenharmony_ci goto fini; 135062306a36Sopenharmony_ci } 135162306a36Sopenharmony_ci drbg->fips_primed = false; 135262306a36Sopenharmony_ci } 135362306a36Sopenharmony_ci 135462306a36Sopenharmony_ci return 0; 135562306a36Sopenharmony_ci 135662306a36Sopenharmony_cifini: 135762306a36Sopenharmony_ci drbg->d_ops->crypto_fini(drbg); 135862306a36Sopenharmony_cierr: 135962306a36Sopenharmony_ci drbg_dealloc_state(drbg); 136062306a36Sopenharmony_ci return ret; 136162306a36Sopenharmony_ci} 136262306a36Sopenharmony_ci 136362306a36Sopenharmony_ci/************************************************************************* 136462306a36Sopenharmony_ci * DRBG interface functions 136562306a36Sopenharmony_ci *************************************************************************/ 136662306a36Sopenharmony_ci 136762306a36Sopenharmony_ci/* 136862306a36Sopenharmony_ci * DRBG generate function as required by SP800-90A - this function 136962306a36Sopenharmony_ci * generates random numbers 137062306a36Sopenharmony_ci * 137162306a36Sopenharmony_ci * @drbg DRBG state handle 137262306a36Sopenharmony_ci * @buf Buffer where to store the random numbers -- the buffer must already 137362306a36Sopenharmony_ci * be pre-allocated by caller 137462306a36Sopenharmony_ci * @buflen Length of output buffer - this value defines the number of random 137562306a36Sopenharmony_ci * bytes pulled from DRBG 137662306a36Sopenharmony_ci * @addtl Additional input that is mixed into state, may be NULL -- note 137762306a36Sopenharmony_ci * the entropy is pulled by the DRBG internally unconditionally 137862306a36Sopenharmony_ci * as defined in SP800-90A. The additional input is mixed into 137962306a36Sopenharmony_ci * the state in addition to the pulled entropy. 138062306a36Sopenharmony_ci * 138162306a36Sopenharmony_ci * return: 0 when all bytes are generated; < 0 in case of an error 138262306a36Sopenharmony_ci */ 138362306a36Sopenharmony_cistatic int drbg_generate(struct drbg_state *drbg, 138462306a36Sopenharmony_ci unsigned char *buf, unsigned int buflen, 138562306a36Sopenharmony_ci struct drbg_string *addtl) 138662306a36Sopenharmony_ci{ 138762306a36Sopenharmony_ci int len = 0; 138862306a36Sopenharmony_ci LIST_HEAD(addtllist); 138962306a36Sopenharmony_ci 139062306a36Sopenharmony_ci if (!drbg->core) { 139162306a36Sopenharmony_ci pr_devel("DRBG: not yet seeded\n"); 139262306a36Sopenharmony_ci return -EINVAL; 139362306a36Sopenharmony_ci } 139462306a36Sopenharmony_ci if (0 == buflen || !buf) { 139562306a36Sopenharmony_ci pr_devel("DRBG: no output buffer provided\n"); 139662306a36Sopenharmony_ci return -EINVAL; 139762306a36Sopenharmony_ci } 139862306a36Sopenharmony_ci if (addtl && NULL == addtl->buf && 0 < addtl->len) { 139962306a36Sopenharmony_ci pr_devel("DRBG: wrong format of additional information\n"); 140062306a36Sopenharmony_ci return -EINVAL; 140162306a36Sopenharmony_ci } 140262306a36Sopenharmony_ci 140362306a36Sopenharmony_ci /* 9.3.1 step 2 */ 140462306a36Sopenharmony_ci len = -EINVAL; 140562306a36Sopenharmony_ci if (buflen > (drbg_max_request_bytes(drbg))) { 140662306a36Sopenharmony_ci pr_devel("DRBG: requested random numbers too large %u\n", 140762306a36Sopenharmony_ci buflen); 140862306a36Sopenharmony_ci goto err; 140962306a36Sopenharmony_ci } 141062306a36Sopenharmony_ci 141162306a36Sopenharmony_ci /* 9.3.1 step 3 is implicit with the chosen DRBG */ 141262306a36Sopenharmony_ci 141362306a36Sopenharmony_ci /* 9.3.1 step 4 */ 141462306a36Sopenharmony_ci if (addtl && addtl->len > (drbg_max_addtl(drbg))) { 141562306a36Sopenharmony_ci pr_devel("DRBG: additional information string too long %zu\n", 141662306a36Sopenharmony_ci addtl->len); 141762306a36Sopenharmony_ci goto err; 141862306a36Sopenharmony_ci } 141962306a36Sopenharmony_ci /* 9.3.1 step 5 is implicit with the chosen DRBG */ 142062306a36Sopenharmony_ci 142162306a36Sopenharmony_ci /* 142262306a36Sopenharmony_ci * 9.3.1 step 6 and 9 supplemented by 9.3.2 step c is implemented 142362306a36Sopenharmony_ci * here. The spec is a bit convoluted here, we make it simpler. 142462306a36Sopenharmony_ci */ 142562306a36Sopenharmony_ci if (drbg->reseed_threshold < drbg->reseed_ctr) 142662306a36Sopenharmony_ci drbg->seeded = DRBG_SEED_STATE_UNSEEDED; 142762306a36Sopenharmony_ci 142862306a36Sopenharmony_ci if (drbg->pr || drbg->seeded == DRBG_SEED_STATE_UNSEEDED) { 142962306a36Sopenharmony_ci pr_devel("DRBG: reseeding before generation (prediction " 143062306a36Sopenharmony_ci "resistance: %s, state %s)\n", 143162306a36Sopenharmony_ci drbg->pr ? "true" : "false", 143262306a36Sopenharmony_ci (drbg->seeded == DRBG_SEED_STATE_FULL ? 143362306a36Sopenharmony_ci "seeded" : "unseeded")); 143462306a36Sopenharmony_ci /* 9.3.1 steps 7.1 through 7.3 */ 143562306a36Sopenharmony_ci len = drbg_seed(drbg, addtl, true); 143662306a36Sopenharmony_ci if (len) 143762306a36Sopenharmony_ci goto err; 143862306a36Sopenharmony_ci /* 9.3.1 step 7.4 */ 143962306a36Sopenharmony_ci addtl = NULL; 144062306a36Sopenharmony_ci } else if (rng_is_initialized() && 144162306a36Sopenharmony_ci (drbg->seeded == DRBG_SEED_STATE_PARTIAL || 144262306a36Sopenharmony_ci drbg_nopr_reseed_interval_elapsed(drbg))) { 144362306a36Sopenharmony_ci len = drbg_seed_from_random(drbg); 144462306a36Sopenharmony_ci if (len) 144562306a36Sopenharmony_ci goto err; 144662306a36Sopenharmony_ci } 144762306a36Sopenharmony_ci 144862306a36Sopenharmony_ci if (addtl && 0 < addtl->len) 144962306a36Sopenharmony_ci list_add_tail(&addtl->list, &addtllist); 145062306a36Sopenharmony_ci /* 9.3.1 step 8 and 10 */ 145162306a36Sopenharmony_ci len = drbg->d_ops->generate(drbg, buf, buflen, &addtllist); 145262306a36Sopenharmony_ci 145362306a36Sopenharmony_ci /* 10.1.1.4 step 6, 10.1.2.5 step 7, 10.2.1.5.2 step 7 */ 145462306a36Sopenharmony_ci drbg->reseed_ctr++; 145562306a36Sopenharmony_ci if (0 >= len) 145662306a36Sopenharmony_ci goto err; 145762306a36Sopenharmony_ci 145862306a36Sopenharmony_ci /* 145962306a36Sopenharmony_ci * Section 11.3.3 requires to re-perform self tests after some 146062306a36Sopenharmony_ci * generated random numbers. The chosen value after which self 146162306a36Sopenharmony_ci * test is performed is arbitrary, but it should be reasonable. 146262306a36Sopenharmony_ci * However, we do not perform the self tests because of the following 146362306a36Sopenharmony_ci * reasons: it is mathematically impossible that the initial self tests 146462306a36Sopenharmony_ci * were successfully and the following are not. If the initial would 146562306a36Sopenharmony_ci * pass and the following would not, the kernel integrity is violated. 146662306a36Sopenharmony_ci * In this case, the entire kernel operation is questionable and it 146762306a36Sopenharmony_ci * is unlikely that the integrity violation only affects the 146862306a36Sopenharmony_ci * correct operation of the DRBG. 146962306a36Sopenharmony_ci * 147062306a36Sopenharmony_ci * Albeit the following code is commented out, it is provided in 147162306a36Sopenharmony_ci * case somebody has a need to implement the test of 11.3.3. 147262306a36Sopenharmony_ci */ 147362306a36Sopenharmony_ci#if 0 147462306a36Sopenharmony_ci if (drbg->reseed_ctr && !(drbg->reseed_ctr % 4096)) { 147562306a36Sopenharmony_ci int err = 0; 147662306a36Sopenharmony_ci pr_devel("DRBG: start to perform self test\n"); 147762306a36Sopenharmony_ci if (drbg->core->flags & DRBG_HMAC) 147862306a36Sopenharmony_ci err = alg_test("drbg_pr_hmac_sha256", 147962306a36Sopenharmony_ci "drbg_pr_hmac_sha256", 0, 0); 148062306a36Sopenharmony_ci else if (drbg->core->flags & DRBG_CTR) 148162306a36Sopenharmony_ci err = alg_test("drbg_pr_ctr_aes128", 148262306a36Sopenharmony_ci "drbg_pr_ctr_aes128", 0, 0); 148362306a36Sopenharmony_ci else 148462306a36Sopenharmony_ci err = alg_test("drbg_pr_sha256", 148562306a36Sopenharmony_ci "drbg_pr_sha256", 0, 0); 148662306a36Sopenharmony_ci if (err) { 148762306a36Sopenharmony_ci pr_err("DRBG: periodical self test failed\n"); 148862306a36Sopenharmony_ci /* 148962306a36Sopenharmony_ci * uninstantiate implies that from now on, only errors 149062306a36Sopenharmony_ci * are returned when reusing this DRBG cipher handle 149162306a36Sopenharmony_ci */ 149262306a36Sopenharmony_ci drbg_uninstantiate(drbg); 149362306a36Sopenharmony_ci return 0; 149462306a36Sopenharmony_ci } else { 149562306a36Sopenharmony_ci pr_devel("DRBG: self test successful\n"); 149662306a36Sopenharmony_ci } 149762306a36Sopenharmony_ci } 149862306a36Sopenharmony_ci#endif 149962306a36Sopenharmony_ci 150062306a36Sopenharmony_ci /* 150162306a36Sopenharmony_ci * All operations were successful, return 0 as mandated by 150262306a36Sopenharmony_ci * the kernel crypto API interface. 150362306a36Sopenharmony_ci */ 150462306a36Sopenharmony_ci len = 0; 150562306a36Sopenharmony_cierr: 150662306a36Sopenharmony_ci return len; 150762306a36Sopenharmony_ci} 150862306a36Sopenharmony_ci 150962306a36Sopenharmony_ci/* 151062306a36Sopenharmony_ci * Wrapper around drbg_generate which can pull arbitrary long strings 151162306a36Sopenharmony_ci * from the DRBG without hitting the maximum request limitation. 151262306a36Sopenharmony_ci * 151362306a36Sopenharmony_ci * Parameters: see drbg_generate 151462306a36Sopenharmony_ci * Return codes: see drbg_generate -- if one drbg_generate request fails, 151562306a36Sopenharmony_ci * the entire drbg_generate_long request fails 151662306a36Sopenharmony_ci */ 151762306a36Sopenharmony_cistatic int drbg_generate_long(struct drbg_state *drbg, 151862306a36Sopenharmony_ci unsigned char *buf, unsigned int buflen, 151962306a36Sopenharmony_ci struct drbg_string *addtl) 152062306a36Sopenharmony_ci{ 152162306a36Sopenharmony_ci unsigned int len = 0; 152262306a36Sopenharmony_ci unsigned int slice = 0; 152362306a36Sopenharmony_ci do { 152462306a36Sopenharmony_ci int err = 0; 152562306a36Sopenharmony_ci unsigned int chunk = 0; 152662306a36Sopenharmony_ci slice = ((buflen - len) / drbg_max_request_bytes(drbg)); 152762306a36Sopenharmony_ci chunk = slice ? drbg_max_request_bytes(drbg) : (buflen - len); 152862306a36Sopenharmony_ci mutex_lock(&drbg->drbg_mutex); 152962306a36Sopenharmony_ci err = drbg_generate(drbg, buf + len, chunk, addtl); 153062306a36Sopenharmony_ci mutex_unlock(&drbg->drbg_mutex); 153162306a36Sopenharmony_ci if (0 > err) 153262306a36Sopenharmony_ci return err; 153362306a36Sopenharmony_ci len += chunk; 153462306a36Sopenharmony_ci } while (slice > 0 && (len < buflen)); 153562306a36Sopenharmony_ci return 0; 153662306a36Sopenharmony_ci} 153762306a36Sopenharmony_ci 153862306a36Sopenharmony_cistatic int drbg_prepare_hrng(struct drbg_state *drbg) 153962306a36Sopenharmony_ci{ 154062306a36Sopenharmony_ci /* We do not need an HRNG in test mode. */ 154162306a36Sopenharmony_ci if (list_empty(&drbg->test_data.list)) 154262306a36Sopenharmony_ci return 0; 154362306a36Sopenharmony_ci 154462306a36Sopenharmony_ci drbg->jent = crypto_alloc_rng("jitterentropy_rng", 0, 0); 154562306a36Sopenharmony_ci if (IS_ERR(drbg->jent)) { 154662306a36Sopenharmony_ci const int err = PTR_ERR(drbg->jent); 154762306a36Sopenharmony_ci 154862306a36Sopenharmony_ci drbg->jent = NULL; 154962306a36Sopenharmony_ci if (fips_enabled) 155062306a36Sopenharmony_ci return err; 155162306a36Sopenharmony_ci pr_info("DRBG: Continuing without Jitter RNG\n"); 155262306a36Sopenharmony_ci } 155362306a36Sopenharmony_ci 155462306a36Sopenharmony_ci return 0; 155562306a36Sopenharmony_ci} 155662306a36Sopenharmony_ci 155762306a36Sopenharmony_ci/* 155862306a36Sopenharmony_ci * DRBG instantiation function as required by SP800-90A - this function 155962306a36Sopenharmony_ci * sets up the DRBG handle, performs the initial seeding and all sanity 156062306a36Sopenharmony_ci * checks required by SP800-90A 156162306a36Sopenharmony_ci * 156262306a36Sopenharmony_ci * @drbg memory of state -- if NULL, new memory is allocated 156362306a36Sopenharmony_ci * @pers Personalization string that is mixed into state, may be NULL -- note 156462306a36Sopenharmony_ci * the entropy is pulled by the DRBG internally unconditionally 156562306a36Sopenharmony_ci * as defined in SP800-90A. The additional input is mixed into 156662306a36Sopenharmony_ci * the state in addition to the pulled entropy. 156762306a36Sopenharmony_ci * @coreref reference to core 156862306a36Sopenharmony_ci * @pr prediction resistance enabled 156962306a36Sopenharmony_ci * 157062306a36Sopenharmony_ci * return 157162306a36Sopenharmony_ci * 0 on success 157262306a36Sopenharmony_ci * error value otherwise 157362306a36Sopenharmony_ci */ 157462306a36Sopenharmony_cistatic int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers, 157562306a36Sopenharmony_ci int coreref, bool pr) 157662306a36Sopenharmony_ci{ 157762306a36Sopenharmony_ci int ret; 157862306a36Sopenharmony_ci bool reseed = true; 157962306a36Sopenharmony_ci 158062306a36Sopenharmony_ci pr_devel("DRBG: Initializing DRBG core %d with prediction resistance " 158162306a36Sopenharmony_ci "%s\n", coreref, pr ? "enabled" : "disabled"); 158262306a36Sopenharmony_ci mutex_lock(&drbg->drbg_mutex); 158362306a36Sopenharmony_ci 158462306a36Sopenharmony_ci /* 9.1 step 1 is implicit with the selected DRBG type */ 158562306a36Sopenharmony_ci 158662306a36Sopenharmony_ci /* 158762306a36Sopenharmony_ci * 9.1 step 2 is implicit as caller can select prediction resistance 158862306a36Sopenharmony_ci * and the flag is copied into drbg->flags -- 158962306a36Sopenharmony_ci * all DRBG types support prediction resistance 159062306a36Sopenharmony_ci */ 159162306a36Sopenharmony_ci 159262306a36Sopenharmony_ci /* 9.1 step 4 is implicit in drbg_sec_strength */ 159362306a36Sopenharmony_ci 159462306a36Sopenharmony_ci if (!drbg->core) { 159562306a36Sopenharmony_ci drbg->core = &drbg_cores[coreref]; 159662306a36Sopenharmony_ci drbg->pr = pr; 159762306a36Sopenharmony_ci drbg->seeded = DRBG_SEED_STATE_UNSEEDED; 159862306a36Sopenharmony_ci drbg->last_seed_time = 0; 159962306a36Sopenharmony_ci drbg->reseed_threshold = drbg_max_requests(drbg); 160062306a36Sopenharmony_ci 160162306a36Sopenharmony_ci ret = drbg_alloc_state(drbg); 160262306a36Sopenharmony_ci if (ret) 160362306a36Sopenharmony_ci goto unlock; 160462306a36Sopenharmony_ci 160562306a36Sopenharmony_ci ret = drbg_prepare_hrng(drbg); 160662306a36Sopenharmony_ci if (ret) 160762306a36Sopenharmony_ci goto free_everything; 160862306a36Sopenharmony_ci 160962306a36Sopenharmony_ci reseed = false; 161062306a36Sopenharmony_ci } 161162306a36Sopenharmony_ci 161262306a36Sopenharmony_ci ret = drbg_seed(drbg, pers, reseed); 161362306a36Sopenharmony_ci 161462306a36Sopenharmony_ci if (ret && !reseed) 161562306a36Sopenharmony_ci goto free_everything; 161662306a36Sopenharmony_ci 161762306a36Sopenharmony_ci mutex_unlock(&drbg->drbg_mutex); 161862306a36Sopenharmony_ci return ret; 161962306a36Sopenharmony_ci 162062306a36Sopenharmony_ciunlock: 162162306a36Sopenharmony_ci mutex_unlock(&drbg->drbg_mutex); 162262306a36Sopenharmony_ci return ret; 162362306a36Sopenharmony_ci 162462306a36Sopenharmony_cifree_everything: 162562306a36Sopenharmony_ci mutex_unlock(&drbg->drbg_mutex); 162662306a36Sopenharmony_ci drbg_uninstantiate(drbg); 162762306a36Sopenharmony_ci return ret; 162862306a36Sopenharmony_ci} 162962306a36Sopenharmony_ci 163062306a36Sopenharmony_ci/* 163162306a36Sopenharmony_ci * DRBG uninstantiate function as required by SP800-90A - this function 163262306a36Sopenharmony_ci * frees all buffers and the DRBG handle 163362306a36Sopenharmony_ci * 163462306a36Sopenharmony_ci * @drbg DRBG state handle 163562306a36Sopenharmony_ci * 163662306a36Sopenharmony_ci * return 163762306a36Sopenharmony_ci * 0 on success 163862306a36Sopenharmony_ci */ 163962306a36Sopenharmony_cistatic int drbg_uninstantiate(struct drbg_state *drbg) 164062306a36Sopenharmony_ci{ 164162306a36Sopenharmony_ci if (!IS_ERR_OR_NULL(drbg->jent)) 164262306a36Sopenharmony_ci crypto_free_rng(drbg->jent); 164362306a36Sopenharmony_ci drbg->jent = NULL; 164462306a36Sopenharmony_ci 164562306a36Sopenharmony_ci if (drbg->d_ops) 164662306a36Sopenharmony_ci drbg->d_ops->crypto_fini(drbg); 164762306a36Sopenharmony_ci drbg_dealloc_state(drbg); 164862306a36Sopenharmony_ci /* no scrubbing of test_data -- this shall survive an uninstantiate */ 164962306a36Sopenharmony_ci return 0; 165062306a36Sopenharmony_ci} 165162306a36Sopenharmony_ci 165262306a36Sopenharmony_ci/* 165362306a36Sopenharmony_ci * Helper function for setting the test data in the DRBG 165462306a36Sopenharmony_ci * 165562306a36Sopenharmony_ci * @drbg DRBG state handle 165662306a36Sopenharmony_ci * @data test data 165762306a36Sopenharmony_ci * @len test data length 165862306a36Sopenharmony_ci */ 165962306a36Sopenharmony_cistatic void drbg_kcapi_set_entropy(struct crypto_rng *tfm, 166062306a36Sopenharmony_ci const u8 *data, unsigned int len) 166162306a36Sopenharmony_ci{ 166262306a36Sopenharmony_ci struct drbg_state *drbg = crypto_rng_ctx(tfm); 166362306a36Sopenharmony_ci 166462306a36Sopenharmony_ci mutex_lock(&drbg->drbg_mutex); 166562306a36Sopenharmony_ci drbg_string_fill(&drbg->test_data, data, len); 166662306a36Sopenharmony_ci mutex_unlock(&drbg->drbg_mutex); 166762306a36Sopenharmony_ci} 166862306a36Sopenharmony_ci 166962306a36Sopenharmony_ci/*************************************************************** 167062306a36Sopenharmony_ci * Kernel crypto API cipher invocations requested by DRBG 167162306a36Sopenharmony_ci ***************************************************************/ 167262306a36Sopenharmony_ci 167362306a36Sopenharmony_ci#if defined(CONFIG_CRYPTO_DRBG_HASH) || defined(CONFIG_CRYPTO_DRBG_HMAC) 167462306a36Sopenharmony_cistruct sdesc { 167562306a36Sopenharmony_ci struct shash_desc shash; 167662306a36Sopenharmony_ci char ctx[]; 167762306a36Sopenharmony_ci}; 167862306a36Sopenharmony_ci 167962306a36Sopenharmony_cistatic int drbg_init_hash_kernel(struct drbg_state *drbg) 168062306a36Sopenharmony_ci{ 168162306a36Sopenharmony_ci struct sdesc *sdesc; 168262306a36Sopenharmony_ci struct crypto_shash *tfm; 168362306a36Sopenharmony_ci 168462306a36Sopenharmony_ci tfm = crypto_alloc_shash(drbg->core->backend_cra_name, 0, 0); 168562306a36Sopenharmony_ci if (IS_ERR(tfm)) { 168662306a36Sopenharmony_ci pr_info("DRBG: could not allocate digest TFM handle: %s\n", 168762306a36Sopenharmony_ci drbg->core->backend_cra_name); 168862306a36Sopenharmony_ci return PTR_ERR(tfm); 168962306a36Sopenharmony_ci } 169062306a36Sopenharmony_ci BUG_ON(drbg_blocklen(drbg) != crypto_shash_digestsize(tfm)); 169162306a36Sopenharmony_ci sdesc = kzalloc(sizeof(struct shash_desc) + crypto_shash_descsize(tfm), 169262306a36Sopenharmony_ci GFP_KERNEL); 169362306a36Sopenharmony_ci if (!sdesc) { 169462306a36Sopenharmony_ci crypto_free_shash(tfm); 169562306a36Sopenharmony_ci return -ENOMEM; 169662306a36Sopenharmony_ci } 169762306a36Sopenharmony_ci 169862306a36Sopenharmony_ci sdesc->shash.tfm = tfm; 169962306a36Sopenharmony_ci drbg->priv_data = sdesc; 170062306a36Sopenharmony_ci 170162306a36Sopenharmony_ci return crypto_shash_alignmask(tfm); 170262306a36Sopenharmony_ci} 170362306a36Sopenharmony_ci 170462306a36Sopenharmony_cistatic int drbg_fini_hash_kernel(struct drbg_state *drbg) 170562306a36Sopenharmony_ci{ 170662306a36Sopenharmony_ci struct sdesc *sdesc = drbg->priv_data; 170762306a36Sopenharmony_ci if (sdesc) { 170862306a36Sopenharmony_ci crypto_free_shash(sdesc->shash.tfm); 170962306a36Sopenharmony_ci kfree_sensitive(sdesc); 171062306a36Sopenharmony_ci } 171162306a36Sopenharmony_ci drbg->priv_data = NULL; 171262306a36Sopenharmony_ci return 0; 171362306a36Sopenharmony_ci} 171462306a36Sopenharmony_ci 171562306a36Sopenharmony_cistatic void drbg_kcapi_hmacsetkey(struct drbg_state *drbg, 171662306a36Sopenharmony_ci const unsigned char *key) 171762306a36Sopenharmony_ci{ 171862306a36Sopenharmony_ci struct sdesc *sdesc = drbg->priv_data; 171962306a36Sopenharmony_ci 172062306a36Sopenharmony_ci crypto_shash_setkey(sdesc->shash.tfm, key, drbg_statelen(drbg)); 172162306a36Sopenharmony_ci} 172262306a36Sopenharmony_ci 172362306a36Sopenharmony_cistatic int drbg_kcapi_hash(struct drbg_state *drbg, unsigned char *outval, 172462306a36Sopenharmony_ci const struct list_head *in) 172562306a36Sopenharmony_ci{ 172662306a36Sopenharmony_ci struct sdesc *sdesc = drbg->priv_data; 172762306a36Sopenharmony_ci struct drbg_string *input = NULL; 172862306a36Sopenharmony_ci 172962306a36Sopenharmony_ci crypto_shash_init(&sdesc->shash); 173062306a36Sopenharmony_ci list_for_each_entry(input, in, list) 173162306a36Sopenharmony_ci crypto_shash_update(&sdesc->shash, input->buf, input->len); 173262306a36Sopenharmony_ci return crypto_shash_final(&sdesc->shash, outval); 173362306a36Sopenharmony_ci} 173462306a36Sopenharmony_ci#endif /* (CONFIG_CRYPTO_DRBG_HASH || CONFIG_CRYPTO_DRBG_HMAC) */ 173562306a36Sopenharmony_ci 173662306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_DRBG_CTR 173762306a36Sopenharmony_cistatic int drbg_fini_sym_kernel(struct drbg_state *drbg) 173862306a36Sopenharmony_ci{ 173962306a36Sopenharmony_ci struct crypto_cipher *tfm = 174062306a36Sopenharmony_ci (struct crypto_cipher *)drbg->priv_data; 174162306a36Sopenharmony_ci if (tfm) 174262306a36Sopenharmony_ci crypto_free_cipher(tfm); 174362306a36Sopenharmony_ci drbg->priv_data = NULL; 174462306a36Sopenharmony_ci 174562306a36Sopenharmony_ci if (drbg->ctr_handle) 174662306a36Sopenharmony_ci crypto_free_skcipher(drbg->ctr_handle); 174762306a36Sopenharmony_ci drbg->ctr_handle = NULL; 174862306a36Sopenharmony_ci 174962306a36Sopenharmony_ci if (drbg->ctr_req) 175062306a36Sopenharmony_ci skcipher_request_free(drbg->ctr_req); 175162306a36Sopenharmony_ci drbg->ctr_req = NULL; 175262306a36Sopenharmony_ci 175362306a36Sopenharmony_ci kfree(drbg->outscratchpadbuf); 175462306a36Sopenharmony_ci drbg->outscratchpadbuf = NULL; 175562306a36Sopenharmony_ci 175662306a36Sopenharmony_ci return 0; 175762306a36Sopenharmony_ci} 175862306a36Sopenharmony_ci 175962306a36Sopenharmony_cistatic int drbg_init_sym_kernel(struct drbg_state *drbg) 176062306a36Sopenharmony_ci{ 176162306a36Sopenharmony_ci struct crypto_cipher *tfm; 176262306a36Sopenharmony_ci struct crypto_skcipher *sk_tfm; 176362306a36Sopenharmony_ci struct skcipher_request *req; 176462306a36Sopenharmony_ci unsigned int alignmask; 176562306a36Sopenharmony_ci char ctr_name[CRYPTO_MAX_ALG_NAME]; 176662306a36Sopenharmony_ci 176762306a36Sopenharmony_ci tfm = crypto_alloc_cipher(drbg->core->backend_cra_name, 0, 0); 176862306a36Sopenharmony_ci if (IS_ERR(tfm)) { 176962306a36Sopenharmony_ci pr_info("DRBG: could not allocate cipher TFM handle: %s\n", 177062306a36Sopenharmony_ci drbg->core->backend_cra_name); 177162306a36Sopenharmony_ci return PTR_ERR(tfm); 177262306a36Sopenharmony_ci } 177362306a36Sopenharmony_ci BUG_ON(drbg_blocklen(drbg) != crypto_cipher_blocksize(tfm)); 177462306a36Sopenharmony_ci drbg->priv_data = tfm; 177562306a36Sopenharmony_ci 177662306a36Sopenharmony_ci if (snprintf(ctr_name, CRYPTO_MAX_ALG_NAME, "ctr(%s)", 177762306a36Sopenharmony_ci drbg->core->backend_cra_name) >= CRYPTO_MAX_ALG_NAME) { 177862306a36Sopenharmony_ci drbg_fini_sym_kernel(drbg); 177962306a36Sopenharmony_ci return -EINVAL; 178062306a36Sopenharmony_ci } 178162306a36Sopenharmony_ci sk_tfm = crypto_alloc_skcipher(ctr_name, 0, 0); 178262306a36Sopenharmony_ci if (IS_ERR(sk_tfm)) { 178362306a36Sopenharmony_ci pr_info("DRBG: could not allocate CTR cipher TFM handle: %s\n", 178462306a36Sopenharmony_ci ctr_name); 178562306a36Sopenharmony_ci drbg_fini_sym_kernel(drbg); 178662306a36Sopenharmony_ci return PTR_ERR(sk_tfm); 178762306a36Sopenharmony_ci } 178862306a36Sopenharmony_ci drbg->ctr_handle = sk_tfm; 178962306a36Sopenharmony_ci crypto_init_wait(&drbg->ctr_wait); 179062306a36Sopenharmony_ci 179162306a36Sopenharmony_ci req = skcipher_request_alloc(sk_tfm, GFP_KERNEL); 179262306a36Sopenharmony_ci if (!req) { 179362306a36Sopenharmony_ci pr_info("DRBG: could not allocate request queue\n"); 179462306a36Sopenharmony_ci drbg_fini_sym_kernel(drbg); 179562306a36Sopenharmony_ci return -ENOMEM; 179662306a36Sopenharmony_ci } 179762306a36Sopenharmony_ci drbg->ctr_req = req; 179862306a36Sopenharmony_ci skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | 179962306a36Sopenharmony_ci CRYPTO_TFM_REQ_MAY_SLEEP, 180062306a36Sopenharmony_ci crypto_req_done, &drbg->ctr_wait); 180162306a36Sopenharmony_ci 180262306a36Sopenharmony_ci alignmask = crypto_skcipher_alignmask(sk_tfm); 180362306a36Sopenharmony_ci drbg->outscratchpadbuf = kmalloc(DRBG_OUTSCRATCHLEN + alignmask, 180462306a36Sopenharmony_ci GFP_KERNEL); 180562306a36Sopenharmony_ci if (!drbg->outscratchpadbuf) { 180662306a36Sopenharmony_ci drbg_fini_sym_kernel(drbg); 180762306a36Sopenharmony_ci return -ENOMEM; 180862306a36Sopenharmony_ci } 180962306a36Sopenharmony_ci drbg->outscratchpad = (u8 *)PTR_ALIGN(drbg->outscratchpadbuf, 181062306a36Sopenharmony_ci alignmask + 1); 181162306a36Sopenharmony_ci 181262306a36Sopenharmony_ci sg_init_table(&drbg->sg_in, 1); 181362306a36Sopenharmony_ci sg_init_one(&drbg->sg_out, drbg->outscratchpad, DRBG_OUTSCRATCHLEN); 181462306a36Sopenharmony_ci 181562306a36Sopenharmony_ci return alignmask; 181662306a36Sopenharmony_ci} 181762306a36Sopenharmony_ci 181862306a36Sopenharmony_cistatic void drbg_kcapi_symsetkey(struct drbg_state *drbg, 181962306a36Sopenharmony_ci const unsigned char *key) 182062306a36Sopenharmony_ci{ 182162306a36Sopenharmony_ci struct crypto_cipher *tfm = drbg->priv_data; 182262306a36Sopenharmony_ci 182362306a36Sopenharmony_ci crypto_cipher_setkey(tfm, key, (drbg_keylen(drbg))); 182462306a36Sopenharmony_ci} 182562306a36Sopenharmony_ci 182662306a36Sopenharmony_cistatic int drbg_kcapi_sym(struct drbg_state *drbg, unsigned char *outval, 182762306a36Sopenharmony_ci const struct drbg_string *in) 182862306a36Sopenharmony_ci{ 182962306a36Sopenharmony_ci struct crypto_cipher *tfm = drbg->priv_data; 183062306a36Sopenharmony_ci 183162306a36Sopenharmony_ci /* there is only component in *in */ 183262306a36Sopenharmony_ci BUG_ON(in->len < drbg_blocklen(drbg)); 183362306a36Sopenharmony_ci crypto_cipher_encrypt_one(tfm, outval, in->buf); 183462306a36Sopenharmony_ci return 0; 183562306a36Sopenharmony_ci} 183662306a36Sopenharmony_ci 183762306a36Sopenharmony_cistatic int drbg_kcapi_sym_ctr(struct drbg_state *drbg, 183862306a36Sopenharmony_ci u8 *inbuf, u32 inlen, 183962306a36Sopenharmony_ci u8 *outbuf, u32 outlen) 184062306a36Sopenharmony_ci{ 184162306a36Sopenharmony_ci struct scatterlist *sg_in = &drbg->sg_in, *sg_out = &drbg->sg_out; 184262306a36Sopenharmony_ci u32 scratchpad_use = min_t(u32, outlen, DRBG_OUTSCRATCHLEN); 184362306a36Sopenharmony_ci int ret; 184462306a36Sopenharmony_ci 184562306a36Sopenharmony_ci if (inbuf) { 184662306a36Sopenharmony_ci /* Use caller-provided input buffer */ 184762306a36Sopenharmony_ci sg_set_buf(sg_in, inbuf, inlen); 184862306a36Sopenharmony_ci } else { 184962306a36Sopenharmony_ci /* Use scratchpad for in-place operation */ 185062306a36Sopenharmony_ci inlen = scratchpad_use; 185162306a36Sopenharmony_ci memset(drbg->outscratchpad, 0, scratchpad_use); 185262306a36Sopenharmony_ci sg_set_buf(sg_in, drbg->outscratchpad, scratchpad_use); 185362306a36Sopenharmony_ci } 185462306a36Sopenharmony_ci 185562306a36Sopenharmony_ci while (outlen) { 185662306a36Sopenharmony_ci u32 cryptlen = min3(inlen, outlen, (u32)DRBG_OUTSCRATCHLEN); 185762306a36Sopenharmony_ci 185862306a36Sopenharmony_ci /* Output buffer may not be valid for SGL, use scratchpad */ 185962306a36Sopenharmony_ci skcipher_request_set_crypt(drbg->ctr_req, sg_in, sg_out, 186062306a36Sopenharmony_ci cryptlen, drbg->V); 186162306a36Sopenharmony_ci ret = crypto_wait_req(crypto_skcipher_encrypt(drbg->ctr_req), 186262306a36Sopenharmony_ci &drbg->ctr_wait); 186362306a36Sopenharmony_ci if (ret) 186462306a36Sopenharmony_ci goto out; 186562306a36Sopenharmony_ci 186662306a36Sopenharmony_ci crypto_init_wait(&drbg->ctr_wait); 186762306a36Sopenharmony_ci 186862306a36Sopenharmony_ci memcpy(outbuf, drbg->outscratchpad, cryptlen); 186962306a36Sopenharmony_ci memzero_explicit(drbg->outscratchpad, cryptlen); 187062306a36Sopenharmony_ci 187162306a36Sopenharmony_ci outlen -= cryptlen; 187262306a36Sopenharmony_ci outbuf += cryptlen; 187362306a36Sopenharmony_ci } 187462306a36Sopenharmony_ci ret = 0; 187562306a36Sopenharmony_ci 187662306a36Sopenharmony_ciout: 187762306a36Sopenharmony_ci return ret; 187862306a36Sopenharmony_ci} 187962306a36Sopenharmony_ci#endif /* CONFIG_CRYPTO_DRBG_CTR */ 188062306a36Sopenharmony_ci 188162306a36Sopenharmony_ci/*************************************************************** 188262306a36Sopenharmony_ci * Kernel crypto API interface to register DRBG 188362306a36Sopenharmony_ci ***************************************************************/ 188462306a36Sopenharmony_ci 188562306a36Sopenharmony_ci/* 188662306a36Sopenharmony_ci * Look up the DRBG flags by given kernel crypto API cra_name 188762306a36Sopenharmony_ci * The code uses the drbg_cores definition to do this 188862306a36Sopenharmony_ci * 188962306a36Sopenharmony_ci * @cra_name kernel crypto API cra_name 189062306a36Sopenharmony_ci * @coreref reference to integer which is filled with the pointer to 189162306a36Sopenharmony_ci * the applicable core 189262306a36Sopenharmony_ci * @pr reference for setting prediction resistance 189362306a36Sopenharmony_ci * 189462306a36Sopenharmony_ci * return: flags 189562306a36Sopenharmony_ci */ 189662306a36Sopenharmony_cistatic inline void drbg_convert_tfm_core(const char *cra_driver_name, 189762306a36Sopenharmony_ci int *coreref, bool *pr) 189862306a36Sopenharmony_ci{ 189962306a36Sopenharmony_ci int i = 0; 190062306a36Sopenharmony_ci size_t start = 0; 190162306a36Sopenharmony_ci int len = 0; 190262306a36Sopenharmony_ci 190362306a36Sopenharmony_ci *pr = true; 190462306a36Sopenharmony_ci /* disassemble the names */ 190562306a36Sopenharmony_ci if (!memcmp(cra_driver_name, "drbg_nopr_", 10)) { 190662306a36Sopenharmony_ci start = 10; 190762306a36Sopenharmony_ci *pr = false; 190862306a36Sopenharmony_ci } else if (!memcmp(cra_driver_name, "drbg_pr_", 8)) { 190962306a36Sopenharmony_ci start = 8; 191062306a36Sopenharmony_ci } else { 191162306a36Sopenharmony_ci return; 191262306a36Sopenharmony_ci } 191362306a36Sopenharmony_ci 191462306a36Sopenharmony_ci /* remove the first part */ 191562306a36Sopenharmony_ci len = strlen(cra_driver_name) - start; 191662306a36Sopenharmony_ci for (i = 0; ARRAY_SIZE(drbg_cores) > i; i++) { 191762306a36Sopenharmony_ci if (!memcmp(cra_driver_name + start, drbg_cores[i].cra_name, 191862306a36Sopenharmony_ci len)) { 191962306a36Sopenharmony_ci *coreref = i; 192062306a36Sopenharmony_ci return; 192162306a36Sopenharmony_ci } 192262306a36Sopenharmony_ci } 192362306a36Sopenharmony_ci} 192462306a36Sopenharmony_ci 192562306a36Sopenharmony_cistatic int drbg_kcapi_init(struct crypto_tfm *tfm) 192662306a36Sopenharmony_ci{ 192762306a36Sopenharmony_ci struct drbg_state *drbg = crypto_tfm_ctx(tfm); 192862306a36Sopenharmony_ci 192962306a36Sopenharmony_ci mutex_init(&drbg->drbg_mutex); 193062306a36Sopenharmony_ci 193162306a36Sopenharmony_ci return 0; 193262306a36Sopenharmony_ci} 193362306a36Sopenharmony_ci 193462306a36Sopenharmony_cistatic void drbg_kcapi_cleanup(struct crypto_tfm *tfm) 193562306a36Sopenharmony_ci{ 193662306a36Sopenharmony_ci drbg_uninstantiate(crypto_tfm_ctx(tfm)); 193762306a36Sopenharmony_ci} 193862306a36Sopenharmony_ci 193962306a36Sopenharmony_ci/* 194062306a36Sopenharmony_ci * Generate random numbers invoked by the kernel crypto API: 194162306a36Sopenharmony_ci * The API of the kernel crypto API is extended as follows: 194262306a36Sopenharmony_ci * 194362306a36Sopenharmony_ci * src is additional input supplied to the RNG. 194462306a36Sopenharmony_ci * slen is the length of src. 194562306a36Sopenharmony_ci * dst is the output buffer where random data is to be stored. 194662306a36Sopenharmony_ci * dlen is the length of dst. 194762306a36Sopenharmony_ci */ 194862306a36Sopenharmony_cistatic int drbg_kcapi_random(struct crypto_rng *tfm, 194962306a36Sopenharmony_ci const u8 *src, unsigned int slen, 195062306a36Sopenharmony_ci u8 *dst, unsigned int dlen) 195162306a36Sopenharmony_ci{ 195262306a36Sopenharmony_ci struct drbg_state *drbg = crypto_rng_ctx(tfm); 195362306a36Sopenharmony_ci struct drbg_string *addtl = NULL; 195462306a36Sopenharmony_ci struct drbg_string string; 195562306a36Sopenharmony_ci 195662306a36Sopenharmony_ci if (slen) { 195762306a36Sopenharmony_ci /* linked list variable is now local to allow modification */ 195862306a36Sopenharmony_ci drbg_string_fill(&string, src, slen); 195962306a36Sopenharmony_ci addtl = &string; 196062306a36Sopenharmony_ci } 196162306a36Sopenharmony_ci 196262306a36Sopenharmony_ci return drbg_generate_long(drbg, dst, dlen, addtl); 196362306a36Sopenharmony_ci} 196462306a36Sopenharmony_ci 196562306a36Sopenharmony_ci/* 196662306a36Sopenharmony_ci * Seed the DRBG invoked by the kernel crypto API 196762306a36Sopenharmony_ci */ 196862306a36Sopenharmony_cistatic int drbg_kcapi_seed(struct crypto_rng *tfm, 196962306a36Sopenharmony_ci const u8 *seed, unsigned int slen) 197062306a36Sopenharmony_ci{ 197162306a36Sopenharmony_ci struct drbg_state *drbg = crypto_rng_ctx(tfm); 197262306a36Sopenharmony_ci struct crypto_tfm *tfm_base = crypto_rng_tfm(tfm); 197362306a36Sopenharmony_ci bool pr = false; 197462306a36Sopenharmony_ci struct drbg_string string; 197562306a36Sopenharmony_ci struct drbg_string *seed_string = NULL; 197662306a36Sopenharmony_ci int coreref = 0; 197762306a36Sopenharmony_ci 197862306a36Sopenharmony_ci drbg_convert_tfm_core(crypto_tfm_alg_driver_name(tfm_base), &coreref, 197962306a36Sopenharmony_ci &pr); 198062306a36Sopenharmony_ci if (0 < slen) { 198162306a36Sopenharmony_ci drbg_string_fill(&string, seed, slen); 198262306a36Sopenharmony_ci seed_string = &string; 198362306a36Sopenharmony_ci } 198462306a36Sopenharmony_ci 198562306a36Sopenharmony_ci return drbg_instantiate(drbg, seed_string, coreref, pr); 198662306a36Sopenharmony_ci} 198762306a36Sopenharmony_ci 198862306a36Sopenharmony_ci/*************************************************************** 198962306a36Sopenharmony_ci * Kernel module: code to load the module 199062306a36Sopenharmony_ci ***************************************************************/ 199162306a36Sopenharmony_ci 199262306a36Sopenharmony_ci/* 199362306a36Sopenharmony_ci * Tests as defined in 11.3.2 in addition to the cipher tests: testing 199462306a36Sopenharmony_ci * of the error handling. 199562306a36Sopenharmony_ci * 199662306a36Sopenharmony_ci * Note: testing of failing seed source as defined in 11.3.2 is not applicable 199762306a36Sopenharmony_ci * as seed source of get_random_bytes does not fail. 199862306a36Sopenharmony_ci * 199962306a36Sopenharmony_ci * Note 2: There is no sensible way of testing the reseed counter 200062306a36Sopenharmony_ci * enforcement, so skip it. 200162306a36Sopenharmony_ci */ 200262306a36Sopenharmony_cistatic inline int __init drbg_healthcheck_sanity(void) 200362306a36Sopenharmony_ci{ 200462306a36Sopenharmony_ci int len = 0; 200562306a36Sopenharmony_ci#define OUTBUFLEN 16 200662306a36Sopenharmony_ci unsigned char buf[OUTBUFLEN]; 200762306a36Sopenharmony_ci struct drbg_state *drbg = NULL; 200862306a36Sopenharmony_ci int ret; 200962306a36Sopenharmony_ci int rc = -EFAULT; 201062306a36Sopenharmony_ci bool pr = false; 201162306a36Sopenharmony_ci int coreref = 0; 201262306a36Sopenharmony_ci struct drbg_string addtl; 201362306a36Sopenharmony_ci size_t max_addtllen, max_request_bytes; 201462306a36Sopenharmony_ci 201562306a36Sopenharmony_ci /* only perform test in FIPS mode */ 201662306a36Sopenharmony_ci if (!fips_enabled) 201762306a36Sopenharmony_ci return 0; 201862306a36Sopenharmony_ci 201962306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_DRBG_CTR 202062306a36Sopenharmony_ci drbg_convert_tfm_core("drbg_nopr_ctr_aes128", &coreref, &pr); 202162306a36Sopenharmony_ci#elif defined CONFIG_CRYPTO_DRBG_HASH 202262306a36Sopenharmony_ci drbg_convert_tfm_core("drbg_nopr_sha256", &coreref, &pr); 202362306a36Sopenharmony_ci#else 202462306a36Sopenharmony_ci drbg_convert_tfm_core("drbg_nopr_hmac_sha256", &coreref, &pr); 202562306a36Sopenharmony_ci#endif 202662306a36Sopenharmony_ci 202762306a36Sopenharmony_ci drbg = kzalloc(sizeof(struct drbg_state), GFP_KERNEL); 202862306a36Sopenharmony_ci if (!drbg) 202962306a36Sopenharmony_ci return -ENOMEM; 203062306a36Sopenharmony_ci 203162306a36Sopenharmony_ci mutex_init(&drbg->drbg_mutex); 203262306a36Sopenharmony_ci drbg->core = &drbg_cores[coreref]; 203362306a36Sopenharmony_ci drbg->reseed_threshold = drbg_max_requests(drbg); 203462306a36Sopenharmony_ci 203562306a36Sopenharmony_ci /* 203662306a36Sopenharmony_ci * if the following tests fail, it is likely that there is a buffer 203762306a36Sopenharmony_ci * overflow as buf is much smaller than the requested or provided 203862306a36Sopenharmony_ci * string lengths -- in case the error handling does not succeed 203962306a36Sopenharmony_ci * we may get an OOPS. And we want to get an OOPS as this is a 204062306a36Sopenharmony_ci * grave bug. 204162306a36Sopenharmony_ci */ 204262306a36Sopenharmony_ci 204362306a36Sopenharmony_ci max_addtllen = drbg_max_addtl(drbg); 204462306a36Sopenharmony_ci max_request_bytes = drbg_max_request_bytes(drbg); 204562306a36Sopenharmony_ci drbg_string_fill(&addtl, buf, max_addtllen + 1); 204662306a36Sopenharmony_ci /* overflow addtllen with additonal info string */ 204762306a36Sopenharmony_ci len = drbg_generate(drbg, buf, OUTBUFLEN, &addtl); 204862306a36Sopenharmony_ci BUG_ON(0 < len); 204962306a36Sopenharmony_ci /* overflow max_bits */ 205062306a36Sopenharmony_ci len = drbg_generate(drbg, buf, (max_request_bytes + 1), NULL); 205162306a36Sopenharmony_ci BUG_ON(0 < len); 205262306a36Sopenharmony_ci 205362306a36Sopenharmony_ci /* overflow max addtllen with personalization string */ 205462306a36Sopenharmony_ci ret = drbg_seed(drbg, &addtl, false); 205562306a36Sopenharmony_ci BUG_ON(0 == ret); 205662306a36Sopenharmony_ci /* all tests passed */ 205762306a36Sopenharmony_ci rc = 0; 205862306a36Sopenharmony_ci 205962306a36Sopenharmony_ci pr_devel("DRBG: Sanity tests for failure code paths successfully " 206062306a36Sopenharmony_ci "completed\n"); 206162306a36Sopenharmony_ci 206262306a36Sopenharmony_ci kfree(drbg); 206362306a36Sopenharmony_ci return rc; 206462306a36Sopenharmony_ci} 206562306a36Sopenharmony_ci 206662306a36Sopenharmony_cistatic struct rng_alg drbg_algs[22]; 206762306a36Sopenharmony_ci 206862306a36Sopenharmony_ci/* 206962306a36Sopenharmony_ci * Fill the array drbg_algs used to register the different DRBGs 207062306a36Sopenharmony_ci * with the kernel crypto API. To fill the array, the information 207162306a36Sopenharmony_ci * from drbg_cores[] is used. 207262306a36Sopenharmony_ci */ 207362306a36Sopenharmony_cistatic inline void __init drbg_fill_array(struct rng_alg *alg, 207462306a36Sopenharmony_ci const struct drbg_core *core, int pr) 207562306a36Sopenharmony_ci{ 207662306a36Sopenharmony_ci int pos = 0; 207762306a36Sopenharmony_ci static int priority = 200; 207862306a36Sopenharmony_ci 207962306a36Sopenharmony_ci memcpy(alg->base.cra_name, "stdrng", 6); 208062306a36Sopenharmony_ci if (pr) { 208162306a36Sopenharmony_ci memcpy(alg->base.cra_driver_name, "drbg_pr_", 8); 208262306a36Sopenharmony_ci pos = 8; 208362306a36Sopenharmony_ci } else { 208462306a36Sopenharmony_ci memcpy(alg->base.cra_driver_name, "drbg_nopr_", 10); 208562306a36Sopenharmony_ci pos = 10; 208662306a36Sopenharmony_ci } 208762306a36Sopenharmony_ci memcpy(alg->base.cra_driver_name + pos, core->cra_name, 208862306a36Sopenharmony_ci strlen(core->cra_name)); 208962306a36Sopenharmony_ci 209062306a36Sopenharmony_ci alg->base.cra_priority = priority; 209162306a36Sopenharmony_ci priority++; 209262306a36Sopenharmony_ci /* 209362306a36Sopenharmony_ci * If FIPS mode enabled, the selected DRBG shall have the 209462306a36Sopenharmony_ci * highest cra_priority over other stdrng instances to ensure 209562306a36Sopenharmony_ci * it is selected. 209662306a36Sopenharmony_ci */ 209762306a36Sopenharmony_ci if (fips_enabled) 209862306a36Sopenharmony_ci alg->base.cra_priority += 200; 209962306a36Sopenharmony_ci 210062306a36Sopenharmony_ci alg->base.cra_ctxsize = sizeof(struct drbg_state); 210162306a36Sopenharmony_ci alg->base.cra_module = THIS_MODULE; 210262306a36Sopenharmony_ci alg->base.cra_init = drbg_kcapi_init; 210362306a36Sopenharmony_ci alg->base.cra_exit = drbg_kcapi_cleanup; 210462306a36Sopenharmony_ci alg->generate = drbg_kcapi_random; 210562306a36Sopenharmony_ci alg->seed = drbg_kcapi_seed; 210662306a36Sopenharmony_ci alg->set_ent = drbg_kcapi_set_entropy; 210762306a36Sopenharmony_ci alg->seedsize = 0; 210862306a36Sopenharmony_ci} 210962306a36Sopenharmony_ci 211062306a36Sopenharmony_cistatic int __init drbg_init(void) 211162306a36Sopenharmony_ci{ 211262306a36Sopenharmony_ci unsigned int i = 0; /* pointer to drbg_algs */ 211362306a36Sopenharmony_ci unsigned int j = 0; /* pointer to drbg_cores */ 211462306a36Sopenharmony_ci int ret; 211562306a36Sopenharmony_ci 211662306a36Sopenharmony_ci ret = drbg_healthcheck_sanity(); 211762306a36Sopenharmony_ci if (ret) 211862306a36Sopenharmony_ci return ret; 211962306a36Sopenharmony_ci 212062306a36Sopenharmony_ci if (ARRAY_SIZE(drbg_cores) * 2 > ARRAY_SIZE(drbg_algs)) { 212162306a36Sopenharmony_ci pr_info("DRBG: Cannot register all DRBG types" 212262306a36Sopenharmony_ci "(slots needed: %zu, slots available: %zu)\n", 212362306a36Sopenharmony_ci ARRAY_SIZE(drbg_cores) * 2, ARRAY_SIZE(drbg_algs)); 212462306a36Sopenharmony_ci return -EFAULT; 212562306a36Sopenharmony_ci } 212662306a36Sopenharmony_ci 212762306a36Sopenharmony_ci /* 212862306a36Sopenharmony_ci * each DRBG definition can be used with PR and without PR, thus 212962306a36Sopenharmony_ci * we instantiate each DRBG in drbg_cores[] twice. 213062306a36Sopenharmony_ci * 213162306a36Sopenharmony_ci * As the order of placing them into the drbg_algs array matters 213262306a36Sopenharmony_ci * (the later DRBGs receive a higher cra_priority) we register the 213362306a36Sopenharmony_ci * prediction resistance DRBGs first as the should not be too 213462306a36Sopenharmony_ci * interesting. 213562306a36Sopenharmony_ci */ 213662306a36Sopenharmony_ci for (j = 0; ARRAY_SIZE(drbg_cores) > j; j++, i++) 213762306a36Sopenharmony_ci drbg_fill_array(&drbg_algs[i], &drbg_cores[j], 1); 213862306a36Sopenharmony_ci for (j = 0; ARRAY_SIZE(drbg_cores) > j; j++, i++) 213962306a36Sopenharmony_ci drbg_fill_array(&drbg_algs[i], &drbg_cores[j], 0); 214062306a36Sopenharmony_ci return crypto_register_rngs(drbg_algs, (ARRAY_SIZE(drbg_cores) * 2)); 214162306a36Sopenharmony_ci} 214262306a36Sopenharmony_ci 214362306a36Sopenharmony_cistatic void __exit drbg_exit(void) 214462306a36Sopenharmony_ci{ 214562306a36Sopenharmony_ci crypto_unregister_rngs(drbg_algs, (ARRAY_SIZE(drbg_cores) * 2)); 214662306a36Sopenharmony_ci} 214762306a36Sopenharmony_ci 214862306a36Sopenharmony_cisubsys_initcall(drbg_init); 214962306a36Sopenharmony_cimodule_exit(drbg_exit); 215062306a36Sopenharmony_ci#ifndef CRYPTO_DRBG_HASH_STRING 215162306a36Sopenharmony_ci#define CRYPTO_DRBG_HASH_STRING "" 215262306a36Sopenharmony_ci#endif 215362306a36Sopenharmony_ci#ifndef CRYPTO_DRBG_HMAC_STRING 215462306a36Sopenharmony_ci#define CRYPTO_DRBG_HMAC_STRING "" 215562306a36Sopenharmony_ci#endif 215662306a36Sopenharmony_ci#ifndef CRYPTO_DRBG_CTR_STRING 215762306a36Sopenharmony_ci#define CRYPTO_DRBG_CTR_STRING "" 215862306a36Sopenharmony_ci#endif 215962306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 216062306a36Sopenharmony_ciMODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>"); 216162306a36Sopenharmony_ciMODULE_DESCRIPTION("NIST SP800-90A Deterministic Random Bit Generator (DRBG) " 216262306a36Sopenharmony_ci "using following cores: " 216362306a36Sopenharmony_ci CRYPTO_DRBG_HASH_STRING 216462306a36Sopenharmony_ci CRYPTO_DRBG_HMAC_STRING 216562306a36Sopenharmony_ci CRYPTO_DRBG_CTR_STRING); 216662306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("stdrng"); 216762306a36Sopenharmony_ciMODULE_IMPORT_NS(CRYPTO_INTERNAL); 2168