Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[CRYPTO] Update IV correctly for Padlock CBC encryption

When the Padlock does CBC encryption, the memory pointed to by EAX is
not updated at all. Instead, it updates the value of EAX by pointing
it to the last block in the output. Therefore to maintain the correct
semantics we need to copy the IV.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Herbert Xu and committed by
David S. Miller
476df259 915e8561

+9 -4
+9 -4
drivers/crypto/padlock-aes.c
··· 400 400 : "d"(control_word), "b"(key), "c"(count)); 401 401 } 402 402 403 - static inline void padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key, 404 - u8 *iv, void *control_word, u32 count) 403 + static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key, 404 + u8 *iv, void *control_word, u32 count) 405 405 { 406 406 /* Enforce key reload. */ 407 407 asm volatile ("pushfl; popfl"); ··· 409 409 asm volatile (".byte 0xf3,0x0f,0xa7,0xd0" 410 410 : "+S" (input), "+D" (output), "+a" (iv) 411 411 : "d" (control_word), "b" (key), "c" (count)); 412 + return iv; 412 413 } 413 414 414 415 static void ··· 448 447 const u8 *in, unsigned int nbytes) 449 448 { 450 449 struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm)); 451 - padlock_xcrypt_cbc(in, out, ctx->E, desc->info, &ctx->cword.encrypt, 452 - nbytes / AES_BLOCK_SIZE); 450 + u8 *iv; 451 + 452 + iv = padlock_xcrypt_cbc(in, out, ctx->E, desc->info, 453 + &ctx->cword.encrypt, nbytes / AES_BLOCK_SIZE); 454 + memcpy(desc->info, iv, AES_BLOCK_SIZE); 455 + 453 456 return nbytes & ~(AES_BLOCK_SIZE - 1); 454 457 } 455 458