Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src pull in AES-GCM/GMAC support from OpenBSD



details:   https://anonhg.NetBSD.org/src/rev/5b4c70e168d4
branches:  trunk
changeset: 765434:5b4c70e168d4
user:      drochner <drochner%NetBSD.org@localhost>
date:      Thu May 26 21:50:02 2011 +0000

description:
pull in AES-GCM/GMAC support from OpenBSD
This is still somewhat experimental. Tested between 2 similar boxes
so far. There is much potential for performance improvement. For now,
I've changed the gmac code to accept any data alignment, as the "char *"
pointer suggests. As the code is practically used, 32-bit alignment
can be assumed, at the cost of data copies. I don't know whether
bytewise access or copies are worse performance-wise. For efficient
implementations using SSE2 instructions on x86, even stricter
alignment requirements might arise.

diffstat:

 crypto/dist/ipsec-tools/src/libipsec/pfkey_dump.c |    8 +-
 crypto/dist/ipsec-tools/src/setkey/token.l        |   12 +-
 sys/net/pfkeyv2.h                                 |   16 +-
 sys/netipsec/xform_esp.c                          |   70 +++++++-
 sys/opencrypto/cryptodev.h                        |    9 +-
 sys/opencrypto/cryptosoft.c                       |  181 +++++++++++++++++++++-
 sys/opencrypto/cryptosoft_xform.c                 |   99 +++++++++--
 sys/opencrypto/files.opencrypto                   |    3 +-
 sys/opencrypto/gmac.c                             |  153 ++++++++++++++++++
 sys/opencrypto/gmac.h                             |   51 ++++++
 sys/opencrypto/xform.c                            |   29 +++-
 sys/opencrypto/xform.h                            |    7 +-
 usr.bin/netstat/fast_ipsec.c                      |    9 +-
 13 files changed, 603 insertions(+), 44 deletions(-)

diffs (truncated from 1092 to 300 lines):

diff -r 05c20fb69d3b -r 5b4c70e168d4 crypto/dist/ipsec-tools/src/libipsec/pfkey_dump.c
--- a/crypto/dist/ipsec-tools/src/libipsec/pfkey_dump.c Thu May 26 21:20:26 2011 +0000
+++ b/crypto/dist/ipsec-tools/src/libipsec/pfkey_dump.c Thu May 26 21:50:02 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pfkey_dump.c,v 1.18 2010/12/03 14:32:52 tteras Exp $   */
+/*     $NetBSD: pfkey_dump.c,v 1.19 2011/05/26 21:50:02 drochner Exp $ */
 
 /*     $KAME: pfkey_dump.c,v 1.45 2003/09/08 10:14:56 itojun Exp $     */
 
@@ -197,6 +197,12 @@
 #ifdef SADB_X_EALG_AESCTR
        { SADB_X_EALG_AESCTR, "aes-ctr", },
 #endif
+#ifdef SADB_X_EALG_AESGCM16
+       { SADB_X_EALG_AESGCM16, "aes-gcm-16", },
+#endif
+#ifdef SADB_X_EALG_AESGMAC
+       { SADB_X_EALG_AESGMAC, "aes-gmac", },
+#endif
 #ifdef SADB_X_EALG_CAMELLIACBC
        { SADB_X_EALG_CAMELLIACBC, "camellia-cbc", },
 #endif
diff -r 05c20fb69d3b -r 5b4c70e168d4 crypto/dist/ipsec-tools/src/setkey/token.l
--- a/crypto/dist/ipsec-tools/src/setkey/token.l        Thu May 26 21:20:26 2011 +0000
+++ b/crypto/dist/ipsec-tools/src/setkey/token.l        Thu May 26 21:50:02 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: token.l,v 1.15 2010/06/04 13:06:03 vanhu Exp $ */
+/*     $NetBSD: token.l,v 1.16 2011/05/26 21:50:02 drochner Exp $      */
 
 /*     $KAME: token.l,v 1.44 2003/10/21 07:20:58 itojun Exp $  */
 
@@ -223,6 +223,16 @@
        yylval.num = SADB_X_EALG_CAMELLIACBC; BEGIN INITIAL; return(ALG_ENC); 
 #endif
 }
