Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 915e8561 authored by Herbert Xu's avatar Herbert Xu Committed by David S. Miller
Browse files

[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: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent fbdae9f3
Loading
Loading
Loading
Loading
+27 −2
Original line number Diff line number Diff line
@@ -154,6 +154,31 @@ static int crypt(const struct cipher_desc *desc,
	return 0;
}

static int crypt_iv_unaligned(struct cipher_desc *desc,
			      struct scatterlist *dst,
			      struct scatterlist *src,
			      unsigned int nbytes)
{
	struct crypto_tfm *tfm = desc->tfm;
	unsigned int alignmask = crypto_tfm_alg_alignmask(tfm);
	u8 *iv = desc->info;

	if (unlikely(((unsigned long)iv & alignmask))) {
		unsigned int ivsize = tfm->crt_cipher.cit_ivsize;
		u8 buffer[ivsize + alignmask];
		u8 *tmp = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
		int err;

		desc->info = memcpy(tmp, iv, ivsize);
		err = crypt(desc, dst, src, nbytes);
		memcpy(iv, tmp, ivsize);

		return err;
	}

	return crypt(desc, dst, src, nbytes);
}

static unsigned int cbc_process_encrypt(const struct cipher_desc *desc,
					u8 *dst, const u8 *src,
					unsigned int nbytes)
@@ -298,7 +323,7 @@ static int cbc_encrypt_iv(struct crypto_tfm *tfm,
	desc.prfn = cipher->cia_encrypt_cbc ?: cbc_process_encrypt;
	desc.info = iv;

	return crypt(&desc, dst, src, nbytes);
	return crypt_iv_unaligned(&desc, dst, src, nbytes);
}

static int cbc_decrypt(struct crypto_tfm *tfm,
@@ -330,7 +355,7 @@ static int cbc_decrypt_iv(struct crypto_tfm *tfm,
	desc.prfn = cipher->cia_decrypt_cbc ?: cbc_process_decrypt;
	desc.info = iv;

	return crypt(&desc, dst, src, nbytes);
	return crypt_iv_unaligned(&desc, dst, src, nbytes);
}

static int nocrypt(struct crypto_tfm *tfm,