summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2015-06-21 07:11:47 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2015-06-22 03:49:28 -0400
commit055906d1e7f94f459a0e80228f15656bf5871311 (patch)
treeed684c45b2e32e3e8a2fdeb6ea909bed22a3ecad /crypto
parent341476d6cf224f1dea5c439cd70181053629ce15 (diff)
crypto: eseqiv - Offer normal cipher functionality without RNG
The RNG may not be available during early boot, e.g., the relevant modules may not be included in the initramfs. As the RNG Is only needed for IPsec, we should not let this prevent use of ciphers without IV generators, e.g., for disk encryption. This patch postpones the RNG allocation to the init function so that one failure during early boot does not make the RNG unavailable for all subsequent users of the same cipher. More importantly, it lets the cipher live even if RNG allocation fails. Of course we no longer offer IV generation and which will fail with an error if invoked. But all other cipher capabilities will function as usual. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/eseqiv.c31
1 files changed, 12 insertions, 19 deletions
diff --git a/crypto/eseqiv.c b/crypto/eseqiv.c
index 78a72645390c..16dda72fc4f8 100644
--- a/crypto/eseqiv.c
+++ b/crypto/eseqiv.c
@@ -152,6 +152,7 @@ static int eseqiv_init(struct crypto_tfm *tfm)
152 struct eseqiv_ctx *ctx = crypto_ablkcipher_ctx(geniv); 152 struct eseqiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
153 unsigned long alignmask; 153 unsigned long alignmask;
154 unsigned int reqsize; 154 unsigned int reqsize;
155 int err;
155 156
156 spin_lock_init(&ctx->lock); 157 spin_lock_init(&ctx->lock);
157 158
@@ -175,9 +176,15 @@ static int eseqiv_init(struct crypto_tfm *tfm)
175 tfm->crt_ablkcipher.reqsize = reqsize + 176 tfm->crt_ablkcipher.reqsize = reqsize +
176 sizeof(struct ablkcipher_request); 177 sizeof(struct ablkcipher_request);
177 178
178 return crypto_rng_get_bytes(crypto_default_rng, ctx->salt, 179 err = 0;
179 crypto_ablkcipher_ivsize(geniv)) ?: 180 if (!crypto_get_default_rng()) {
180 skcipher_geniv_init(tfm); 181 crypto_ablkcipher_crt(geniv)->givencrypt = eseqiv_givencrypt;
182 err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt,
183 crypto_ablkcipher_ivsize(geniv));
184 crypto_put_default_rng();
185 }
186
187 return err ?: skcipher_geniv_init(tfm);
181} 188}
182 189
183static struct crypto_template eseqiv_tmpl; 190static struct crypto_template eseqiv_tmpl;
@@ -187,20 +194,14 @@ static struct crypto_instance *eseqiv_alloc(struct rtattr **tb)
187 struct crypto_instance *inst; 194 struct crypto_instance *inst;
188 int err; 195 int err;
189 196
190 err = crypto_get_default_rng();
191 if (err)
192 return ERR_PTR(err);
193
194 inst = skcipher_geniv_alloc(&eseqiv_tmpl, tb, 0, 0); 197 inst = skcipher_geniv_alloc(&eseqiv_tmpl, tb, 0, 0);
195 if (IS_ERR(inst)) 198 if (IS_ERR(inst))
196 goto put_rng; 199 goto out;
197 200
198 err = -EINVAL; 201 err = -EINVAL;
199 if (inst->alg.cra_ablkcipher.ivsize != inst->alg.cra_blocksize) 202 if (inst->alg.cra_ablkcipher.ivsize != inst->alg.cra_blocksize)
200 goto free_inst; 203 goto free_inst;
201 204
202 inst->alg.cra_ablkcipher.givencrypt = eseqiv_givencrypt;
203
204 inst->alg.cra_init = eseqiv_init; 205 inst->alg.cra_init = eseqiv_init;
205 inst->alg.cra_exit = skcipher_geniv_exit; 206 inst->alg.cra_exit = skcipher_geniv_exit;
206 207
@@ -213,21 +214,13 @@ out:
213free_inst: 214free_inst:
214 skcipher_geniv_free(inst); 215 skcipher_geniv_free(inst);
215 inst = ERR_PTR(err); 216 inst = ERR_PTR(err);
216put_rng:
217 crypto_put_default_rng();
218 goto out; 217 goto out;
219} 218}
220 219
221static void eseqiv_free(struct crypto_instance *inst)
222{
223 skcipher_geniv_free(inst);
224 crypto_put_default_rng();
225}
226
227static struct crypto_template eseqiv_tmpl = { 220static struct crypto_template eseqiv_tmpl = {
228 .name = "eseqiv", 221 .name = "eseqiv",
229 .alloc = eseqiv_alloc, 222 .alloc = eseqiv_alloc,
230 .free = eseqiv_free, 223 .free = skcipher_geniv_free,
231 .module = THIS_MODULE, 224 .module = THIS_MODULE,
232}; 225};
233 226