1 /* 2 * Cryptographic API for algorithms (i.e., low-level API). 3 * 4 * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au> 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the Free 8 * Software Foundation; either version 2 of the License, or (at your option) 9 * any later version. 10 * 11 */ 12 13 #include <linux/err.h> 14 #include <linux/errno.h> 15 #include <linux/init.h> 16 #include <linux/kernel.h> 17 #include <linux/list.h> 18 #include <linux/module.h> 19 #include <linux/rtnetlink.h> 20 #include <linux/string.h> 21 22 #include "internal.h" 23 24 static LIST_HEAD(crypto_template_list); 25 26 void crypto_larval_error(const char *name, u32 type, u32 mask) 27 { 28 struct crypto_alg *alg; 29 30 down_read(&crypto_alg_sem); 31 alg = __crypto_alg_lookup(name, type, mask); 32 up_read(&crypto_alg_sem); 33 34 if (alg) { 35 if (crypto_is_larval(alg)) { 36 struct crypto_larval *larval = (void *)alg; 37 complete(&larval->completion); 38 } 39 crypto_mod_put(alg); 40 } 41 } 42 EXPORT_SYMBOL_GPL(crypto_larval_error); 43 44 static inline int crypto_set_driver_name(struct crypto_alg *alg) 45 { 46 static const char suffix[] = "-generic"; 47 char *driver_name = alg->cra_driver_name; 48 int len; 49 50 if (*driver_name) 51 return 0; 52 53 len = strlcpy(driver_name, alg->cra_name, CRYPTO_MAX_ALG_NAME); 54 if (len + sizeof(suffix) > CRYPTO_MAX_ALG_NAME) 55 return -ENAMETOOLONG; 56 57 memcpy(driver_name + len, suffix, sizeof(suffix)); 58 return 0; 59 } 60 61 static int crypto_check_alg(struct crypto_alg *alg) 62 { 63 if (alg->cra_alignmask & (alg->cra_alignmask + 1)) 64 return -EINVAL; 65 66 if (alg->cra_alignmask & alg->cra_blocksize) 67 return -EINVAL; 68 69 if (alg->cra_blocksize > PAGE_SIZE / 8) 70 return -EINVAL; 71 72 if (alg->cra_priority < 0) 73 return -EINVAL; 74 75 return crypto_set_driver_name(alg); 76 } 77 78 static void crypto_destroy_instance(struct crypto_alg *alg) 79 { 80 struct crypto_instance *inst = (void *)alg; 81 struct crypto_template *tmpl = inst->tmpl; 82 83 tmpl->free(inst); 84 crypto_tmpl_put(tmpl); 85 } 86 87 static void crypto_remove_spawns(struct list_head *spawns, 88 struct list_head *list) 89 { 90 struct crypto_spawn *spawn, *n; 91 92 list_for_each_entry_safe(spawn, n, spawns, list) { 93 struct crypto_instance *inst = spawn->inst; 94 struct crypto_template *tmpl = inst->tmpl; 95 96 list_del_init(&spawn->list); 97 spawn->alg = NULL; 98 99 if (crypto_is_dead(&inst->alg)) 100 continue; 101 102 inst->alg.cra_flags |= CRYPTO_ALG_DEAD; 103 if (!tmpl || !crypto_tmpl_get(tmpl)) 104 continue; 105 106 crypto_notify(CRYPTO_MSG_ALG_UNREGISTER, &inst->alg); 107 list_move(&inst->alg.cra_list, list); 108 hlist_del(&inst->list); 109 inst->alg.cra_destroy = crypto_destroy_instance; 110 111 if (!list_empty(&inst->alg.cra_users)) { 112 if (&n->list == spawns) 113 n = list_entry(inst->alg.cra_users.next, 114 typeof(*n), list); 115 __list_splice(&inst->alg.cra_users, spawns->prev); 116 } 117 } 118 } 119 120 static int __crypto_register_alg(struct crypto_alg *alg, 121 struct list_head *list) 122 { 123 struct crypto_alg *q; 124 int ret = -EAGAIN; 125 126 if (crypto_is_dead(alg)) 127 goto out; 128 129 INIT_LIST_HEAD(&alg->cra_users); 130 131 ret = -EEXIST; 132 133 atomic_set(&alg->cra_refcnt, 1); 134 list_for_each_entry(q, &crypto_alg_list, cra_list) { 135 if (q == alg) 136 goto out; 137 138 if (crypto_is_moribund(q)) 139 continue; 140 141 if (crypto_is_larval(q)) { 142 struct crypto_larval *larval = (void *)q; 143 144 if (strcmp(alg->cra_name, q->cra_name) && 145 strcmp(alg->cra_driver_name, q->cra_name)) 146 continue; 147 148 if (larval->adult) 149 continue; 150 if ((q->cra_flags ^ alg->cra_flags) & larval->mask) 151 continue; 152 if (!crypto_mod_get(alg)) 153 continue; 154 155 larval->adult = alg; 156 complete(&larval->completion); 157 continue; 158 } 159 160 if (strcmp(alg->cra_name, q->cra_name)) 161 continue; 162 163 if (strcmp(alg->cra_driver_name, q->cra_driver_name) && 164 q->cra_priority > alg->cra_priority) 165 continue; 166 167 crypto_remove_spawns(&q->cra_users, list); 168 } 169 170 list_add(&alg->cra_list, &crypto_alg_list); 171 172 crypto_notify(CRYPTO_MSG_ALG_REGISTER, alg); 173 ret = 0; 174 175 out: 176 return ret; 177 } 178 179 static void crypto_remove_final(struct list_head *list) 180 { 181 struct crypto_alg *alg; 182 struct crypto_alg *n; 183 184 list_for_each_entry_safe(alg, n, list, cra_list) { 185 list_del_init(&alg->cra_list); 186 crypto_alg_put(alg); 187 } 188 } 189 190 int crypto_register_alg(struct crypto_alg *alg) 191 { 192 LIST_HEAD(list); 193 int err; 194 195 err = crypto_check_alg(alg); 196 if (err) 197 return err; 198 199 down_write(&crypto_alg_sem); 200 err = __crypto_register_alg(alg, &list); 201 up_write(&crypto_alg_sem); 202 203 crypto_remove_final(&list); 204 return err; 205 } 206 EXPORT_SYMBOL_GPL(crypto_register_alg); 207 208 static int crypto_remove_alg(struct crypto_alg *alg, struct list_head *list) 209 { 210 if (unlikely(list_empty(&alg->cra_list))) 211 return -ENOENT; 212 213 alg->cra_flags |= CRYPTO_ALG_DEAD; 214 215 crypto_notify(CRYPTO_MSG_ALG_UNREGISTER, alg); 216 list_del_init(&alg->cra_list); 217 crypto_remove_spawns(&alg->cra_users, list); 218 219 return 0; 220 } 221 222 int crypto_unregister_alg(struct crypto_alg *alg) 223 { 224 int ret; 225 LIST_HEAD(list); 226 227 down_write(&crypto_alg_sem); 228 ret = crypto_remove_alg(alg, &list); 229 up_write(&crypto_alg_sem); 230 231 if (ret) 232 return ret; 233 234 BUG_ON(atomic_read(&alg->cra_refcnt) != 1); 235 if (alg->cra_destroy) 236 alg->cra_destroy(alg); 237 238 crypto_remove_final(&list); 239 return 0; 240 } 241 EXPORT_SYMBOL_GPL(crypto_unregister_alg); 242 243 int crypto_register_template(struct crypto_template *tmpl) 244 { 245 struct crypto_template *q; 246 int err = -EEXIST; 247 248 down_write(&crypto_alg_sem); 249 250 list_for_each_entry(q, &crypto_template_list, list) { 251 if (q == tmpl) 252 goto out; 253 } 254 255 list_add(&tmpl->list, &crypto_template_list); 256 crypto_notify(CRYPTO_MSG_TMPL_REGISTER, tmpl); 257 err = 0; 258 out: 259 up_write(&crypto_alg_sem); 260 return err; 261 } 262 EXPORT_SYMBOL_GPL(crypto_register_template); 263 264 void crypto_unregister_template(struct crypto_template *tmpl) 265 { 266 struct crypto_instance *inst; 267 struct hlist_node *p, *n; 268 struct hlist_head *list; 269 LIST_HEAD(users); 270 271 down_write(&crypto_alg_sem); 272 273 BUG_ON(list_empty(&tmpl->list)); 274 list_del_init(&tmpl->list); 275 276 list = &tmpl->instances; 277 hlist_for_each_entry(inst, p, list, list) { 278 int err = crypto_remove_alg(&inst->alg, &users); 279 BUG_ON(err); 280 } 281 282 crypto_notify(CRYPTO_MSG_TMPL_UNREGISTER, tmpl); 283 284 up_write(&crypto_alg_sem); 285 286 hlist_for_each_entry_safe(inst, p, n, list, list) { 287 BUG_ON(atomic_read(&inst->alg.cra_refcnt) != 1); 288 tmpl->free(inst); 289 } 290 crypto_remove_final(&users); 291 } 292 EXPORT_SYMBOL_GPL(crypto_unregister_template); 293 294 static struct crypto_template *__crypto_lookup_template(const char *name) 295 { 296 struct crypto_template *q, *tmpl = NULL; 297 298 down_read(&crypto_alg_sem); 299 list_for_each_entry(q, &crypto_template_list, list) { 300 if (strcmp(q->name, name)) 301 continue; 302 if (unlikely(!crypto_tmpl_get(q))) 303 continue; 304 305 tmpl = q; 306 break; 307 } 308 up_read(&crypto_alg_sem); 309 310 return tmpl; 311 } 312 313 struct crypto_template *crypto_lookup_template(const char *name) 314 { 315 return try_then_request_module(__crypto_lookup_template(name), name); 316 } 317 EXPORT_SYMBOL_GPL(crypto_lookup_template); 318 319 int crypto_register_instance(struct crypto_template *tmpl, 320 struct crypto_instance *inst) 321 { 322 LIST_HEAD(list); 323 int err = -EINVAL; 324 325 if (inst->alg.cra_destroy) 326 goto err; 327 328 err = crypto_check_alg(&inst->alg); 329 if (err) 330 goto err; 331 332 inst->alg.cra_module = tmpl->module; 333 334 down_write(&crypto_alg_sem); 335 336 err = __crypto_register_alg(&inst->alg, &list); 337 if (err) 338 goto unlock; 339 340 hlist_add_head(&inst->list, &tmpl->instances); 341 inst->tmpl = tmpl; 342 343 unlock: 344 up_write(&crypto_alg_sem); 345 346 crypto_remove_final(&list); 347 348 err: 349 return err; 350 } 351 EXPORT_SYMBOL_GPL(crypto_register_instance); 352 353 int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg, 354 struct crypto_instance *inst) 355 { 356 int err = -EAGAIN; 357 358 spawn->inst = inst; 359 360 down_write(&crypto_alg_sem); 361 if (!crypto_is_moribund(alg)) { 362 list_add(&spawn->list, &alg->cra_users); 363 spawn->alg = alg; 364 err = 0; 365 } 366 up_write(&crypto_alg_sem); 367 368 return err; 369 } 370 EXPORT_SYMBOL_GPL(crypto_init_spawn); 371 372 void crypto_drop_spawn(struct crypto_spawn *spawn) 373 { 374 down_write(&crypto_alg_sem); 375 list_del(&spawn->list); 376 up_write(&crypto_alg_sem); 377 } 378 EXPORT_SYMBOL_GPL(crypto_drop_spawn); 379 380 struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn) 381 { 382 struct crypto_alg *alg; 383 struct crypto_alg *alg2; 384 struct crypto_tfm *tfm; 385 386 down_read(&crypto_alg_sem); 387 alg = spawn->alg; 388 alg2 = alg; 389 if (alg2) 390 alg2 = crypto_mod_get(alg2); 391 up_read(&crypto_alg_sem); 392 393 if (!alg2) { 394 if (alg) 395 crypto_shoot_alg(alg); 396 return ERR_PTR(-EAGAIN); 397 } 398 399 tfm = __crypto_alloc_tfm(alg, 0); 400 if (IS_ERR(tfm)) 401 crypto_mod_put(alg); 402 403 return tfm; 404 } 405 EXPORT_SYMBOL_GPL(crypto_spawn_tfm); 406 407 int crypto_register_notifier(struct notifier_block *nb) 408 { 409 return blocking_notifier_chain_register(&crypto_chain, nb); 410 } 411 EXPORT_SYMBOL_GPL(crypto_register_notifier); 412 413 int crypto_unregister_notifier(struct notifier_block *nb) 414 { 415 return blocking_notifier_chain_unregister(&crypto_chain, nb); 416 } 417 EXPORT_SYMBOL_GPL(crypto_unregister_notifier); 418 419 struct crypto_alg *crypto_get_attr_alg(void *param, unsigned int len, 420 u32 type, u32 mask) 421 { 422 struct rtattr *rta = param; 423 struct crypto_attr_alg *alga; 424 425 if (!RTA_OK(rta, len)) 426 return ERR_PTR(-EBADR); 427 if (rta->rta_type != CRYPTOA_ALG || RTA_PAYLOAD(rta) < sizeof(*alga)) 428 return ERR_PTR(-EINVAL); 429 430 alga = RTA_DATA(rta); 431 alga->name[CRYPTO_MAX_ALG_NAME - 1] = 0; 432 433 return crypto_alg_mod_lookup(alga->name, type, mask); 434 } 435 EXPORT_SYMBOL_GPL(crypto_get_attr_alg); 436 437 struct crypto_instance *crypto_alloc_instance(const char *name, 438 struct crypto_alg *alg) 439 { 440 struct crypto_instance *inst; 441 struct crypto_spawn *spawn; 442 int err; 443 444 inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); 445 if (!inst) 446 return ERR_PTR(-ENOMEM); 447 448 err = -ENAMETOOLONG; 449 if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, "%s(%s)", name, 450 alg->cra_name) >= CRYPTO_MAX_ALG_NAME) 451 goto err_free_inst; 452 453 if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s(%s)", 454 name, alg->cra_driver_name) >= CRYPTO_MAX_ALG_NAME) 455 goto err_free_inst; 456 457 spawn = crypto_instance_ctx(inst); 458 err = crypto_init_spawn(spawn, alg, inst); 459 460 if (err) 461 goto err_free_inst; 462 463 return inst; 464 465 err_free_inst: 466 kfree(inst); 467 return ERR_PTR(err); 468 } 469 EXPORT_SYMBOL_GPL(crypto_alloc_instance); 470 471 static int __init crypto_algapi_init(void) 472 { 473 crypto_init_proc(); 474 return 0; 475 } 476 477 static void __exit crypto_algapi_exit(void) 478 { 479 crypto_exit_proc(); 480 } 481 482 module_init(crypto_algapi_init); 483 module_exit(crypto_algapi_exit); 484 485 MODULE_LICENSE("GPL"); 486 MODULE_DESCRIPTION("Cryptographic algorithms API"); 487