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)