diff options
author | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2010-09-22 14:04:10 +0000 |
---|---|---|
committer | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2010-09-22 14:04:10 +0000 |
commit | 97afe07d2323d09ba39e51a7a164327cc271f4a3 (patch) | |
tree | 9a9084ee5c2651032a69e868f2904ad53a2c61d3 /sbin | |
parent | 533fada97d278985d68180ce3facee30f580a937 (diff) |
Support AES-GCM-16 (as aes-gcm) and ENCR_NULL_AUTH_AES_GMAC
(as aes-gmac) encryption transformations in the ipsec.conf(5).
Available "enc" arguments denoting use of
1) AES-GCM-16:
aes-128-gcm for 160 bit key (128+nonce)
aes-192-gcm for 224 bit key (192+nonce)
aes-256-gcm for 288 bit key (256+nonce)
2) ENCR_NULL_AUTH_AES_GMAC:
aes-128-gmac for 160 bit key (128+nonce)
aes-192-gmac for 224 bit key (192+nonce)
aes-256-gmac for 288 bit key (256+nonce)
Please note that aes-gmac family performs no encryption and provides
no confidentiality and is intended for cases in which confidentiality
is not desired (it can be thought of as AH with NAT-T support).
Also, although this implementation supports manual keying, it's
use is strictly discouraged as AES-GCM security depends on frequent
re-keying. So it can be thought of as a debug facility only.
Example configuration:
ike esp from 172.23.61.36 to 172.23.61.156 \
quick enc aes-256-gcm \
psk humppa
Thoroughly tested by me and naddy. Works fine with Linux.
Requires updated pfkeyv2.h include file.
OK naddy
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/ipsecctl/ike.c | 51 | ||||
-rw-r--r-- | sbin/ipsecctl/ipsec.conf.5 | 14 | ||||
-rw-r--r-- | sbin/ipsecctl/ipsecctl.h | 7 | ||||
-rw-r--r-- | sbin/ipsecctl/parse.y | 98 | ||||
-rw-r--r-- | sbin/ipsecctl/pfkdump.c | 33 | ||||
-rw-r--r-- | sbin/ipsecctl/pfkey.c | 15 |
6 files changed, 161 insertions, 57 deletions
diff --git a/sbin/ipsecctl/ike.c b/sbin/ipsecctl/ike.c index d51dfe04250..13aeaa161ab 100644 --- a/sbin/ipsecctl/ike.c +++ b/sbin/ipsecctl/ike.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ike.c,v 1.67 2009/10/04 11:39:32 jsing Exp $ */ +/* $OpenBSD: ike.c,v 1.68 2010/09/22 14:04:09 mikeb Exp $ */ /* * Copyright (c) 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org> * @@ -161,6 +161,7 @@ static int ike_section_p2(struct ipsec_rule *r, FILE *fd) { char *exchange_type, *sprefix; + int needauth = 1; switch (r->p2ie) { case IKE_QM: @@ -224,6 +225,30 @@ ike_section_p2(struct ipsec_rule *r, FILE *fd) case ENCXF_AESCTR: fprintf(fd, "AESCTR"); break; + case ENCXF_AES_128_GCM: + fprintf(fd, "AESGCM-128"); + needauth = 0; + break; + case ENCXF_AES_192_GCM: + fprintf(fd, "AESGCM-192"); + needauth = 0; + break; + case ENCXF_AES_256_GCM: + fprintf(fd, "AESGCM-256"); + needauth = 0; + break; + case ENCXF_AES_128_GMAC: + fprintf(fd, "AESGMAC-128"); + needauth = 0; + break; + case ENCXF_AES_192_GMAC: + fprintf(fd, "AESGMAC-192"); + needauth = 0; + break; + case ENCXF_AES_256_GMAC: + fprintf(fd, "AESGMAC-256"); + needauth = 0; + break; case ENCXF_BLOWFISH: fprintf(fd, "BLF"); break; @@ -232,6 +257,7 @@ ike_section_p2(struct ipsec_rule *r, FILE *fd) break; case ENCXF_NULL: fprintf(fd, "NULL"); + needauth = 0; break; default: warnx("illegal transform %s", @@ -270,43 +296,44 @@ ike_section_p2(struct ipsec_rule *r, FILE *fd) warnx("illegal transform %s", r->p2xfs->authxf->name); return (-1); } - } else - fprintf(fd, "SHA2-256"); + fprintf(fd, "-"); + } else if (needauth) + fprintf(fd, "SHA2-256-"); if (r->p2xfs && r->p2xfs->groupxf) { switch (r->p2xfs->groupxf->id) { case GROUPXF_NONE: break; case GROUPXF_768: - fprintf(fd, "-PFS-GRP1"); + fprintf(fd, "PFS-GRP1"); break; case GROUPXF_1024: - fprintf(fd, "-PFS-GRP2"); + fprintf(fd, "PFS-GRP2"); break; case GROUPXF_1536: - fprintf(fd, "-PFS-GRP5"); + fprintf(fd, "PFS-GRP5"); break; case GROUPXF_2048: - fprintf(fd, "-PFS-GRP14"); + fprintf(fd, "PFS-GRP14"); break; case GROUPXF_3072: - fprintf(fd, "-PFS-GRP15"); + fprintf(fd, "PFS-GRP15"); break; case GROUPXF_4096: - fprintf(fd, "-PFS-GRP16"); + fprintf(fd, "PFS-GRP16"); break; case GROUPXF_6144: - fprintf(fd, "-PFS-GRP17"); + fprintf(fd, "PFS-GRP17"); break; case GROUPXF_8192: - fprintf(fd, "-PFS-GRP18"); + fprintf(fd, "PFS-GRP18"); break; default: warnx("illegal group %s", r->p2xfs->groupxf->name); return (-1); }; } else - fprintf(fd, "-PFS"); + fprintf(fd, "PFS"); fprintf(fd, "-SUITE force\n"); return (0); diff --git a/sbin/ipsecctl/ipsec.conf.5 b/sbin/ipsecctl/ipsec.conf.5 index f00a29fdfe6..f155f13866e 100644 --- a/sbin/ipsecctl/ipsec.conf.5 +++ b/sbin/ipsecctl/ipsec.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ipsec.conf.5,v 1.127 2010/09/19 20:59:20 jmc Exp $ +.\" $OpenBSD: ipsec.conf.5,v 1.128 2010/09/22 14:04:09 mikeb Exp $ .\" .\" Copyright (c) 2004 Mathieu Sauve-Frankel All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: September 19 2010 $ +.Dd $Mdocdate: September 22 2010 $ .Dt IPSEC.CONF 5 .Os .Sh NAME @@ -612,6 +612,12 @@ keyword: .It Li aes-192 Ta "192 bits" .It Li aes-256 Ta "256 bits" .It Li aesctr Ta "160 bits" Ta "[phase 2 only]" +.It Li aes-128-gcm Ta "160 bits" Ta "[phase 2 only]" +.It Li aes-192-gcm Ta "224 bits" Ta "[phase 2 only]" +.It Li aes-256-gcm Ta "288 bits" Ta "[phase 2 only]" +.It Li aes-128-gmac Ta "160 bits" Ta "[phase 2 only]" +.It Li aes-192-gmac Ta "224 bits" Ta "[phase 2 only]" +.It Li aes-256-gmac Ta "288 bits" Ta "[phase 2 only]" .It Li blowfish Ta "160 bits" .It Li cast Ta "128 bits" .It Li skipjack Ta "80 bits" @@ -630,6 +636,10 @@ This is because the most significant bit of each byte is used for parity. The keysize of AES-CTR is actually 128-bit. However as well as the key, a 32-bit nonce has to be supplied. Thus 160 bits of key material have to be supplied. +The same applies to AES-GCM and AES-GMAC. +.Pp +Please note that AES-GMAC performs no encryption and provides no +confidentiality. .Pp Using NULL with ESP will only provide authentication. This is useful in setups where AH can not be used, e.g. when NAT is involved. diff --git a/sbin/ipsecctl/ipsecctl.h b/sbin/ipsecctl/ipsecctl.h index e44dfb6d8e2..d0d88109eda 100644 --- a/sbin/ipsecctl/ipsecctl.h +++ b/sbin/ipsecctl/ipsecctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ipsecctl.h,v 1.59 2009/08/04 15:05:50 jsing Exp $ */ +/* $OpenBSD: ipsecctl.h,v 1.60 2010/09/22 14:04:09 mikeb Exp $ */ /* * Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org> * @@ -63,7 +63,9 @@ enum { }; enum { ENCXF_UNKNOWN, ENCXF_NONE, ENCXF_3DES_CBC, ENCXF_DES_CBC, ENCXF_AES, - ENCXF_AES_128, ENCXF_AES_192, ENCXF_AES_256, ENCXF_AESCTR, + ENCXF_AES_128, ENCXF_AES_192, ENCXF_AES_256, ENCXF_AESCTR, + ENCXF_AES_128_GCM, ENCXF_AES_192_GCM, ENCXF_AES_256_GCM, + ENCXF_AES_128_GMAC, ENCXF_AES_192_GMAC, ENCXF_AES_256_GMAC, ENCXF_BLOWFISH, ENCXF_CAST128, ENCXF_NULL, ENCXF_SKIPJACK }; enum { @@ -140,6 +142,7 @@ struct ipsec_xf { u_int16_t id; size_t keymin; size_t keymax; + int noauth; }; struct ipsec_transforms { diff --git a/sbin/ipsecctl/parse.y b/sbin/ipsecctl/parse.y index 13e33fc845d..0afe1c29767 100644 --- a/sbin/ipsecctl/parse.y +++ b/sbin/ipsecctl/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.148 2010/08/03 18:42:40 henning Exp $ */ +/* $OpenBSD: parse.y,v 1.149 2010/09/22 14:04:09 mikeb Exp $ */ /* * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -98,20 +98,26 @@ const struct ipsec_xf authxfs[] = { }; const struct ipsec_xf encxfs[] = { - { "unknown", ENCXF_UNKNOWN, 0, 0 }, - { "none", ENCXF_NONE, 0, 0 }, - { "3des-cbc", ENCXF_3DES_CBC, 24, 24 }, - { "des-cbc", ENCXF_DES_CBC, 8, 8 }, - { "aes", ENCXF_AES, 16, 32 }, - { "aes-128", ENCXF_AES_128, 16, 16 }, - { "aes-192", ENCXF_AES_192, 24, 24 }, - { "aes-256", ENCXF_AES_256, 32, 32 }, - { "aesctr", ENCXF_AESCTR, 16+4, 32+4 }, - { "blowfish", ENCXF_BLOWFISH, 5, 56 }, - { "cast128", ENCXF_CAST128, 5, 16 }, - { "null", ENCXF_NULL, 0, 0 }, - { "skipjack", ENCXF_SKIPJACK, 10, 10 }, - { NULL, 0, 0, 0 }, + { "unknown", ENCXF_UNKNOWN, 0, 0, 0 }, + { "none", ENCXF_NONE, 0, 0, 0 }, + { "3des-cbc", ENCXF_3DES_CBC, 24, 24, 0 }, + { "des-cbc", ENCXF_DES_CBC, 8, 8, 0 }, + { "aes", ENCXF_AES, 16, 32, 0 }, + { "aes-128", ENCXF_AES_128, 16, 16, 0 }, + { "aes-192", ENCXF_AES_192, 24, 24, 0 }, + { "aes-256", ENCXF_AES_256, 32, 32, 0 }, + { "aesctr", ENCXF_AESCTR, 16+4, 32+4, 0 }, + { "aes-128-gcm", ENCXF_AES_128_GCM, 16+4, 16+4, 1 }, + { "aes-192-gcm", ENCXF_AES_192_GCM, 24+4, 24+4, 1 }, + { "aes-256-gcm", ENCXF_AES_256_GCM, 32+4, 32+4, 1 }, + { "aes-128-gmac", ENCXF_AES_128_GMAC, 16+4, 16+4, 1 }, + { "aes-192-gmac", ENCXF_AES_192_GMAC, 24+4, 24+4, 1 }, + { "aes-256-gmac", ENCXF_AES_256_GMAC, 32+4, 32+4, 1 }, + { "blowfish", ENCXF_BLOWFISH, 5, 56, 0 }, + { "cast128", ENCXF_CAST128, 5, 16, 0 }, + { "null", ENCXF_NULL, 0, 0, 0 }, + { "skipjack", ENCXF_SKIPJACK, 10, 10, 0 }, + { NULL, 0, 0, 0, 0 }, }; const struct ipsec_xf compxfs[] = { @@ -2209,10 +2215,14 @@ validate_sa(u_int32_t spi, u_int8_t satype, struct ipsec_transforms *xfs, yyerror("esp does not provide compression"); return (0); } - if (!xfs->authxf) - xfs->authxf = &authxfs[AUTHXF_HMAC_SHA2_256]; if (!xfs->encxf) xfs->encxf = &encxfs[ENCXF_AES]; + if (xfs->encxf->noauth && xfs->authxf) { + yyerror("authentication is implicit for %s", + xfs->encxf->name); + return (0); + } else if (!xfs->encxf->noauth && !xfs->authxf) + xfs->authxf = &authxfs[AUTHXF_HMAC_SHA2_256]; } if (satype == IPSEC_IPCOMP) { if (!xfs) { @@ -2694,28 +2704,7 @@ create_ike(u_int8_t proto, struct ipsec_hosts *hosts, if ((hosts->sport != 0 || hosts->dport != 0) && (proto != IPPROTO_TCP && proto != IPPROTO_UDP)) { yyerror("no protocol supplied with source/destination ports"); - free(r); - free(hosts->src); - hosts->src = NULL; - free(hosts->dst); - hosts->dst = NULL; - if (phase1mode) { - free(phase1mode->xfs); - phase1mode->xfs = NULL; - free(phase1mode->life); - phase1mode->life = NULL; - } - if (phase2mode) { - free(phase2mode->xfs); - phase2mode->xfs = NULL; - free(phase2mode->life); - phase2mode->life = NULL; - } - if (srcid) - free(srcid); - if (dstid) - free(dstid); - return NULL; + goto errout; } r->satype = satype; @@ -2729,6 +2718,13 @@ create_ike(u_int8_t proto, struct ipsec_hosts *hosts, r->p1ie = IKE_MM; } if (phase2mode) { + if (phase2mode->xfs && phase2mode->xfs->encxf && + phase2mode->xfs->encxf->noauth && + phase2mode->xfs->authxf) { + yyerror("authentication is implicit for %s", + phase2mode->xfs->encxf->name); + goto errout; + } r->p2xfs = phase2mode->xfs; r->p2life = phase2mode->life; r->p2ie = phase2mode->ike_exch; @@ -2751,4 +2747,28 @@ create_ike(u_int8_t proto, struct ipsec_hosts *hosts, r->tag = tag; return (r); + +errout: + free(r); + free(hosts->src); + hosts->src = NULL; + free(hosts->dst); + hosts->dst = NULL; + if (phase1mode) { + free(phase1mode->xfs); + phase1mode->xfs = NULL; + free(phase1mode->life); + phase1mode->life = NULL; + } + if (phase2mode) { + free(phase2mode->xfs); + phase2mode->xfs = NULL; + free(phase2mode->life); + phase2mode->life = NULL; + } + if (srcid) + free(srcid); + if (dstid) + free(dstid); + return NULL; } diff --git a/sbin/ipsecctl/pfkdump.c b/sbin/ipsecctl/pfkdump.c index 7b6831855f5..8c502d0b85c 100644 --- a/sbin/ipsecctl/pfkdump.c +++ b/sbin/ipsecctl/pfkdump.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfkdump.c,v 1.27 2010/07/01 02:11:35 reyk Exp $ */ +/* $OpenBSD: pfkdump.c,v 1.28 2010/09/22 14:04:09 mikeb Exp $ */ /* * Copyright (c) 2003 Markus Friedl. All rights reserved. @@ -153,6 +153,9 @@ struct idname auth_types[] = { { SADB_X_AALG_SHA2_256, "hmac-sha2-256", NULL }, { SADB_X_AALG_SHA2_384, "hmac-sha2-384", NULL }, { SADB_X_AALG_SHA2_512, "hmac-sha2-512", NULL }, + { SADB_X_AALG_AES128GMAC, "gmac-aes-128", NULL }, + { SADB_X_AALG_AES192GMAC, "gmac-aes-192", NULL }, + { SADB_X_AALG_AES256GMAC, "gmac-aes-256", NULL }, { SADB_X_AALG_MD5, "md5", NULL }, { SADB_X_AALG_SHA1, "sha1", NULL }, { 0, NULL, NULL } @@ -171,6 +174,8 @@ struct idname enc_types[] = { { SADB_X_EALG_3IDEA, "idea3", NULL }, { SADB_X_EALG_AES, "aes", NULL }, { SADB_X_EALG_AESCTR, "aesctr", NULL }, + { SADB_X_EALG_AESGCM16, "aes-gcm", NULL }, + { SADB_X_EALG_AESGMAC, "aes-gmac", NULL }, { SADB_X_EALG_BLF, "blowfish", NULL }, { SADB_X_EALG_CAST, "cast128", NULL }, { SADB_X_EALG_DES_IV32, "des-iv32", NULL }, @@ -708,6 +713,32 @@ pfkey_print_sa(struct sadb_msg *msg, int opts) case SADB_X_EALG_AESCTR: xfs.encxf = &encxfs[ENCXF_AESCTR]; break; + case SADB_X_EALG_AESGCM16: + switch (r.enckey->len) { + case 28: + xfs.encxf = &encxfs[ENCXF_AES_192_GCM]; + break; + case 36: + xfs.encxf = &encxfs[ENCXF_AES_256_GCM]; + break; + default: + xfs.encxf = &encxfs[ENCXF_AES_128_GCM]; + break; + } + break; + case SADB_X_EALG_AESGMAC: + switch (r.enckey->len) { + case 28: + xfs.encxf = &encxfs[ENCXF_AES_192_GMAC]; + break; + case 36: + xfs.encxf = &encxfs[ENCXF_AES_256_GMAC]; + break; + default: + xfs.encxf = &encxfs[ENCXF_AES_128_GMAC]; + break; + } + break; case SADB_X_EALG_BLF: xfs.encxf = &encxfs[ENCXF_BLOWFISH]; break; diff --git a/sbin/ipsecctl/pfkey.c b/sbin/ipsecctl/pfkey.c index c1c88e3bf52..ad8dc2c14ad 100644 --- a/sbin/ipsecctl/pfkey.c +++ b/sbin/ipsecctl/pfkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfkey.c,v 1.49 2008/12/22 17:00:37 hshoexer Exp $ */ +/* $OpenBSD: pfkey.c,v 1.50 2010/09/22 14:04:09 mikeb Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> * Copyright (c) 2003, 2004 Markus Friedl <markus@openbsd.org> @@ -488,11 +488,24 @@ pfkey_sa(int sd, u_int8_t satype, u_int8_t action, u_int32_t spi, sa.sadb_sa_encrypt = SADB_EALG_DESCBC; break; case ENCXF_AES: + case ENCXF_AES_128: + case ENCXF_AES_192: + case ENCXF_AES_256: sa.sadb_sa_encrypt = SADB_X_EALG_AES; break; case ENCXF_AESCTR: sa.sadb_sa_encrypt = SADB_X_EALG_AESCTR; break; + case ENCXF_AES_128_GCM: + case ENCXF_AES_192_GCM: + case ENCXF_AES_256_GCM: + sa.sadb_sa_encrypt = SADB_X_EALG_AESGCM16; + break; + case ENCXF_AES_128_GMAC: + case ENCXF_AES_192_GMAC: + case ENCXF_AES_256_GMAC: + sa.sadb_sa_encrypt = SADB_X_EALG_AESGMAC; + break; case ENCXF_BLOWFISH: sa.sadb_sa_encrypt = SADB_X_EALG_BLF; break; |