aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/Kconfig4
-rw-r--r--crypto/Makefile1
-rw-r--r--crypto/aead.c101
-rw-r--r--include/crypto/algapi.h6
-rw-r--r--include/linux/crypto.h200
5 files changed, 312 insertions, 0 deletions
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 981497c89752..f42bc7715f48 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -28,6 +28,10 @@ config CRYPTO_ABLKCIPHER
28 tristate 28 tristate
29 select CRYPTO_BLKCIPHER 29 select CRYPTO_BLKCIPHER
30 30
31config CRYPTO_AEAD
32 tristate
33 select CRYPTO_ALGAPI
34
31config CRYPTO_BLKCIPHER 35config CRYPTO_BLKCIPHER
32 tristate 36 tristate
33 select CRYPTO_ALGAPI 37 select CRYPTO_ALGAPI
diff --git a/crypto/Makefile b/crypto/Makefile
index a070dcc074ff..9821c5ba054e 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -9,6 +9,7 @@ crypto_algapi-objs := algapi.o $(crypto_algapi-y)
9obj-$(CONFIG_CRYPTO_ALGAPI) += crypto_algapi.o 9obj-$(CONFIG_CRYPTO_ALGAPI) += crypto_algapi.o
10 10
11obj-$(CONFIG_CRYPTO_ABLKCIPHER) += ablkcipher.o 11obj-$(CONFIG_CRYPTO_ABLKCIPHER) += ablkcipher.o
12obj-$(CONFIG_CRYPTO_AEAD) += aead.o
12obj-$(CONFIG_CRYPTO_BLKCIPHER) += blkcipher.o 13obj-$(CONFIG_CRYPTO_BLKCIPHER) += blkcipher.o
13 14
14crypto_hash-objs := hash.o 15crypto_hash-objs := hash.o
diff --git a/crypto/aead.c b/crypto/aead.c
new file mode 100644
index 000000000000..84a3501fb478
--- /dev/null
+++ b/crypto/aead.c
@@ -0,0 +1,101 @@
1/*
2 * AEAD: Authenticated Encryption with Associated Data
3 *
4 * This file provides API support for AEAD algorithms.
5 *
6 * Copyright (c) 2007 Herbert Xu <herbert@gondor.apana.org.au>
7 *
8 * 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 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 */
14
15#include <crypto/algapi.h>
16#include <linux/errno.h>
17#include <linux/init.h>
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/slab.h>
21#include <linux/seq_file.h>
22
23static int setkey_unaligned(struct crypto_aead *tfm, const u8 *key,
24 unsigned int keylen)
25{
26 struct aead_alg *aead = crypto_aead_alg(tfm);
27 unsigned long alignmask = crypto_aead_alignmask(tfm);
28 int ret;
29 u8 *buffer, *alignbuffer;
30 unsigned long absize;
31
32 absize = keylen + alignmask;
33 buffer = kmalloc(absize, GFP_ATOMIC);
34 if (!buffer)
35 return -ENOMEM;
36
37 alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
38 memcpy(alignbuffer, key, keylen);
39 ret = aead->setkey(tfm, alignbuffer, keylen);
40 memset(alignbuffer, 0, keylen);
41 kfree(buffer);
42 return ret;
43}
44
45static int setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen)
46{
47 struct aead_alg *aead = crypto_aead_alg(tfm);
48 unsigned long alignmask = crypto_aead_alignmask(tfm);
49
50 if ((unsigned long)key & alignmask)
51 return setkey_unaligned(tfm, key, keylen);
52
53 return aead->setkey(tfm, key, keylen);
54}
55
56static unsigned int crypto_aead_ctxsize(struct crypto_alg *alg, u32 type,
57 u32 mask)
58{
59 return alg->cra_ctxsize;
60}
61
62static int crypto_init_aead_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
63{
64 struct aead_alg *alg = &tfm->__crt_alg->cra_aead;
65 struct aead_tfm *crt = &tfm->crt_aead;
66
67 if (max(alg->authsize, alg->ivsize) > PAGE_SIZE / 8)
68 return -EINVAL;
69
70 crt->setkey = setkey;
71 crt->encrypt = alg->encrypt;
72 crt->decrypt = alg->decrypt;
73 crt->ivsize = alg->ivsize;
74 crt->authsize = alg->authsize;
75
76 return 0;
77}
78
79static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg)
80 __attribute__ ((unused));
81static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg)
82{
83 struct aead_alg *aead = &alg->cra_aead;
84
85 seq_printf(m, "type : aead\n");
86 seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
87 seq_printf(m, "ivsize : %u\n", aead->ivsize);
88 seq_printf(m, "authsize : %u\n", aead->authsize);
89}
90
91const struct crypto_type crypto_aead_type = {
92 .ctxsize = crypto_aead_ctxsize,
93 .init = crypto_init_aead_ops,
94#ifdef CONFIG_PROC_FS
95 .show = crypto_aead_show,
96#endif
97};
98EXPORT_SYMBOL_GPL(crypto_aead_type);
99
100MODULE_LICENSE("GPL");
101MODULE_DESCRIPTION("Authenticated Encryption with Associated Data (AEAD)");
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h
index 8081294e4328..290bce0c5bd5 100644
--- a/include/crypto/algapi.h
+++ b/include/crypto/algapi.h
@@ -94,6 +94,7 @@ struct blkcipher_walk {
94}; 94};
95 95
96extern const struct crypto_type crypto_ablkcipher_type; 96extern const struct crypto_type crypto_ablkcipher_type;
97extern const struct crypto_type crypto_aead_type;
97extern const struct crypto_type crypto_blkcipher_type; 98extern const struct crypto_type crypto_blkcipher_type;
98extern const struct crypto_type crypto_hash_type; 99extern const struct crypto_type crypto_hash_type;
99 100
@@ -165,6 +166,11 @@ static inline void *crypto_ablkcipher_ctx_aligned(struct crypto_ablkcipher *tfm)
165 return crypto_tfm_ctx_aligned(&tfm->base); 166 return crypto_tfm_ctx_aligned(&tfm->base);
166} 167}
167 168
169static inline struct aead_alg *crypto_aead_alg(struct crypto_aead *tfm)
170{
171 return &crypto_aead_tfm(tfm)->__crt_alg->cra_aead;
172}
173
168static inline struct crypto_blkcipher *crypto_spawn_blkcipher( 174static inline struct crypto_blkcipher *crypto_spawn_blkcipher(
169 struct crypto_spawn *spawn) 175 struct crypto_spawn *spawn)
170{ 176{
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 357e8cfedc37..1072f9abaef6 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -34,6 +34,7 @@
34#define CRYPTO_ALG_TYPE_HASH 0x00000003 34#define CRYPTO_ALG_TYPE_HASH 0x00000003
35#define CRYPTO_ALG_TYPE_BLKCIPHER 0x00000004 35#define CRYPTO_ALG_TYPE_BLKCIPHER 0x00000004
36#define CRYPTO_ALG_TYPE_COMPRESS 0x00000005 36#define CRYPTO_ALG_TYPE_COMPRESS 0x00000005
37#define CRYPTO_ALG_TYPE_AEAD 0x00000006
37 38
38#define CRYPTO_ALG_TYPE_HASH_MASK 0x0000000e 39#define CRYPTO_ALG_TYPE_HASH_MASK 0x0000000e
39 40
@@ -91,6 +92,7 @@
91struct scatterlist; 92struct scatterlist;
92struct crypto_ablkcipher; 93struct crypto_ablkcipher;
93struct crypto_async_request; 94struct crypto_async_request;
95struct crypto_aead;
94struct crypto_blkcipher; 96struct crypto_blkcipher;
95struct crypto_hash; 97struct crypto_hash;
96struct crypto_queue; 98struct crypto_queue;
@@ -121,6 +123,32 @@ struct ablkcipher_request {
121 void *__ctx[] CRYPTO_MINALIGN_ATTR; 123 void *__ctx[] CRYPTO_MINALIGN_ATTR;
122}; 124};
123 125
126/**
127 * struct aead_request - AEAD request
128 * @base: Common attributes for async crypto requests
129 * @assoclen: Length in bytes of associated data for authentication
130 * @cryptlen: Length of data to be encrypted or decrypted
131 * @iv: Initialisation vector
132 * @assoc: Associated data
133 * @src: Source data
134 * @dst: Destination data
135 * @__ctx: Start of private context data
136 */
137struct aead_request {
138 struct crypto_async_request base;
139
140 unsigned int assoclen;
141 unsigned int cryptlen;
142
143 u8 *iv;
144
145 struct scatterlist *assoc;
146 struct scatterlist *src;
147 struct scatterlist *dst;
148
149 void *__ctx[] CRYPTO_MINALIGN_ATTR;
150};
151
124struct blkcipher_desc { 152struct blkcipher_desc {
125 struct crypto_blkcipher *tfm; 153 struct crypto_blkcipher *tfm;
126 void *info; 154 void *info;
@@ -157,6 +185,16 @@ struct ablkcipher_alg {
157 unsigned int ivsize; 185 unsigned int ivsize;
158}; 186};
159 187
188struct aead_alg {
189 int (*setkey)(struct crypto_aead *tfm, const u8 *key,
190 unsigned int keylen);
191 int (*encrypt)(struct aead_request *req);
192 int (*decrypt)(struct aead_request *req);
193
194 unsigned int ivsize;
195 unsigned int authsize;
196};
197
160struct blkcipher_alg { 198struct blkcipher_alg {
161 int (*setkey)(struct crypto_tfm *tfm, const u8 *key, 199 int (*setkey)(struct crypto_tfm *tfm, const u8 *key,
162 unsigned int keylen); 200 unsigned int keylen);
@@ -212,6 +250,7 @@ struct compress_alg {
212}; 250};
213 251
214#define cra_ablkcipher cra_u.ablkcipher 252#define cra_ablkcipher cra_u.ablkcipher
253#define cra_aead cra_u.aead
215#define cra_blkcipher cra_u.blkcipher 254#define cra_blkcipher cra_u.blkcipher
216#define cra_cipher cra_u.cipher 255#define cra_cipher cra_u.cipher
217#define cra_digest cra_u.digest 256#define cra_digest cra_u.digest
@@ -237,6 +276,7 @@ struct crypto_alg {
237 276
238 union { 277 union {
239 struct ablkcipher_alg ablkcipher; 278 struct ablkcipher_alg ablkcipher;
279 struct aead_alg aead;
240 struct blkcipher_alg blkcipher; 280 struct blkcipher_alg blkcipher;
241 struct cipher_alg cipher; 281 struct cipher_alg cipher;
242 struct digest_alg digest; 282 struct digest_alg digest;
@@ -284,6 +324,16 @@ struct ablkcipher_tfm {
284 unsigned int reqsize; 324 unsigned int reqsize;
285}; 325};
286 326
327struct aead_tfm {
328 int (*setkey)(struct crypto_aead *tfm, const u8 *key,
329 unsigned int keylen);
330 int (*encrypt)(struct aead_request *req);
331 int (*decrypt)(struct aead_request *req);
332 unsigned int ivsize;
333 unsigned int authsize;
334 unsigned int reqsize;
335};
336
287struct blkcipher_tfm { 337struct blkcipher_tfm {
288 void *iv; 338 void *iv;
289 int (*setkey)(struct crypto_tfm *tfm, const u8 *key, 339 int (*setkey)(struct crypto_tfm *tfm, const u8 *key,
@@ -323,6 +373,7 @@ struct compress_tfm {
323}; 373};
324 374
325#define crt_ablkcipher crt_u.ablkcipher 375#define crt_ablkcipher crt_u.ablkcipher
376#define crt_aead crt_u.aead
326#define crt_blkcipher crt_u.blkcipher 377#define crt_blkcipher crt_u.blkcipher
327#define crt_cipher crt_u.cipher 378#define crt_cipher crt_u.cipher
328#define crt_hash crt_u.hash 379#define crt_hash crt_u.hash
@@ -334,6 +385,7 @@ struct crypto_tfm {
334 385
335 union { 386 union {
336 struct ablkcipher_tfm ablkcipher; 387 struct ablkcipher_tfm ablkcipher;
388 struct aead_tfm aead;
337 struct blkcipher_tfm blkcipher; 389 struct blkcipher_tfm blkcipher;
338 struct cipher_tfm cipher; 390 struct cipher_tfm cipher;
339 struct hash_tfm hash; 391 struct hash_tfm hash;
@@ -349,6 +401,10 @@ struct crypto_ablkcipher {
349 struct crypto_tfm base; 401 struct crypto_tfm base;
350}; 402};
351 403
404struct crypto_aead {
405 struct crypto_tfm base;
406};
407
352struct crypto_blkcipher { 408struct crypto_blkcipher {
353 struct crypto_tfm base; 409 struct crypto_tfm base;
354}; 410};
@@ -619,6 +675,150 @@ static inline void ablkcipher_request_set_crypt(
619 req->info = iv; 675 req->info = iv;
620} 676}
621 677
678static inline struct crypto_aead *__crypto_aead_cast(struct crypto_tfm *tfm)
679{
680 return (struct crypto_aead *)tfm;
681}
682
683static inline struct crypto_aead *crypto_alloc_aead(const char *alg_name,
684 u32 type, u32 mask)
685{
686 type &= ~CRYPTO_ALG_TYPE_MASK;
687 type |= CRYPTO_ALG_TYPE_AEAD;
688 mask |= CRYPTO_ALG_TYPE_MASK;
689
690 return __crypto_aead_cast(crypto_alloc_base(alg_name, type, mask));
691}
692
693static inline struct crypto_tfm *crypto_aead_tfm(struct crypto_aead *tfm)
694{
695 return &tfm->base;
696}
697
698static inline void crypto_free_aead(struct crypto_aead *tfm)
699{
700 crypto_free_tfm(crypto_aead_tfm(tfm));
701}
702
703static inline struct aead_tfm *crypto_aead_crt(struct crypto_aead *tfm)
704{
705 return &crypto_aead_tfm(tfm)->crt_aead;
706}
707
708static inline unsigned int crypto_aead_ivsize(struct crypto_aead *tfm)
709{
710 return crypto_aead_crt(tfm)->ivsize;
711}
712
713static inline unsigned int crypto_aead_authsize(struct crypto_aead *tfm)
714{
715 return crypto_aead_crt(tfm)->authsize;
716}
717
718static inline unsigned int crypto_aead_blocksize(struct crypto_aead *tfm)
719{
720 return crypto_tfm_alg_blocksize(crypto_aead_tfm(tfm));
721}
722
723static inline unsigned int crypto_aead_alignmask(struct crypto_aead *tfm)
724{
725 return crypto_tfm_alg_alignmask(crypto_aead_tfm(tfm));
726}
727
728static inline u32 crypto_aead_get_flags(struct crypto_aead *tfm)
729{
730 return crypto_tfm_get_flags(crypto_aead_tfm(tfm));
731}
732
733static inline void crypto_aead_set_flags(struct crypto_aead *tfm, u32 flags)
734{
735 crypto_tfm_set_flags(crypto_aead_tfm(tfm), flags);
736}
737
738static inline void crypto_aead_clear_flags(struct crypto_aead *tfm, u32 flags)
739{
740 crypto_tfm_clear_flags(crypto_aead_tfm(tfm), flags);
741}
742
743static inline int crypto_aead_setkey(struct crypto_aead *tfm, const u8 *key,
744 unsigned int keylen)
745{
746 return crypto_aead_crt(tfm)->setkey(tfm, key, keylen);
747}
748
749static inline struct crypto_aead *crypto_aead_reqtfm(struct aead_request *req)
750{
751 return __crypto_aead_cast(req->base.tfm);
752}
753
754static inline int crypto_aead_encrypt(struct aead_request *req)
755{
756 return crypto_aead_crt(crypto_aead_reqtfm(req))->encrypt(req);
757}
758
759static inline int crypto_aead_decrypt(struct aead_request *req)
760{
761 return crypto_aead_crt(crypto_aead_reqtfm(req))->decrypt(req);
762}
763
764static inline int crypto_aead_reqsize(struct crypto_aead *tfm)
765{
766 return crypto_aead_crt(tfm)->reqsize;
767}
768
769static inline void aead_request_set_tfm(struct aead_request *req,
770 struct crypto_aead *tfm)
771{
772 req->base.tfm = crypto_aead_tfm(tfm);
773}
774
775static inline struct aead_request *aead_request_alloc(struct crypto_aead *tfm,
776 gfp_t gfp)
777{
778 struct aead_request *req;
779
780 req = kmalloc(sizeof(*req) + crypto_aead_reqsize(tfm), gfp);
781
782 if (likely(req))
783 aead_request_set_tfm(req, tfm);
784
785 return req;
786}
787
788static inline void aead_request_free(struct aead_request *req)
789{
790 kfree(req);
791}
792
793static inline void aead_request_set_callback(struct aead_request *req,
794 u32 flags,
795 crypto_completion_t complete,
796 void *data)
797{
798 req->base.complete = complete;
799 req->base.data = data;
800 req->base.flags = flags;
801}
802
803static inline void aead_request_set_crypt(struct aead_request *req,
804 struct scatterlist *src,
805 struct scatterlist *dst,
806 unsigned int cryptlen, u8 *iv)
807{
808 req->src = src;
809 req->dst = dst;
810 req->cryptlen = cryptlen;
811 req->iv = iv;
812}
813
814static inline void aead_request_set_assoc(struct aead_request *req,
815 struct scatterlist *assoc,
816 unsigned int assoclen)
817{
818 req->assoc = assoc;
819 req->assoclen = assoclen;
820}
821
622static inline struct crypto_blkcipher *__crypto_blkcipher_cast( 822static inline struct crypto_blkcipher *__crypto_blkcipher_cast(
623 struct crypto_tfm *tfm) 823 struct crypto_tfm *tfm)
624{ 824{