diff options
-rw-r--r-- | crypto/Kconfig | 4 | ||||
-rw-r--r-- | crypto/Makefile | 3 | ||||
-rw-r--r-- | crypto/digest.c | 129 | ||||
-rw-r--r-- | crypto/hash.c | 61 | ||||
-rw-r--r-- | crypto/hmac.c | 12 | ||||
-rw-r--r-- | crypto/scatterwalk.h | 4 | ||||
-rw-r--r-- | include/crypto/algapi.h | 6 | ||||
-rw-r--r-- | include/linux/crypto.h | 172 |
8 files changed, 321 insertions, 70 deletions
diff --git a/crypto/Kconfig b/crypto/Kconfig index be5eb0cb7c30..69c5f992bcd4 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig | |||
@@ -20,6 +20,10 @@ config CRYPTO_BLKCIPHER | |||
20 | tristate | 20 | tristate |
21 | select CRYPTO_ALGAPI | 21 | select CRYPTO_ALGAPI |
22 | 22 | ||
23 | config CRYPTO_HASH | ||
24 | tristate | ||
25 | select CRYPTO_ALGAPI | ||
26 | |||
23 | config CRYPTO_MANAGER | 27 | config CRYPTO_MANAGER |
24 | tristate "Cryptographic algorithm manager" | 28 | tristate "Cryptographic algorithm manager" |
25 | select CRYPTO_ALGAPI | 29 | select CRYPTO_ALGAPI |
diff --git a/crypto/Makefile b/crypto/Makefile index 5e1ff4e0b1fc..72366208e291 100644 --- a/crypto/Makefile +++ b/crypto/Makefile | |||
@@ -10,6 +10,9 @@ obj-$(CONFIG_CRYPTO_ALGAPI) += crypto_algapi.o | |||
10 | 10 | ||
11 | obj-$(CONFIG_CRYPTO_BLKCIPHER) += blkcipher.o | 11 | obj-$(CONFIG_CRYPTO_BLKCIPHER) += blkcipher.o |
12 | 12 | ||
13 | crypto_hash-objs := hash.o | ||
14 | obj-$(CONFIG_CRYPTO_HASH) += crypto_hash.o | ||
15 | |||
13 | obj-$(CONFIG_CRYPTO_MANAGER) += cryptomgr.o | 16 | obj-$(CONFIG_CRYPTO_MANAGER) += cryptomgr.o |
14 | obj-$(CONFIG_CRYPTO_HMAC) += hmac.o | 17 | obj-$(CONFIG_CRYPTO_HMAC) += hmac.o |
15 | obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o | 18 | obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o |
diff --git a/crypto/digest.c b/crypto/digest.c index 96244a528844..5873063db840 100644 --- a/crypto/digest.c +++ b/crypto/digest.c | |||
@@ -11,29 +11,89 @@ | |||
11 | * any later version. | 11 | * any later version. |
12 | * | 12 | * |
13 | */ | 13 | */ |
14 | #include <linux/crypto.h> | 14 | |
15 | #include <linux/mm.h> | 15 | #include <linux/mm.h> |
16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
17 | #include <linux/highmem.h> | 17 | #include <linux/highmem.h> |
18 | #include <asm/scatterlist.h> | 18 | #include <linux/module.h> |
19 | #include <linux/scatterlist.h> | ||
20 | |||
19 | #include "internal.h" | 21 | #include "internal.h" |
22 | #include "scatterwalk.h" | ||
20 | 23 | ||
21 | static void init(struct crypto_tfm *tfm) | 24 | void crypto_digest_init(struct crypto_tfm *tfm) |
22 | { | 25 | { |
23 | tfm->__crt_alg->cra_digest.dia_init(tfm); | 26 | struct crypto_hash *hash = crypto_hash_cast(tfm); |
27 | struct hash_desc desc = { .tfm = hash, .flags = tfm->crt_flags }; | ||
28 | |||
29 | crypto_hash_init(&desc); | ||
24 | } | 30 | } |
31 | EXPORT_SYMBOL_GPL(crypto_digest_init); | ||
25 | 32 | ||
26 | static void update(struct crypto_tfm *tfm, | 33 | void crypto_digest_update(struct crypto_tfm *tfm, |
27 | struct scatterlist *sg, unsigned int nsg) | 34 | struct scatterlist *sg, unsigned int nsg) |
28 | { | 35 | { |
36 | struct crypto_hash *hash = crypto_hash_cast(tfm); | ||
37 | struct hash_desc desc = { .tfm = hash, .flags = tfm->crt_flags }; | ||
38 | unsigned int nbytes = 0; | ||
29 | unsigned int i; | 39 | unsigned int i; |
40 | |||
41 | for (i = 0; i < nsg; i++) | ||
42 | nbytes += sg[i].length; | ||
43 | |||
44 | crypto_hash_update(&desc, sg, nbytes); | ||
45 | } | ||
46 | EXPORT_SYMBOL_GPL(crypto_digest_update); | ||
47 | |||
48 | void crypto_digest_final(struct crypto_tfm *tfm, u8 *out) | ||
49 | { | ||
50 | struct crypto_hash *hash = crypto_hash_cast(tfm); | ||
51 | struct hash_desc desc = { .tfm = hash, .flags = tfm->crt_flags }; | ||
52 | |||
53 | crypto_hash_final(&desc, out); | ||
54 | } | ||
55 | EXPORT_SYMBOL_GPL(crypto_digest_final); | ||
56 | |||
57 | void crypto_digest_digest(struct crypto_tfm *tfm, | ||
58 | struct scatterlist *sg, unsigned int nsg, u8 *out) | ||
59 | { | ||
60 | struct crypto_hash *hash = crypto_hash_cast(tfm); | ||
61 | struct hash_desc desc = { .tfm = hash, .flags = tfm->crt_flags }; | ||
62 | unsigned int nbytes = 0; | ||
63 | unsigned int i; | ||
64 | |||
65 | for (i = 0; i < nsg; i++) | ||
66 | nbytes += sg[i].length; | ||
67 | |||
68 | crypto_hash_digest(&desc, sg, nbytes, out); | ||
69 | } | ||
70 | EXPORT_SYMBOL_GPL(crypto_digest_digest); | ||
71 | |||
72 | static int init(struct hash_desc *desc) | ||
73 | { | ||
74 | struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm); | ||
75 | |||
76 | tfm->__crt_alg->cra_digest.dia_init(tfm); | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static int update(struct hash_desc *desc, | ||
81 | struct scatterlist *sg, unsigned int nbytes) | ||
82 | { | ||
83 | struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm); | ||
30 | unsigned int alignmask = crypto_tfm_alg_alignmask(tfm); | 84 | unsigned int alignmask = crypto_tfm_alg_alignmask(tfm); |
31 | 85 | ||
32 | for (i = 0; i < nsg; i++) { | 86 | if (!nbytes) |
87 | return 0; | ||
88 | |||
89 | for (;;) { | ||
90 | struct page *pg = sg->page; | ||
91 | unsigned int offset = sg->offset; | ||
92 | unsigned int l = sg->length; | ||
33 | 93 | ||
34 | struct page *pg = sg[i].page; | 94 | if (unlikely(l > nbytes)) |
35 | unsigned int offset = sg[i].offset; | 95 | l = nbytes; |
36 | unsigned int l = sg[i].length; | 96 | nbytes -= l; |
37 | 97 | ||
38 | do { | 98 | do { |
39 | unsigned int bytes_from_page = min(l, ((unsigned int) | 99 | unsigned int bytes_from_page = min(l, ((unsigned int) |
@@ -55,16 +115,23 @@ static void update(struct crypto_tfm *tfm, | |||
55 | tfm->__crt_alg->cra_digest.dia_update(tfm, p, | 115 | tfm->__crt_alg->cra_digest.dia_update(tfm, p, |
56 | bytes_from_page); | 116 | bytes_from_page); |
57 | crypto_kunmap(src, 0); | 117 | crypto_kunmap(src, 0); |
58 | crypto_yield(tfm->crt_flags); | 118 | crypto_yield(desc->flags); |
59 | offset = 0; | 119 | offset = 0; |
60 | pg++; | 120 | pg++; |
61 | l -= bytes_from_page; | 121 | l -= bytes_from_page; |
62 | } while (l > 0); | 122 | } while (l > 0); |
123 | |||
124 | if (!nbytes) | ||
125 | break; | ||
126 | sg = sg_next(sg); | ||
63 | } | 127 | } |
128 | |||
129 | return 0; | ||
64 | } | 130 | } |
65 | 131 | ||
66 | static void final(struct crypto_tfm *tfm, u8 *out) | 132 | static int final(struct hash_desc *desc, u8 *out) |
67 | { | 133 | { |
134 | struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm); | ||
68 | unsigned long alignmask = crypto_tfm_alg_alignmask(tfm); | 135 | unsigned long alignmask = crypto_tfm_alg_alignmask(tfm); |
69 | struct digest_alg *digest = &tfm->__crt_alg->cra_digest; | 136 | struct digest_alg *digest = &tfm->__crt_alg->cra_digest; |
70 | 137 | ||
@@ -78,26 +145,30 @@ static void final(struct crypto_tfm *tfm, u8 *out) | |||
78 | memcpy(out, dst, digest->dia_digestsize); | 145 | memcpy(out, dst, digest->dia_digestsize); |
79 | } else | 146 | } else |
80 | digest->dia_final(tfm, out); | 147 | digest->dia_final(tfm, out); |
148 | |||
149 | return 0; | ||
81 | } | 150 | } |
82 | 151 | ||
83 | static int nosetkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) | 152 | static int nosetkey(struct crypto_hash *tfm, const u8 *key, unsigned int keylen) |
84 | { | 153 | { |
85 | tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK; | 154 | crypto_hash_clear_flags(tfm, CRYPTO_TFM_RES_MASK); |
86 | return -ENOSYS; | 155 | return -ENOSYS; |
87 | } | 156 | } |
88 | 157 | ||
89 | static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) | 158 | static int setkey(struct crypto_hash *hash, const u8 *key, unsigned int keylen) |
90 | { | 159 | { |
91 | tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK; | 160 | struct crypto_tfm *tfm = crypto_hash_tfm(hash); |
161 | |||
162 | crypto_hash_clear_flags(hash, CRYPTO_TFM_RES_MASK); | ||
92 | return tfm->__crt_alg->cra_digest.dia_setkey(tfm, key, keylen); | 163 | return tfm->__crt_alg->cra_digest.dia_setkey(tfm, key, keylen); |
93 | } | 164 | } |
94 | 165 | ||
95 | static void digest(struct crypto_tfm *tfm, | 166 | static int digest(struct hash_desc *desc, |
96 | struct scatterlist *sg, unsigned int nsg, u8 *out) | 167 | struct scatterlist *sg, unsigned int nbytes, u8 *out) |
97 | { | 168 | { |
98 | init(tfm); | 169 | init(desc); |
99 | update(tfm, sg, nsg); | 170 | update(desc, sg, nbytes); |
100 | final(tfm, out); | 171 | return final(desc, out); |
101 | } | 172 | } |
102 | 173 | ||
103 | int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags) | 174 | int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags) |
@@ -107,14 +178,18 @@ int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags) | |||
107 | 178 | ||
108 | int crypto_init_digest_ops(struct crypto_tfm *tfm) | 179 | int crypto_init_digest_ops(struct crypto_tfm *tfm) |
109 | { | 180 | { |
110 | struct digest_tfm *ops = &tfm->crt_digest; | 181 | struct hash_tfm *ops = &tfm->crt_hash; |
111 | struct digest_alg *dalg = &tfm->__crt_alg->cra_digest; | 182 | struct digest_alg *dalg = &tfm->__crt_alg->cra_digest; |
183 | |||
184 | if (dalg->dia_digestsize > crypto_tfm_alg_blocksize(tfm)) | ||
185 | return -EINVAL; | ||
112 | 186 | ||
113 | ops->dit_init = init; | 187 | ops->init = init; |
114 | ops->dit_update = update; | 188 | ops->update = update; |
115 | ops->dit_final = final; | 189 | ops->final = final; |
116 | ops->dit_digest = digest; | 190 | ops->digest = digest; |
117 | ops->dit_setkey = dalg->dia_setkey ? setkey : nosetkey; | 191 | ops->setkey = dalg->dia_setkey ? setkey : nosetkey; |
192 | ops->digestsize = dalg->dia_digestsize; | ||
118 | 193 | ||
119 | return crypto_alloc_hmac_block(tfm); | 194 | return crypto_alloc_hmac_block(tfm); |
120 | } | 195 | } |
diff --git a/crypto/hash.c b/crypto/hash.c new file mode 100644 index 000000000000..cdec23d885fe --- /dev/null +++ b/crypto/hash.c | |||
@@ -0,0 +1,61 @@ | |||
1 | /* | ||
2 | * Cryptographic Hash operations. | ||
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 | #include <linux/errno.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/seq_file.h> | ||
16 | |||
17 | #include "internal.h" | ||
18 | |||
19 | static unsigned int crypto_hash_ctxsize(struct crypto_alg *alg) | ||
20 | { | ||
21 | return alg->cra_ctxsize; | ||
22 | } | ||
23 | |||
24 | static int crypto_init_hash_ops(struct crypto_tfm *tfm) | ||
25 | { | ||
26 | struct hash_tfm *crt = &tfm->crt_hash; | ||
27 | struct hash_alg *alg = &tfm->__crt_alg->cra_hash; | ||
28 | |||
29 | if (alg->digestsize > crypto_tfm_alg_blocksize(tfm)) | ||
30 | return -EINVAL; | ||
31 | |||
32 | crt->init = alg->init; | ||
33 | crt->update = alg->update; | ||
34 | crt->final = alg->final; | ||
35 | crt->digest = alg->digest; | ||
36 | crt->setkey = alg->setkey; | ||
37 | crt->digestsize = alg->digestsize; | ||
38 | |||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg) | ||
43 | __attribute_used__; | ||
44 | static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg) | ||
45 | { | ||
46 | seq_printf(m, "type : hash\n"); | ||
47 | seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); | ||
48 | seq_printf(m, "digestsize : %u\n", alg->cra_hash.digestsize); | ||
49 | } | ||
50 | |||
51 | const struct crypto_type crypto_hash_type = { | ||
52 | .ctxsize = crypto_hash_ctxsize, | ||
53 | .init = crypto_init_hash_ops, | ||
54 | #ifdef CONFIG_PROC_FS | ||
55 | .show = crypto_hash_show, | ||
56 | #endif | ||
57 | }; | ||
58 | EXPORT_SYMBOL_GPL(crypto_hash_type); | ||
59 | |||
60 | MODULE_LICENSE("GPL"); | ||
61 | MODULE_DESCRIPTION("Generic cryptographic hash type"); | ||
diff --git a/crypto/hmac.c b/crypto/hmac.c index 46120dee5ada..ecf7b0a95b56 100644 --- a/crypto/hmac.c +++ b/crypto/hmac.c | |||
@@ -35,9 +35,9 @@ int crypto_alloc_hmac_block(struct crypto_tfm *tfm) | |||
35 | 35 | ||
36 | BUG_ON(!crypto_tfm_alg_blocksize(tfm)); | 36 | BUG_ON(!crypto_tfm_alg_blocksize(tfm)); |
37 | 37 | ||
38 | tfm->crt_digest.dit_hmac_block = kmalloc(crypto_tfm_alg_blocksize(tfm), | 38 | tfm->crt_hash.hmac_block = kmalloc(crypto_tfm_alg_blocksize(tfm), |
39 | GFP_KERNEL); | 39 | GFP_KERNEL); |
40 | if (tfm->crt_digest.dit_hmac_block == NULL) | 40 | if (tfm->crt_hash.hmac_block == NULL) |
41 | ret = -ENOMEM; | 41 | ret = -ENOMEM; |
42 | 42 | ||
43 | return ret; | 43 | return ret; |
@@ -46,14 +46,14 @@ int crypto_alloc_hmac_block(struct crypto_tfm *tfm) | |||
46 | 46 | ||
47 | void crypto_free_hmac_block(struct crypto_tfm *tfm) | 47 | void crypto_free_hmac_block(struct crypto_tfm *tfm) |
48 | { | 48 | { |
49 | kfree(tfm->crt_digest.dit_hmac_block); | 49 | kfree(tfm->crt_hash.hmac_block); |
50 | } | 50 | } |
51 | 51 | ||
52 | void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen) | 52 | void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen) |
53 | { | 53 | { |
54 | unsigned int i; | 54 | unsigned int i; |
55 | struct scatterlist tmp; | 55 | struct scatterlist tmp; |
56 | char *ipad = tfm->crt_digest.dit_hmac_block; | 56 | char *ipad = tfm->crt_hash.hmac_block; |
57 | 57 | ||
58 | if (*keylen > crypto_tfm_alg_blocksize(tfm)) { | 58 | if (*keylen > crypto_tfm_alg_blocksize(tfm)) { |
59 | hash_key(tfm, key, *keylen); | 59 | hash_key(tfm, key, *keylen); |
@@ -83,7 +83,7 @@ void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key, | |||
83 | { | 83 | { |
84 | unsigned int i; | 84 | unsigned int i; |
85 | struct scatterlist tmp; | 85 | struct scatterlist tmp; |
86 | char *opad = tfm->crt_digest.dit_hmac_block; | 86 | char *opad = tfm->crt_hash.hmac_block; |
87 | 87 | ||
88 | if (*keylen > crypto_tfm_alg_blocksize(tfm)) { | 88 | if (*keylen > crypto_tfm_alg_blocksize(tfm)) { |
89 | hash_key(tfm, key, *keylen); | 89 | hash_key(tfm, key, *keylen); |
diff --git a/crypto/scatterwalk.h b/crypto/scatterwalk.h index ace595a2e119..f1592cc2d0f4 100644 --- a/crypto/scatterwalk.h +++ b/crypto/scatterwalk.h | |||
@@ -20,11 +20,9 @@ | |||
20 | 20 | ||
21 | #include "internal.h" | 21 | #include "internal.h" |
22 | 22 | ||
23 | /* Define sg_next is an inline routine now in case we want to change | ||
24 | scatterlist to a linked list later. */ | ||
25 | static inline struct scatterlist *sg_next(struct scatterlist *sg) | 23 | static inline struct scatterlist *sg_next(struct scatterlist *sg) |
26 | { | 24 | { |
27 | return sg + 1; | 25 | return (++sg)->length ? sg : (void *)sg->page; |
28 | } | 26 | } |
29 | 27 | ||
30 | static inline unsigned long scatterwalk_samebuf(struct scatter_walk *walk_in, | 28 | static inline unsigned long scatterwalk_samebuf(struct scatter_walk *walk_in, |
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 444f602724db..5748aecdb414 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h | |||
@@ -82,6 +82,7 @@ struct blkcipher_walk { | |||
82 | }; | 82 | }; |
83 | 83 | ||
84 | extern const struct crypto_type crypto_blkcipher_type; | 84 | extern const struct crypto_type crypto_blkcipher_type; |
85 | extern const struct crypto_type crypto_hash_type; | ||
85 | 86 | ||
86 | void crypto_mod_put(struct crypto_alg *alg); | 87 | void crypto_mod_put(struct crypto_alg *alg); |
87 | 88 | ||
@@ -136,6 +137,11 @@ static inline struct cipher_alg *crypto_cipher_alg(struct crypto_cipher *tfm) | |||
136 | return &crypto_cipher_tfm(tfm)->__crt_alg->cra_cipher; | 137 | return &crypto_cipher_tfm(tfm)->__crt_alg->cra_cipher; |
137 | } | 138 | } |
138 | 139 | ||
140 | static inline void *crypto_hash_ctx_aligned(struct crypto_hash *tfm) | ||
141 | { | ||
142 | return crypto_tfm_ctx_aligned(&tfm->base); | ||
143 | } | ||
144 | |||
139 | static inline void blkcipher_walk_init(struct blkcipher_walk *walk, | 145 | static inline void blkcipher_walk_init(struct blkcipher_walk *walk, |
140 | struct scatterlist *dst, | 146 | struct scatterlist *dst, |
141 | struct scatterlist *src, | 147 | struct scatterlist *src, |
diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 0be666b50463..40c0aab8ad4c 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h | |||
@@ -31,8 +31,11 @@ | |||
31 | #define CRYPTO_ALG_TYPE_MASK 0x0000000f | 31 | #define CRYPTO_ALG_TYPE_MASK 0x0000000f |
32 | #define CRYPTO_ALG_TYPE_CIPHER 0x00000001 | 32 | #define CRYPTO_ALG_TYPE_CIPHER 0x00000001 |
33 | #define CRYPTO_ALG_TYPE_DIGEST 0x00000002 | 33 | #define CRYPTO_ALG_TYPE_DIGEST 0x00000002 |
34 | #define CRYPTO_ALG_TYPE_BLKCIPHER 0x00000003 | 34 | #define CRYPTO_ALG_TYPE_HASH 0x00000003 |
35 | #define CRYPTO_ALG_TYPE_COMPRESS 0x00000004 | 35 | #define CRYPTO_ALG_TYPE_BLKCIPHER 0x00000004 |
36 | #define CRYPTO_ALG_TYPE_COMPRESS 0x00000005 | ||
37 | |||
38 | #define CRYPTO_ALG_TYPE_HASH_MASK 0x0000000e | ||
36 | 39 | ||
37 | #define CRYPTO_ALG_LARVAL 0x00000010 | 40 | #define CRYPTO_ALG_LARVAL 0x00000010 |
38 | #define CRYPTO_ALG_DEAD 0x00000020 | 41 | #define CRYPTO_ALG_DEAD 0x00000020 |
@@ -90,6 +93,7 @@ | |||
90 | 93 | ||
91 | struct scatterlist; | 94 | struct scatterlist; |
92 | struct crypto_blkcipher; | 95 | struct crypto_blkcipher; |
96 | struct crypto_hash; | ||
93 | struct crypto_tfm; | 97 | struct crypto_tfm; |
94 | struct crypto_type; | 98 | struct crypto_type; |
95 | 99 | ||
@@ -107,6 +111,11 @@ struct cipher_desc { | |||
107 | void *info; | 111 | void *info; |
108 | }; | 112 | }; |
109 | 113 | ||
114 | struct hash_desc { | ||
115 | struct crypto_hash *tfm; | ||
116 | u32 flags; | ||
117 | }; | ||
118 | |||
110 | /* | 119 | /* |
111 | * Algorithms: modular crypto algorithm implementations, managed | 120 | * Algorithms: modular crypto algorithm implementations, managed |
112 | * via crypto_register_alg() and crypto_unregister_alg(). | 121 | * via crypto_register_alg() and crypto_unregister_alg(). |
@@ -158,6 +167,19 @@ struct digest_alg { | |||
158 | unsigned int keylen); | 167 | unsigned int keylen); |
159 | }; | 168 | }; |
160 | 169 | ||
170 | struct hash_alg { | ||
171 | int (*init)(struct hash_desc *desc); | ||
172 | int (*update)(struct hash_desc *desc, struct scatterlist *sg, | ||
173 | unsigned int nbytes); | ||
174 | int (*final)(struct hash_desc *desc, u8 *out); | ||
175 | int (*digest)(struct hash_desc *desc, struct scatterlist *sg, | ||
176 | unsigned int nbytes, u8 *out); | ||
177 | int (*setkey)(struct crypto_hash *tfm, const u8 *key, | ||
178 | unsigned int keylen); | ||
179 | |||
180 | unsigned int digestsize; | ||
181 | }; | ||
182 | |||
161 | struct compress_alg { | 183 | struct compress_alg { |
162 | int (*coa_compress)(struct crypto_tfm *tfm, const u8 *src, | 184 | int (*coa_compress)(struct crypto_tfm *tfm, const u8 *src, |
163 | unsigned int slen, u8 *dst, unsigned int *dlen); | 185 | unsigned int slen, u8 *dst, unsigned int *dlen); |
@@ -168,6 +190,7 @@ struct compress_alg { | |||
168 | #define cra_blkcipher cra_u.blkcipher | 190 | #define cra_blkcipher cra_u.blkcipher |
169 | #define cra_cipher cra_u.cipher | 191 | #define cra_cipher cra_u.cipher |
170 | #define cra_digest cra_u.digest | 192 | #define cra_digest cra_u.digest |
193 | #define cra_hash cra_u.hash | ||
171 | #define cra_compress cra_u.compress | 194 | #define cra_compress cra_u.compress |
172 | 195 | ||
173 | struct crypto_alg { | 196 | struct crypto_alg { |
@@ -191,6 +214,7 @@ struct crypto_alg { | |||
191 | struct blkcipher_alg blkcipher; | 214 | struct blkcipher_alg blkcipher; |
192 | struct cipher_alg cipher; | 215 | struct cipher_alg cipher; |
193 | struct digest_alg digest; | 216 | struct digest_alg digest; |
217 | struct hash_alg hash; | ||
194 | struct compress_alg compress; | 218 | struct compress_alg compress; |
195 | } cra_u; | 219 | } cra_u; |
196 | 220 | ||
@@ -262,18 +286,19 @@ struct cipher_tfm { | |||
262 | void (*cit_decrypt_one)(struct crypto_tfm *tfm, u8 *dst, const u8 *src); | 286 | void (*cit_decrypt_one)(struct crypto_tfm *tfm, u8 *dst, const u8 *src); |
263 | }; | 287 | }; |
264 | 288 | ||
265 | struct digest_tfm { | 289 | struct hash_tfm { |
266 | void (*dit_init)(struct crypto_tfm *tfm); | 290 | int (*init)(struct hash_desc *desc); |
267 | void (*dit_update)(struct crypto_tfm *tfm, | 291 | int (*update)(struct hash_desc *desc, |
268 | struct scatterlist *sg, unsigned int nsg); | 292 | struct scatterlist *sg, unsigned int nsg); |
269 | void (*dit_final)(struct crypto_tfm *tfm, u8 *out); | 293 | int (*final)(struct hash_desc *desc, u8 *out); |
270 | void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg, | 294 | int (*digest)(struct hash_desc *desc, struct scatterlist *sg, |
271 | unsigned int nsg, u8 *out); | 295 | unsigned int nsg, u8 *out); |
272 | int (*dit_setkey)(struct crypto_tfm *tfm, | 296 | int (*setkey)(struct crypto_hash *tfm, const u8 *key, |
273 | const u8 *key, unsigned int keylen); | 297 | unsigned int keylen); |
274 | #ifdef CONFIG_CRYPTO_HMAC | 298 | #ifdef CONFIG_CRYPTO_HMAC |
275 | void *dit_hmac_block; | 299 | void *hmac_block; |
276 | #endif | 300 | #endif |
301 | unsigned int digestsize; | ||
277 | }; | 302 | }; |
278 | 303 | ||
279 | struct compress_tfm { | 304 | struct compress_tfm { |
@@ -287,7 +312,7 @@ struct compress_tfm { | |||
287 | 312 | ||
288 | #define crt_blkcipher crt_u.blkcipher | 313 | #define crt_blkcipher crt_u.blkcipher |
289 | #define crt_cipher crt_u.cipher | 314 | #define crt_cipher crt_u.cipher |
290 | #define crt_digest crt_u.digest | 315 | #define crt_hash crt_u.hash |
291 | #define crt_compress crt_u.compress | 316 | #define crt_compress crt_u.compress |
292 | 317 | ||
293 | struct crypto_tfm { | 318 | struct crypto_tfm { |
@@ -297,7 +322,7 @@ struct crypto_tfm { | |||
297 | union { | 322 | union { |
298 | struct blkcipher_tfm blkcipher; | 323 | struct blkcipher_tfm blkcipher; |
299 | struct cipher_tfm cipher; | 324 | struct cipher_tfm cipher; |
300 | struct digest_tfm digest; | 325 | struct hash_tfm hash; |
301 | struct compress_tfm compress; | 326 | struct compress_tfm compress; |
302 | } crt_u; | 327 | } crt_u; |
303 | 328 | ||
@@ -312,6 +337,10 @@ struct crypto_blkcipher { | |||
312 | struct crypto_tfm base; | 337 | struct crypto_tfm base; |
313 | }; | 338 | }; |
314 | 339 | ||
340 | struct crypto_hash { | ||
341 | struct crypto_tfm base; | ||
342 | }; | ||
343 | |||
315 | enum { | 344 | enum { |
316 | CRYPTOA_UNSPEC, | 345 | CRYPTOA_UNSPEC, |
317 | CRYPTOA_ALG, | 346 | CRYPTOA_ALG, |
@@ -647,39 +676,114 @@ static inline void crypto_cipher_decrypt_one(struct crypto_cipher *tfm, | |||
647 | dst, src); | 676 | dst, src); |
648 | } | 677 | } |
649 | 678 | ||
650 | static inline void crypto_digest_init(struct crypto_tfm *tfm) | 679 | void crypto_digest_init(struct crypto_tfm *tfm); |
680 | void crypto_digest_update(struct crypto_tfm *tfm, | ||
681 | struct scatterlist *sg, unsigned int nsg); | ||
682 | void crypto_digest_final(struct crypto_tfm *tfm, u8 *out); | ||
683 | void crypto_digest_digest(struct crypto_tfm *tfm, | ||
684 | struct scatterlist *sg, unsigned int nsg, u8 *out); | ||
685 | |||
686 | static inline struct crypto_hash *__crypto_hash_cast(struct crypto_tfm *tfm) | ||
651 | { | 687 | { |
652 | BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); | 688 | return (struct crypto_hash *)tfm; |
653 | tfm->crt_digest.dit_init(tfm); | ||
654 | } | 689 | } |
655 | 690 | ||
656 | static inline void crypto_digest_update(struct crypto_tfm *tfm, | 691 | static inline struct crypto_hash *crypto_hash_cast(struct crypto_tfm *tfm) |
657 | struct scatterlist *sg, | ||
658 | unsigned int nsg) | ||
659 | { | 692 | { |
660 | BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); | 693 | BUG_ON((crypto_tfm_alg_type(tfm) ^ CRYPTO_ALG_TYPE_HASH) & |
661 | tfm->crt_digest.dit_update(tfm, sg, nsg); | 694 | CRYPTO_ALG_TYPE_HASH_MASK); |
695 | return __crypto_hash_cast(tfm); | ||
662 | } | 696 | } |
663 | 697 | ||
664 | static inline void crypto_digest_final(struct crypto_tfm *tfm, u8 *out) | 698 | static inline int crypto_digest_setkey(struct crypto_tfm *tfm, |
699 | const u8 *key, unsigned int keylen) | ||
665 | { | 700 | { |
666 | BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); | 701 | return tfm->crt_hash.setkey(crypto_hash_cast(tfm), key, keylen); |
667 | tfm->crt_digest.dit_final(tfm, out); | ||
668 | } | 702 | } |
669 | 703 | ||
670 | static inline void crypto_digest_digest(struct crypto_tfm *tfm, | 704 | static inline struct crypto_hash *crypto_alloc_hash(const char *alg_name, |
671 | struct scatterlist *sg, | 705 | u32 type, u32 mask) |
672 | unsigned int nsg, u8 *out) | ||
673 | { | 706 | { |
674 | BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); | 707 | type &= ~CRYPTO_ALG_TYPE_MASK; |
675 | tfm->crt_digest.dit_digest(tfm, sg, nsg, out); | 708 | type |= CRYPTO_ALG_TYPE_HASH; |
709 | mask |= CRYPTO_ALG_TYPE_HASH_MASK; | ||
710 | |||
711 | return __crypto_hash_cast(crypto_alloc_base(alg_name, type, mask)); | ||
676 | } | 712 | } |
677 | 713 | ||
678 | static inline int crypto_digest_setkey(struct crypto_tfm *tfm, | 714 | static inline struct crypto_tfm *crypto_hash_tfm(struct crypto_hash *tfm) |
679 | const u8 *key, unsigned int keylen) | ||
680 | { | 715 | { |
681 | BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); | 716 | return &tfm->base; |
682 | return tfm->crt_digest.dit_setkey(tfm, key, keylen); | 717 | } |
718 | |||
719 | static inline void crypto_free_hash(struct crypto_hash *tfm) | ||
720 | { | ||
721 | crypto_free_tfm(crypto_hash_tfm(tfm)); | ||
722 | } | ||
723 | |||
724 | static inline struct hash_tfm *crypto_hash_crt(struct crypto_hash *tfm) | ||
725 | { | ||
726 | return &crypto_hash_tfm(tfm)->crt_hash; | ||
727 | } | ||
728 | |||
729 | static inline unsigned int crypto_hash_blocksize(struct crypto_hash *tfm) | ||
730 | { | ||
731 | return crypto_tfm_alg_blocksize(crypto_hash_tfm(tfm)); | ||
732 | } | ||
733 | |||
734 | static inline unsigned int crypto_hash_alignmask(struct crypto_hash *tfm) | ||
735 | { | ||
736 | return crypto_tfm_alg_alignmask(crypto_hash_tfm(tfm)); | ||
737 | } | ||
738 | |||
739 | static inline unsigned int crypto_hash_digestsize(struct crypto_hash *tfm) | ||
740 | { | ||
741 | return crypto_hash_crt(tfm)->digestsize; | ||
742 | } | ||
743 | |||
744 | static inline u32 crypto_hash_get_flags(struct crypto_hash *tfm) | ||
745 | { | ||
746 | return crypto_tfm_get_flags(crypto_hash_tfm(tfm)); | ||
747 | } | ||
748 | |||
749 | static inline void crypto_hash_set_flags(struct crypto_hash *tfm, u32 flags) | ||
750 | { | ||
751 | crypto_tfm_set_flags(crypto_hash_tfm(tfm), flags); | ||
752 | } | ||
753 | |||
754 | static inline void crypto_hash_clear_flags(struct crypto_hash *tfm, u32 flags) | ||
755 | { | ||
756 | crypto_tfm_clear_flags(crypto_hash_tfm(tfm), flags); | ||
757 | } | ||
758 | |||
759 | static inline int crypto_hash_init(struct hash_desc *desc) | ||
760 | { | ||
761 | return crypto_hash_crt(desc->tfm)->init(desc); | ||
762 | } | ||
763 | |||
764 | static inline int crypto_hash_update(struct hash_desc *desc, | ||
765 | struct scatterlist *sg, | ||
766 | unsigned int nbytes) | ||
767 | { | ||
768 | return crypto_hash_crt(desc->tfm)->update(desc, sg, nbytes); | ||
769 | } | ||
770 | |||
771 | static inline int crypto_hash_final(struct hash_desc *desc, u8 *out) | ||
772 | { | ||
773 | return crypto_hash_crt(desc->tfm)->final(desc, out); | ||
774 | } | ||
775 | |||
776 | static inline int crypto_hash_digest(struct hash_desc *desc, | ||
777 | struct scatterlist *sg, | ||
778 | unsigned int nbytes, u8 *out) | ||
779 | { | ||
780 | return crypto_hash_crt(desc->tfm)->digest(desc, sg, nbytes, out); | ||
781 | } | ||
782 | |||
783 | static inline int crypto_hash_setkey(struct crypto_hash *hash, | ||
784 | const u8 *key, unsigned int keylen) | ||
785 | { | ||
786 | return crypto_hash_crt(hash)->setkey(hash, key, keylen); | ||
683 | } | 787 | } |
684 | 788 | ||
685 | static int crypto_cipher_encrypt(struct crypto_tfm *tfm, | 789 | static int crypto_cipher_encrypt(struct crypto_tfm *tfm, |