| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Cryptographic API for algorithms (i.e., low-level API). |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * 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 | 6 | */ |
|---|
| 12 | 7 | |
|---|
| 13 | 8 | #include <crypto/algapi.h> |
|---|
| .. | .. |
|---|
| 26 | 21 | |
|---|
| 27 | 22 | static LIST_HEAD(crypto_template_list); |
|---|
| 28 | 23 | |
|---|
| 29 | | -static inline int crypto_set_driver_name(struct crypto_alg *alg) |
|---|
| 30 | | -{ |
|---|
| 31 | | - static const char suffix[] = "-generic"; |
|---|
| 32 | | - char *driver_name = alg->cra_driver_name; |
|---|
| 33 | | - int len; |
|---|
| 34 | | - |
|---|
| 35 | | - if (*driver_name) |
|---|
| 36 | | - return 0; |
|---|
| 37 | | - |
|---|
| 38 | | - len = strlcpy(driver_name, alg->cra_name, CRYPTO_MAX_ALG_NAME); |
|---|
| 39 | | - if (len + sizeof(suffix) > CRYPTO_MAX_ALG_NAME) |
|---|
| 40 | | - return -ENAMETOOLONG; |
|---|
| 41 | | - |
|---|
| 42 | | - memcpy(driver_name + len, suffix, sizeof(suffix)); |
|---|
| 43 | | - return 0; |
|---|
| 44 | | -} |
|---|
| 45 | | - |
|---|
| 46 | 24 | static inline void crypto_check_module_sig(struct module *mod) |
|---|
| 47 | 25 | { |
|---|
| 48 | 26 | if (fips_enabled && mod && !module_sig_ok(mod)) |
|---|
| .. | .. |
|---|
| 54 | 32 | { |
|---|
| 55 | 33 | crypto_check_module_sig(alg->cra_module); |
|---|
| 56 | 34 | |
|---|
| 35 | + if (!alg->cra_name[0] || !alg->cra_driver_name[0]) |
|---|
| 36 | + return -EINVAL; |
|---|
| 37 | + |
|---|
| 57 | 38 | if (alg->cra_alignmask & (alg->cra_alignmask + 1)) |
|---|
| 58 | 39 | return -EINVAL; |
|---|
| 59 | 40 | |
|---|
| 60 | | - if (alg->cra_blocksize > PAGE_SIZE / 8) |
|---|
| 41 | + /* General maximums for all algs. */ |
|---|
| 42 | + if (alg->cra_alignmask > MAX_ALGAPI_ALIGNMASK) |
|---|
| 61 | 43 | return -EINVAL; |
|---|
| 62 | 44 | |
|---|
| 45 | + if (alg->cra_blocksize > MAX_ALGAPI_BLOCKSIZE) |
|---|
| 46 | + return -EINVAL; |
|---|
| 47 | + |
|---|
| 48 | + /* Lower maximums for specific alg types. */ |
|---|
| 63 | 49 | if (!alg->cra_type && (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == |
|---|
| 64 | 50 | CRYPTO_ALG_TYPE_CIPHER) { |
|---|
| 65 | 51 | if (alg->cra_alignmask > MAX_CIPHER_ALIGNMASK) |
|---|
| .. | .. |
|---|
| 74 | 60 | |
|---|
| 75 | 61 | refcount_set(&alg->cra_refcnt, 1); |
|---|
| 76 | 62 | |
|---|
| 77 | | - return crypto_set_driver_name(alg); |
|---|
| 63 | + return 0; |
|---|
| 78 | 64 | } |
|---|
| 79 | 65 | |
|---|
| 80 | 66 | static void crypto_free_instance(struct crypto_instance *inst) |
|---|
| 81 | 67 | { |
|---|
| 82 | | - if (!inst->alg.cra_type->free) { |
|---|
| 83 | | - inst->tmpl->free(inst); |
|---|
| 84 | | - return; |
|---|
| 85 | | - } |
|---|
| 86 | | - |
|---|
| 87 | 68 | inst->alg.cra_type->free(inst); |
|---|
| 88 | 69 | } |
|---|
| 89 | 70 | |
|---|
| .. | .. |
|---|
| 96 | 77 | crypto_tmpl_put(tmpl); |
|---|
| 97 | 78 | } |
|---|
| 98 | 79 | |
|---|
| 80 | +/* |
|---|
| 81 | + * This function adds a spawn to the list secondary_spawns which |
|---|
| 82 | + * will be used at the end of crypto_remove_spawns to unregister |
|---|
| 83 | + * instances, unless the spawn happens to be one that is depended |
|---|
| 84 | + * on by the new algorithm (nalg in crypto_remove_spawns). |
|---|
| 85 | + * |
|---|
| 86 | + * This function is also responsible for resurrecting any algorithms |
|---|
| 87 | + * in the dependency chain of nalg by unsetting n->dead. |
|---|
| 88 | + */ |
|---|
| 99 | 89 | static struct list_head *crypto_more_spawns(struct crypto_alg *alg, |
|---|
| 100 | 90 | struct list_head *stack, |
|---|
| 101 | 91 | struct list_head *top, |
|---|
| .. | .. |
|---|
| 107 | 97 | if (!spawn) |
|---|
| 108 | 98 | return NULL; |
|---|
| 109 | 99 | |
|---|
| 110 | | - n = list_next_entry(spawn, list); |
|---|
| 111 | | - |
|---|
| 112 | | - if (spawn->alg && &n->list != stack && !n->alg) |
|---|
| 113 | | - n->alg = (n->list.next == stack) ? alg : |
|---|
| 114 | | - &list_next_entry(n, list)->inst->alg; |
|---|
| 115 | | - |
|---|
| 100 | + n = list_prev_entry(spawn, list); |
|---|
| 116 | 101 | list_move(&spawn->list, secondary_spawns); |
|---|
| 117 | 102 | |
|---|
| 118 | | - return &n->list == stack ? top : &n->inst->alg.cra_users; |
|---|
| 103 | + if (list_is_last(&n->list, stack)) |
|---|
| 104 | + return top; |
|---|
| 105 | + |
|---|
| 106 | + n = list_next_entry(n, list); |
|---|
| 107 | + if (!spawn->dead) |
|---|
| 108 | + n->dead = false; |
|---|
| 109 | + |
|---|
| 110 | + return &n->inst->alg.cra_users; |
|---|
| 119 | 111 | } |
|---|
| 120 | 112 | |
|---|
| 121 | 113 | static void crypto_remove_instance(struct crypto_instance *inst, |
|---|
| .. | .. |
|---|
| 127 | 119 | return; |
|---|
| 128 | 120 | |
|---|
| 129 | 121 | inst->alg.cra_flags |= CRYPTO_ALG_DEAD; |
|---|
| 130 | | - if (hlist_unhashed(&inst->list)) |
|---|
| 131 | | - return; |
|---|
| 132 | 122 | |
|---|
| 133 | 123 | if (!tmpl || !crypto_tmpl_get(tmpl)) |
|---|
| 134 | 124 | return; |
|---|
| .. | .. |
|---|
| 140 | 130 | BUG_ON(!list_empty(&inst->alg.cra_users)); |
|---|
| 141 | 131 | } |
|---|
| 142 | 132 | |
|---|
| 133 | +/* |
|---|
| 134 | + * Given an algorithm alg, remove all algorithms that depend on it |
|---|
| 135 | + * through spawns. If nalg is not null, then exempt any algorithms |
|---|
| 136 | + * that is depended on by nalg. This is useful when nalg itself |
|---|
| 137 | + * depends on alg. |
|---|
| 138 | + */ |
|---|
| 143 | 139 | void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list, |
|---|
| 144 | 140 | struct crypto_alg *nalg) |
|---|
| 145 | 141 | { |
|---|
| .. | .. |
|---|
| 158 | 154 | list_move(&spawn->list, &top); |
|---|
| 159 | 155 | } |
|---|
| 160 | 156 | |
|---|
| 157 | + /* |
|---|
| 158 | + * Perform a depth-first walk starting from alg through |
|---|
| 159 | + * the cra_users tree. The list stack records the path |
|---|
| 160 | + * from alg to the current spawn. |
|---|
| 161 | + */ |
|---|
| 161 | 162 | spawns = ⊤ |
|---|
| 162 | 163 | do { |
|---|
| 163 | 164 | while (!list_empty(spawns)) { |
|---|
| .. | .. |
|---|
| 167 | 168 | list); |
|---|
| 168 | 169 | inst = spawn->inst; |
|---|
| 169 | 170 | |
|---|
| 170 | | - BUG_ON(&inst->alg == alg); |
|---|
| 171 | | - |
|---|
| 172 | 171 | list_move(&spawn->list, &stack); |
|---|
| 172 | + spawn->dead = !spawn->registered || &inst->alg != nalg; |
|---|
| 173 | + |
|---|
| 174 | + if (!spawn->registered) |
|---|
| 175 | + break; |
|---|
| 176 | + |
|---|
| 177 | + BUG_ON(&inst->alg == alg); |
|---|
| 173 | 178 | |
|---|
| 174 | 179 | if (&inst->alg == nalg) |
|---|
| 175 | 180 | break; |
|---|
| 176 | 181 | |
|---|
| 177 | | - spawn->alg = NULL; |
|---|
| 178 | 182 | spawns = &inst->alg.cra_users; |
|---|
| 179 | 183 | |
|---|
| 180 | 184 | /* |
|---|
| 185 | + * Even if spawn->registered is true, the |
|---|
| 186 | + * instance itself may still be unregistered. |
|---|
| 187 | + * This is because it may have failed during |
|---|
| 188 | + * registration. Therefore we still need to |
|---|
| 189 | + * make the following test. |
|---|
| 190 | + * |
|---|
| 181 | 191 | * We may encounter an unregistered instance here, since |
|---|
| 182 | 192 | * an instance's spawns are set up prior to the instance |
|---|
| 183 | 193 | * being registered. An unregistered instance will have |
|---|
| .. | .. |
|---|
| 192 | 202 | } while ((spawns = crypto_more_spawns(alg, &stack, &top, |
|---|
| 193 | 203 | &secondary_spawns))); |
|---|
| 194 | 204 | |
|---|
| 205 | + /* |
|---|
| 206 | + * Remove all instances that are marked as dead. Also |
|---|
| 207 | + * complete the resurrection of the others by moving them |
|---|
| 208 | + * back to the cra_users list. |
|---|
| 209 | + */ |
|---|
| 195 | 210 | list_for_each_entry_safe(spawn, n, &secondary_spawns, list) { |
|---|
| 196 | | - if (spawn->alg) |
|---|
| 211 | + if (!spawn->dead) |
|---|
| 197 | 212 | list_move(&spawn->list, &spawn->alg->cra_users); |
|---|
| 198 | | - else |
|---|
| 213 | + else if (spawn->registered) |
|---|
| 199 | 214 | crypto_remove_instance(spawn->inst, list); |
|---|
| 200 | 215 | } |
|---|
| 201 | 216 | } |
|---|
| .. | .. |
|---|
| 253 | 268 | list_add(&alg->cra_list, &crypto_alg_list); |
|---|
| 254 | 269 | list_add(&larval->alg.cra_list, &crypto_alg_list); |
|---|
| 255 | 270 | |
|---|
| 271 | + crypto_stats_init(alg); |
|---|
| 272 | + |
|---|
| 256 | 273 | out: |
|---|
| 257 | 274 | return larval; |
|---|
| 258 | 275 | |
|---|
| .. | .. |
|---|
| 269 | 286 | struct crypto_alg *alg; |
|---|
| 270 | 287 | struct crypto_alg *q; |
|---|
| 271 | 288 | LIST_HEAD(list); |
|---|
| 289 | + bool best; |
|---|
| 272 | 290 | |
|---|
| 273 | 291 | down_write(&crypto_alg_sem); |
|---|
| 274 | 292 | list_for_each_entry(q, &crypto_alg_list, cra_list) { |
|---|
| .. | .. |
|---|
| 291 | 309 | goto complete; |
|---|
| 292 | 310 | |
|---|
| 293 | 311 | alg->cra_flags |= CRYPTO_ALG_TESTED; |
|---|
| 312 | + |
|---|
| 313 | + /* Only satisfy larval waiters if we are the best. */ |
|---|
| 314 | + best = true; |
|---|
| 315 | + list_for_each_entry(q, &crypto_alg_list, cra_list) { |
|---|
| 316 | + if (crypto_is_moribund(q) || !crypto_is_larval(q)) |
|---|
| 317 | + continue; |
|---|
| 318 | + |
|---|
| 319 | + if (strcmp(alg->cra_name, q->cra_name)) |
|---|
| 320 | + continue; |
|---|
| 321 | + |
|---|
| 322 | + if (q->cra_priority > alg->cra_priority) { |
|---|
| 323 | + best = false; |
|---|
| 324 | + break; |
|---|
| 325 | + } |
|---|
| 326 | + } |
|---|
| 294 | 327 | |
|---|
| 295 | 328 | list_for_each_entry(q, &crypto_alg_list, cra_list) { |
|---|
| 296 | 329 | if (q == alg) |
|---|
| .. | .. |
|---|
| 315 | 348 | continue; |
|---|
| 316 | 349 | if ((q->cra_flags ^ alg->cra_flags) & larval->mask) |
|---|
| 317 | 350 | continue; |
|---|
| 318 | | - if (!crypto_mod_get(alg)) |
|---|
| 319 | | - continue; |
|---|
| 320 | 351 | |
|---|
| 321 | | - larval->adult = alg; |
|---|
| 352 | + if (best && crypto_mod_get(alg)) |
|---|
| 353 | + larval->adult = alg; |
|---|
| 354 | + else |
|---|
| 355 | + larval->adult = ERR_PTR(-EAGAIN); |
|---|
| 356 | + |
|---|
| 322 | 357 | continue; |
|---|
| 323 | 358 | } |
|---|
| 324 | 359 | |
|---|
| .. | .. |
|---|
| 367 | 402 | |
|---|
| 368 | 403 | err = wait_for_completion_killable(&larval->completion); |
|---|
| 369 | 404 | WARN_ON(err); |
|---|
| 405 | + if (!err) |
|---|
| 406 | + crypto_notify(CRYPTO_MSG_ALG_LOADED, larval); |
|---|
| 370 | 407 | |
|---|
| 371 | 408 | out: |
|---|
| 372 | 409 | crypto_larval_kill(&larval->alg); |
|---|
| .. | .. |
|---|
| 407 | 444 | return 0; |
|---|
| 408 | 445 | } |
|---|
| 409 | 446 | |
|---|
| 410 | | -int crypto_unregister_alg(struct crypto_alg *alg) |
|---|
| 447 | +void crypto_unregister_alg(struct crypto_alg *alg) |
|---|
| 411 | 448 | { |
|---|
| 412 | 449 | int ret; |
|---|
| 413 | 450 | LIST_HEAD(list); |
|---|
| .. | .. |
|---|
| 416 | 453 | ret = crypto_remove_alg(alg, &list); |
|---|
| 417 | 454 | up_write(&crypto_alg_sem); |
|---|
| 418 | 455 | |
|---|
| 419 | | - if (ret) |
|---|
| 420 | | - return ret; |
|---|
| 456 | + if (WARN(ret, "Algorithm %s is not registered", alg->cra_driver_name)) |
|---|
| 457 | + return; |
|---|
| 421 | 458 | |
|---|
| 422 | | - BUG_ON(refcount_read(&alg->cra_refcnt) != 1); |
|---|
| 459 | + if (WARN_ON(refcount_read(&alg->cra_refcnt) != 1)) |
|---|
| 460 | + return; |
|---|
| 461 | + |
|---|
| 423 | 462 | if (alg->cra_destroy) |
|---|
| 424 | 463 | alg->cra_destroy(alg); |
|---|
| 425 | 464 | |
|---|
| 426 | 465 | crypto_remove_final(&list); |
|---|
| 427 | | - return 0; |
|---|
| 428 | 466 | } |
|---|
| 429 | 467 | EXPORT_SYMBOL_GPL(crypto_unregister_alg); |
|---|
| 430 | 468 | |
|---|
| .. | .. |
|---|
| 448 | 486 | } |
|---|
| 449 | 487 | EXPORT_SYMBOL_GPL(crypto_register_algs); |
|---|
| 450 | 488 | |
|---|
| 451 | | -int crypto_unregister_algs(struct crypto_alg *algs, int count) |
|---|
| 489 | +void crypto_unregister_algs(struct crypto_alg *algs, int count) |
|---|
| 452 | 490 | { |
|---|
| 453 | | - int i, ret; |
|---|
| 491 | + int i; |
|---|
| 454 | 492 | |
|---|
| 455 | | - for (i = 0; i < count; i++) { |
|---|
| 456 | | - ret = crypto_unregister_alg(&algs[i]); |
|---|
| 457 | | - if (ret) |
|---|
| 458 | | - pr_err("Failed to unregister %s %s: %d\n", |
|---|
| 459 | | - algs[i].cra_driver_name, algs[i].cra_name, ret); |
|---|
| 460 | | - } |
|---|
| 461 | | - |
|---|
| 462 | | - return 0; |
|---|
| 493 | + for (i = 0; i < count; i++) |
|---|
| 494 | + crypto_unregister_alg(&algs[i]); |
|---|
| 463 | 495 | } |
|---|
| 464 | 496 | EXPORT_SYMBOL_GPL(crypto_unregister_algs); |
|---|
| 465 | 497 | |
|---|
| .. | .. |
|---|
| 484 | 516 | return err; |
|---|
| 485 | 517 | } |
|---|
| 486 | 518 | EXPORT_SYMBOL_GPL(crypto_register_template); |
|---|
| 519 | + |
|---|
| 520 | +int crypto_register_templates(struct crypto_template *tmpls, int count) |
|---|
| 521 | +{ |
|---|
| 522 | + int i, err; |
|---|
| 523 | + |
|---|
| 524 | + for (i = 0; i < count; i++) { |
|---|
| 525 | + err = crypto_register_template(&tmpls[i]); |
|---|
| 526 | + if (err) |
|---|
| 527 | + goto out; |
|---|
| 528 | + } |
|---|
| 529 | + return 0; |
|---|
| 530 | + |
|---|
| 531 | +out: |
|---|
| 532 | + for (--i; i >= 0; --i) |
|---|
| 533 | + crypto_unregister_template(&tmpls[i]); |
|---|
| 534 | + return err; |
|---|
| 535 | +} |
|---|
| 536 | +EXPORT_SYMBOL_GPL(crypto_register_templates); |
|---|
| 487 | 537 | |
|---|
| 488 | 538 | void crypto_unregister_template(struct crypto_template *tmpl) |
|---|
| 489 | 539 | { |
|---|
| .. | .. |
|---|
| 513 | 563 | crypto_remove_final(&users); |
|---|
| 514 | 564 | } |
|---|
| 515 | 565 | EXPORT_SYMBOL_GPL(crypto_unregister_template); |
|---|
| 566 | + |
|---|
| 567 | +void crypto_unregister_templates(struct crypto_template *tmpls, int count) |
|---|
| 568 | +{ |
|---|
| 569 | + int i; |
|---|
| 570 | + |
|---|
| 571 | + for (i = count - 1; i >= 0; --i) |
|---|
| 572 | + crypto_unregister_template(&tmpls[i]); |
|---|
| 573 | +} |
|---|
| 574 | +EXPORT_SYMBOL_GPL(crypto_unregister_templates); |
|---|
| 516 | 575 | |
|---|
| 517 | 576 | static struct crypto_template *__crypto_lookup_template(const char *name) |
|---|
| 518 | 577 | { |
|---|
| .. | .. |
|---|
| 544 | 603 | struct crypto_instance *inst) |
|---|
| 545 | 604 | { |
|---|
| 546 | 605 | struct crypto_larval *larval; |
|---|
| 606 | + struct crypto_spawn *spawn; |
|---|
| 547 | 607 | int err; |
|---|
| 548 | 608 | |
|---|
| 549 | 609 | err = crypto_check_alg(&inst->alg); |
|---|
| .. | .. |
|---|
| 554 | 614 | inst->alg.cra_flags |= CRYPTO_ALG_INSTANCE; |
|---|
| 555 | 615 | |
|---|
| 556 | 616 | down_write(&crypto_alg_sem); |
|---|
| 617 | + |
|---|
| 618 | + larval = ERR_PTR(-EAGAIN); |
|---|
| 619 | + for (spawn = inst->spawns; spawn;) { |
|---|
| 620 | + struct crypto_spawn *next; |
|---|
| 621 | + |
|---|
| 622 | + if (spawn->dead) |
|---|
| 623 | + goto unlock; |
|---|
| 624 | + |
|---|
| 625 | + next = spawn->next; |
|---|
| 626 | + spawn->inst = inst; |
|---|
| 627 | + spawn->registered = true; |
|---|
| 628 | + |
|---|
| 629 | + crypto_mod_put(spawn->alg); |
|---|
| 630 | + |
|---|
| 631 | + spawn = next; |
|---|
| 632 | + } |
|---|
| 557 | 633 | |
|---|
| 558 | 634 | larval = __crypto_register_alg(&inst->alg); |
|---|
| 559 | 635 | if (IS_ERR(larval)) |
|---|
| .. | .. |
|---|
| 577 | 653 | } |
|---|
| 578 | 654 | EXPORT_SYMBOL_GPL(crypto_register_instance); |
|---|
| 579 | 655 | |
|---|
| 580 | | -int crypto_unregister_instance(struct crypto_instance *inst) |
|---|
| 656 | +void crypto_unregister_instance(struct crypto_instance *inst) |
|---|
| 581 | 657 | { |
|---|
| 582 | 658 | LIST_HEAD(list); |
|---|
| 583 | 659 | |
|---|
| .. | .. |
|---|
| 589 | 665 | up_write(&crypto_alg_sem); |
|---|
| 590 | 666 | |
|---|
| 591 | 667 | crypto_remove_final(&list); |
|---|
| 592 | | - |
|---|
| 593 | | - return 0; |
|---|
| 594 | 668 | } |
|---|
| 595 | 669 | EXPORT_SYMBOL_GPL(crypto_unregister_instance); |
|---|
| 596 | 670 | |
|---|
| 597 | | -int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg, |
|---|
| 598 | | - struct crypto_instance *inst, u32 mask) |
|---|
| 599 | | -{ |
|---|
| 600 | | - int err = -EAGAIN; |
|---|
| 601 | | - |
|---|
| 602 | | - spawn->inst = inst; |
|---|
| 603 | | - spawn->mask = mask; |
|---|
| 604 | | - |
|---|
| 605 | | - down_write(&crypto_alg_sem); |
|---|
| 606 | | - if (!crypto_is_moribund(alg)) { |
|---|
| 607 | | - list_add(&spawn->list, &alg->cra_users); |
|---|
| 608 | | - spawn->alg = alg; |
|---|
| 609 | | - err = 0; |
|---|
| 610 | | - } |
|---|
| 611 | | - up_write(&crypto_alg_sem); |
|---|
| 612 | | - |
|---|
| 613 | | - return err; |
|---|
| 614 | | -} |
|---|
| 615 | | -EXPORT_SYMBOL_GPL(crypto_init_spawn); |
|---|
| 616 | | - |
|---|
| 617 | | -int crypto_init_spawn2(struct crypto_spawn *spawn, struct crypto_alg *alg, |
|---|
| 618 | | - struct crypto_instance *inst, |
|---|
| 619 | | - const struct crypto_type *frontend) |
|---|
| 620 | | -{ |
|---|
| 621 | | - int err = -EINVAL; |
|---|
| 622 | | - |
|---|
| 623 | | - if ((alg->cra_flags ^ frontend->type) & frontend->maskset) |
|---|
| 624 | | - goto out; |
|---|
| 625 | | - |
|---|
| 626 | | - spawn->frontend = frontend; |
|---|
| 627 | | - err = crypto_init_spawn(spawn, alg, inst, frontend->maskset); |
|---|
| 628 | | - |
|---|
| 629 | | -out: |
|---|
| 630 | | - return err; |
|---|
| 631 | | -} |
|---|
| 632 | | -EXPORT_SYMBOL_GPL(crypto_init_spawn2); |
|---|
| 633 | | - |
|---|
| 634 | | -int crypto_grab_spawn(struct crypto_spawn *spawn, const char *name, |
|---|
| 635 | | - u32 type, u32 mask) |
|---|
| 671 | +int crypto_grab_spawn(struct crypto_spawn *spawn, struct crypto_instance *inst, |
|---|
| 672 | + const char *name, u32 type, u32 mask) |
|---|
| 636 | 673 | { |
|---|
| 637 | 674 | struct crypto_alg *alg; |
|---|
| 638 | | - int err; |
|---|
| 675 | + int err = -EAGAIN; |
|---|
| 676 | + |
|---|
| 677 | + if (WARN_ON_ONCE(inst == NULL)) |
|---|
| 678 | + return -EINVAL; |
|---|
| 679 | + |
|---|
| 680 | + /* Allow the result of crypto_attr_alg_name() to be passed directly */ |
|---|
| 681 | + if (IS_ERR(name)) |
|---|
| 682 | + return PTR_ERR(name); |
|---|
| 639 | 683 | |
|---|
| 640 | 684 | alg = crypto_find_alg(name, spawn->frontend, type, mask); |
|---|
| 641 | 685 | if (IS_ERR(alg)) |
|---|
| 642 | 686 | return PTR_ERR(alg); |
|---|
| 643 | 687 | |
|---|
| 644 | | - err = crypto_init_spawn(spawn, alg, spawn->inst, mask); |
|---|
| 645 | | - crypto_mod_put(alg); |
|---|
| 688 | + down_write(&crypto_alg_sem); |
|---|
| 689 | + if (!crypto_is_moribund(alg)) { |
|---|
| 690 | + list_add(&spawn->list, &alg->cra_users); |
|---|
| 691 | + spawn->alg = alg; |
|---|
| 692 | + spawn->mask = mask; |
|---|
| 693 | + spawn->next = inst->spawns; |
|---|
| 694 | + inst->spawns = spawn; |
|---|
| 695 | + inst->alg.cra_flags |= |
|---|
| 696 | + (alg->cra_flags & CRYPTO_ALG_INHERITED_FLAGS); |
|---|
| 697 | + err = 0; |
|---|
| 698 | + } |
|---|
| 699 | + up_write(&crypto_alg_sem); |
|---|
| 700 | + if (err) |
|---|
| 701 | + crypto_mod_put(alg); |
|---|
| 646 | 702 | return err; |
|---|
| 647 | 703 | } |
|---|
| 648 | 704 | EXPORT_SYMBOL_GPL(crypto_grab_spawn); |
|---|
| 649 | 705 | |
|---|
| 650 | 706 | void crypto_drop_spawn(struct crypto_spawn *spawn) |
|---|
| 651 | 707 | { |
|---|
| 708 | + if (!spawn->alg) /* not yet initialized? */ |
|---|
| 709 | + return; |
|---|
| 710 | + |
|---|
| 652 | 711 | down_write(&crypto_alg_sem); |
|---|
| 653 | | - if (spawn->alg) |
|---|
| 712 | + if (!spawn->dead) |
|---|
| 654 | 713 | list_del(&spawn->list); |
|---|
| 655 | 714 | up_write(&crypto_alg_sem); |
|---|
| 715 | + |
|---|
| 716 | + if (!spawn->registered) |
|---|
| 717 | + crypto_mod_put(spawn->alg); |
|---|
| 656 | 718 | } |
|---|
| 657 | 719 | EXPORT_SYMBOL_GPL(crypto_drop_spawn); |
|---|
| 658 | 720 | |
|---|
| 659 | 721 | static struct crypto_alg *crypto_spawn_alg(struct crypto_spawn *spawn) |
|---|
| 660 | 722 | { |
|---|
| 661 | | - struct crypto_alg *alg; |
|---|
| 723 | + struct crypto_alg *alg = ERR_PTR(-EAGAIN); |
|---|
| 724 | + struct crypto_alg *target; |
|---|
| 725 | + bool shoot = false; |
|---|
| 662 | 726 | |
|---|
| 663 | 727 | down_read(&crypto_alg_sem); |
|---|
| 664 | | - alg = spawn->alg; |
|---|
| 665 | | - if (alg && !crypto_mod_get(alg)) { |
|---|
| 666 | | - alg->cra_flags |= CRYPTO_ALG_DYING; |
|---|
| 667 | | - alg = NULL; |
|---|
| 728 | + if (!spawn->dead) { |
|---|
| 729 | + alg = spawn->alg; |
|---|
| 730 | + if (!crypto_mod_get(alg)) { |
|---|
| 731 | + target = crypto_alg_get(alg); |
|---|
| 732 | + shoot = true; |
|---|
| 733 | + alg = ERR_PTR(-EAGAIN); |
|---|
| 734 | + } |
|---|
| 668 | 735 | } |
|---|
| 669 | 736 | up_read(&crypto_alg_sem); |
|---|
| 670 | 737 | |
|---|
| 671 | | - return alg ?: ERR_PTR(-EAGAIN); |
|---|
| 738 | + if (shoot) { |
|---|
| 739 | + crypto_shoot_alg(target); |
|---|
| 740 | + crypto_alg_put(target); |
|---|
| 741 | + } |
|---|
| 742 | + |
|---|
| 743 | + return alg; |
|---|
| 672 | 744 | } |
|---|
| 673 | 745 | |
|---|
| 674 | 746 | struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type, |
|---|
| .. | .. |
|---|
| 748 | 820 | } |
|---|
| 749 | 821 | EXPORT_SYMBOL_GPL(crypto_get_attr_type); |
|---|
| 750 | 822 | |
|---|
| 751 | | -int crypto_check_attr_type(struct rtattr **tb, u32 type) |
|---|
| 823 | +/** |
|---|
| 824 | + * crypto_check_attr_type() - check algorithm type and compute inherited mask |
|---|
| 825 | + * @tb: the template parameters |
|---|
| 826 | + * @type: the algorithm type the template would be instantiated as |
|---|
| 827 | + * @mask_ret: (output) the mask that should be passed to crypto_grab_*() |
|---|
| 828 | + * to restrict the flags of any inner algorithms |
|---|
| 829 | + * |
|---|
| 830 | + * Validate that the algorithm type the user requested is compatible with the |
|---|
| 831 | + * one the template would actually be instantiated as. E.g., if the user is |
|---|
| 832 | + * doing crypto_alloc_shash("cbc(aes)", ...), this would return an error because |
|---|
| 833 | + * the "cbc" template creates an "skcipher" algorithm, not an "shash" algorithm. |
|---|
| 834 | + * |
|---|
| 835 | + * Also compute the mask to use to restrict the flags of any inner algorithms. |
|---|
| 836 | + * |
|---|
| 837 | + * Return: 0 on success; -errno on failure |
|---|
| 838 | + */ |
|---|
| 839 | +int crypto_check_attr_type(struct rtattr **tb, u32 type, u32 *mask_ret) |
|---|
| 752 | 840 | { |
|---|
| 753 | 841 | struct crypto_attr_type *algt; |
|---|
| 754 | 842 | |
|---|
| .. | .. |
|---|
| 759 | 847 | if ((algt->type ^ type) & algt->mask) |
|---|
| 760 | 848 | return -EINVAL; |
|---|
| 761 | 849 | |
|---|
| 850 | + *mask_ret = crypto_algt_inherited_mask(algt); |
|---|
| 762 | 851 | return 0; |
|---|
| 763 | 852 | } |
|---|
| 764 | 853 | EXPORT_SYMBOL_GPL(crypto_check_attr_type); |
|---|
| .. | .. |
|---|
| 780 | 869 | return alga->name; |
|---|
| 781 | 870 | } |
|---|
| 782 | 871 | EXPORT_SYMBOL_GPL(crypto_attr_alg_name); |
|---|
| 783 | | - |
|---|
| 784 | | -struct crypto_alg *crypto_attr_alg2(struct rtattr *rta, |
|---|
| 785 | | - const struct crypto_type *frontend, |
|---|
| 786 | | - u32 type, u32 mask) |
|---|
| 787 | | -{ |
|---|
| 788 | | - const char *name; |
|---|
| 789 | | - |
|---|
| 790 | | - name = crypto_attr_alg_name(rta); |
|---|
| 791 | | - if (IS_ERR(name)) |
|---|
| 792 | | - return ERR_CAST(name); |
|---|
| 793 | | - |
|---|
| 794 | | - return crypto_find_alg(name, frontend, type, mask); |
|---|
| 795 | | -} |
|---|
| 796 | | -EXPORT_SYMBOL_GPL(crypto_attr_alg2); |
|---|
| 797 | 872 | |
|---|
| 798 | 873 | int crypto_attr_u32(struct rtattr *rta, u32 *num) |
|---|
| 799 | 874 | { |
|---|
| .. | .. |
|---|
| 828 | 903 | } |
|---|
| 829 | 904 | EXPORT_SYMBOL_GPL(crypto_inst_setname); |
|---|
| 830 | 905 | |
|---|
| 831 | | -void *crypto_alloc_instance2(const char *name, struct crypto_alg *alg, |
|---|
| 832 | | - unsigned int head) |
|---|
| 833 | | -{ |
|---|
| 834 | | - struct crypto_instance *inst; |
|---|
| 835 | | - char *p; |
|---|
| 836 | | - int err; |
|---|
| 837 | | - |
|---|
| 838 | | - p = kzalloc(head + sizeof(*inst) + sizeof(struct crypto_spawn), |
|---|
| 839 | | - GFP_KERNEL); |
|---|
| 840 | | - if (!p) |
|---|
| 841 | | - return ERR_PTR(-ENOMEM); |
|---|
| 842 | | - |
|---|
| 843 | | - inst = (void *)(p + head); |
|---|
| 844 | | - |
|---|
| 845 | | - err = crypto_inst_setname(inst, name, alg); |
|---|
| 846 | | - if (err) |
|---|
| 847 | | - goto err_free_inst; |
|---|
| 848 | | - |
|---|
| 849 | | - return p; |
|---|
| 850 | | - |
|---|
| 851 | | -err_free_inst: |
|---|
| 852 | | - kfree(p); |
|---|
| 853 | | - return ERR_PTR(err); |
|---|
| 854 | | -} |
|---|
| 855 | | -EXPORT_SYMBOL_GPL(crypto_alloc_instance2); |
|---|
| 856 | | - |
|---|
| 857 | | -struct crypto_instance *crypto_alloc_instance(const char *name, |
|---|
| 858 | | - struct crypto_alg *alg) |
|---|
| 859 | | -{ |
|---|
| 860 | | - struct crypto_instance *inst; |
|---|
| 861 | | - struct crypto_spawn *spawn; |
|---|
| 862 | | - int err; |
|---|
| 863 | | - |
|---|
| 864 | | - inst = crypto_alloc_instance2(name, alg, 0); |
|---|
| 865 | | - if (IS_ERR(inst)) |
|---|
| 866 | | - goto out; |
|---|
| 867 | | - |
|---|
| 868 | | - spawn = crypto_instance_ctx(inst); |
|---|
| 869 | | - err = crypto_init_spawn(spawn, alg, inst, |
|---|
| 870 | | - CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC); |
|---|
| 871 | | - |
|---|
| 872 | | - if (err) |
|---|
| 873 | | - goto err_free_inst; |
|---|
| 874 | | - |
|---|
| 875 | | - return inst; |
|---|
| 876 | | - |
|---|
| 877 | | -err_free_inst: |
|---|
| 878 | | - kfree(inst); |
|---|
| 879 | | - inst = ERR_PTR(err); |
|---|
| 880 | | - |
|---|
| 881 | | -out: |
|---|
| 882 | | - return inst; |
|---|
| 883 | | -} |
|---|
| 884 | | -EXPORT_SYMBOL_GPL(crypto_alloc_instance); |
|---|
| 885 | | - |
|---|
| 886 | 906 | void crypto_init_queue(struct crypto_queue *queue, unsigned int max_qlen) |
|---|
| 887 | 907 | { |
|---|
| 888 | 908 | INIT_LIST_HEAD(&queue->list); |
|---|
| .. | .. |
|---|
| 915 | 935 | } |
|---|
| 916 | 936 | EXPORT_SYMBOL_GPL(crypto_enqueue_request); |
|---|
| 917 | 937 | |
|---|
| 938 | +void crypto_enqueue_request_head(struct crypto_queue *queue, |
|---|
| 939 | + struct crypto_async_request *request) |
|---|
| 940 | +{ |
|---|
| 941 | + queue->qlen++; |
|---|
| 942 | + list_add(&request->list, &queue->list); |
|---|
| 943 | +} |
|---|
| 944 | +EXPORT_SYMBOL_GPL(crypto_enqueue_request_head); |
|---|
| 945 | + |
|---|
| 918 | 946 | struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue) |
|---|
| 919 | 947 | { |
|---|
| 920 | 948 | struct list_head *request; |
|---|
| .. | .. |
|---|
| 933 | 961 | return list_entry(request, struct crypto_async_request, list); |
|---|
| 934 | 962 | } |
|---|
| 935 | 963 | EXPORT_SYMBOL_GPL(crypto_dequeue_request); |
|---|
| 936 | | - |
|---|
| 937 | | -int crypto_tfm_in_queue(struct crypto_queue *queue, struct crypto_tfm *tfm) |
|---|
| 938 | | -{ |
|---|
| 939 | | - struct crypto_async_request *req; |
|---|
| 940 | | - |
|---|
| 941 | | - list_for_each_entry(req, &queue->list, list) { |
|---|
| 942 | | - if (req->tfm == tfm) |
|---|
| 943 | | - return 1; |
|---|
| 944 | | - } |
|---|
| 945 | | - |
|---|
| 946 | | - return 0; |
|---|
| 947 | | -} |
|---|
| 948 | | -EXPORT_SYMBOL_GPL(crypto_tfm_in_queue); |
|---|
| 949 | 964 | |
|---|
| 950 | 965 | static inline void crypto_inc_byte(u8 *a, unsigned int size) |
|---|
| 951 | 966 | { |
|---|
| .. | .. |
|---|
| 1053 | 1068 | } |
|---|
| 1054 | 1069 | EXPORT_SYMBOL_GPL(crypto_type_has_alg); |
|---|
| 1055 | 1070 | |
|---|
| 1071 | +#ifdef CONFIG_CRYPTO_STATS |
|---|
| 1072 | +void crypto_stats_init(struct crypto_alg *alg) |
|---|
| 1073 | +{ |
|---|
| 1074 | + memset(&alg->stats, 0, sizeof(alg->stats)); |
|---|
| 1075 | +} |
|---|
| 1076 | +EXPORT_SYMBOL_GPL(crypto_stats_init); |
|---|
| 1077 | + |
|---|
| 1078 | +void crypto_stats_get(struct crypto_alg *alg) |
|---|
| 1079 | +{ |
|---|
| 1080 | + crypto_alg_get(alg); |
|---|
| 1081 | +} |
|---|
| 1082 | +EXPORT_SYMBOL_GPL(crypto_stats_get); |
|---|
| 1083 | + |
|---|
| 1084 | +void crypto_stats_aead_encrypt(unsigned int cryptlen, struct crypto_alg *alg, |
|---|
| 1085 | + int ret) |
|---|
| 1086 | +{ |
|---|
| 1087 | + if (ret && ret != -EINPROGRESS && ret != -EBUSY) { |
|---|
| 1088 | + atomic64_inc(&alg->stats.aead.err_cnt); |
|---|
| 1089 | + } else { |
|---|
| 1090 | + atomic64_inc(&alg->stats.aead.encrypt_cnt); |
|---|
| 1091 | + atomic64_add(cryptlen, &alg->stats.aead.encrypt_tlen); |
|---|
| 1092 | + } |
|---|
| 1093 | + crypto_alg_put(alg); |
|---|
| 1094 | +} |
|---|
| 1095 | +EXPORT_SYMBOL_GPL(crypto_stats_aead_encrypt); |
|---|
| 1096 | + |
|---|
| 1097 | +void crypto_stats_aead_decrypt(unsigned int cryptlen, struct crypto_alg *alg, |
|---|
| 1098 | + int ret) |
|---|
| 1099 | +{ |
|---|
| 1100 | + if (ret && ret != -EINPROGRESS && ret != -EBUSY) { |
|---|
| 1101 | + atomic64_inc(&alg->stats.aead.err_cnt); |
|---|
| 1102 | + } else { |
|---|
| 1103 | + atomic64_inc(&alg->stats.aead.decrypt_cnt); |
|---|
| 1104 | + atomic64_add(cryptlen, &alg->stats.aead.decrypt_tlen); |
|---|
| 1105 | + } |
|---|
| 1106 | + crypto_alg_put(alg); |
|---|
| 1107 | +} |
|---|
| 1108 | +EXPORT_SYMBOL_GPL(crypto_stats_aead_decrypt); |
|---|
| 1109 | + |
|---|
| 1110 | +void crypto_stats_akcipher_encrypt(unsigned int src_len, int ret, |
|---|
| 1111 | + struct crypto_alg *alg) |
|---|
| 1112 | +{ |
|---|
| 1113 | + if (ret && ret != -EINPROGRESS && ret != -EBUSY) { |
|---|
| 1114 | + atomic64_inc(&alg->stats.akcipher.err_cnt); |
|---|
| 1115 | + } else { |
|---|
| 1116 | + atomic64_inc(&alg->stats.akcipher.encrypt_cnt); |
|---|
| 1117 | + atomic64_add(src_len, &alg->stats.akcipher.encrypt_tlen); |
|---|
| 1118 | + } |
|---|
| 1119 | + crypto_alg_put(alg); |
|---|
| 1120 | +} |
|---|
| 1121 | +EXPORT_SYMBOL_GPL(crypto_stats_akcipher_encrypt); |
|---|
| 1122 | + |
|---|
| 1123 | +void crypto_stats_akcipher_decrypt(unsigned int src_len, int ret, |
|---|
| 1124 | + struct crypto_alg *alg) |
|---|
| 1125 | +{ |
|---|
| 1126 | + if (ret && ret != -EINPROGRESS && ret != -EBUSY) { |
|---|
| 1127 | + atomic64_inc(&alg->stats.akcipher.err_cnt); |
|---|
| 1128 | + } else { |
|---|
| 1129 | + atomic64_inc(&alg->stats.akcipher.decrypt_cnt); |
|---|
| 1130 | + atomic64_add(src_len, &alg->stats.akcipher.decrypt_tlen); |
|---|
| 1131 | + } |
|---|
| 1132 | + crypto_alg_put(alg); |
|---|
| 1133 | +} |
|---|
| 1134 | +EXPORT_SYMBOL_GPL(crypto_stats_akcipher_decrypt); |
|---|
| 1135 | + |
|---|
| 1136 | +void crypto_stats_akcipher_sign(int ret, struct crypto_alg *alg) |
|---|
| 1137 | +{ |
|---|
| 1138 | + if (ret && ret != -EINPROGRESS && ret != -EBUSY) |
|---|
| 1139 | + atomic64_inc(&alg->stats.akcipher.err_cnt); |
|---|
| 1140 | + else |
|---|
| 1141 | + atomic64_inc(&alg->stats.akcipher.sign_cnt); |
|---|
| 1142 | + crypto_alg_put(alg); |
|---|
| 1143 | +} |
|---|
| 1144 | +EXPORT_SYMBOL_GPL(crypto_stats_akcipher_sign); |
|---|
| 1145 | + |
|---|
| 1146 | +void crypto_stats_akcipher_verify(int ret, struct crypto_alg *alg) |
|---|
| 1147 | +{ |
|---|
| 1148 | + if (ret && ret != -EINPROGRESS && ret != -EBUSY) |
|---|
| 1149 | + atomic64_inc(&alg->stats.akcipher.err_cnt); |
|---|
| 1150 | + else |
|---|
| 1151 | + atomic64_inc(&alg->stats.akcipher.verify_cnt); |
|---|
| 1152 | + crypto_alg_put(alg); |
|---|
| 1153 | +} |
|---|
| 1154 | +EXPORT_SYMBOL_GPL(crypto_stats_akcipher_verify); |
|---|
| 1155 | + |
|---|
| 1156 | +void crypto_stats_compress(unsigned int slen, int ret, struct crypto_alg *alg) |
|---|
| 1157 | +{ |
|---|
| 1158 | + if (ret && ret != -EINPROGRESS && ret != -EBUSY) { |
|---|
| 1159 | + atomic64_inc(&alg->stats.compress.err_cnt); |
|---|
| 1160 | + } else { |
|---|
| 1161 | + atomic64_inc(&alg->stats.compress.compress_cnt); |
|---|
| 1162 | + atomic64_add(slen, &alg->stats.compress.compress_tlen); |
|---|
| 1163 | + } |
|---|
| 1164 | + crypto_alg_put(alg); |
|---|
| 1165 | +} |
|---|
| 1166 | +EXPORT_SYMBOL_GPL(crypto_stats_compress); |
|---|
| 1167 | + |
|---|
| 1168 | +void crypto_stats_decompress(unsigned int slen, int ret, struct crypto_alg *alg) |
|---|
| 1169 | +{ |
|---|
| 1170 | + if (ret && ret != -EINPROGRESS && ret != -EBUSY) { |
|---|
| 1171 | + atomic64_inc(&alg->stats.compress.err_cnt); |
|---|
| 1172 | + } else { |
|---|
| 1173 | + atomic64_inc(&alg->stats.compress.decompress_cnt); |
|---|
| 1174 | + atomic64_add(slen, &alg->stats.compress.decompress_tlen); |
|---|
| 1175 | + } |
|---|
| 1176 | + crypto_alg_put(alg); |
|---|
| 1177 | +} |
|---|
| 1178 | +EXPORT_SYMBOL_GPL(crypto_stats_decompress); |
|---|
| 1179 | + |
|---|
| 1180 | +void crypto_stats_ahash_update(unsigned int nbytes, int ret, |
|---|
| 1181 | + struct crypto_alg *alg) |
|---|
| 1182 | +{ |
|---|
| 1183 | + if (ret && ret != -EINPROGRESS && ret != -EBUSY) |
|---|
| 1184 | + atomic64_inc(&alg->stats.hash.err_cnt); |
|---|
| 1185 | + else |
|---|
| 1186 | + atomic64_add(nbytes, &alg->stats.hash.hash_tlen); |
|---|
| 1187 | + crypto_alg_put(alg); |
|---|
| 1188 | +} |
|---|
| 1189 | +EXPORT_SYMBOL_GPL(crypto_stats_ahash_update); |
|---|
| 1190 | + |
|---|
| 1191 | +void crypto_stats_ahash_final(unsigned int nbytes, int ret, |
|---|
| 1192 | + struct crypto_alg *alg) |
|---|
| 1193 | +{ |
|---|
| 1194 | + if (ret && ret != -EINPROGRESS && ret != -EBUSY) { |
|---|
| 1195 | + atomic64_inc(&alg->stats.hash.err_cnt); |
|---|
| 1196 | + } else { |
|---|
| 1197 | + atomic64_inc(&alg->stats.hash.hash_cnt); |
|---|
| 1198 | + atomic64_add(nbytes, &alg->stats.hash.hash_tlen); |
|---|
| 1199 | + } |
|---|
| 1200 | + crypto_alg_put(alg); |
|---|
| 1201 | +} |
|---|
| 1202 | +EXPORT_SYMBOL_GPL(crypto_stats_ahash_final); |
|---|
| 1203 | + |
|---|
| 1204 | +void crypto_stats_kpp_set_secret(struct crypto_alg *alg, int ret) |
|---|
| 1205 | +{ |
|---|
| 1206 | + if (ret) |
|---|
| 1207 | + atomic64_inc(&alg->stats.kpp.err_cnt); |
|---|
| 1208 | + else |
|---|
| 1209 | + atomic64_inc(&alg->stats.kpp.setsecret_cnt); |
|---|
| 1210 | + crypto_alg_put(alg); |
|---|
| 1211 | +} |
|---|
| 1212 | +EXPORT_SYMBOL_GPL(crypto_stats_kpp_set_secret); |
|---|
| 1213 | + |
|---|
| 1214 | +void crypto_stats_kpp_generate_public_key(struct crypto_alg *alg, int ret) |
|---|
| 1215 | +{ |
|---|
| 1216 | + if (ret) |
|---|
| 1217 | + atomic64_inc(&alg->stats.kpp.err_cnt); |
|---|
| 1218 | + else |
|---|
| 1219 | + atomic64_inc(&alg->stats.kpp.generate_public_key_cnt); |
|---|
| 1220 | + crypto_alg_put(alg); |
|---|
| 1221 | +} |
|---|
| 1222 | +EXPORT_SYMBOL_GPL(crypto_stats_kpp_generate_public_key); |
|---|
| 1223 | + |
|---|
| 1224 | +void crypto_stats_kpp_compute_shared_secret(struct crypto_alg *alg, int ret) |
|---|
| 1225 | +{ |
|---|
| 1226 | + if (ret) |
|---|
| 1227 | + atomic64_inc(&alg->stats.kpp.err_cnt); |
|---|
| 1228 | + else |
|---|
| 1229 | + atomic64_inc(&alg->stats.kpp.compute_shared_secret_cnt); |
|---|
| 1230 | + crypto_alg_put(alg); |
|---|
| 1231 | +} |
|---|
| 1232 | +EXPORT_SYMBOL_GPL(crypto_stats_kpp_compute_shared_secret); |
|---|
| 1233 | + |
|---|
| 1234 | +void crypto_stats_rng_seed(struct crypto_alg *alg, int ret) |
|---|
| 1235 | +{ |
|---|
| 1236 | + if (ret && ret != -EINPROGRESS && ret != -EBUSY) |
|---|
| 1237 | + atomic64_inc(&alg->stats.rng.err_cnt); |
|---|
| 1238 | + else |
|---|
| 1239 | + atomic64_inc(&alg->stats.rng.seed_cnt); |
|---|
| 1240 | + crypto_alg_put(alg); |
|---|
| 1241 | +} |
|---|
| 1242 | +EXPORT_SYMBOL_GPL(crypto_stats_rng_seed); |
|---|
| 1243 | + |
|---|
| 1244 | +void crypto_stats_rng_generate(struct crypto_alg *alg, unsigned int dlen, |
|---|
| 1245 | + int ret) |
|---|
| 1246 | +{ |
|---|
| 1247 | + if (ret && ret != -EINPROGRESS && ret != -EBUSY) { |
|---|
| 1248 | + atomic64_inc(&alg->stats.rng.err_cnt); |
|---|
| 1249 | + } else { |
|---|
| 1250 | + atomic64_inc(&alg->stats.rng.generate_cnt); |
|---|
| 1251 | + atomic64_add(dlen, &alg->stats.rng.generate_tlen); |
|---|
| 1252 | + } |
|---|
| 1253 | + crypto_alg_put(alg); |
|---|
| 1254 | +} |
|---|
| 1255 | +EXPORT_SYMBOL_GPL(crypto_stats_rng_generate); |
|---|
| 1256 | + |
|---|
| 1257 | +void crypto_stats_skcipher_encrypt(unsigned int cryptlen, int ret, |
|---|
| 1258 | + struct crypto_alg *alg) |
|---|
| 1259 | +{ |
|---|
| 1260 | + if (ret && ret != -EINPROGRESS && ret != -EBUSY) { |
|---|
| 1261 | + atomic64_inc(&alg->stats.cipher.err_cnt); |
|---|
| 1262 | + } else { |
|---|
| 1263 | + atomic64_inc(&alg->stats.cipher.encrypt_cnt); |
|---|
| 1264 | + atomic64_add(cryptlen, &alg->stats.cipher.encrypt_tlen); |
|---|
| 1265 | + } |
|---|
| 1266 | + crypto_alg_put(alg); |
|---|
| 1267 | +} |
|---|
| 1268 | +EXPORT_SYMBOL_GPL(crypto_stats_skcipher_encrypt); |
|---|
| 1269 | + |
|---|
| 1270 | +void crypto_stats_skcipher_decrypt(unsigned int cryptlen, int ret, |
|---|
| 1271 | + struct crypto_alg *alg) |
|---|
| 1272 | +{ |
|---|
| 1273 | + if (ret && ret != -EINPROGRESS && ret != -EBUSY) { |
|---|
| 1274 | + atomic64_inc(&alg->stats.cipher.err_cnt); |
|---|
| 1275 | + } else { |
|---|
| 1276 | + atomic64_inc(&alg->stats.cipher.decrypt_cnt); |
|---|
| 1277 | + atomic64_add(cryptlen, &alg->stats.cipher.decrypt_tlen); |
|---|
| 1278 | + } |
|---|
| 1279 | + crypto_alg_put(alg); |
|---|
| 1280 | +} |
|---|
| 1281 | +EXPORT_SYMBOL_GPL(crypto_stats_skcipher_decrypt); |
|---|
| 1282 | +#endif |
|---|
| 1283 | + |
|---|
| 1056 | 1284 | static int __init crypto_algapi_init(void) |
|---|
| 1057 | 1285 | { |
|---|
| 1058 | 1286 | crypto_init_proc(); |
|---|
| .. | .. |
|---|
| 1069 | 1297 | |
|---|
| 1070 | 1298 | MODULE_LICENSE("GPL"); |
|---|
| 1071 | 1299 | MODULE_DESCRIPTION("Cryptographic algorithms API"); |
|---|
| 1300 | +MODULE_SOFTDEP("pre: cryptomgr"); |
|---|