summaryrefslogtreecommitdiff
path: root/crypto/drbg.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-05-17 09:33:39 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-17 09:33:39 -0700
commit045d243889e6ef958655226694646fa82b4716c7 (patch)
treeb23449f4d0e46a35210c2f703a46c31107f9b0a3 /crypto/drbg.c
parent72003fbce7e444f52fdd2caae1b365bee23aa6f8 (diff)
parentff644448e8377b252ca07da3d156d700ebfa5c6c (diff)
downloadlinux-crypto-045d243889e6ef958655226694646fa82b4716c7.tar.gz
linux-crypto-045d243889e6ef958655226694646fa82b4716c7.zip
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto update from Herbert Xu: "API: - Crypto self tests can now be disabled at boot/run time. - Add async support to algif_aead. Algorithms: - A large number of fixes to MPI from Nicolai Stange. - Performance improvement for HMAC DRBG. Drivers: - Use generic crypto engine in omap-des. - Merge ppc4xx-rng and crypto4xx drivers. - Fix lockups in sun4i-ss driver by disabling IRQs. - Add DMA engine support to ccp. - Reenable talitos hash algorithms. - Add support for Hisilicon SoC RNG. - Add basic crypto driver for the MXC SCC. Others: - Do not allocate crypto hash tfm in NORECLAIM context in ecryptfs" * 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (77 commits) crypto: qat - change the adf_ctl_stop_devices to void crypto: caam - fix caam_jr_alloc() ret code crypto: vmx - comply with ABIs that specify vrsave as reserved. crypto: testmgr - Add a flag allowing the self-tests to be disabled at runtime. crypto: ccp - constify ccp_actions structure crypto: marvell/cesa - Use dma_pool_zalloc crypto: qat - make adf_vf_isr.c dependant on IOV config crypto: qat - Fix typo in comments lib: asn1_decoder - add MODULE_LICENSE("GPL") crypto: omap-sham - Use dma_request_chan() for requesting DMA channel crypto: omap-des - Use dma_request_chan() for requesting DMA channel crypto: omap-aes - Use dma_request_chan() for requesting DMA channel crypto: omap-des - Integrate with the crypto engine framework crypto: s5p-sss - fix incorrect usage of scatterlists api crypto: s5p-sss - Fix missed interrupts when working with 8 kB blocks crypto: s5p-sss - Use common BIT macro crypto: mxc-scc - fix unwinding in mxc_scc_crypto_register() crypto: mxc-scc - signedness bugs in mxc_scc_ablkcipher_req_init() crypto: talitos - fix ahash algorithms registration crypto: ccp - Ensure all dependencies are specified ...
Diffstat (limited to 'crypto/drbg.c')
-rw-r--r--crypto/drbg.c39
1 files changed, 25 insertions, 14 deletions
diff --git a/crypto/drbg.c b/crypto/drbg.c
index 1b86310d..0a3538f6 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -592,8 +592,10 @@ static const struct drbg_state_ops drbg_ctr_ops = {
******************************************************************/
#if defined(CONFIG_CRYPTO_DRBG_HASH) || defined(CONFIG_CRYPTO_DRBG_HMAC)
-static int drbg_kcapi_hash(struct drbg_state *drbg, const unsigned char *key,
- unsigned char *outval, const struct list_head *in);
+static int drbg_kcapi_hash(struct drbg_state *drbg, unsigned char *outval,
+ const struct list_head *in);
+static void drbg_kcapi_hmacsetkey(struct drbg_state *drbg,
+ const unsigned char *key);
static int drbg_init_hash_kernel(struct drbg_state *drbg);
static int drbg_fini_hash_kernel(struct drbg_state *drbg);
#endif /* (CONFIG_CRYPTO_DRBG_HASH || CONFIG_CRYPTO_DRBG_HMAC) */
@@ -619,9 +621,11 @@ static int drbg_hmac_update(struct drbg_state *drbg, struct list_head *seed,
LIST_HEAD(seedlist);
LIST_HEAD(vdatalist);
- if (!reseed)
+ if (!reseed) {
/* 10.1.2.3 step 2 -- memset(0) of C is implicit with kzalloc */
memset(drbg->V, 1, drbg_statelen(drbg));
+ drbg_kcapi_hmacsetkey(drbg, drbg->C);
+ }
drbg_string_fill(&seed1, drbg->V, drbg_statelen(drbg));
list_add_tail(&seed1.list, &seedlist);
@@ -641,12 +645,13 @@ static int drbg_hmac_update(struct drbg_state *drbg, struct list_head *seed,
prefix = DRBG_PREFIX1;
/* 10.1.2.2 step 1 and 4 -- concatenation and HMAC for key */
seed2.buf = &prefix;
- ret = drbg_kcapi_hash(drbg, drbg->C, drbg->C, &seedlist);
+ ret = drbg_kcapi_hash(drbg, drbg->C, &seedlist);
if (ret)
return ret;
+ drbg_kcapi_hmacsetkey(drbg, drbg->C);
/* 10.1.2.2 step 2 and 5 -- HMAC for V */
- ret = drbg_kcapi_hash(drbg, drbg->C, drbg->V, &vdatalist);
+ ret = drbg_kcapi_hash(drbg, drbg->V, &vdatalist);
if (ret)
return ret;
@@ -681,7 +686,7 @@ static int drbg_hmac_generate(struct drbg_state *drbg,
while (len < buflen) {
unsigned int outlen = 0;
/* 10.1.2.5 step 4.1 */
- ret = drbg_kcapi_hash(drbg, drbg->C, drbg->V, &datalist);
+ ret = drbg_kcapi_hash(drbg, drbg->V, &datalist);
if (ret)
return ret;
outlen = (drbg_blocklen(drbg) < (buflen - len)) ?
@@ -796,7 +801,7 @@ static int drbg_hash_df(struct drbg_state *drbg,
while (len < outlen) {
short blocklen = 0;
/* 10.4.1 step 4.1 */
- ret = drbg_kcapi_hash(drbg, NULL, tmp, entropylist);
+ ret = drbg_kcapi_hash(drbg, tmp, entropylist);
if (ret)
goto out;
/* 10.4.1 step 4.2 */
@@ -874,7 +879,7 @@ static int drbg_hash_process_addtl(struct drbg_state *drbg,
list_add_tail(&data1.list, &datalist);
list_add_tail(&data2.list, &datalist);
list_splice_tail(addtl, &datalist);
- ret = drbg_kcapi_hash(drbg, NULL, drbg->scratchpad, &datalist);
+ ret = drbg_kcapi_hash(drbg, drbg->scratchpad, &datalist);
if (ret)
goto out;
@@ -907,7 +912,7 @@ static int drbg_hash_hashgen(struct drbg_state *drbg,
while (len < buflen) {
unsigned int outlen = 0;
/* 10.1.1.4 step hashgen 4.1 */
- ret = drbg_kcapi_hash(drbg, NULL, dst, &datalist);
+ ret = drbg_kcapi_hash(drbg, dst, &datalist);
if (ret) {
len = ret;
goto out;
@@ -956,7 +961,7 @@ static int drbg_hash_generate(struct drbg_state *drbg,
list_add_tail(&data1.list, &datalist);
drbg_string_fill(&data2, drbg->V, drbg_statelen(drbg));
list_add_tail(&data2.list, &datalist);
- ret = drbg_kcapi_hash(drbg, NULL, drbg->scratchpad, &datalist);
+ ret = drbg_kcapi_hash(drbg, drbg->scratchpad, &datalist);
if (ret) {
len = ret;
goto out;
@@ -1600,14 +1605,20 @@ static int drbg_fini_hash_kernel(struct drbg_state *drbg)
return 0;
}
-static int drbg_kcapi_hash(struct drbg_state *drbg, const unsigned char *key,
- unsigned char *outval, const struct list_head *in)
+static void drbg_kcapi_hmacsetkey(struct drbg_state *drbg,
+ const unsigned char *key)
+{
+ struct sdesc *sdesc = (struct sdesc *)drbg->priv_data;
+
+ crypto_shash_setkey(sdesc->shash.tfm, key, drbg_statelen(drbg));
+}
+
+static int drbg_kcapi_hash(struct drbg_state *drbg, unsigned char *outval,
+ const struct list_head *in)
{
struct sdesc *sdesc = (struct sdesc *)drbg->priv_data;
struct drbg_string *input = NULL;
- if (key)
- crypto_shash_setkey(sdesc->shash.tfm, key, drbg_statelen(drbg));
crypto_shash_init(&sdesc->shash);
list_for_each_entry(input, in, list)
crypto_shash_update(&sdesc->shash, input->buf, input->len);