diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2005-07-06 16:53:47 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-07-06 16:53:47 -0400 |
commit | 915e8561d559abba1b81934e31e54a3f850fa7bf (patch) | |
tree | 12c08e7ec182ca11125097e2f485eab7a48b03df /crypto/cipher.c | |
parent | fbdae9f3e7fb57c07cb0d973f113eb25da2e8ff2 (diff) |
[CRYPTO] Handle unaligned iv from encrypt_iv/decrypt_iv
Even though cit_iv is now always aligned, the user can still supply an
unaligned iv through crypto_cipher_encrypt_iv/crypto_cipher_decrypt_iv.
This patch will check the alignment of the user-supplied iv and copy
it if necessary.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'crypto/cipher.c')
-rw-r--r-- | crypto/cipher.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/crypto/cipher.c b/crypto/cipher.c index d3295ce14a57..1c92c6bb138b 100644 --- a/crypto/cipher.c +++ b/crypto/cipher.c | |||
@@ -154,6 +154,31 @@ static int crypt(const struct cipher_desc *desc, | |||
154 | return 0; | 154 | return 0; |
155 | } | 155 | } |
156 | 156 | ||
157 | static int crypt_iv_unaligned(struct cipher_desc *desc, | ||
158 | struct scatterlist *dst, | ||
159 | struct scatterlist *src, | ||
160 | unsigned int nbytes) | ||
161 | { | ||
162 | struct crypto_tfm *tfm = desc->tfm; | ||
163 | unsigned int alignmask = crypto_tfm_alg_alignmask(tfm); | ||
164 | u8 *iv = desc->info; | ||
165 | |||
166 | if (unlikely(((unsigned long)iv & alignmask))) { | ||
167 | unsigned int ivsize = tfm->crt_cipher.cit_ivsize; | ||
168 | u8 buffer[ivsize + alignmask]; | ||
169 | u8 *tmp = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); | ||
170 | int err; | ||
171 | |||
172 | desc->info = memcpy(tmp, iv, ivsize); | ||
173 | err = crypt(desc, dst, src, nbytes); | ||
174 | memcpy(iv, tmp, ivsize); | ||
175 | |||
176 | return err; | ||
177 | } | ||
178 | |||
179 | return crypt(desc, dst, src, nbytes); | ||
180 | } | ||
181 | |||
157 | static unsigned int cbc_process_encrypt(const struct cipher_desc *desc, | 182 | static unsigned int cbc_process_encrypt(const struct cipher_desc *desc, |
158 | u8 *dst, const u8 *src, | 183 | u8 *dst, const u8 *src, |
159 | unsigned int nbytes) | 184 | unsigned int nbytes) |
@@ -298,7 +323,7 @@ static int cbc_encrypt_iv(struct crypto_tfm *tfm, | |||
298 | desc.prfn = cipher->cia_encrypt_cbc ?: cbc_process_encrypt; | 323 | desc.prfn = cipher->cia_encrypt_cbc ?: cbc_process_encrypt; |
299 | desc.info = iv; | 324 | desc.info = iv; |
300 | 325 | ||
301 | return crypt(&desc, dst, src, nbytes); | 326 | return crypt_iv_unaligned(&desc, dst, src, nbytes); |
302 | } | 327 | } |
303 | 328 | ||
304 | static int cbc_decrypt(struct crypto_tfm *tfm, | 329 | static int cbc_decrypt(struct crypto_tfm *tfm, |
@@ -330,7 +355,7 @@ static int cbc_decrypt_iv(struct crypto_tfm *tfm, | |||
330 | desc.prfn = cipher->cia_decrypt_cbc ?: cbc_process_decrypt; | 355 | desc.prfn = cipher->cia_decrypt_cbc ?: cbc_process_decrypt; |
331 | desc.info = iv; | 356 | desc.info = iv; |
332 | 357 | ||
333 | return crypt(&desc, dst, src, nbytes); | 358 | return crypt_iv_unaligned(&desc, dst, src, nbytes); |
334 | } | 359 | } |
335 | 360 | ||
336 | static int nocrypt(struct crypto_tfm *tfm, | 361 | static int nocrypt(struct crypto_tfm *tfm, |