diff options
-rw-r--r-- | crypto/api.c | 52 | ||||
-rw-r--r-- | crypto/internal.h | 6 | ||||
-rw-r--r-- | crypto/proc.c | 6 | ||||
-rw-r--r-- | include/linux/crypto.h | 5 |
4 files changed, 60 insertions, 9 deletions
diff --git a/crypto/api.c b/crypto/api.c index 40ae42e9b6a6..2715afdf678c 100644 --- a/crypto/api.c +++ b/crypto/api.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> | 4 | * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> |
5 | * Copyright (c) 2002 David S. Miller (davem@redhat.com) | 5 | * Copyright (c) 2002 David S. Miller (davem@redhat.com) |
6 | * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au> | ||
6 | * | 7 | * |
7 | * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no> | 8 | * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no> |
8 | * and Nettle, by Niels Möller. | 9 | * and Nettle, by Niels Möller. |
@@ -18,9 +19,11 @@ | |||
18 | #include <linux/init.h> | 19 | #include <linux/init.h> |
19 | #include <linux/crypto.h> | 20 | #include <linux/crypto.h> |
20 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
22 | #include <linux/kernel.h> | ||
21 | #include <linux/kmod.h> | 23 | #include <linux/kmod.h> |
22 | #include <linux/rwsem.h> | 24 | #include <linux/rwsem.h> |
23 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/string.h> | ||
24 | #include "internal.h" | 27 | #include "internal.h" |
25 | 28 | ||
26 | LIST_HEAD(crypto_alg_list); | 29 | LIST_HEAD(crypto_alg_list); |
@@ -39,6 +42,7 @@ static inline void crypto_alg_put(struct crypto_alg *alg) | |||
39 | static struct crypto_alg *crypto_alg_lookup(const char *name) | 42 | static struct crypto_alg *crypto_alg_lookup(const char *name) |
40 | { | 43 | { |
41 | struct crypto_alg *q, *alg = NULL; | 44 | struct crypto_alg *q, *alg = NULL; |
45 | int best = -1; | ||
42 | 46 | ||
43 | if (!name) | 47 | if (!name) |
44 | return NULL; | 48 | return NULL; |
@@ -46,11 +50,23 @@ static struct crypto_alg *crypto_alg_lookup(const char *name) | |||
46 | down_read(&crypto_alg_sem); | 50 | down_read(&crypto_alg_sem); |
47 | 51 | ||
48 | list_for_each_entry(q, &crypto_alg_list, cra_list) { | 52 | list_for_each_entry(q, &crypto_alg_list, cra_list) { |
49 | if (!(strcmp(q->cra_name, name))) { | 53 | int exact, fuzzy; |
50 | if (crypto_alg_get(q)) | 54 | |
51 | alg = q; | 55 | exact = !strcmp(q->cra_driver_name, name); |
56 | fuzzy = !strcmp(q->cra_name, name); | ||
57 | if (!exact && !(fuzzy && q->cra_priority > best)) | ||
58 | continue; | ||
59 | |||
60 | if (unlikely(!crypto_alg_get(q))) | ||
61 | continue; | ||
62 | |||
63 | best = q->cra_priority; | ||
64 | if (alg) | ||
65 | crypto_alg_put(alg); | ||
66 | alg = q; | ||
67 | |||
68 | if (exact) | ||
52 | break; | 69 | break; |
53 | } | ||
54 | } | 70 | } |
55 | 71 | ||
56 | up_read(&crypto_alg_sem); | 72 | up_read(&crypto_alg_sem); |
@@ -207,9 +223,26 @@ void crypto_free_tfm(struct crypto_tfm *tfm) | |||
207 | kfree(tfm); | 223 | kfree(tfm); |
208 | } | 224 | } |
209 | 225 | ||
226 | static inline int crypto_set_driver_name(struct crypto_alg *alg) | ||
227 | { | ||
228 | static const char suffix[] = "-generic"; | ||
229 | char *driver_name = (char *)alg->cra_driver_name; | ||
230 | int len; | ||
231 | |||
232 | if (*driver_name) | ||
233 | return 0; | ||
234 | |||
235 | len = strlcpy(driver_name, alg->cra_name, CRYPTO_MAX_ALG_NAME); | ||
236 | if (len + sizeof(suffix) > CRYPTO_MAX_ALG_NAME) | ||
237 | return -ENAMETOOLONG; | ||
238 | |||
239 | memcpy(driver_name + len, suffix, sizeof(suffix)); | ||
240 | return 0; | ||
241 | } | ||
242 | |||
210 | int crypto_register_alg(struct crypto_alg *alg) | 243 | int crypto_register_alg(struct crypto_alg *alg) |
211 | { | 244 | { |
212 | int ret = 0; | 245 | int ret; |
213 | struct crypto_alg *q; | 246 | struct crypto_alg *q; |
214 | 247 | ||
215 | if (alg->cra_alignmask & (alg->cra_alignmask + 1)) | 248 | if (alg->cra_alignmask & (alg->cra_alignmask + 1)) |
@@ -220,11 +253,18 @@ int crypto_register_alg(struct crypto_alg *alg) | |||
220 | 253 | ||
221 | if (alg->cra_blocksize > PAGE_SIZE) | 254 | if (alg->cra_blocksize > PAGE_SIZE) |
222 | return -EINVAL; | 255 | return -EINVAL; |
256 | |||
257 | if (alg->cra_priority < 0) | ||
258 | return -EINVAL; | ||
223 | 259 | ||
260 | ret = crypto_set_driver_name(alg); | ||
261 | if (unlikely(ret)) | ||
262 | return ret; | ||
263 | |||
224 | down_write(&crypto_alg_sem); | 264 | down_write(&crypto_alg_sem); |
225 | 265 | ||
226 | list_for_each_entry(q, &crypto_alg_list, cra_list) { | 266 | list_for_each_entry(q, &crypto_alg_list, cra_list) { |
227 | if (!(strcmp(q->cra_name, alg->cra_name))) { | 267 | if (!strcmp(q->cra_driver_name, alg->cra_driver_name)) { |
228 | ret = -EEXIST; | 268 | ret = -EEXIST; |
229 | goto out; | 269 | goto out; |
230 | } | 270 | } |
diff --git a/crypto/internal.h b/crypto/internal.h index 37aa652ce5ce..959e602909a6 100644 --- a/crypto/internal.h +++ b/crypto/internal.h | |||
@@ -2,6 +2,7 @@ | |||
2 | * Cryptographic API. | 2 | * Cryptographic API. |
3 | * | 3 | * |
4 | * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> | 4 | * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> |
5 | * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au> | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 7 | * 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 | * under the terms of the GNU General Public License as published by the Free |
@@ -16,10 +17,15 @@ | |||
16 | #include <linux/highmem.h> | 17 | #include <linux/highmem.h> |
17 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
18 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/list.h> | ||
19 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/rwsem.h> | ||
20 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
21 | #include <asm/kmap_types.h> | 24 | #include <asm/kmap_types.h> |
22 | 25 | ||
26 | extern struct list_head crypto_alg_list; | ||
27 | extern struct rw_semaphore crypto_alg_sem; | ||
28 | |||
23 | extern enum km_type crypto_km_types[]; | 29 | extern enum km_type crypto_km_types[]; |
24 | 30 | ||
25 | static inline enum km_type crypto_kmap_type(int out) | 31 | static inline enum km_type crypto_kmap_type(int out) |
diff --git a/crypto/proc.c b/crypto/proc.c index 630ba91c08f1..c0a5dd7ce2cc 100644 --- a/crypto/proc.c +++ b/crypto/proc.c | |||
@@ -4,6 +4,7 @@ | |||
4 | * Procfs information. | 4 | * Procfs information. |
5 | * | 5 | * |
6 | * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> | 6 | * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> |
7 | * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au> | ||
7 | * | 8 | * |
8 | * This program is free software; you can redistribute it and/or modify it | 9 | * This program is free software; you can redistribute it and/or modify it |
9 | * under the terms of the GNU General Public License as published by the Free | 10 | * under the terms of the GNU General Public License as published by the Free |
@@ -18,9 +19,6 @@ | |||
18 | #include <linux/seq_file.h> | 19 | #include <linux/seq_file.h> |
19 | #include "internal.h" | 20 | #include "internal.h" |
20 | 21 | ||
21 | extern struct list_head crypto_alg_list; | ||
22 | extern struct rw_semaphore crypto_alg_sem; | ||
23 | |||
24 | static void *c_start(struct seq_file *m, loff_t *pos) | 22 | static void *c_start(struct seq_file *m, loff_t *pos) |
25 | { | 23 | { |
26 | struct list_head *v; | 24 | struct list_head *v; |
@@ -53,7 +51,9 @@ static int c_show(struct seq_file *m, void *p) | |||
53 | struct crypto_alg *alg = (struct crypto_alg *)p; | 51 | struct crypto_alg *alg = (struct crypto_alg *)p; |
54 | 52 | ||
55 | seq_printf(m, "name : %s\n", alg->cra_name); | 53 | seq_printf(m, "name : %s\n", alg->cra_name); |
54 | seq_printf(m, "driver : %s\n", alg->cra_driver_name); | ||
56 | seq_printf(m, "module : %s\n", module_name(alg->cra_module)); | 55 | seq_printf(m, "module : %s\n", module_name(alg->cra_module)); |
56 | seq_printf(m, "priority : %d\n", alg->cra_priority); | ||
57 | 57 | ||
58 | switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) { | 58 | switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) { |
59 | case CRYPTO_ALG_TYPE_CIPHER: | 59 | case CRYPTO_ALG_TYPE_CIPHER: |
diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 3c89df6e7768..d88bf8aa8b47 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> | 4 | * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> |
5 | * Copyright (c) 2002 David S. Miller (davem@redhat.com) | 5 | * Copyright (c) 2002 David S. Miller (davem@redhat.com) |
6 | * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au> | ||
6 | * | 7 | * |
7 | * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no> | 8 | * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no> |
8 | * and Nettle, by Niels Möller. | 9 | * and Nettle, by Niels Möller. |
@@ -126,7 +127,11 @@ struct crypto_alg { | |||
126 | unsigned int cra_blocksize; | 127 | unsigned int cra_blocksize; |
127 | unsigned int cra_ctxsize; | 128 | unsigned int cra_ctxsize; |
128 | unsigned int cra_alignmask; | 129 | unsigned int cra_alignmask; |
130 | |||
131 | int cra_priority; | ||
132 | |||
129 | const char cra_name[CRYPTO_MAX_ALG_NAME]; | 133 | const char cra_name[CRYPTO_MAX_ALG_NAME]; |
134 | const char cra_driver_name[CRYPTO_MAX_ALG_NAME]; | ||
130 | 135 | ||
131 | union { | 136 | union { |
132 | struct cipher_alg cipher; | 137 | struct cipher_alg cipher; |