On Mon, Aug 23, 2010 at 20:19 +0200, Mike Belopuhov wrote:
> ESP part gets a nice hack (esp_gcm_init_auth) that fakes an
> authentication part of GCM from the encryption one.  Frankly,
> I'd rather put this into the userland, but it won't be that
> simple and contained.  Turned out, that it's much easier not
> to touch SADB/PFKEY interface and deal with this at the ESP
> initialization time.

OK, I lied.  It's easy to do it at least in isakmpd.  New diff.

Index: net/pfkeyv2.h
===================================================================
RCS file: /home/cvs/src/sys/net/pfkeyv2.h,v
retrieving revision 1.58
diff -u -p -r1.58 pfkeyv2.h
--- net/pfkeyv2.h       9 Jul 2010 16:58:06 -0000       1.58
+++ net/pfkeyv2.h       23 Aug 2010 16:56:23 -0000
@@ -297,6 +297,9 @@ struct sadb_x_tap {
 #define SADB_X_AALG_SHA2_384         6
 #define SADB_X_AALG_SHA2_512         7
 #define SADB_X_AALG_RIPEMD160HMAC    8
+#define SADB_X_AALG_AES128GMAC       9
+#define SADB_X_AALG_AES192GMAC       10
+#define SADB_X_AALG_AES256GMAC       11
 #define SADB_X_AALG_MD5              249
 #define SADB_X_AALG_SHA1             250
 #define SADB_AALG_MAX                250
@@ -315,6 +318,10 @@ struct sadb_x_tap {
 #define SADB_EALG_NULL        11
 #define SADB_X_EALG_AES       12
 #define SADB_X_EALG_AESCTR    13
+#define SADB_X_EALG_AESGCM8   18
+#define SADB_X_EALG_AESGCM12  19
+#define SADB_X_EALG_AESGCM16  20
+#define SADB_X_EALG_AESGMAC   21
 #define SADB_X_EALG_SKIPJACK  249
 #define SADB_EALG_MAX         249
 
Index: net/pfkeyv2_convert.c
===================================================================
RCS file: /home/cvs/src/sys/net/pfkeyv2_convert.c,v
retrieving revision 1.32
diff -u -p -r1.32 pfkeyv2_convert.c
--- net/pfkeyv2_convert.c       1 Jul 2010 02:09:45 -0000       1.32
+++ net/pfkeyv2_convert.c       23 Aug 2010 16:08:56 -0000
@@ -211,6 +211,18 @@ export_sa(void **p, struct tdb *tdb)
                        sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_512;
                        break;
 
+               case CRYPTO_AES_128_GMAC:
+                       sadb_sa->sadb_sa_auth = SADB_X_AALG_AES128GMAC;
+                       break;
+
+               case CRYPTO_AES_192_GMAC:
+                       sadb_sa->sadb_sa_auth = SADB_X_AALG_AES192GMAC;
+                       break;
+
+               case CRYPTO_AES_256_GMAC:
+                       sadb_sa->sadb_sa_auth = SADB_X_AALG_AES256GMAC;
+                       break;
+
                case CRYPTO_MD5_KPDK:
                        sadb_sa->sadb_sa_auth = SADB_X_AALG_MD5;
                        break;
@@ -241,6 +253,14 @@ export_sa(void **p, struct tdb *tdb)
 
                case CRYPTO_AES_CTR:
                        sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESCTR;
+                       break;
+
+               case CRYPTO_AES_GCM_16:
+                       sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESGCM16;
+                       break;
+
+               case CRYPTO_AES_GMAC:
+                       sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESGMAC;
                        break;
 
                case CRYPTO_CAST_CBC:
Index: netinet/ip_esp.c
===================================================================
RCS file: /home/cvs/src/sys/netinet/ip_esp.c,v
retrieving revision 1.111
diff -u -p -r1.111 ip_esp.c
--- netinet/ip_esp.c    20 Jul 2010 15:36:03 -0000      1.111
+++ netinet/ip_esp.c    24 Aug 2010 10:54:01 -0000
@@ -131,6 +131,14 @@ esp_init(struct tdb *tdbp, struct xforms
                        txform = &enc_xform_aes_ctr;
                        break;
 
+               case SADB_X_EALG_AESGCM16:
+                       txform = &enc_xform_aes_gcm;
+                       break;
+
+               case SADB_X_EALG_AESGMAC:
+                       txform = &enc_xform_aes_gmac;
+                       break;
+
                case SADB_X_EALG_BLF:
                        txform = &enc_xform_blf;
                        break;
@@ -194,6 +202,18 @@ esp_init(struct tdb *tdbp, struct xforms
                        thash = &auth_hash_hmac_sha2_512_256;
                        break;
 
+               case SADB_X_AALG_AES128GMAC:
+                       thash = &auth_hash_gmac_aes_128;
+                       break;
+
+               case SADB_X_AALG_AES192GMAC:
+                       thash = &auth_hash_gmac_aes_192;
+                       break;
+
+               case SADB_X_AALG_AES256GMAC:
+                       thash = &auth_hash_gmac_aes_256;
+                       break;
+
                default:
                        DPRINTF(("esp_init(): unsupported authentication 
algorithm %d specified\n", ii->ii_authalg));
                        return EINVAL;
@@ -290,14 +310,13 @@ esp_input(struct mbuf *m, struct tdb *td
 {
        struct auth_hash *esph = (struct auth_hash *) tdb->tdb_authalgxform;
        struct enc_xform *espx = (struct enc_xform *) tdb->tdb_encalgxform;
+       struct cryptodesc *crde = NULL, *crda = NULL;
+       struct cryptop *crp;
        struct tdb_crypto *tc;
        int plen, alen, hlen;
        struct m_tag *mtag;
        u_int32_t btsx;
 
-       struct cryptodesc *crde = NULL, *crda = NULL;
-       struct cryptop *crp;
-
        /* Determine the ESP header length */
        if (tdb->tdb_flags & TDBF_NOREPLAY)
                hlen = sizeof(u_int32_t) + tdb->tdb_ivlen; /* "old" ESP */
@@ -424,13 +443,17 @@ esp_input(struct mbuf *m, struct tdb *td
 
                /* Authentication descriptor */
                crda->crd_skip = skip;
-               crda->crd_len = m->m_pkthdr.len - (skip + alen);
                crda->crd_inject = m->m_pkthdr.len - alen;
 
                crda->crd_alg = esph->type;
                crda->crd_key = tdb->tdb_amxkey;
                crda->crd_klen = tdb->tdb_amxkeylen * 8;
 
+               if (espx && espx->type == CRYPTO_AES_GCM_16)
+                       crda->crd_len = hlen - tdb->tdb_ivlen;
+               else
+                       crda->crd_len = m->m_pkthdr.len - (skip + alen);
+
                /* Copy the authenticator */
                if (mtag == NULL)
                        m_copydata(m, m->m_pkthdr.len - alen, alen, (caddr_t) 
(tc + 1));
@@ -456,7 +479,6 @@ esp_input(struct mbuf *m, struct tdb *td
        /* Decryption descriptor */
        if (espx) {
                crde->crd_skip = skip + hlen;
-               crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen);
                crde->crd_inject = skip + hlen - tdb->tdb_ivlen;
 
                if (tdb->tdb_flags & TDBF_HALFIV) {
@@ -474,6 +496,11 @@ esp_input(struct mbuf *m, struct tdb *td
                crde->crd_key = tdb->tdb_emxkey;
                crde->crd_klen = tdb->tdb_emxkeylen * 8;
                /* XXX Rounds ? */
+
+               if (crde->crd_alg == CRYPTO_AES_GMAC)
+                       crde->crd_len = 0;
+               else
+                       crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen);
        }
 
        if (mtag == NULL)
@@ -764,7 +791,7 @@ esp_output(struct mbuf *m, struct tdb *t
 
        rlen = m->m_pkthdr.len - skip; /* Raw payload length. */
        if (espx)
-               blks = espx->blocksize;
+               blks = MAX(espx->blocksize, 4);
        else
                blks = 4; /* If no encryption, we have to be 4-byte aligned. */
 
@@ -926,7 +959,6 @@ esp_output(struct mbuf *m, struct tdb *t
 
                /* Encryption descriptor. */
                crde->crd_skip = skip + hlen;
-               crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen);
                crde->crd_flags = CRD_F_ENCRYPT;
                crde->crd_inject = skip + hlen - tdb->tdb_ivlen;
 
@@ -950,6 +982,11 @@ esp_output(struct mbuf *m, struct tdb *t
                crde->crd_key = tdb->tdb_emxkey;
                crde->crd_klen = tdb->tdb_emxkeylen * 8;
                /* XXX Rounds ? */
+
+               if (crde->crd_alg == CRYPTO_AES_GMAC)
+                       crde->crd_len = 0;
+               else
+                       crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen);
        } else
                crda = crp->crp_desc;
 
@@ -979,13 +1016,17 @@ esp_output(struct mbuf *m, struct tdb *t
        if (esph) {
                /* Authentication descriptor. */
                crda->crd_skip = skip;
-               crda->crd_len = m->m_pkthdr.len - (skip + alen);
                crda->crd_inject = m->m_pkthdr.len - alen;
 
                /* Authentication operation. */
                crda->crd_alg = esph->type;
                crda->crd_key = tdb->tdb_amxkey;
                crda->crd_klen = tdb->tdb_amxkeylen * 8;
+
+               if (espx && espx->type == CRYPTO_AES_GCM_16)
+                       crda->crd_len = hlen - tdb->tdb_ivlen;
+               else
+                       crda->crd_len = m->m_pkthdr.len - (skip + alen);
        }
 
        if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0)

Reply via email to