aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/authenc.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/authenc.c')
-rw-r--r--crypto/authenc.c61
1 files changed, 37 insertions, 24 deletions
diff --git a/crypto/authenc.c b/crypto/authenc.c
index ffce19de05cf..e1223559d5df 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -52,40 +52,52 @@ static void authenc_request_complete(struct aead_request *req, int err)
52 aead_request_complete(req, err); 52 aead_request_complete(req, err);
53} 53}
54 54
55static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key, 55int crypto_authenc_extractkeys(struct crypto_authenc_keys *keys, const u8 *key,
56 unsigned int keylen) 56 unsigned int keylen)
57{ 57{
58 unsigned int authkeylen; 58 struct rtattr *rta = (struct rtattr *)key;
59 unsigned int enckeylen;
60 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
61 struct crypto_ahash *auth = ctx->auth;
62 struct crypto_ablkcipher *enc = ctx->enc;
63 struct rtattr *rta = (void *)key;
64 struct crypto_authenc_key_param *param; 59 struct crypto_authenc_key_param *param;
65 int err = -EINVAL;
66 60
67 if (!RTA_OK(rta, keylen)) 61 if (!RTA_OK(rta, keylen))
68 goto badkey; 62 return -EINVAL;
69 if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM) 63 if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
70 goto badkey; 64 return -EINVAL;
71 if (RTA_PAYLOAD(rta) < sizeof(*param)) 65 if (RTA_PAYLOAD(rta) < sizeof(*param))
72 goto badkey; 66 return -EINVAL;
73 67
74 param = RTA_DATA(rta); 68 param = RTA_DATA(rta);
75 enckeylen = be32_to_cpu(param->enckeylen); 69 keys->enckeylen = be32_to_cpu(param->enckeylen);
76 70
77 key += RTA_ALIGN(rta->rta_len); 71 key += RTA_ALIGN(rta->rta_len);
78 keylen -= RTA_ALIGN(rta->rta_len); 72 keylen -= RTA_ALIGN(rta->rta_len);
79 73
80 if (keylen < enckeylen) 74 if (keylen < keys->enckeylen)
81 goto badkey; 75 return -EINVAL;
82 76
83 authkeylen = keylen - enckeylen; 77 keys->authkeylen = keylen - keys->enckeylen;
78 keys->authkey = key;
79 keys->enckey = key + keys->authkeylen;
80
81 return 0;
82}
83EXPORT_SYMBOL_GPL(crypto_authenc_extractkeys);
84
85static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key,
86 unsigned int keylen)
87{
88 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
89 struct crypto_ahash *auth = ctx->auth;
90 struct crypto_ablkcipher *enc = ctx->enc;
91 struct crypto_authenc_keys keys;
92 int err = -EINVAL;
93
94 if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
95 goto badkey;
84 96
85 crypto_ahash_clear_flags(auth, CRYPTO_TFM_REQ_MASK); 97 crypto_ahash_clear_flags(auth, CRYPTO_TFM_REQ_MASK);
86 crypto_ahash_set_flags(auth, crypto_aead_get_flags(authenc) & 98 crypto_ahash_set_flags(auth, crypto_aead_get_flags(authenc) &
87 CRYPTO_TFM_REQ_MASK); 99 CRYPTO_TFM_REQ_MASK);
88 err = crypto_ahash_setkey(auth, key, authkeylen); 100 err = crypto_ahash_setkey(auth, keys.authkey, keys.authkeylen);
89 crypto_aead_set_flags(authenc, crypto_ahash_get_flags(auth) & 101 crypto_aead_set_flags(authenc, crypto_ahash_get_flags(auth) &
90 CRYPTO_TFM_RES_MASK); 102 CRYPTO_TFM_RES_MASK);
91 103
@@ -95,7 +107,7 @@ static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key,
95 crypto_ablkcipher_clear_flags(enc, CRYPTO_TFM_REQ_MASK); 107 crypto_ablkcipher_clear_flags(enc, CRYPTO_TFM_REQ_MASK);
96 crypto_ablkcipher_set_flags(enc, crypto_aead_get_flags(authenc) & 108 crypto_ablkcipher_set_flags(enc, crypto_aead_get_flags(authenc) &
97 CRYPTO_TFM_REQ_MASK); 109 CRYPTO_TFM_REQ_MASK);
98 err = crypto_ablkcipher_setkey(enc, key + authkeylen, enckeylen); 110 err = crypto_ablkcipher_setkey(enc, keys.enckey, keys.enckeylen);
99 crypto_aead_set_flags(authenc, crypto_ablkcipher_get_flags(enc) & 111 crypto_aead_set_flags(authenc, crypto_ablkcipher_get_flags(enc) &
100 CRYPTO_TFM_RES_MASK); 112 CRYPTO_TFM_RES_MASK);
101 113
@@ -188,7 +200,7 @@ static void authenc_verify_ahash_update_done(struct crypto_async_request *areq,
188 scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen, 200 scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
189 authsize, 0); 201 authsize, 0);
190 202
191 err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0; 203 err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
192 if (err) 204 if (err)
193 goto out; 205 goto out;
194 206
@@ -227,7 +239,7 @@ static void authenc_verify_ahash_done(struct crypto_async_request *areq,
227 scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen, 239 scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
228 authsize, 0); 240 authsize, 0);
229 241
230 err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0; 242 err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
231 if (err) 243 if (err)
232 goto out; 244 goto out;
233 245
@@ -368,9 +380,10 @@ static void crypto_authenc_encrypt_done(struct crypto_async_request *req,
368 if (!err) { 380 if (!err) {
369 struct crypto_aead *authenc = crypto_aead_reqtfm(areq); 381 struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
370 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); 382 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
371 struct ablkcipher_request *abreq = aead_request_ctx(areq); 383 struct authenc_request_ctx *areq_ctx = aead_request_ctx(areq);
372 u8 *iv = (u8 *)(abreq + 1) + 384 struct ablkcipher_request *abreq = (void *)(areq_ctx->tail
373 crypto_ablkcipher_reqsize(ctx->enc); 385 + ctx->reqoff);
386 u8 *iv = (u8 *)abreq - crypto_ablkcipher_ivsize(ctx->enc);
374 387
375 err = crypto_authenc_genicv(areq, iv, 0); 388 err = crypto_authenc_genicv(areq, iv, 0);
376 } 389 }
@@ -462,7 +475,7 @@ static int crypto_authenc_verify(struct aead_request *req,
462 ihash = ohash + authsize; 475 ihash = ohash + authsize;
463 scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen, 476 scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
464 authsize, 0); 477 authsize, 0);
465 return memcmp(ihash, ohash, authsize) ? -EBADMSG : 0; 478 return crypto_memneq(ihash, ohash, authsize) ? -EBADMSG : 0;
466} 479}
467 480
468static int crypto_authenc_iverify(struct aead_request *req, u8 *iv, 481static int crypto_authenc_iverify(struct aead_request *req, u8 *iv,