xfrm: esp: add extack to esp_init_state, esp6_init_state
authorSabrina Dubroca <sd@queasysnail.net>
Tue, 27 Sep 2022 15:45:31 +0000 (17:45 +0200)
committerSteffen Klassert <steffen.klassert@secunet.com>
Thu, 29 Sep 2022 05:17:59 +0000 (07:17 +0200)
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
net/ipv4/esp4.c
net/ipv6/esp6.c

index bc2b2c5717b5d14853b2da65be619705d01287c4..751a05276f4894b8df466f3063b8e7b4385150a7 100644 (file)
@@ -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,17 +1113,16 @@ 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);
@@ -1139,10 +1145,14 @@ static int esp_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
 
        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, struct netlink_ext_ack *extack)
 
                switch (encap->encap_type) {
                default:
+                       NL_SET_ERR_MSG(extack, "Unsupported encapsulation type for ESP");
                        err = -EINVAL;
                        goto error;
                case UDP_ENCAP_ESPINUDP:
index 2ca9b7b7e5004ad0b908e5929c4920c4c9b38c34..e7a16f9643e5295eb398a3280905ffde272e5d3d 100644 (file)
@@ -1050,16 +1050,17 @@ static void esp6_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);
@@ -1077,11 +1078,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;
@@ -1092,10 +1097,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)) {
@@ -1104,22 +1105,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;
 
@@ -1149,17 +1156,16 @@ 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);
@@ -1182,10 +1188,14 @@ static int esp6_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
 
        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;
@@ -1213,6 +1223,7 @@ static int esp6_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
 
                switch (encap->encap_type) {
                default:
+                       NL_SET_ERR_MSG(extack, "Unsupported encapsulation type for ESP");
                        err = -EINVAL;
                        goto error;
                case UDP_ENCAP_ESPINUDP: