summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'crypto')
-rw-r--r--crypto/aead.c58
1 files changed, 56 insertions, 2 deletions
diff --git a/crypto/aead.c b/crypto/aead.c
index 717b2f6ec9bb..c2bf3b313354 100644
--- a/crypto/aead.c
+++ b/crypto/aead.c
@@ -13,6 +13,7 @@
13 */ 13 */
14 14
15#include <crypto/internal/aead.h> 15#include <crypto/internal/aead.h>
16#include <crypto/scatterwalk.h>
16#include <linux/err.h> 17#include <linux/err.h>
17#include <linux/init.h> 18#include <linux/init.h>
18#include <linux/kernel.h> 19#include <linux/kernel.h>
@@ -85,6 +86,59 @@ int crypto_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize)
85} 86}
86EXPORT_SYMBOL_GPL(crypto_aead_setauthsize); 87EXPORT_SYMBOL_GPL(crypto_aead_setauthsize);
87 88
89struct aead_old_request {
90 struct scatterlist srcbuf[2];
91 struct scatterlist dstbuf[2];
92 struct aead_request subreq;
93};
94
95unsigned int crypto_aead_reqsize(struct crypto_aead *tfm)
96{
97 return tfm->reqsize + sizeof(struct aead_old_request);
98}
99EXPORT_SYMBOL_GPL(crypto_aead_reqsize);
100
101static int old_crypt(struct aead_request *req,
102 int (*crypt)(struct aead_request *req))
103{
104 struct aead_old_request *nreq = aead_request_ctx(req);
105 struct crypto_aead *aead = crypto_aead_reqtfm(req);
106 struct scatterlist *src, *dst;
107
108 if (req->old)
109 return crypt(req);
110
111 src = scatterwalk_ffwd(nreq->srcbuf, req->src,
112 req->assoclen + req->cryptoff);
113 dst = scatterwalk_ffwd(nreq->dstbuf, req->dst,
114 req->assoclen + req->cryptoff);
115
116 aead_request_set_tfm(&nreq->subreq, aead);
117 aead_request_set_callback(&nreq->subreq, aead_request_flags(req),
118 req->base.complete, req->base.data);
119 aead_request_set_crypt(&nreq->subreq, src, dst, req->cryptlen,
120 req->iv);
121 aead_request_set_assoc(&nreq->subreq, req->src, req->assoclen);
122
123 return crypt(&nreq->subreq);
124}
125
126static int old_encrypt(struct aead_request *req)
127{
128 struct crypto_aead *aead = crypto_aead_reqtfm(req);
129 struct aead_alg *alg = crypto_aead_alg(aead);
130
131 return old_crypt(req, alg->encrypt);
132}
133
134static int old_decrypt(struct aead_request *req)
135{
136 struct crypto_aead *aead = crypto_aead_reqtfm(req);
137 struct aead_alg *alg = crypto_aead_alg(aead);
138
139 return old_crypt(req, alg->decrypt);
140}
141
88static int no_givcrypt(struct aead_givcrypt_request *req) 142static int no_givcrypt(struct aead_givcrypt_request *req)
89{ 143{
90 return -ENOSYS; 144 return -ENOSYS;
@@ -98,8 +152,8 @@ static int crypto_aead_init_tfm(struct crypto_tfm *tfm)
98 if (max(alg->maxauthsize, alg->ivsize) > PAGE_SIZE / 8) 152 if (max(alg->maxauthsize, alg->ivsize) > PAGE_SIZE / 8)
99 return -EINVAL; 153 return -EINVAL;
100 154
101 crt->encrypt = alg->encrypt; 155 crt->encrypt = old_encrypt;
102 crt->decrypt = alg->decrypt; 156 crt->decrypt = old_decrypt;
103 if (alg->ivsize) { 157 if (alg->ivsize) {
104 crt->givencrypt = alg->givencrypt ?: no_givcrypt; 158 crt->givencrypt = alg->givencrypt ?: no_givcrypt;
105 crt->givdecrypt = alg->givdecrypt ?: no_givcrypt; 159 crt->givdecrypt = alg->givdecrypt ?: no_givcrypt;