Commit 3cfc3b97 authored by Stephan Mueller's avatar Stephan Mueller Committed by Herbert Xu

crypto: drbg - use aligned buffers

Hardware cipher implementation may require aligned buffers. All buffers
that potentially are processed with a cipher are now aligned.
Signed-off-by: default avatarStephan Mueller <smueller@chronox.de>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 35591285
...@@ -1139,11 +1139,11 @@ static inline void drbg_dealloc_state(struct drbg_state *drbg) ...@@ -1139,11 +1139,11 @@ static inline void drbg_dealloc_state(struct drbg_state *drbg)
if (!drbg) if (!drbg)
return; return;
kzfree(drbg->V); kzfree(drbg->V);
drbg->V = NULL; drbg->Vbuf = NULL;
kzfree(drbg->C); kzfree(drbg->C);
drbg->C = NULL; drbg->Cbuf = NULL;
kzfree(drbg->scratchpad); kzfree(drbg->scratchpadbuf);
drbg->scratchpad = NULL; drbg->scratchpadbuf = NULL;
drbg->reseed_ctr = 0; drbg->reseed_ctr = 0;
drbg->d_ops = NULL; drbg->d_ops = NULL;
drbg->core = NULL; drbg->core = NULL;
...@@ -1179,12 +1179,18 @@ static inline int drbg_alloc_state(struct drbg_state *drbg) ...@@ -1179,12 +1179,18 @@ static inline int drbg_alloc_state(struct drbg_state *drbg)
goto err; goto err;
} }
drbg->V = kmalloc(drbg_statelen(drbg), GFP_KERNEL); ret = drbg->d_ops->crypto_init(drbg);
if (!drbg->V) if (ret < 0)
goto err;
drbg->C = kmalloc(drbg_statelen(drbg), GFP_KERNEL);
if (!drbg->C)
goto err; goto err;
drbg->Vbuf = kmalloc(drbg_statelen(drbg) + ret, GFP_KERNEL);
if (!drbg->Vbuf)
goto fini;
drbg->V = PTR_ALIGN(drbg->Vbuf, ret + 1);
drbg->Cbuf = kmalloc(drbg_statelen(drbg) + ret, GFP_KERNEL);
if (!drbg->Cbuf)
goto fini;
drbg->C = PTR_ALIGN(drbg->Cbuf, ret + 1);
/* scratchpad is only generated for CTR and Hash */ /* scratchpad is only generated for CTR and Hash */
if (drbg->core->flags & DRBG_HMAC) if (drbg->core->flags & DRBG_HMAC)
sb_size = 0; sb_size = 0;
...@@ -1198,13 +1204,16 @@ static inline int drbg_alloc_state(struct drbg_state *drbg) ...@@ -1198,13 +1204,16 @@ static inline int drbg_alloc_state(struct drbg_state *drbg)
sb_size = drbg_statelen(drbg) + drbg_blocklen(drbg); sb_size = drbg_statelen(drbg) + drbg_blocklen(drbg);
if (0 < sb_size) { if (0 < sb_size) {
drbg->scratchpad = kzalloc(sb_size, GFP_KERNEL); drbg->scratchpadbuf = kzalloc(sb_size + ret, GFP_KERNEL);
if (!drbg->scratchpad) if (!drbg->scratchpadbuf)
goto err; goto fini;
drbg->scratchpad = PTR_ALIGN(drbg->scratchpadbuf, ret + 1);
} }
return 0; return 0;
fini:
drbg->d_ops->crypto_fini(drbg);
err: err:
drbg_dealloc_state(drbg); drbg_dealloc_state(drbg);
return ret; return ret;
...@@ -1472,10 +1481,6 @@ static int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers, ...@@ -1472,10 +1481,6 @@ static int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers,
if (ret) if (ret)
goto unlock; goto unlock;
ret = -EFAULT;
if (drbg->d_ops->crypto_init(drbg))
goto err;
ret = drbg_prepare_hrng(drbg); ret = drbg_prepare_hrng(drbg);
if (ret) if (ret)
goto free_everything; goto free_everything;
...@@ -1499,8 +1504,6 @@ static int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers, ...@@ -1499,8 +1504,6 @@ static int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers,
mutex_unlock(&drbg->drbg_mutex); mutex_unlock(&drbg->drbg_mutex);
return ret; return ret;
err:
drbg_dealloc_state(drbg);
unlock: unlock:
mutex_unlock(&drbg->drbg_mutex); mutex_unlock(&drbg->drbg_mutex);
return ret; return ret;
...@@ -1585,7 +1588,8 @@ static int drbg_init_hash_kernel(struct drbg_state *drbg) ...@@ -1585,7 +1588,8 @@ static int drbg_init_hash_kernel(struct drbg_state *drbg)
sdesc->shash.tfm = tfm; sdesc->shash.tfm = tfm;
sdesc->shash.flags = 0; sdesc->shash.flags = 0;
drbg->priv_data = sdesc; drbg->priv_data = sdesc;
return 0;
return crypto_shash_alignmask(tfm);
} }
static int drbg_fini_hash_kernel(struct drbg_state *drbg) static int drbg_fini_hash_kernel(struct drbg_state *drbg)
...@@ -1705,7 +1709,7 @@ static int drbg_init_sym_kernel(struct drbg_state *drbg) ...@@ -1705,7 +1709,7 @@ static int drbg_init_sym_kernel(struct drbg_state *drbg)
drbg->ctr_null_value = (u8 *)PTR_ALIGN(drbg->ctr_null_value_buf, drbg->ctr_null_value = (u8 *)PTR_ALIGN(drbg->ctr_null_value_buf,
alignmask + 1); alignmask + 1);
return 0; return alignmask;
} }
static void drbg_kcapi_symsetkey(struct drbg_state *drbg, static void drbg_kcapi_symsetkey(struct drbg_state *drbg,
......
...@@ -108,13 +108,16 @@ struct drbg_test_data { ...@@ -108,13 +108,16 @@ struct drbg_test_data {
struct drbg_state { struct drbg_state {
struct mutex drbg_mutex; /* lock around DRBG */ struct mutex drbg_mutex; /* lock around DRBG */
unsigned char *V; /* internal state 10.1.1.1 1a) */ unsigned char *V; /* internal state 10.1.1.1 1a) */
unsigned char *Vbuf;
/* hash: static value 10.1.1.1 1b) hmac / ctr: key */ /* hash: static value 10.1.1.1 1b) hmac / ctr: key */
unsigned char *C; unsigned char *C;
unsigned char *Cbuf;
/* Number of RNG requests since last reseed -- 10.1.1.1 1c) */ /* Number of RNG requests since last reseed -- 10.1.1.1 1c) */
size_t reseed_ctr; size_t reseed_ctr;
size_t reseed_threshold; size_t reseed_threshold;
/* some memory the DRBG can use for its operation */ /* some memory the DRBG can use for its operation */
unsigned char *scratchpad; unsigned char *scratchpad;
unsigned char *scratchpadbuf;
void *priv_data; /* Cipher handle */ void *priv_data; /* Cipher handle */
struct crypto_skcipher *ctr_handle; /* CTR mode cipher handle */ struct crypto_skcipher *ctr_handle; /* CTR mode cipher handle */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment