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

Commit fc86d27b authored by Herbert Xu's avatar Herbert Xu Committed by Greg Kroah-Hartman
Browse files

crypto: bcm - Verify GCM/CCM key length in setkey



commit 10a2f0b311094ffd45463a529a410a51ca025f27 upstream.

The setkey function for GCM/CCM algorithms didn't verify the key
length before copying the key and subtracting the salt length.

This patch delays the copying of the key til after the verification
has been done.  It also adds checks on the key length to ensure
that it's at least as long as the salt.

Fixes: 9d12ba86 ("crypto: brcm - Add Broadcom SPU driver")
Cc: <stable@vger.kernel.org>
Reported-by: default avatarkiyin(尹亮) <kiyin@tencent.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent bc9c21f8
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -2980,7 +2980,6 @@ static int aead_gcm_ccm_setkey(struct crypto_aead *cipher,

	ctx->enckeylen = keylen;
	ctx->authkeylen = 0;
	memcpy(ctx->enckey, key, ctx->enckeylen);

	switch (ctx->enckeylen) {
	case AES_KEYSIZE_128:
@@ -2996,6 +2995,8 @@ static int aead_gcm_ccm_setkey(struct crypto_aead *cipher,
		goto badkey;
	}

	memcpy(ctx->enckey, key, ctx->enckeylen);

	flow_log("  enckeylen:%u authkeylen:%u\n", ctx->enckeylen,
		 ctx->authkeylen);
	flow_dump("  enc: ", ctx->enckey, ctx->enckeylen);
@@ -3056,6 +3057,10 @@ static int aead_gcm_esp_setkey(struct crypto_aead *cipher,
	struct iproc_ctx_s *ctx = crypto_aead_ctx(cipher);

	flow_log("%s\n", __func__);

	if (keylen < GCM_ESP_SALT_SIZE)
		return -EINVAL;

	ctx->salt_len = GCM_ESP_SALT_SIZE;
	ctx->salt_offset = GCM_ESP_SALT_OFFSET;
	memcpy(ctx->salt, key + keylen - GCM_ESP_SALT_SIZE, GCM_ESP_SALT_SIZE);
@@ -3084,6 +3089,10 @@ static int rfc4543_gcm_esp_setkey(struct crypto_aead *cipher,
	struct iproc_ctx_s *ctx = crypto_aead_ctx(cipher);

	flow_log("%s\n", __func__);

	if (keylen < GCM_ESP_SALT_SIZE)
		return -EINVAL;

	ctx->salt_len = GCM_ESP_SALT_SIZE;
	ctx->salt_offset = GCM_ESP_SALT_OFFSET;
	memcpy(ctx->salt, key + keylen - GCM_ESP_SALT_SIZE, GCM_ESP_SALT_SIZE);
@@ -3113,6 +3122,10 @@ static int aead_ccm_esp_setkey(struct crypto_aead *cipher,
	struct iproc_ctx_s *ctx = crypto_aead_ctx(cipher);

	flow_log("%s\n", __func__);

	if (keylen < CCM_ESP_SALT_SIZE)
		return -EINVAL;

	ctx->salt_len = CCM_ESP_SALT_SIZE;
	ctx->salt_offset = CCM_ESP_SALT_OFFSET;
	memcpy(ctx->salt, key + keylen - CCM_ESP_SALT_SIZE, CCM_ESP_SALT_SIZE);