On Tue, Aug 24, 2010 at 12:57 +0200, Mike Belopuhov wrote:
> 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.
>
after another round of poking, looks like it's better to do this
in the kernel so that userland applications won't need to care
about faking anything and will just provide the encryption part.
i decided to inline esp_gcm_init_auth content to the esp_init.
Index: net/pfkeyv2.h
===================================================================
RCS file: /home/cvs/src/sys/net/pfkeyv2.h,v
retrieving revision 1.58
diff -u -p -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 -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 -u -p -r1.111 ip_esp.c
--- netinet/ip_esp.c 20 Jul 2010 15:36:03 -0000 1.111
+++ netinet/ip_esp.c 30 Aug 2010 18:37:27 -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;
@@ -158,6 +166,23 @@ esp_init(struct tdb *tdbp, struct xforms
return EINVAL;
}
+ if (ii->ii_encalg == SADB_X_EALG_AESGCM16 ||
+ ii->ii_encalg == SADB_X_EALG_AESGMAC) {
+ switch (ii->ii_enckeylen) {
+ case 20:
+ ii->ii_authalg = SADB_X_AALG_AES128GMAC;
+ break;
+ case 28:
+ ii->ii_authalg = SADB_X_AALG_AES192GMAC;
+ break;
+ case 36:
+ ii->ii_authalg = SADB_X_AALG_AES256GMAC;
+ break;
+ }
+ ii->ii_authkeylen = ii->ii_enckeylen;
+ ii->ii_authkey = ii->ii_enckey;
+ }
+
tdbp->tdb_encalgxform = txform;
DPRINTF(("esp_init(): initialized TDB with enc algorithm %s\n",
@@ -194,6 +219,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 +327,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 +460,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 +496,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 +513,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 +808,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. */
@@ -888,7 +932,13 @@ esp_output(struct mbuf *m, struct tdb *t
* Add padding -- better to do it ourselves than use the crypto engine,
* although if/when we support compression, we'd have to do that.
*/
+#if 1
pad = (u_char *) m_pad(m, padding + alen);
+#else
+ mo = NULL;
+ mo = m_inject(m, m->m_pkthdr.len, padding + alen, M_DONTWAIT);
+ pad = mtod(mo, u_char *);
+#endif
if (pad == NULL) {
DPRINTF(("esp_output(): m_pad() failed for SA %s/%08x\n",
ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
@@ -926,7 +976,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 +999,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 +1033,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)