The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/crypto/api.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Scatterlist Cryptographic API.
    3  *
    4  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
    5  * Copyright (c) 2002 David S. Miller (davem@redhat.com)
    6  *
    7  * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
    8  * and Nettle, by Niels Möller.
    9  *
   10  * This program is free software; you can redistribute it and/or modify it
   11  * under the terms of the GNU General Public License as published by the Free
   12  * Software Foundation; either version 2 of the License, or (at your option) 
   13  * any later version.
   14  *
   15  */
   16 #include <linux/init.h>
   17 #include <linux/crypto.h>
   18 #include <linux/errno.h>
   19 #include <linux/rwsem.h>
   20 #include <linux/slab.h>
   21 #include "internal.h"
   22 
   23 LIST_HEAD(crypto_alg_list);
   24 DECLARE_RWSEM(crypto_alg_sem);
   25 
   26 static inline int crypto_alg_get(struct crypto_alg *alg)
   27 {
   28         return try_inc_mod_count(alg->cra_module);
   29 }
   30 
   31 static inline void crypto_alg_put(struct crypto_alg *alg)
   32 {
   33         if (alg->cra_module)
   34                 __MOD_DEC_USE_COUNT(alg->cra_module);
   35 }
   36 
   37 struct crypto_alg *crypto_alg_lookup(const char *name)
   38 {
   39         struct crypto_alg *q, *alg = NULL;
   40         
   41         down_read(&crypto_alg_sem);
   42         
   43         list_for_each_entry(q, &crypto_alg_list, cra_list) {
   44                 if (!(strcmp(q->cra_name, name))) {
   45                         if (crypto_alg_get(q))
   46                                 alg = q;
   47                         break;
   48                 }
   49         }
   50         
   51         up_read(&crypto_alg_sem);
   52         return alg;
   53 }
   54 
   55 static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags)
   56 {
   57         tfm->crt_flags = 0;
   58         
   59         switch (crypto_tfm_alg_type(tfm)) {
   60         case CRYPTO_ALG_TYPE_CIPHER:
   61                 return crypto_init_cipher_flags(tfm, flags);
   62                 
   63         case CRYPTO_ALG_TYPE_DIGEST:
   64                 return crypto_init_digest_flags(tfm, flags);
   65                 
   66         case CRYPTO_ALG_TYPE_COMPRESS:
   67                 return crypto_init_compress_flags(tfm, flags);
   68         
   69         default:
   70                 break;
   71         }
   72         
   73         BUG();
   74         return -EINVAL;
   75 }
   76 
   77 static int crypto_init_ops(struct crypto_tfm *tfm)
   78 {
   79         switch (crypto_tfm_alg_type(tfm)) {
   80         case CRYPTO_ALG_TYPE_CIPHER:
   81                 return crypto_init_cipher_ops(tfm);
   82                 
   83         case CRYPTO_ALG_TYPE_DIGEST:
   84                 return crypto_init_digest_ops(tfm);
   85                 
   86         case CRYPTO_ALG_TYPE_COMPRESS:
   87                 return crypto_init_compress_ops(tfm);
   88         
   89         default:
   90                 break;
   91         }
   92         
   93         BUG();
   94         return -EINVAL;
   95 }
   96 
   97 static void crypto_exit_ops(struct crypto_tfm *tfm)
   98 {
   99         switch (crypto_tfm_alg_type(tfm)) {
  100         case CRYPTO_ALG_TYPE_CIPHER:
  101                 crypto_exit_cipher_ops(tfm);
  102                 break;
  103                 
  104         case CRYPTO_ALG_TYPE_DIGEST:
  105                 crypto_exit_digest_ops(tfm);
  106                 break;
  107                 
  108         case CRYPTO_ALG_TYPE_COMPRESS:
  109                 crypto_exit_compress_ops(tfm);
  110                 break;
  111         
  112         default:
  113                 BUG();
  114                 
  115         }
  116 }
  117 
  118 struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
  119 {
  120         struct crypto_tfm *tfm = NULL;
  121         struct crypto_alg *alg;
  122 
  123         alg = crypto_alg_mod_lookup(name);
  124         if (alg == NULL)
  125                 goto out;
  126         
  127         tfm = kmalloc(sizeof(*tfm) + alg->cra_ctxsize, GFP_KERNEL);
  128         if (tfm == NULL)
  129                 goto out_put;
  130 
  131         memset(tfm, 0, sizeof(*tfm) + alg->cra_ctxsize);
  132         
  133         tfm->__crt_alg = alg;
  134         
  135         if (crypto_init_flags(tfm, flags))
  136                 goto out_free_tfm;
  137                 
  138         if (crypto_init_ops(tfm)) {
  139                 crypto_exit_ops(tfm);
  140                 goto out_free_tfm;
  141         }
  142 
  143         goto out;
  144 
  145 out_free_tfm:
  146         kfree(tfm);
  147         tfm = NULL;
  148 out_put:
  149         crypto_alg_put(alg);
  150 out:
  151         return tfm;
  152 }
  153 
  154 void crypto_free_tfm(struct crypto_tfm *tfm)
  155 {
  156         crypto_exit_ops(tfm);
  157         crypto_alg_put(tfm->__crt_alg);
  158         kfree(tfm);
  159 }
  160 
  161 int crypto_register_alg(struct crypto_alg *alg)
  162 {
  163         int ret = 0;
  164         struct crypto_alg *q;
  165         
  166         down_write(&crypto_alg_sem);
  167         
  168         list_for_each_entry(q, &crypto_alg_list, cra_list) {
  169                 if (!(strcmp(q->cra_name, alg->cra_name))) {
  170                         ret = -EEXIST;
  171                         goto out;
  172                 }
  173         }
  174         
  175         list_add_tail(&alg->cra_list, &crypto_alg_list);
  176 out:    
  177         up_write(&crypto_alg_sem);
  178         return ret;
  179 }
  180 
  181 int crypto_unregister_alg(struct crypto_alg *alg)
  182 {
  183         int ret = -ENOENT;
  184         struct crypto_alg *q;
  185         
  186         BUG_ON(!alg->cra_module);
  187         
  188         down_write(&crypto_alg_sem);
  189         list_for_each_entry(q, &crypto_alg_list, cra_list) {
  190                 if (alg == q) {
  191                         list_del(&alg->cra_list);
  192                         ret = 0;
  193                         goto out;
  194                 }
  195         }
  196 out:    
  197         up_write(&crypto_alg_sem);
  198         return ret;
  199 }
  200 
  201 int crypto_alg_available(const char *name, u32 flags)
  202 {
  203         int ret = 0;
  204         struct crypto_alg *alg = crypto_alg_mod_lookup(name);
  205         
  206         if (alg) {
  207                 crypto_alg_put(alg);
  208                 ret = 1;
  209         }
  210         
  211         return ret;
  212 }
  213 
  214 static int __init init_crypto(void)
  215 {
  216         printk(KERN_INFO "Initializing Cryptographic API\n");
  217         crypto_init_proc();
  218         return 0;
  219 }
  220 
  221 __initcall(init_crypto);
  222 
  223 EXPORT_SYMBOL_GPL(crypto_register_alg);
  224 EXPORT_SYMBOL_GPL(crypto_unregister_alg);
  225 EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
  226 EXPORT_SYMBOL_GPL(crypto_free_tfm);
  227 EXPORT_SYMBOL_GPL(crypto_alg_available);

Cache object: cce57a339db8130cafd68a5d326b8a6f


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.