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 | |
| 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')
| -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, |
