diff options
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/aead.c | 58 |
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 | } |
86 | EXPORT_SYMBOL_GPL(crypto_aead_setauthsize); | 87 | EXPORT_SYMBOL_GPL(crypto_aead_setauthsize); |
87 | 88 | ||
89 | struct aead_old_request { | ||
90 | struct scatterlist srcbuf[2]; | ||
91 | struct scatterlist dstbuf[2]; | ||
92 | struct aead_request subreq; | ||
93 | }; | ||
94 | |||
95 | unsigned int crypto_aead_reqsize(struct crypto_aead *tfm) | ||
96 | { | ||
97 | return tfm->reqsize + sizeof(struct aead_old_request); | ||
98 | } | ||
99 | EXPORT_SYMBOL_GPL(crypto_aead_reqsize); | ||
100 | |||
101 | static 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 | |||
126 | static 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 | |||
134 | static 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 | |||
88 | static int no_givcrypt(struct aead_givcrypt_request *req) | 142 | static 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; |