diff options
author | Stephan Mueller <smueller@chronox.de> | 2016-06-14 07:35:37 +0200 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2016-06-15 17:07:53 +0800 |
commit | a07203fbfcf146b737781ee4658ed198956036ca (patch) | |
tree | 9e9363c209c5180745039ed672b9b5f0682315a6 /crypto | |
parent | 3cfc3b97211238ffc1a7885ebe62f899180fe043 (diff) | |
download | linux-a07203fbfcf146b737781ee4658ed198956036ca.tar.bz2 |
crypto: drbg - use full CTR AES for update
The CTR DRBG update function performs a full CTR AES operation including
the XOR with "plaintext" data. Hence, remove the XOR from the code and
use the CTR mode to do the XOR.
Signed-off-by: Stephan Mueller <smueller@chronox.de>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/drbg.c | 30 |
1 files changed, 13 insertions, 17 deletions
diff --git a/crypto/drbg.c b/crypto/drbg.c index 8ac3ea11d437..8ceb71699dea 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -258,7 +258,10 @@ static int drbg_kcapi_sym(struct drbg_state *drbg, unsigned char *outval, const struct drbg_string *in); static int drbg_init_sym_kernel(struct drbg_state *drbg); static int drbg_fini_sym_kernel(struct drbg_state *drbg); -static int drbg_kcapi_sym_ctr(struct drbg_state *drbg, u8 *outbuf, u32 outlen); +static int drbg_kcapi_sym_ctr(struct drbg_state *drbg, + u8 *inbuf, u32 inbuflen, + u8 *outbuf, u32 outlen); +#define DRBG_CTR_NULL_LEN 128 /* BCC function for CTR DRBG as defined in 10.4.3 */ static int drbg_ctr_bcc(struct drbg_state *drbg, @@ -481,8 +484,6 @@ static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed, unsigned char *temp = drbg->scratchpad; unsigned char *df_data = drbg->scratchpad + drbg_statelen(drbg) + drbg_blocklen(drbg); - unsigned char *temp_p, *df_data_p; /* pointer to iterate over buffers */ - unsigned int len = 0; if (3 > reseed) memset(df_data, 0, drbg_statelen(drbg)); @@ -510,18 +511,11 @@ static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed, goto out; } - ret = drbg_kcapi_sym_ctr(drbg, temp, drbg_statelen(drbg)); + ret = drbg_kcapi_sym_ctr(drbg, df_data, drbg_statelen(drbg), + temp, drbg_statelen(drbg)); if (ret) return ret; - /* 10.2.1.2 step 4 */ - temp_p = temp; - df_data_p = df_data; - for (len = 0; len < drbg_statelen(drbg); len++) { - *temp_p ^= *df_data_p; - df_data_p++; temp_p++; - } - /* 10.2.1.2 step 5 */ memcpy(drbg->C, temp, drbg_keylen(drbg)); ret = crypto_skcipher_setkey(drbg->ctr_handle, drbg->C, @@ -561,7 +555,8 @@ static int drbg_ctr_generate(struct drbg_state *drbg, } /* 10.2.1.5.2 step 4.1 */ - ret = drbg_kcapi_sym_ctr(drbg, buf, len); + ret = drbg_kcapi_sym_ctr(drbg, drbg->ctr_null_value, DRBG_CTR_NULL_LEN, + buf, len); if (ret) return ret; @@ -1657,7 +1652,6 @@ static void drbg_skcipher_cb(struct crypto_async_request *req, int error) complete(&drbg->ctr_completion); } -#define DRBG_CTR_NULL_LEN 128 static int drbg_init_sym_kernel(struct drbg_state *drbg) { struct crypto_cipher *tfm; @@ -1733,14 +1727,16 @@ static int drbg_kcapi_sym(struct drbg_state *drbg, unsigned char *outval, return 0; } -static int drbg_kcapi_sym_ctr(struct drbg_state *drbg, u8 *outbuf, u32 outlen) +static int drbg_kcapi_sym_ctr(struct drbg_state *drbg, + u8 *inbuf, u32 inlen, + u8 *outbuf, u32 outlen) { struct scatterlist sg_in; - sg_init_one(&sg_in, drbg->ctr_null_value, DRBG_CTR_NULL_LEN); + sg_init_one(&sg_in, inbuf, inlen); while (outlen) { - u32 cryptlen = min_t(u32, outlen, DRBG_CTR_NULL_LEN); + u32 cryptlen = min_t(u32, inlen, outlen); struct scatterlist sg_out; int ret; |