aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/authenc.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/authenc.c')
-rw-r--r--crypto/authenc.c66
1 files changed, 28 insertions, 38 deletions
diff --git a/crypto/authenc.c b/crypto/authenc.c
index aa442dea5c43..394e73308e31 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -87,17 +87,18 @@ badkey:
87 goto out; 87 goto out;
88} 88}
89 89
90static int crypto_authenc_hash(struct aead_request *req) 90static u8 *crypto_authenc_hash(struct aead_request *req, unsigned int flags,
91 struct scatterlist *cipher,
92 unsigned int cryptlen)
91{ 93{
92 struct crypto_aead *authenc = crypto_aead_reqtfm(req); 94 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
93 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); 95 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
94 struct crypto_hash *auth = ctx->auth; 96 struct crypto_hash *auth = ctx->auth;
95 struct hash_desc desc = { 97 struct hash_desc desc = {
96 .tfm = auth, 98 .tfm = auth,
99 .flags = aead_request_flags(req) & flags,
97 }; 100 };
98 u8 *hash = aead_request_ctx(req); 101 u8 *hash = aead_request_ctx(req);
99 struct scatterlist *dst = req->dst;
100 unsigned int cryptlen = req->cryptlen;
101 int err; 102 int err;
102 103
103 hash = (u8 *)ALIGN((unsigned long)hash + crypto_hash_alignmask(auth), 104 hash = (u8 *)ALIGN((unsigned long)hash + crypto_hash_alignmask(auth),
@@ -112,7 +113,7 @@ static int crypto_authenc_hash(struct aead_request *req)
112 if (err) 113 if (err)
113 goto auth_unlock; 114 goto auth_unlock;
114 115
115 err = crypto_hash_update(&desc, dst, cryptlen); 116 err = crypto_hash_update(&desc, cipher, cryptlen);
116 if (err) 117 if (err)
117 goto auth_unlock; 118 goto auth_unlock;
118 119
@@ -121,7 +122,21 @@ auth_unlock:
121 spin_unlock_bh(&ctx->auth_lock); 122 spin_unlock_bh(&ctx->auth_lock);
122 123
123 if (err) 124 if (err)
124 return err; 125 return ERR_PTR(err);
126
127 return hash;
128}
129
130static int crypto_authenc_genicv(struct aead_request *req, unsigned int flags)
131{
132 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
133 struct scatterlist *dst = req->dst;
134 unsigned int cryptlen = req->cryptlen;
135 u8 *hash;
136
137 hash = crypto_authenc_hash(req, flags, dst, cryptlen);
138 if (IS_ERR(hash))
139 return PTR_ERR(hash);
125 140
126 scatterwalk_map_and_copy(hash, dst, cryptlen, 141 scatterwalk_map_and_copy(hash, dst, cryptlen,
127 crypto_aead_authsize(authenc), 1); 142 crypto_aead_authsize(authenc), 1);
@@ -132,7 +147,7 @@ static void crypto_authenc_encrypt_done(struct crypto_async_request *req,
132 int err) 147 int err)
133{ 148{
134 if (!err) 149 if (!err)
135 err = crypto_authenc_hash(req->data); 150 err = crypto_authenc_genicv(req->data, 0);
136 151
137 aead_request_complete(req->data, err); 152 aead_request_complete(req->data, err);
138} 153}
@@ -154,50 +169,25 @@ static int crypto_authenc_encrypt(struct aead_request *req)
154 if (err) 169 if (err)
155 return err; 170 return err;
156 171
157 return crypto_authenc_hash(req); 172 return crypto_authenc_genicv(req, CRYPTO_TFM_REQ_MAY_SLEEP);
158} 173}
159 174
160static int crypto_authenc_verify(struct aead_request *req, 175static int crypto_authenc_verify(struct aead_request *req,
161 unsigned int cryptlen) 176 unsigned int cryptlen)
162{ 177{
163 struct crypto_aead *authenc = crypto_aead_reqtfm(req); 178 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
164 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); 179 u8 *ohash;
165 struct crypto_hash *auth = ctx->auth;
166 struct hash_desc desc = {
167 .tfm = auth,
168 .flags = aead_request_flags(req),
169 };
170 u8 *ohash = aead_request_ctx(req);
171 u8 *ihash; 180 u8 *ihash;
172 struct scatterlist *src = req->src; 181 struct scatterlist *src = req->src;
173 unsigned int authsize; 182 unsigned int authsize;
174 int err;
175 183
176 ohash = (u8 *)ALIGN((unsigned long)ohash + crypto_hash_alignmask(auth), 184 ohash = crypto_authenc_hash(req, CRYPTO_TFM_REQ_MAY_SLEEP, src,
177 crypto_hash_alignmask(auth) + 1); 185 cryptlen);
178 ihash = ohash + crypto_hash_digestsize(auth); 186 if (IS_ERR(ohash))
179 187 return PTR_ERR(ohash);
180 spin_lock_bh(&ctx->auth_lock);
181 err = crypto_hash_init(&desc);
182 if (err)
183 goto auth_unlock;
184
185 err = crypto_hash_update(&desc, req->assoc, req->assoclen);
186 if (err)
187 goto auth_unlock;
188
189 err = crypto_hash_update(&desc, src, cryptlen);
190 if (err)
191 goto auth_unlock;
192
193 err = crypto_hash_final(&desc, ohash);
194auth_unlock:
195 spin_unlock_bh(&ctx->auth_lock);
196
197 if (err)
198 return err;
199 188
200 authsize = crypto_aead_authsize(authenc); 189 authsize = crypto_aead_authsize(authenc);
190 ihash = ohash + authsize;
201 scatterwalk_map_and_copy(ihash, src, cryptlen, authsize, 0); 191 scatterwalk_map_and_copy(ihash, src, cryptlen, authsize, 0);
202 return memcmp(ihash, ohash, authsize) ? -EBADMSG: 0; 192 return memcmp(ihash, ohash, authsize) ? -EBADMSG: 0;
203} 193}