diff options
| author | Herbert Xu <herbert@gondor.apana.org.au> | 2007-12-10 03:15:41 -0500 |
|---|---|---|
| committer | Herbert Xu <herbert@gondor.apana.org.au> | 2008-01-10 16:16:38 -0500 |
| commit | 7c3d703fa81db42f9766325cebd6bfc1c5eac838 (patch) | |
| tree | 1f18f35a20dd1ca32d3a436f21c189a0868bb242 /crypto | |
| parent | 12dc5e62b4f93f1d399fd81e35be3f9ea0027712 (diff) | |
[CRYPTO] authenc: Merge common hashing code
This patch merges the common hashing code between encryption and decryption.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
| -rw-r--r-- | crypto/authenc.c | 66 |
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 | ||
| 90 | static int crypto_authenc_hash(struct aead_request *req) | 90 | static 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 | |||
| 130 | static 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 | ||
| 160 | static int crypto_authenc_verify(struct aead_request *req, | 175 | static 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); | ||
| 194 | auth_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 | } |
