Hi,

now that we finally have AES-GCM in IKE and ESP I would like to add them as
defaults.

This is a bit more complicated than one might think because AEADs and non-AEADs
can not be sent in the same proposal.  Instead we must send one proposal
for each and adjust the config parser a bit.

Test feedback welcome. ok?

diff --git a/sbin/iked/parse.y b/sbin/iked/parse.y
index 2cb00c29833..b92a4306e5d 100644
--- a/sbin/iked/parse.y
+++ b/sbin/iked/parse.y
@@ -159,6 +159,28 @@ struct iked_transform ikev2_default_ike_transforms[] = {
 size_t ikev2_default_nike_transforms = ((sizeof(ikev2_default_ike_transforms) /
     sizeof(ikev2_default_ike_transforms[0])) - 1);
 
+struct iked_transform ikev2_default_ike_transforms_noauth[] = {
+       { IKEV2_XFORMTYPE_ENCR, IKEV2_XFORMENCR_AES_GCM_16, 256 },
+       { IKEV2_XFORMTYPE_ENCR, IKEV2_XFORMENCR_AES_GCM_16, 128 },
+       { IKEV2_XFORMTYPE_PRF,  IKEV2_XFORMPRF_HMAC_SHA2_512 },
+       { IKEV2_XFORMTYPE_PRF,  IKEV2_XFORMPRF_HMAC_SHA2_384 },
+       { IKEV2_XFORMTYPE_PRF,  IKEV2_XFORMPRF_HMAC_SHA2_256 },
+       { IKEV2_XFORMTYPE_PRF,  IKEV2_XFORMPRF_HMAC_SHA1 },
+       { IKEV2_XFORMTYPE_DH,   IKEV2_XFORMDH_CURVE25519 },
+       { IKEV2_XFORMTYPE_DH,   IKEV2_XFORMDH_ECP_521 },
+       { IKEV2_XFORMTYPE_DH,   IKEV2_XFORMDH_ECP_384 },
+       { IKEV2_XFORMTYPE_DH,   IKEV2_XFORMDH_ECP_256 },
+       { IKEV2_XFORMTYPE_DH,   IKEV2_XFORMDH_MODP_4096 },
+       { IKEV2_XFORMTYPE_DH,   IKEV2_XFORMDH_MODP_3072 },
+       { IKEV2_XFORMTYPE_DH,   IKEV2_XFORMDH_MODP_2048 },
+       { IKEV2_XFORMTYPE_DH,   IKEV2_XFORMDH_MODP_1536 },
+       { IKEV2_XFORMTYPE_DH,   IKEV2_XFORMDH_MODP_1024 },
+       { 0 }
+};
+size_t ikev2_default_nike_transforms_noauth =
+    ((sizeof(ikev2_default_ike_transforms_noauth) /
+    sizeof(ikev2_default_ike_transforms_noauth[0])) - 1);
+
 struct iked_transform ikev2_default_esp_transforms[] = {
        { IKEV2_XFORMTYPE_ENCR, IKEV2_XFORMENCR_AES_CBC, 256 },
        { IKEV2_XFORMTYPE_ENCR, IKEV2_XFORMENCR_AES_CBC, 192 },
@@ -172,6 +194,17 @@ struct iked_transform ikev2_default_esp_transforms[] = {
 size_t ikev2_default_nesp_transforms = ((sizeof(ikev2_default_esp_transforms) /
     sizeof(ikev2_default_esp_transforms[0])) - 1);
 
+struct iked_transform ikev2_default_esp_transforms_noauth[] = {
+       { IKEV2_XFORMTYPE_ENCR, IKEV2_XFORMENCR_AES_GCM_16, 256 },
+       { IKEV2_XFORMTYPE_ENCR, IKEV2_XFORMENCR_AES_GCM_16, 128 },
+       { IKEV2_XFORMTYPE_ESN,  IKEV2_XFORMESN_ESN },
+       { IKEV2_XFORMTYPE_ESN,  IKEV2_XFORMESN_NONE },
+       { 0 }
+};
+size_t ikev2_default_nesp_transforms_noauth =
+    ((sizeof(ikev2_default_esp_transforms_noauth) /
+    sizeof(ikev2_default_esp_transforms_noauth[0])) - 1);
+
 const struct ipsec_xf authxfs[] = {
        { "hmac-md5",           IKEV2_XFORMAUTH_HMAC_MD5_96,            16 },
        { "hmac-sha1",          IKEV2_XFORMAUTH_HMAC_SHA1_96,           20 },
@@ -2727,7 +2760,7 @@ create_ike(char *name, int af, uint8_t ipproto,
        struct iked_policy       pol;
        struct iked_proposal    *p, *ptmp;
        struct iked_transform   *xf;
-       unsigned int             i, j, xfi, noauth;
+       unsigned int             i, j, xfi, noauth, auth;
        unsigned int             ikepropid = 1, ipsecpropid = 1;
        struct iked_flow        *flow, *ftmp;
        static unsigned int      policy_id = 0;
@@ -2857,6 +2890,17 @@ create_ike(char *name, int af, uint8_t ipproto,
        RB_INIT(&pol.pol_flows);
 
        if (ike_sa == NULL || ike_sa->nxfs == 0) {
+               /* AES-GCM proposal */
+               if ((p = calloc(1, sizeof(*p))) == NULL)
+                       err(1, "%s", __func__);
+               p->prop_id = ikepropid++;
+               p->prop_protoid = IKEV2_SAPROTO_IKE;
+               p->prop_nxforms = ikev2_default_nike_transforms_noauth;
+               p->prop_xforms = ikev2_default_ike_transforms_noauth;
+               TAILQ_INSERT_TAIL(&pol.pol_proposals, p, prop_entry);
+               pol.pol_nproposals++;
+
+               /* Non GCM proposal */
                if ((p = calloc(1, sizeof(*p))) == NULL)
                        err(1, "%s", __func__);
                p->prop_id = ikepropid++;
@@ -2867,11 +2911,16 @@ create_ike(char *name, int af, uint8_t ipproto,
                pol.pol_nproposals++;
        } else {
                for (i = 0; i < ike_sa->nxfs; i++) {
-                       noauth = 0;
+                       noauth = auth = 0;
                        for (j = 0; j < ike_sa->xfs[i]->nencxf; j++) {
                                if (ike_sa->xfs[i]->encxf[j]->noauth)
                                        noauth++;
+                               else
+                                       auth++;
                        }
+                       if (ike_sa->xfs[i]->nauthxf)
+                               auth++;
+
                        if (ike_sa->xfs[i]->nesnxf) {
                                yyerror("cannot use ESN with ikesa.");
                                goto done;
@@ -2887,43 +2936,82 @@ create_ike(char *name, int af, uint8_t ipproto,
                                goto done;
                        }
 
-                       if ((p = calloc(1, sizeof(*p))) == NULL)
-                               err(1, "%s", __func__);
+                       if (!auth) {
+                               if ((p = calloc(1, sizeof(*p))) == NULL)
+                                       err(1, "%s", __func__);
+
+                               xf = NULL;
+                               xfi = 0;
+                               copy_transforms(IKEV2_XFORMTYPE_ENCR,
+                                   ike_sa->xfs[i]->encxf,
+                                   ike_sa->xfs[i]->nencxf, &xf, &xfi,
+                                   ikev2_default_ike_transforms_noauth,
+                                   ikev2_default_nike_transforms_noauth);
+                               copy_transforms(IKEV2_XFORMTYPE_DH,
+                                   ike_sa->xfs[i]->groupxf,
+                                   ike_sa->xfs[i]->ngroupxf, &xf, &xfi,
+                                   ikev2_default_ike_transforms_noauth,
+                                   ikev2_default_nike_transforms_noauth);
+                               copy_transforms(IKEV2_XFORMTYPE_PRF,
+                                   ike_sa->xfs[i]->prfxf,
+                                   ike_sa->xfs[i]->nprfxf, &xf, &xfi,
+                                   ikev2_default_ike_transforms_noauth,
+                                   ikev2_default_nike_transforms_noauth);
+
+                               p->prop_id = ikepropid++;
+                               p->prop_protoid = IKEV2_SAPROTO_IKE;
+                               p->prop_xforms = xf;
+                               p->prop_nxforms = xfi;
+                               TAILQ_INSERT_TAIL(&pol.pol_proposals, p, 
prop_entry);
+                               pol.pol_nproposals++;
+                       }
+                       if (!noauth) {
+                               if ((p = calloc(1, sizeof(*p))) == NULL)
+                                       err(1, "%s", __func__);
 
-                       xf = NULL;
-                       xfi = 0;
-                       if (!ike_sa->xfs[i]->nencxf || !noauth)
+                               xf = NULL;
+                               xfi = 0;
                                copy_transforms(IKEV2_XFORMTYPE_INTEGR,
                                    ike_sa->xfs[i]->authxf,
                                    ike_sa->xfs[i]->nauthxf, &xf, &xfi,
                                    ikev2_default_ike_transforms,
                                    ikev2_default_nike_transforms);
-                       copy_transforms(IKEV2_XFORMTYPE_ENCR,
-                           ike_sa->xfs[i]->encxf,
-                           ike_sa->xfs[i]->nencxf, &xf, &xfi,
-                           ikev2_default_ike_transforms,
-                           ikev2_default_nike_transforms);
-                       copy_transforms(IKEV2_XFORMTYPE_DH,
-                           ike_sa->xfs[i]->groupxf,
-                           ike_sa->xfs[i]->ngroupxf, &xf, &xfi,
-                           ikev2_default_ike_transforms,
-                           ikev2_default_nike_transforms);
-                       copy_transforms(IKEV2_XFORMTYPE_PRF,
-                           ike_sa->xfs[i]->prfxf,
-                           ike_sa->xfs[i]->nprfxf, &xf, &xfi,
-                           ikev2_default_ike_transforms,
-                           ikev2_default_nike_transforms);
-
-                       p->prop_id = ikepropid++;
-                       p->prop_protoid = IKEV2_SAPROTO_IKE;
-                       p->prop_xforms = xf;
-                       p->prop_nxforms = xfi;
-                       TAILQ_INSERT_TAIL(&pol.pol_proposals, p, prop_entry);
-                       pol.pol_nproposals++;
+                               copy_transforms(IKEV2_XFORMTYPE_ENCR,
+                                   ike_sa->xfs[i]->encxf,
+                                   ike_sa->xfs[i]->nencxf, &xf, &xfi,
+                                   ikev2_default_ike_transforms,
+                                   ikev2_default_nike_transforms);
+                               copy_transforms(IKEV2_XFORMTYPE_DH,
+                                   ike_sa->xfs[i]->groupxf,
+                                   ike_sa->xfs[i]->ngroupxf, &xf, &xfi,
+                                   ikev2_default_ike_transforms,
+                                   ikev2_default_nike_transforms);
+                               copy_transforms(IKEV2_XFORMTYPE_PRF,
+                                   ike_sa->xfs[i]->prfxf,
+                                   ike_sa->xfs[i]->nprfxf, &xf, &xfi,
+                                   ikev2_default_ike_transforms,
+                                   ikev2_default_nike_transforms);
+
+                               p->prop_id = ikepropid++;
+                               p->prop_protoid = IKEV2_SAPROTO_IKE;
+                               p->prop_xforms = xf;
+                               p->prop_nxforms = xfi;
+                               TAILQ_INSERT_TAIL(&pol.pol_proposals, p, 
prop_entry);
+                               pol.pol_nproposals++;
+                       }
                }
        }
 
        if (ipsec_sa == NULL || ipsec_sa->nxfs == 0) {
+               if ((p = calloc(1, sizeof(*p))) == NULL)
+                       err(1, "%s", __func__);
+               p->prop_id = ipsecpropid++;
+               p->prop_protoid = saproto;
+               p->prop_nxforms = ikev2_default_nesp_transforms_noauth;
+               p->prop_xforms = ikev2_default_esp_transforms_noauth;
+               TAILQ_INSERT_TAIL(&pol.pol_proposals, p, prop_entry);
+               pol.pol_nproposals++;
+
                if ((p = calloc(1, sizeof(*p))) == NULL)
                        err(1, "%s", __func__);
                p->prop_id = ipsecpropid++;
@@ -2934,11 +3022,16 @@ create_ike(char *name, int af, uint8_t ipproto,
                pol.pol_nproposals++;
        } else {
                for (i = 0; i < ipsec_sa->nxfs; i++) {
-                       noauth = 0;
+                       noauth = auth = 0;
                        for (j = 0; j < ipsec_sa->xfs[i]->nencxf; j++) {
                                if (ipsec_sa->xfs[i]->encxf[j]->noauth)
                                        noauth++;
+                               else
+                                       auth++;
                        }
+                       if (ipsec_sa->xfs[i]->nauthxf)
+                               auth++;
+
                        if (noauth && noauth != ipsec_sa->xfs[i]->nencxf) {
                                yyerror("cannot mix encryption transforms with "
                                    "implicit and non-implicit authentication");
@@ -2950,39 +3043,69 @@ create_ike(char *name, int af, uint8_t ipproto,
                                goto done;
                        }
 
-                       if ((p = calloc(1, sizeof(*p))) == NULL)
-                               err(1, "%s", __func__);
+                       if (!auth) {
+                               if ((p = calloc(1, sizeof(*p))) == NULL)
+                                       err(1, "%s", __func__);
+
+                               xf = NULL;
+                               xfi = 0;
+                               copy_transforms(IKEV2_XFORMTYPE_ENCR,
+                                   ipsec_sa->xfs[i]->encxf,
+                                   ipsec_sa->xfs[i]->nencxf, &xf, &xfi,
+                                   ikev2_default_esp_transforms_noauth,
+                                   ikev2_default_nesp_transforms_noauth);
+                               copy_transforms(IKEV2_XFORMTYPE_DH,
+                                   ipsec_sa->xfs[i]->groupxf,
+                                   ipsec_sa->xfs[i]->ngroupxf, &xf, &xfi,
+                                   ikev2_default_esp_transforms_noauth,
+                                   ikev2_default_nesp_transforms_noauth);
+                               copy_transforms(IKEV2_XFORMTYPE_ESN,
+                                   ipsec_sa->xfs[i]->esnxf,
+                                   ipsec_sa->xfs[i]->nesnxf, &xf, &xfi,
+                                   ikev2_default_esp_transforms_noauth,
+                                   ikev2_default_nesp_transforms_noauth);
+
+                               p->prop_id = ipsecpropid++;
+                               p->prop_protoid = saproto;
+                               p->prop_xforms = xf;
+                               p->prop_nxforms = xfi;
+                               TAILQ_INSERT_TAIL(&pol.pol_proposals, p, 
prop_entry);
+                               pol.pol_nproposals++;
+                       }
+                       if (!noauth) {
+                               if ((p = calloc(1, sizeof(*p))) == NULL)
+                                       err(1, "%s", __func__);
 
-                       xf = NULL;
-                       xfi = 0;
-                       if (!ipsec_sa->xfs[i]->nencxf || !noauth)
+                               xf = NULL;
+                               xfi = 0;
                                copy_transforms(IKEV2_XFORMTYPE_INTEGR,
                                    ipsec_sa->xfs[i]->authxf,
                                    ipsec_sa->xfs[i]->nauthxf, &xf, &xfi,
                                    ikev2_default_esp_transforms,
                                    ikev2_default_nesp_transforms);
-                       copy_transforms(IKEV2_XFORMTYPE_ENCR,
-                           ipsec_sa->xfs[i]->encxf,
-                           ipsec_sa->xfs[i]->nencxf, &xf, &xfi,
-                           ikev2_default_esp_transforms,
-                           ikev2_default_nesp_transforms);
-                       copy_transforms(IKEV2_XFORMTYPE_DH,
-                           ipsec_sa->xfs[i]->groupxf,
-                           ipsec_sa->xfs[i]->ngroupxf, &xf, &xfi,
-                           ikev2_default_esp_transforms,
-                           ikev2_default_nesp_transforms);
-                       copy_transforms(IKEV2_XFORMTYPE_ESN,
-                           ipsec_sa->xfs[i]->esnxf,
-                           ipsec_sa->xfs[i]->nesnxf, &xf, &xfi,
-                           ikev2_default_esp_transforms,
-                           ikev2_default_nesp_transforms);
-
-                       p->prop_id = ipsecpropid++;
-                       p->prop_protoid = saproto;
-                       p->prop_xforms = xf;
-                       p->prop_nxforms = xfi;
-                       TAILQ_INSERT_TAIL(&pol.pol_proposals, p, prop_entry);
-                       pol.pol_nproposals++;
+                               copy_transforms(IKEV2_XFORMTYPE_ENCR,
+                                   ipsec_sa->xfs[i]->encxf,
+                                   ipsec_sa->xfs[i]->nencxf, &xf, &xfi,
+                                   ikev2_default_esp_transforms,
+                                   ikev2_default_nesp_transforms);
+                               copy_transforms(IKEV2_XFORMTYPE_DH,
+                                   ipsec_sa->xfs[i]->groupxf,
+                                   ipsec_sa->xfs[i]->ngroupxf, &xf, &xfi,
+                                   ikev2_default_esp_transforms,
+                                   ikev2_default_nesp_transforms);
+                               copy_transforms(IKEV2_XFORMTYPE_ESN,
+                                   ipsec_sa->xfs[i]->esnxf,
+                                   ipsec_sa->xfs[i]->nesnxf, &xf, &xfi,
+                                   ikev2_default_esp_transforms,
+                                   ikev2_default_nesp_transforms);
+
+                               p->prop_id = ipsecpropid++;
+                               p->prop_protoid = saproto;
+                               p->prop_xforms = xf;
+                               p->prop_nxforms = xfi;
+                               TAILQ_INSERT_TAIL(&pol.pol_proposals, p, 
prop_entry);
+                               pol.pol_nproposals++;
+                       }
                }
        }
 
@@ -3099,7 +3222,9 @@ done:
        }
        TAILQ_FOREACH_SAFE(p, &pol.pol_proposals, prop_entry, ptmp) {
                if (p->prop_xforms != ikev2_default_ike_transforms &&
-                   p->prop_xforms != ikev2_default_esp_transforms)
+                   p->prop_xforms != ikev2_default_ike_transforms_noauth &&
+                   p->prop_xforms != ikev2_default_esp_transforms &&
+                   p->prop_xforms != ikev2_default_esp_transforms_noauth)
                        free(p->prop_xforms);
                free(p);
        }

Reply via email to