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

Commit ef3263e3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull crypto fixes from Herbert Xu:
 "This fixes the following issues:

   - Intermittent build failure in RSA

   - Memory corruption in chelsio crypto driver

   - Regression in DRBG due to vmalloced stack"

* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6:
  crypto: rsa - Add Makefile dependencies to fix parallel builds
  crypto: chcr - Fix memory corruption
  crypto: drbg - prevent invalid SG mappings
parents 3e5de27e 57891633
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -40,6 +40,7 @@ obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generic.o


$(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
$(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
$(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
$(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
$(obj)/rsa_helper.o: $(obj)/rsapubkey-asn1.h $(obj)/rsaprivkey-asn1.h
clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
clean-files += rsaprivkey-asn1.c rsaprivkey-asn1.h
clean-files += rsaprivkey-asn1.c rsaprivkey-asn1.h


+24 −5
Original line number Original line Diff line number Diff line
@@ -262,6 +262,7 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
			      u8 *inbuf, u32 inbuflen,
			      u8 *inbuf, u32 inbuflen,
			      u8 *outbuf, u32 outlen);
			      u8 *outbuf, u32 outlen);
#define DRBG_CTR_NULL_LEN 128
#define DRBG_CTR_NULL_LEN 128
#define DRBG_OUTSCRATCHLEN DRBG_CTR_NULL_LEN


/* BCC function for CTR DRBG as defined in 10.4.3 */
/* BCC function for CTR DRBG as defined in 10.4.3 */
static int drbg_ctr_bcc(struct drbg_state *drbg,
static int drbg_ctr_bcc(struct drbg_state *drbg,
@@ -1644,6 +1645,9 @@ static int drbg_fini_sym_kernel(struct drbg_state *drbg)
	kfree(drbg->ctr_null_value_buf);
	kfree(drbg->ctr_null_value_buf);
	drbg->ctr_null_value = NULL;
	drbg->ctr_null_value = NULL;


	kfree(drbg->outscratchpadbuf);
	drbg->outscratchpadbuf = NULL;

	return 0;
	return 0;
}
}


@@ -1708,6 +1712,15 @@ static int drbg_init_sym_kernel(struct drbg_state *drbg)
	drbg->ctr_null_value = (u8 *)PTR_ALIGN(drbg->ctr_null_value_buf,
	drbg->ctr_null_value = (u8 *)PTR_ALIGN(drbg->ctr_null_value_buf,
					       alignmask + 1);
					       alignmask + 1);


	drbg->outscratchpadbuf = kmalloc(DRBG_OUTSCRATCHLEN + alignmask,
					 GFP_KERNEL);
	if (!drbg->outscratchpadbuf) {
		drbg_fini_sym_kernel(drbg);
		return -ENOMEM;
	}
	drbg->outscratchpad = (u8 *)PTR_ALIGN(drbg->outscratchpadbuf,
					      alignmask + 1);

	return alignmask;
	return alignmask;
}
}


@@ -1737,15 +1750,16 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
			      u8 *outbuf, u32 outlen)
			      u8 *outbuf, u32 outlen)
{
{
	struct scatterlist sg_in;
	struct scatterlist sg_in;
	int ret;


	sg_init_one(&sg_in, inbuf, inlen);
	sg_init_one(&sg_in, inbuf, inlen);


	while (outlen) {
	while (outlen) {
		u32 cryptlen = min_t(u32, inlen, outlen);
		u32 cryptlen = min3(inlen, outlen, (u32)DRBG_OUTSCRATCHLEN);
		struct scatterlist sg_out;
		struct scatterlist sg_out;
		int ret;


		sg_init_one(&sg_out, outbuf, cryptlen);
		/* Output buffer may not be valid for SGL, use scratchpad */
		sg_init_one(&sg_out, drbg->outscratchpad, cryptlen);
		skcipher_request_set_crypt(drbg->ctr_req, &sg_in, &sg_out,
		skcipher_request_set_crypt(drbg->ctr_req, &sg_in, &sg_out,
					   cryptlen, drbg->V);
					   cryptlen, drbg->V);
		ret = crypto_skcipher_encrypt(drbg->ctr_req);
		ret = crypto_skcipher_encrypt(drbg->ctr_req);
@@ -1761,14 +1775,19 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
				break;
				break;
			}
			}
		default:
		default:
			return ret;
			goto out;
		}
		}
		init_completion(&drbg->ctr_completion);
		init_completion(&drbg->ctr_completion);


		memcpy(outbuf, drbg->outscratchpad, cryptlen);

		outlen -= cryptlen;
		outlen -= cryptlen;
	}
	}
	ret = 0;


	return 0;
out:
	memzero_explicit(drbg->outscratchpad, DRBG_OUTSCRATCHLEN);
	return ret;
}
}
#endif /* CONFIG_CRYPTO_DRBG_CTR */
#endif /* CONFIG_CRYPTO_DRBG_CTR */


+2 −1
Original line number Original line Diff line number Diff line
@@ -422,7 +422,7 @@ static inline void get_aes_decrypt_key(unsigned char *dec_key,
{
{
	u32 temp;
	u32 temp;
	u32 w_ring[MAX_NK];
	u32 w_ring[MAX_NK];
	int i, j, k = 0;
	int i, j, k;
	u8  nr, nk;
	u8  nr, nk;


	switch (keylength) {
	switch (keylength) {
@@ -460,6 +460,7 @@ static inline void get_aes_decrypt_key(unsigned char *dec_key,
		temp = w_ring[i % nk];
		temp = w_ring[i % nk];
		i++;
		i++;
	}
	}
	i--;
	for (k = 0, j = i % nk; k < nk; k++) {
	for (k = 0, j = i % nk; k < nk; k++) {
		*((u32 *)dec_key + k) = htonl(w_ring[j]);
		*((u32 *)dec_key + k) = htonl(w_ring[j]);
		j--;
		j--;
+2 −0
Original line number Original line Diff line number Diff line
@@ -124,6 +124,8 @@ struct drbg_state {
	struct skcipher_request *ctr_req;	/* CTR mode request handle */
	struct skcipher_request *ctr_req;	/* CTR mode request handle */
	__u8 *ctr_null_value_buf;		/* CTR mode unaligned buffer */
	__u8 *ctr_null_value_buf;		/* CTR mode unaligned buffer */
	__u8 *ctr_null_value;			/* CTR mode aligned zero buf */
	__u8 *ctr_null_value;			/* CTR mode aligned zero buf */
	__u8 *outscratchpadbuf;			/* CTR mode output scratchpad */
        __u8 *outscratchpad;			/* CTR mode aligned outbuf */
	struct completion ctr_completion;	/* CTR mode async handler */
	struct completion ctr_completion;	/* CTR mode async handler */
	int ctr_async_err;			/* CTR mode async error */
	int ctr_async_err;			/* CTR mode async error */