aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/api.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/api.c')
-rw-r--r--crypto/api.c60
1 files changed, 54 insertions, 6 deletions
diff --git a/crypto/api.c b/crypto/api.c
index 394169a8577d..b4728811ce3b 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -13,9 +13,12 @@
13 * any later version. 13 * any later version.
14 * 14 *
15 */ 15 */
16
17#include <linux/compiler.h>
16#include <linux/init.h> 18#include <linux/init.h>
17#include <linux/crypto.h> 19#include <linux/crypto.h>
18#include <linux/errno.h> 20#include <linux/errno.h>
21#include <linux/kmod.h>
19#include <linux/rwsem.h> 22#include <linux/rwsem.h>
20#include <linux/slab.h> 23#include <linux/slab.h>
21#include "internal.h" 24#include "internal.h"
@@ -33,7 +36,7 @@ static inline void crypto_alg_put(struct crypto_alg *alg)
33 module_put(alg->cra_module); 36 module_put(alg->cra_module);
34} 37}
35 38
36struct crypto_alg *crypto_alg_lookup(const char *name) 39static struct crypto_alg *crypto_alg_lookup(const char *name)
37{ 40{
38 struct crypto_alg *q, *alg = NULL; 41 struct crypto_alg *q, *alg = NULL;
39 42
@@ -54,6 +57,13 @@ struct crypto_alg *crypto_alg_lookup(const char *name)
54 return alg; 57 return alg;
55} 58}
56 59
60/* A far more intelligent version of this is planned. For now, just
61 * try an exact match on the name of the algorithm. */
62static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name)
63{
64 return try_then_request_module(crypto_alg_lookup(name), name);
65}
66
57static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags) 67static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags)
58{ 68{
59 tfm->crt_flags = 0; 69 tfm->crt_flags = 0;
@@ -117,20 +127,46 @@ static void crypto_exit_ops(struct crypto_tfm *tfm)
117 } 127 }
118} 128}
119 129
130static unsigned int crypto_ctxsize(struct crypto_alg *alg, int flags)
131{
132 unsigned int len;
133
134 switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
135 default:
136 BUG();
137
138 case CRYPTO_ALG_TYPE_CIPHER:
139 len = crypto_cipher_ctxsize(alg, flags);
140 break;
141
142 case CRYPTO_ALG_TYPE_DIGEST:
143 len = crypto_digest_ctxsize(alg, flags);
144 break;
145
146 case CRYPTO_ALG_TYPE_COMPRESS:
147 len = crypto_compress_ctxsize(alg, flags);
148 break;
149 }
150
151 return len + alg->cra_alignmask;
152}
153
120struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags) 154struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
121{ 155{
122 struct crypto_tfm *tfm = NULL; 156 struct crypto_tfm *tfm = NULL;
123 struct crypto_alg *alg; 157 struct crypto_alg *alg;
158 unsigned int tfm_size;
124 159
125 alg = crypto_alg_mod_lookup(name); 160 alg = crypto_alg_mod_lookup(name);
126 if (alg == NULL) 161 if (alg == NULL)
127 goto out; 162 goto out;
128 163
129 tfm = kmalloc(sizeof(*tfm) + alg->cra_ctxsize, GFP_KERNEL); 164 tfm_size = sizeof(*tfm) + crypto_ctxsize(alg, flags);
165 tfm = kmalloc(tfm_size, GFP_KERNEL);
130 if (tfm == NULL) 166 if (tfm == NULL)
131 goto out_put; 167 goto out_put;
132 168
133 memset(tfm, 0, sizeof(*tfm) + alg->cra_ctxsize); 169 memset(tfm, 0, tfm_size);
134 170
135 tfm->__crt_alg = alg; 171 tfm->__crt_alg = alg;
136 172
@@ -155,8 +191,14 @@ out:
155 191
156void crypto_free_tfm(struct crypto_tfm *tfm) 192void crypto_free_tfm(struct crypto_tfm *tfm)
157{ 193{
158 struct crypto_alg *alg = tfm->__crt_alg; 194 struct crypto_alg *alg;
159 int size = sizeof(*tfm) + alg->cra_ctxsize; 195 int size;
196
197 if (unlikely(!tfm))
198 return;
199
200 alg = tfm->__crt_alg;
201 size = sizeof(*tfm) + alg->cra_ctxsize;
160 202
161 crypto_exit_ops(tfm); 203 crypto_exit_ops(tfm);
162 crypto_alg_put(alg); 204 crypto_alg_put(alg);
@@ -168,6 +210,12 @@ int crypto_register_alg(struct crypto_alg *alg)
168{ 210{
169 int ret = 0; 211 int ret = 0;
170 struct crypto_alg *q; 212 struct crypto_alg *q;
213
214 if (alg->cra_alignmask & (alg->cra_alignmask + 1))
215 return -EINVAL;
216
217 if (alg->cra_alignmask > PAGE_SIZE)
218 return -EINVAL;
171 219
172 down_write(&crypto_alg_sem); 220 down_write(&crypto_alg_sem);
173 221