at v2.6.26-rc3 343 lines 9.0 kB view raw
1/* 2 * Asynchronous block chaining cipher operations. 3 * 4 * This is the asynchronous version of blkcipher.c indicating completion 5 * via a callback. 6 * 7 * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au> 8 * 9 * This program is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU General Public License as published by the Free 11 * Software Foundation; either version 2 of the License, or (at your option) 12 * any later version. 13 * 14 */ 15 16#include <crypto/internal/skcipher.h> 17#include <linux/err.h> 18#include <linux/init.h> 19#include <linux/kernel.h> 20#include <linux/module.h> 21#include <linux/rtnetlink.h> 22#include <linux/sched.h> 23#include <linux/slab.h> 24#include <linux/seq_file.h> 25 26#include "internal.h" 27 28static int setkey_unaligned(struct crypto_ablkcipher *tfm, const u8 *key, 29 unsigned int keylen) 30{ 31 struct ablkcipher_alg *cipher = crypto_ablkcipher_alg(tfm); 32 unsigned long alignmask = crypto_ablkcipher_alignmask(tfm); 33 int ret; 34 u8 *buffer, *alignbuffer; 35 unsigned long absize; 36 37 absize = keylen + alignmask; 38 buffer = kmalloc(absize, GFP_ATOMIC); 39 if (!buffer) 40 return -ENOMEM; 41 42 alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); 43 memcpy(alignbuffer, key, keylen); 44 ret = cipher->setkey(tfm, alignbuffer, keylen); 45 memset(alignbuffer, 0, keylen); 46 kfree(buffer); 47 return ret; 48} 49 50static int setkey(struct crypto_ablkcipher *tfm, const u8 *key, 51 unsigned int keylen) 52{ 53 struct ablkcipher_alg *cipher = crypto_ablkcipher_alg(tfm); 54 unsigned long alignmask = crypto_ablkcipher_alignmask(tfm); 55 56 if (keylen < cipher->min_keysize || keylen > cipher->max_keysize) { 57 crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 58 return -EINVAL; 59 } 60 61 if ((unsigned long)key & alignmask) 62 return setkey_unaligned(tfm, key, keylen); 63 64 return cipher->setkey(tfm, key, keylen); 65} 66 67static unsigned int crypto_ablkcipher_ctxsize(struct crypto_alg *alg, u32 type, 68 u32 mask) 69{ 70 return alg->cra_ctxsize; 71} 72 73int skcipher_null_givencrypt(struct skcipher_givcrypt_request *req) 74{ 75 return crypto_ablkcipher_encrypt(&req->creq); 76} 77 78int skcipher_null_givdecrypt(struct skcipher_givcrypt_request *req) 79{ 80 return crypto_ablkcipher_decrypt(&req->creq); 81} 82 83static int crypto_init_ablkcipher_ops(struct crypto_tfm *tfm, u32 type, 84 u32 mask) 85{ 86 struct ablkcipher_alg *alg = &tfm->__crt_alg->cra_ablkcipher; 87 struct ablkcipher_tfm *crt = &tfm->crt_ablkcipher; 88 89 if (alg->ivsize > PAGE_SIZE / 8) 90 return -EINVAL; 91 92 crt->setkey = setkey; 93 crt->encrypt = alg->encrypt; 94 crt->decrypt = alg->decrypt; 95 if (!alg->ivsize) { 96 crt->givencrypt = skcipher_null_givencrypt; 97 crt->givdecrypt = skcipher_null_givdecrypt; 98 } 99 crt->base = __crypto_ablkcipher_cast(tfm); 100 crt->ivsize = alg->ivsize; 101 102 return 0; 103} 104 105static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg) 106 __attribute__ ((unused)); 107static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg) 108{ 109 struct ablkcipher_alg *ablkcipher = &alg->cra_ablkcipher; 110 111 seq_printf(m, "type : ablkcipher\n"); 112 seq_printf(m, "async : %s\n", alg->cra_flags & CRYPTO_ALG_ASYNC ? 113 "yes" : "no"); 114 seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); 115 seq_printf(m, "min keysize : %u\n", ablkcipher->min_keysize); 116 seq_printf(m, "max keysize : %u\n", ablkcipher->max_keysize); 117 seq_printf(m, "ivsize : %u\n", ablkcipher->ivsize); 118 seq_printf(m, "geniv : %s\n", ablkcipher->geniv ?: "<default>"); 119} 120 121const struct crypto_type crypto_ablkcipher_type = { 122 .ctxsize = crypto_ablkcipher_ctxsize, 123 .init = crypto_init_ablkcipher_ops, 124#ifdef CONFIG_PROC_FS 125 .show = crypto_ablkcipher_show, 126#endif 127}; 128EXPORT_SYMBOL_GPL(crypto_ablkcipher_type); 129 130static int no_givdecrypt(struct skcipher_givcrypt_request *req) 131{ 132 return -ENOSYS; 133} 134 135static int crypto_init_givcipher_ops(struct crypto_tfm *tfm, u32 type, 136 u32 mask) 137{ 138 struct ablkcipher_alg *alg = &tfm->__crt_alg->cra_ablkcipher; 139 struct ablkcipher_tfm *crt = &tfm->crt_ablkcipher; 140 141 if (alg->ivsize > PAGE_SIZE / 8) 142 return -EINVAL; 143 144 crt->setkey = tfm->__crt_alg->cra_flags & CRYPTO_ALG_GENIV ? 145 alg->setkey : setkey; 146 crt->encrypt = alg->encrypt; 147 crt->decrypt = alg->decrypt; 148 crt->givencrypt = alg->givencrypt; 149 crt->givdecrypt = alg->givdecrypt ?: no_givdecrypt; 150 crt->base = __crypto_ablkcipher_cast(tfm); 151 crt->ivsize = alg->ivsize; 152 153 return 0; 154} 155 156static void crypto_givcipher_show(struct seq_file *m, struct crypto_alg *alg) 157 __attribute__ ((unused)); 158static void crypto_givcipher_show(struct seq_file *m, struct crypto_alg *alg) 159{ 160 struct ablkcipher_alg *ablkcipher = &alg->cra_ablkcipher; 161 162 seq_printf(m, "type : givcipher\n"); 163 seq_printf(m, "async : %s\n", alg->cra_flags & CRYPTO_ALG_ASYNC ? 164 "yes" : "no"); 165 seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); 166 seq_printf(m, "min keysize : %u\n", ablkcipher->min_keysize); 167 seq_printf(m, "max keysize : %u\n", ablkcipher->max_keysize); 168 seq_printf(m, "ivsize : %u\n", ablkcipher->ivsize); 169 seq_printf(m, "geniv : %s\n", ablkcipher->geniv ?: "<built-in>"); 170} 171 172const struct crypto_type crypto_givcipher_type = { 173 .ctxsize = crypto_ablkcipher_ctxsize, 174 .init = crypto_init_givcipher_ops, 175#ifdef CONFIG_PROC_FS 176 .show = crypto_givcipher_show, 177#endif 178}; 179EXPORT_SYMBOL_GPL(crypto_givcipher_type); 180 181const char *crypto_default_geniv(const struct crypto_alg *alg) 182{ 183 return alg->cra_flags & CRYPTO_ALG_ASYNC ? "eseqiv" : "chainiv"; 184} 185 186static int crypto_givcipher_default(struct crypto_alg *alg, u32 type, u32 mask) 187{ 188 struct rtattr *tb[3]; 189 struct { 190 struct rtattr attr; 191 struct crypto_attr_type data; 192 } ptype; 193 struct { 194 struct rtattr attr; 195 struct crypto_attr_alg data; 196 } palg; 197 struct crypto_template *tmpl; 198 struct crypto_instance *inst; 199 struct crypto_alg *larval; 200 const char *geniv; 201 int err; 202 203 larval = crypto_larval_lookup(alg->cra_driver_name, 204 CRYPTO_ALG_TYPE_GIVCIPHER, 205 CRYPTO_ALG_TYPE_MASK); 206 err = PTR_ERR(larval); 207 if (IS_ERR(larval)) 208 goto out; 209 210 err = -EAGAIN; 211 if (!crypto_is_larval(larval)) 212 goto drop_larval; 213 214 ptype.attr.rta_len = sizeof(ptype); 215 ptype.attr.rta_type = CRYPTOA_TYPE; 216 ptype.data.type = type | CRYPTO_ALG_GENIV; 217 /* GENIV tells the template that we're making a default geniv. */ 218 ptype.data.mask = mask | CRYPTO_ALG_GENIV; 219 tb[0] = &ptype.attr; 220 221 palg.attr.rta_len = sizeof(palg); 222 palg.attr.rta_type = CRYPTOA_ALG; 223 /* Must use the exact name to locate ourselves. */ 224 memcpy(palg.data.name, alg->cra_driver_name, CRYPTO_MAX_ALG_NAME); 225 tb[1] = &palg.attr; 226 227 tb[2] = NULL; 228 229 if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == 230 CRYPTO_ALG_TYPE_BLKCIPHER) 231 geniv = alg->cra_blkcipher.geniv; 232 else 233 geniv = alg->cra_ablkcipher.geniv; 234 235 if (!geniv) 236 geniv = crypto_default_geniv(alg); 237 238 tmpl = crypto_lookup_template(geniv); 239 err = -ENOENT; 240 if (!tmpl) 241 goto kill_larval; 242 243 inst = tmpl->alloc(tb); 244 err = PTR_ERR(inst); 245 if (IS_ERR(inst)) 246 goto put_tmpl; 247 248 if ((err = crypto_register_instance(tmpl, inst))) { 249 tmpl->free(inst); 250 goto put_tmpl; 251 } 252 253 /* Redo the lookup to use the instance we just registered. */ 254 err = -EAGAIN; 255 256put_tmpl: 257 crypto_tmpl_put(tmpl); 258kill_larval: 259 crypto_larval_kill(larval); 260drop_larval: 261 crypto_mod_put(larval); 262out: 263 crypto_mod_put(alg); 264 return err; 265} 266 267static struct crypto_alg *crypto_lookup_skcipher(const char *name, u32 type, 268 u32 mask) 269{ 270 struct crypto_alg *alg; 271 272 alg = crypto_alg_mod_lookup(name, type, mask); 273 if (IS_ERR(alg)) 274 return alg; 275 276 if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == 277 CRYPTO_ALG_TYPE_GIVCIPHER) 278 return alg; 279 280 if (!((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == 281 CRYPTO_ALG_TYPE_BLKCIPHER ? alg->cra_blkcipher.ivsize : 282 alg->cra_ablkcipher.ivsize)) 283 return alg; 284 285 return ERR_PTR(crypto_givcipher_default(alg, type, mask)); 286} 287 288int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn, const char *name, 289 u32 type, u32 mask) 290{ 291 struct crypto_alg *alg; 292 int err; 293 294 type = crypto_skcipher_type(type); 295 mask = crypto_skcipher_mask(mask); 296 297 alg = crypto_lookup_skcipher(name, type, mask); 298 if (IS_ERR(alg)) 299 return PTR_ERR(alg); 300 301 err = crypto_init_spawn(&spawn->base, alg, spawn->base.inst, mask); 302 crypto_mod_put(alg); 303 return err; 304} 305EXPORT_SYMBOL_GPL(crypto_grab_skcipher); 306 307struct crypto_ablkcipher *crypto_alloc_ablkcipher(const char *alg_name, 308 u32 type, u32 mask) 309{ 310 struct crypto_tfm *tfm; 311 int err; 312 313 type = crypto_skcipher_type(type); 314 mask = crypto_skcipher_mask(mask); 315 316 for (;;) { 317 struct crypto_alg *alg; 318 319 alg = crypto_lookup_skcipher(alg_name, type, mask); 320 if (IS_ERR(alg)) { 321 err = PTR_ERR(alg); 322 goto err; 323 } 324 325 tfm = __crypto_alloc_tfm(alg, type, mask); 326 if (!IS_ERR(tfm)) 327 return __crypto_ablkcipher_cast(tfm); 328 329 crypto_mod_put(alg); 330 err = PTR_ERR(tfm); 331 332err: 333 if (err != -EAGAIN) 334 break; 335 if (signal_pending(current)) { 336 err = -EINTR; 337 break; 338 } 339 } 340 341 return ERR_PTR(err); 342} 343EXPORT_SYMBOL_GPL(crypto_alloc_ablkcipher);