+<S_ENCALG>aes-gcm-16   {
+#ifdef SADB_X_EALG_AESGCM16
+       yylval.num = SADB_X_EALG_AESGCM16; BEGIN INITIAL; return(ALG_ENC);
+#endif
+}
+<S_ENCALG>aes-gmac     {
+#ifdef SADB_X_EALG_AESGMAC
+       yylval.num = SADB_X_EALG_AESGMAC; BEGIN INITIAL; return(ALG_ENC);
+#endif
+}
 
        /* compression algorithms */
 {hyphen}C      { return(F_COMP); }
diff -r 05c20fb69d3b -r 5b4c70e168d4 sys/net/pfkeyv2.h
--- a/sys/net/pfkeyv2.h Thu May 26 21:20:26 2011 +0000
+++ b/sys/net/pfkeyv2.h Thu May 26 21:50:02 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pfkeyv2.h,v 1.28 2011/05/05 17:46:48 drochner Exp $    */
+/*     $NetBSD: pfkeyv2.h,v 1.29 2011/05/26 21:50:02 drochner Exp $    */
 /*     $KAME: pfkeyv2.h,v 1.36 2003/07/25 09:33:37 itojun Exp $        */
 
 /*
@@ -351,7 +351,10 @@
 #define SADB_X_AALG_SHA2_384   6
 #define SADB_X_AALG_SHA2_512   7
 #define SADB_X_AALG_RIPEMD160HMAC 8
-#define SADB_X_AALG_AES_XCBC_MAC 9 /* draft-ietf-ipsec-ciph-aes-xcbc-mac-04 */
+#define SADB_X_AALG_AES_XCBC_MAC 9 /* RFC3566 */
+#define SADB_X_AALG_AES128GMAC 11 /* RFC4543 + Errata1821 */
+#define SADB_X_AALG_AES192GMAC 12
+#define SADB_X_AALG_AES256GMAC 13
 /* private allocations should use 249-255 (RFC2407) */
 #define SADB_X_AALG_MD5                249     /* Keyed MD5 */
 #define SADB_X_AALG_SHA                250     /* Keyed SHA */
@@ -369,9 +372,12 @@
 #define SADB_X_EALG_BLOWFISHCBC        7
 #define SADB_X_EALG_RIJNDAELCBC        12
 #define SADB_X_EALG_AES                12
-#define SADB_X_EALG_AESCTR     13
-/* private allocations - based on RFC4312/IANA assignment */
-#define SADB_X_EALG_CAMELLIACBC        22
+#define SADB_X_EALG_AESCTR     13 /* RFC3686 */
+#define SADB_X_EALG_AESGCM8    18 /* RFC4106 */
+#define SADB_X_EALG_AESGCM12   19
+#define SADB_X_EALG_AESGCM16   20
+#define SADB_X_EALG_CAMELLIACBC        22 /* RFC4312 */
+#define SADB_X_EALG_AESGMAC    23 /* RFC4543 + Errata1821 */
 /* private allocations should use 249-255 (RFC2407) */
 #define SADB_X_EALG_SKIPJACK    250
 
diff -r 05c20fb69d3b -r 5b4c70e168d4 sys/netipsec/xform_esp.c
--- a/sys/netipsec/xform_esp.c  Thu May 26 21:20:26 2011 +0000
+++ b/sys/netipsec/xform_esp.c  Thu May 26 21:50:02 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: xform_esp.c,v 1.37 2011/05/23 15:17:25 drochner Exp $  */
+/*     $NetBSD: xform_esp.c,v 1.38 2011/05/26 21:50:02 drochner Exp $  */
 /*     $FreeBSD: src/sys/netipsec/xform_esp.c,v 1.2.2.1 2003/01/24 05:11:36 sam Exp $  */
 /*     $OpenBSD: ip_esp.c,v 1.69 2001/06/26 06:18:59 angelos Exp $ */
 
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xform_esp.c,v 1.37 2011/05/23 15:17:25 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xform_esp.c,v 1.38 2011/05/26 21:50:02 drochner Exp $");
 
 #include "opt_inet.h"
 #ifdef __FreeBSD__
@@ -132,6 +132,10 @@
                return &enc_xform_camellia;
        case SADB_X_EALG_AESCTR:
                return &enc_xform_aes_ctr;
+       case SADB_X_EALG_AESGCM16:
+               return &enc_xform_aes_gcm;
+       case SADB_X_EALG_AESGMAC:
+               return &enc_xform_aes_gmac;
        case SADB_EALG_NULL:
                return &enc_xform_null;
        }
