OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
Re: AES-GCM Part 2: PFKEY/ESP

From: Mike Belopuhov (mkbcrypt.org.ru)
Date: Tue Aug 24 2010 - 05:57:12 CDT


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)