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

Commit fda5e142 authored by Jan Glauber's avatar Jan Glauber Committed by Linus Torvalds
Browse files

[PATCH] s390: aes crypto code fixes



Call KM[C] only with a multiple of block size.  Check return value of KM[C]
instructions and complain about erros

Signed-off-by: default avatarJan Glauber <jan.glauber@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent b8dc6038
Loading
Loading
Loading
Loading
+44 −16
Original line number Diff line number Diff line
@@ -114,80 +114,108 @@ static unsigned int aes_encrypt_ecb(const struct cipher_desc *desc, u8 *out,
				    const u8 *in, unsigned int nbytes)
{
	struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
	int ret;

	/* only use complete blocks */
	nbytes &= ~(AES_BLOCK_SIZE - 1);

	switch (sctx->key_len) {
	case 16:
		crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in, nbytes);
		ret = crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in, nbytes);
		BUG_ON((ret < 0) || (ret != nbytes));
		break;
	case 24:
		crypt_s390_km(KM_AES_192_ENCRYPT, &sctx->key, out, in, nbytes);
		ret = crypt_s390_km(KM_AES_192_ENCRYPT, &sctx->key, out, in, nbytes);
		BUG_ON((ret < 0) || (ret != nbytes));
		break;
	case 32:
		crypt_s390_km(KM_AES_256_ENCRYPT, &sctx->key, out, in, nbytes);
		ret = crypt_s390_km(KM_AES_256_ENCRYPT, &sctx->key, out, in, nbytes);
		BUG_ON((ret < 0) || (ret != nbytes));
		break;
	}
	return nbytes & ~(AES_BLOCK_SIZE - 1);
	return nbytes;
}

static unsigned int aes_decrypt_ecb(const struct cipher_desc *desc, u8 *out,
				    const u8 *in, unsigned int nbytes)
{
	struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
	int ret;

	/* only use complete blocks */
	nbytes &= ~(AES_BLOCK_SIZE - 1);

	switch (sctx->key_len) {
	case 16:
		crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in, nbytes);
		ret = crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in, nbytes);
		BUG_ON((ret < 0) || (ret != nbytes));
		break;
	case 24:
		crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in, nbytes);
		ret = crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in, nbytes);
		BUG_ON((ret < 0) || (ret != nbytes));
		break;
	case 32:
		crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in, nbytes);
		ret = crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in, nbytes);
		BUG_ON((ret < 0) || (ret != nbytes));
		break;
	}
	return nbytes & ~(AES_BLOCK_SIZE - 1);
	return nbytes;
}

static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out,
				    const u8 *in, unsigned int nbytes)
{
	struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
	int ret;

	/* only use complete blocks */
	nbytes &= ~(AES_BLOCK_SIZE - 1);

	memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE);
	switch (sctx->key_len) {
	case 16:
		crypt_s390_kmc(KMC_AES_128_ENCRYPT, &sctx->iv, out, in, nbytes);
		ret = crypt_s390_kmc(KMC_AES_128_ENCRYPT, &sctx->iv, out, in, nbytes);
		BUG_ON((ret < 0) || (ret != nbytes));
		break;
	case 24:
		crypt_s390_kmc(KMC_AES_192_ENCRYPT, &sctx->iv, out, in, nbytes);
		ret = crypt_s390_kmc(KMC_AES_192_ENCRYPT, &sctx->iv, out, in, nbytes);
		BUG_ON((ret < 0) || (ret != nbytes));
		break;
	case 32:
		crypt_s390_kmc(KMC_AES_256_ENCRYPT, &sctx->iv, out, in, nbytes);
		ret = crypt_s390_kmc(KMC_AES_256_ENCRYPT, &sctx->iv, out, in, nbytes);
		BUG_ON((ret < 0) || (ret != nbytes));
		break;
	}
	memcpy(desc->info, &sctx->iv, AES_BLOCK_SIZE);

	return nbytes & ~(AES_BLOCK_SIZE - 1);
	return nbytes;
}

static unsigned int aes_decrypt_cbc(const struct cipher_desc *desc, u8 *out,
				    const u8 *in, unsigned int nbytes)
{
	struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
	int ret;

	/* only use complete blocks */
	nbytes &= ~(AES_BLOCK_SIZE - 1);

	memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE);
	switch (sctx->key_len) {
	case 16:
		crypt_s390_kmc(KMC_AES_128_DECRYPT, &sctx->iv, out, in, nbytes);
		ret = crypt_s390_kmc(KMC_AES_128_DECRYPT, &sctx->iv, out, in, nbytes);
		BUG_ON((ret < 0) || (ret != nbytes));
		break;
	case 24:
		crypt_s390_kmc(KMC_AES_192_DECRYPT, &sctx->iv, out, in, nbytes);
		ret = crypt_s390_kmc(KMC_AES_192_DECRYPT, &sctx->iv, out, in, nbytes);
		BUG_ON((ret < 0) || (ret != nbytes));
		break;
	case 32:
		crypt_s390_kmc(KMC_AES_256_DECRYPT, &sctx->iv, out, in, nbytes);
		ret = crypt_s390_kmc(KMC_AES_256_DECRYPT, &sctx->iv, out, in, nbytes);
		BUG_ON((ret < 0) || (ret != nbytes));
		break;
	}
	return nbytes & ~(AES_BLOCK_SIZE - 1);
	return nbytes;
}