@@ -219,6 +223,28 @@
        sav->tdb_xform = xsp;
        sav->tdb_encalgxform = txform;
 
+       if (sav->alg_enc == SADB_X_EALG_AESGCM16 ||
+           sav->alg_enc == SADB_X_EALG_AESGMAC) {
+               switch (keylen) {
+               case 20:
+                       sav->alg_auth = SADB_X_AALG_AES128GMAC;
+                       sav->tdb_authalgxform = &auth_hash_gmac_aes_128;
+                       break;
+               case 28:
+                       sav->alg_auth = SADB_X_AALG_AES192GMAC;
+                       sav->tdb_authalgxform = &auth_hash_gmac_aes_192;
+                       break;
+               case 36:
+                       sav->alg_auth = SADB_X_AALG_AES256GMAC;
+                       sav->tdb_authalgxform = &auth_hash_gmac_aes_256;
+                       break;
+               }
+               memset(&cria, 0, sizeof(cria));
+               cria.cri_alg = sav->tdb_authalgxform->type;
+               cria.cri_klen = _KEYBITS(sav->key_enc);
+               cria.cri_key = _KEYBUF(sav->key_enc);
+       }
+
        /* Initialize crypto session. */
        memset(&crie, 0, sizeof (crie));
        crie.cri_alg = sav->tdb_encalgxform->type;
@@ -381,12 +407,21 @@
 
                /* Authentication descriptor */
                crda->crd_skip = skip;
-               crda->crd_len = m->m_pkthdr.len - (skip + alen);
+               if (espx && espx->type == CRYPTO_AES_GCM_16)
+                       crda->crd_len = hlen - sav->ivlen;
+               else
+                       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 = _KEYBUF(sav->key_auth);
-               crda->crd_klen = _KEYBITS(sav->key_auth);
+               if (espx && (espx->type == CRYPTO_AES_GCM_16 ||
+                            espx->type == CRYPTO_AES_GMAC)) {
+                       crda->crd_key = _KEYBUF(sav->key_enc);
+                       crda->crd_klen = _KEYBITS(sav->key_enc);
+               } else {
+                       crda->crd_key = _KEYBUF(sav->key_auth);
+                       crda->crd_klen = _KEYBITS(sav->key_auth);
+               }
 
                /* Copy the authenticator */
                if (mtag == NULL)
@@ -418,7 +453,10 @@
        if (espx) {
                IPSEC_ASSERT(crde != NULL, ("esp_input: null esp crypto descriptor"));
                crde->crd_skip = skip + hlen;
-               crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen);
+               if (espx->type == CRYPTO_AES_GMAC)
+                       crde->crd_len = 0;
+               else
+                       crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen);
                crde->crd_inject = skip + hlen - sav->ivlen;
 
                crde->crd_alg = espx->type;
@@ -856,7 +894,10 @@
 
                /* Encryption descriptor. */
                crde->crd_skip = skip + hlen;
-               crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen);
+               if (espx->type == CRYPTO_AES_GMAC)
+                       crde->crd_len = 0;
+               else
+                       crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen);
                crde->crd_flags = CRD_F_ENCRYPT;
                crde->crd_inject = skip + hlen - sav->ivlen;
 
@@ -896,13 +937,22 @@
        if (esph) {
                /* Authentication descriptor. */
                crda->crd_skip = skip;
-               crda->crd_len = m->m_pkthdr.len - (skip + alen);
+               if (espx && espx->type == CRYPTO_AES_GCM_16)
+                       crda->crd_len = hlen - sav->ivlen;
+               else
+                       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 = _KEYBUF(sav->key_auth);
-               crda->crd_klen = _KEYBITS(sav->key_auth);
+               if (espx && (espx->type == CRYPTO_AES_GCM_16 ||
+                            espx->type == CRYPTO_AES_GMAC)) {
+                       crda->crd_key = _KEYBUF(sav->key_enc);
+                       crda->crd_klen = _KEYBITS(sav->key_enc);
+               } else {
+                       crda->crd_key = _KEYBUF(sav->key_auth);
+                       crda->crd_klen = _KEYBITS(sav->key_auth);
+               }
        }
 
        return crypto_dispatch(crp);
