Commit c39596f6 authored by Steffen Klassert's avatar Steffen Klassert
Browse files

Merge branch 'xfrm: add netlink extack to all the ->init_stat'



Sabrina Dubroca says:

============
This series completes extack support for state creation.
============

Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
parents 48ff45da 28b5dbd5
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ struct xfrm_state;
int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb);
int ipcomp_output(struct xfrm_state *x, struct sk_buff *skb);
void ipcomp_destroy(struct xfrm_state *x);
int ipcomp_init_state(struct xfrm_state *x);
int ipcomp_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack);

static inline struct ip_comp_hdr *ip_comp_hdr(const struct sk_buff *skb)
{
+2 −1
Original line number Diff line number Diff line
@@ -405,7 +405,8 @@ struct xfrm_type {
#define XFRM_TYPE_LOCAL_COADDR	4
#define XFRM_TYPE_REMOTE_COADDR	8

	int			(*init_state)(struct xfrm_state *x);
	int			(*init_state)(struct xfrm_state *x,
					      struct netlink_ext_ack *extack);
	void			(*destructor)(struct xfrm_state *);
	int			(*input)(struct xfrm_state *, struct sk_buff *skb);
	int			(*output)(struct xfrm_state *, struct sk_buff *pskb);
+14 −9
Original line number Diff line number Diff line
@@ -471,30 +471,38 @@ static int ah4_err(struct sk_buff *skb, u32 info)
	return 0;
}

static int ah_init_state(struct xfrm_state *x)
static int ah_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
{
	struct ah_data *ahp = NULL;
	struct xfrm_algo_desc *aalg_desc;
	struct crypto_ahash *ahash;

	if (!x->aalg)
	if (!x->aalg) {
		NL_SET_ERR_MSG(extack, "AH requires a state with an AUTH algorithm");
		goto error;
	}

	if (x->encap)
	if (x->encap) {
		NL_SET_ERR_MSG(extack, "AH is not compatible with encapsulation");
		goto error;
	}

	ahp = kzalloc(sizeof(*ahp), GFP_KERNEL);
	if (!ahp)
		return -ENOMEM;

	ahash = crypto_alloc_ahash(x->aalg->alg_name, 0, 0);
	if (IS_ERR(ahash))
	if (IS_ERR(ahash)) {
		NL_SET_ERR_MSG(extack, "Kernel was unable to initialize cryptographic operations");
		goto error;
	}

	ahp->ahash = ahash;
	if (crypto_ahash_setkey(ahash, x->aalg->alg_key,
				(x->aalg->alg_key_len + 7) / 8))
				(x->aalg->alg_key_len + 7) / 8)) {
		NL_SET_ERR_MSG(extack, "Kernel was unable to initialize cryptographic operations");
		goto error;
	}

	/*
	 * Lookup the algorithm description maintained by xfrm_algo,
@@ -507,10 +515,7 @@ static int ah_init_state(struct xfrm_state *x)

	if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
	    crypto_ahash_digestsize(ahash)) {
		pr_info("%s: %s digestsize %u != %u\n",
			__func__, x->aalg->alg_name,
			crypto_ahash_digestsize(ahash),
			aalg_desc->uinfo.auth.icv_fullbits / 8);
		NL_SET_ERR_MSG(extack, "Kernel was unable to initialize cryptographic operations");
		goto error;
	}

+33 −22
Original line number Diff line number Diff line
@@ -1007,16 +1007,17 @@ static void esp_destroy(struct xfrm_state *x)
	crypto_free_aead(aead);
}

static int esp_init_aead(struct xfrm_state *x)
static int esp_init_aead(struct xfrm_state *x, struct netlink_ext_ack *extack)
{
	char aead_name[CRYPTO_MAX_ALG_NAME];
	struct crypto_aead *aead;
	int err;

	err = -ENAMETOOLONG;
	if (snprintf(aead_name, CRYPTO_MAX_ALG_NAME, "%s(%s)",
		     x->geniv, x->aead->alg_name) >= CRYPTO_MAX_ALG_NAME)
		goto error;
		     x->geniv, x->aead->alg_name) >= CRYPTO_MAX_ALG_NAME) {
		NL_SET_ERR_MSG(extack, "Algorithm name is too long");
		return -ENAMETOOLONG;
	}

	aead = crypto_alloc_aead(aead_name, 0, 0);
	err = PTR_ERR(aead);
@@ -1034,11 +1035,15 @@ static int esp_init_aead(struct xfrm_state *x)
	if (err)
		goto error;

	return 0;

error:
	NL_SET_ERR_MSG(extack, "Kernel was unable to initialize cryptographic operations");
	return err;
}

static int esp_init_authenc(struct xfrm_state *x)
static int esp_init_authenc(struct xfrm_state *x,
			    struct netlink_ext_ack *extack)
{
	struct crypto_aead *aead;
	struct crypto_authenc_key_param *param;
@@ -1049,10 +1054,6 @@ static int esp_init_authenc(struct xfrm_state *x)
	unsigned int keylen;
	int err;

	err = -EINVAL;
	if (!x->ealg)
		goto error;

	err = -ENAMETOOLONG;

	if ((x->props.flags & XFRM_STATE_ESN)) {
@@ -1061,22 +1062,28 @@ static int esp_init_authenc(struct xfrm_state *x)
			     x->geniv ?: "", x->geniv ? "(" : "",
			     x->aalg ? x->aalg->alg_name : "digest_null",
			     x->ealg->alg_name,
			     x->geniv ? ")" : "") >= CRYPTO_MAX_ALG_NAME)
			     x->geniv ? ")" : "") >= CRYPTO_MAX_ALG_NAME) {
			NL_SET_ERR_MSG(extack, "Algorithm name is too long");
			goto error;
		}
	} else {
		if (snprintf(authenc_name, CRYPTO_MAX_ALG_NAME,
			     "%s%sauthenc(%s,%s)%s",
			     x->geniv ?: "", x->geniv ? "(" : "",
			     x->aalg ? x->aalg->alg_name : "digest_null",
			     x->ealg->alg_name,
			     x->geniv ? ")" : "") >= CRYPTO_MAX_ALG_NAME)
			     x->geniv ? ")" : "") >= CRYPTO_MAX_ALG_NAME) {
			NL_SET_ERR_MSG(extack, "Algorithm name is too long");
			goto error;
		}
	}

	aead = crypto_alloc_aead(authenc_name, 0, 0);
	err = PTR_ERR(aead);
	if (IS_ERR(aead))
	if (IS_ERR(aead)) {
		NL_SET_ERR_MSG(extack, "Kernel was unable to initialize cryptographic operations");
		goto error;
	}

	x->data = aead;

@@ -1106,18 +1113,17 @@ static int esp_init_authenc(struct xfrm_state *x)
		err = -EINVAL;
		if (aalg_desc->uinfo.auth.icv_fullbits / 8 !=
		    crypto_aead_authsize(aead)) {
			pr_info("ESP: %s digestsize %u != %u\n",
				x->aalg->alg_name,
				crypto_aead_authsize(aead),
				aalg_desc->uinfo.auth.icv_fullbits / 8);
			NL_SET_ERR_MSG(extack, "Kernel was unable to initialize cryptographic operations");
			goto free_key;
		}

		err = crypto_aead_setauthsize(
			aead, x->aalg->alg_trunc_len / 8);
		if (err)
		if (err) {
			NL_SET_ERR_MSG(extack, "Kernel was unable to initialize cryptographic operations");
			goto free_key;
		}
	}

	param->enckeylen = cpu_to_be32((x->ealg->alg_key_len + 7) / 8);
	memcpy(p, x->ealg->alg_key, (x->ealg->alg_key_len + 7) / 8);
@@ -1131,7 +1137,7 @@ static int esp_init_authenc(struct xfrm_state *x)
	return err;
}

static int esp_init_state(struct xfrm_state *x)
static int esp_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
{
	struct crypto_aead *aead;
	u32 align;
@@ -1139,10 +1145,14 @@ static int esp_init_state(struct xfrm_state *x)

	x->data = NULL;

	if (x->aead)
		err = esp_init_aead(x);
	else
		err = esp_init_authenc(x);
	if (x->aead) {
		err = esp_init_aead(x, extack);
	} else if (x->ealg) {
		err = esp_init_authenc(x, extack);
	} else {
		NL_SET_ERR_MSG(extack, "ESP: AEAD or CRYPT must be provided");
		err = -EINVAL;
	}

	if (err)
		goto error;
@@ -1160,6 +1170,7 @@ static int esp_init_state(struct xfrm_state *x)

		switch (encap->encap_type) {
		default:
			NL_SET_ERR_MSG(extack, "Unsupported encapsulation type for ESP");
			err = -EINVAL;
			goto error;
		case UDP_ENCAP_ESPINUDP:
+7 −3
Original line number Diff line number Diff line
@@ -117,7 +117,8 @@ static int ipcomp_tunnel_attach(struct xfrm_state *x)
	return err;
}

static int ipcomp4_init_state(struct xfrm_state *x)
static int ipcomp4_init_state(struct xfrm_state *x,
			      struct netlink_ext_ack *extack)
{
	int err = -EINVAL;

@@ -129,18 +130,21 @@ static int ipcomp4_init_state(struct xfrm_state *x)
		x->props.header_len += sizeof(struct iphdr);
		break;
	default:
		NL_SET_ERR_MSG(extack, "Unsupported XFRM mode for IPcomp");
		goto out;
	}

	err = ipcomp_init_state(x);
	err = ipcomp_init_state(x, extack);
	if (err)
		goto out;

	if (x->props.mode == XFRM_MODE_TUNNEL) {
		err = ipcomp_tunnel_attach(x);
		if (err)
		if (err) {
			NL_SET_ERR_MSG(extack, "Kernel error: failed to initialize the associated state");
			goto out;
		}
	}

	err = 0;
out:
Loading