diff -r 05c20fb69d3b -r 5b4c70e168d4 sys/opencrypto/cryptodev.h
--- a/sys/opencrypto/cryptodev.h        Thu May 26 21:20:26 2011 +0000
+++ b/sys/opencrypto/cryptodev.h        Thu May 26 21:50:02 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cryptodev.h,v 1.23 2011/05/24 19:10:09 drochner Exp $ */
+/*     $NetBSD: cryptodev.h,v 1.24 2011/05/26 21:50:03 drochner Exp $ */
 /*     $FreeBSD: src/sys/opencrypto/cryptodev.h,v 1.2.2.6 2003/07/02 17:04:50 sam Exp $        */
 /*     $OpenBSD: cryptodev.h,v 1.33 2002/07/17 23:52:39 art Exp $      */
 
@@ -140,7 +140,12 @@
 #define CRYPTO_CAMELLIA_CBC    26
 #define CRYPTO_AES_CTR         27
 #define CRYPTO_AES_XCBC_MAC_96 28
-#define CRYPTO_ALGORITHM_MAX   28 /* Keep updated - see below */
+#define CRYPTO_AES_GCM_16      29
+#define CRYPTO_AES_128_GMAC    30
+#define CRYPTO_AES_192_GMAC    31
+#define CRYPTO_AES_256_GMAC    32
+#define CRYPTO_AES_GMAC                33
+#define CRYPTO_ALGORITHM_MAX   33 /* Keep updated - see below */
 
 /* Algorithm flags */
 #define        CRYPTO_ALG_FLAG_SUPPORTED       0x01 /* Algorithm is supported */
diff -r 05c20fb69d3b -r 5b4c70e168d4 sys/opencrypto/cryptosoft.c
--- a/sys/opencrypto/cryptosoft.c       Thu May 26 21:20:26 2011 +0000
+++ b/sys/opencrypto/cryptosoft.c       Thu May 26 21:50:02 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cryptosoft.c,v 1.36 2011/05/24 19:10:10 drochner Exp $ */
+/*     $NetBSD: cryptosoft.c,v 1.37 2011/05/26 21:50:03 drochner Exp $ */
 /*     $FreeBSD: src/sys/opencrypto/cryptosoft.c,v 1.2.2.1 2002/11/21 23:34:23 sam Exp $       */
 /*     $OpenBSD: cryptosoft.c,v 1.35 2002/04/26 08:43:50 deraadt Exp $ */
 
@@ -24,7 +24,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.36 2011/05/24 19:10:10 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.37 2011/05/26 21:50:03 drochner Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -48,6 +48,7 @@
        SHA384_CTX sha384ctx;
        SHA512_CTX sha512ctx;
        aesxcbc_ctx aesxcbcctx;
+       AES_GMAC_CTX aesgmacctx;
 };
 
 struct swcr_data **swcr_sessions = NULL;
@@ -63,6 +64,7 @@
 
 static int swcr_encdec(struct cryptodesc *, const struct swcr_data *, void *, int);
 static int swcr_compdec(struct cryptodesc *, const struct swcr_data *, void *, int, int *);
+static int swcr_combined(struct cryptop *, int);
 static int swcr_process(void *, struct cryptop *, int);
 static int swcr_newsession(void *, u_int32_t *, struct cryptoini *);
 static int swcr_freesession(void *, u_int64_t);
@@ -562,6 +564,143 @@
 }
 
 /*
+ * Apply a combined encryption-authentication transformation
+ */
+static int
+swcr_combined(struct cryptop *crp, int outtype)
+{
+       uint32_t blkbuf[howmany(EALG_MAX_BLOCK_LEN, sizeof(uint32_t))];
+       u_char *blk = (u_char *)blkbuf;
+       u_char aalg[AALG_MAX_RESULT_LEN];
+       u_char iv[EALG_MAX_BLOCK_LEN];
+       union authctx ctx;
+       struct cryptodesc *crd, *crda = NULL, *crde = NULL;
+       struct swcr_data *sw, *swa, *swe = NULL;
+       const struct swcr_auth_hash *axf = NULL;
+       const struct swcr_enc_xform *exf = NULL;
+       void *buf = (void *)crp->crp_buf;
+       uint32_t *blkp;
+       int i, blksz = 0, ivlen = 0, len;
+
+       for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
+               for (sw = swcr_sessions[crp->crp_sid & 0xffffffff];
+                    sw && sw->sw_alg != crd->crd_alg;



Home | Main Index | Thread Index | Old Index