diff options
author | Kristof Provost <kp@FreeBSD.org> | 2022-10-18 16:31:02 +0000 |
---|---|---|
committer | Kristof Provost <kp@FreeBSD.org> | 2022-11-02 13:19:04 +0000 |
commit | 9f8f3a8e9ad4fbdcdfd14eb4d3977e587ab41341 (patch) | |
tree | b71aea09daf3fb4f0e2b48f1fd9b1d2e140da373 | |
parent | e1274b5b2646a49c1e3efce6c9918c99716d3c07 (diff) | |
download | src-9f8f3a8e9ad4fbdcdfd14eb4d3977e587ab41341.tar.gz src-9f8f3a8e9ad4fbdcdfd14eb4d3977e587ab41341.zip |
ipsec: add support for CHACHA20POLY1305
Based on a patch by ae@.
Reviewed by: gbe (man page), pauamma (man page)
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D37180
-rw-r--r-- | lib/libipsec/pfkey_dump.c | 6 | ||||
-rw-r--r-- | sbin/setkey/setkey.8 | 4 | ||||
-rw-r--r-- | sbin/setkey/token.l | 2 | ||||
-rw-r--r-- | sys/net/pfkeyv2.h | 2 | ||||
-rw-r--r-- | sys/netipsec/key.c | 2 | ||||
-rw-r--r-- | sys/netipsec/keydb.h | 2 | ||||
-rw-r--r-- | sys/netipsec/xform_ah.c | 1 | ||||
-rw-r--r-- | sys/netipsec/xform_esp.c | 23 |
8 files changed, 33 insertions, 9 deletions
diff --git a/lib/libipsec/pfkey_dump.c b/lib/libipsec/pfkey_dump.c index f4a003b94905..99a02ae24bc4 100644 --- a/lib/libipsec/pfkey_dump.c +++ b/lib/libipsec/pfkey_dump.c @@ -150,6 +150,9 @@ static struct val2str str_alg_auth[] = { #ifdef SADB_X_AALG_AES_XCBC_MAC { SADB_X_AALG_AES_XCBC_MAC, "aes-xcbc-mac", }, #endif +#ifdef SADB_X_AALG_CHACHA20POLY1305 + { SADB_X_AALG_CHACHA20POLY1305, "chacha20-poly1305", }, +#endif { -1, NULL, }, }; @@ -171,6 +174,9 @@ static struct val2str str_alg_enc[] = { #ifdef SADB_X_EALG_AESGCM16 { SADB_X_EALG_AESGCM16, "aes-gcm-16", }, #endif +#ifdef SADB_X_EALG_CHACHA20POLY1305 + { SADB_X_EALG_CHACHA20POLY1305, "chacha20-poly1305", }, +#endif { -1, NULL, }, }; diff --git a/sbin/setkey/setkey.8 b/sbin/setkey/setkey.8 index ff36c53a2f7f..6df1839ca6e4 100644 --- a/sbin/setkey/setkey.8 +++ b/sbin/setkey/setkey.8 @@ -29,7 +29,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 13, 2022 +.Dd October 19, 2022 .Dt SETKEY 8 .Os .\" @@ -598,6 +598,7 @@ hmac-sha2-512 512 ah/esp: 256bit ICV (RFC4868) aes-xcbc-mac 128 ah/esp: 96bit ICV (RFC3566) 128 ah-old/esp-old: 128bit ICV (no document) tcp-md5 8 to 640 tcp: rfc2385 +chacha20-poly1305 256 ah/esp: 128bit ICV (RFC7634) .Ed .Ss Encryption Algorithms The following encryption algorithms can be used as the @@ -613,6 +614,7 @@ null 0 to 2048 rfc2410 aes-cbc 128/192/256 rfc3602 aes-ctr 160/224/288 rfc3686 aes-gcm-16 160/224/288 AEAD; rfc4106 +chacha20-poly1305 256 rfc7634 .Ed .Pp Note that the first 128/192/256 bits of a key for diff --git a/sbin/setkey/token.l b/sbin/setkey/token.l index 9a0cc9ea1915..1cf2a43fe323 100644 --- a/sbin/setkey/token.l +++ b/sbin/setkey/token.l @@ -147,6 +147,7 @@ tcp { yylval.num = 0; return(PR_TCP); } /* authentication alogorithm */ {hyphen}A { BEGIN S_AUTHALG; return(F_AUTH); } +<S_AUTHALG>chacha20-poly1305 { yylval.num = SADB_X_AALG_CHACHA20POLY1305; BEGIN INITIAL; return(ALG_AUTH); } <S_AUTHALG>hmac-sha1 { yylval.num = SADB_AALG_SHA1HMAC; BEGIN INITIAL; return(ALG_AUTH); } <S_AUTHALG>hmac-sha2-256 { yylval.num = SADB_X_AALG_SHA2_256; BEGIN INITIAL; return(ALG_AUTH); } <S_AUTHALG>hmac-sha2-384 { yylval.num = SADB_X_AALG_SHA2_384; BEGIN INITIAL; return(ALG_AUTH); } @@ -163,6 +164,7 @@ tcp { yylval.num = 0; return(PR_TCP); } <S_ENCALG>aes-cbc { yylval.num = SADB_X_EALG_AESCBC; BEGIN INITIAL; return(ALG_ENC); } <S_ENCALG>aes-ctr { yylval.num = SADB_X_EALG_AESCTR; BEGIN INITIAL; return(ALG_ENC_SALT); } <S_ENCALG>aes-gcm-16 { yylval.num = SADB_X_EALG_AESGCM16; BEGIN INITIAL; return(ALG_ENC_SALT); } +<S_ENCALG>chacha20-poly1305 { yylval.num = SADB_X_EALG_CHACHA20POLY1305; BEGIN INITIAL; return(ALG_ENC_SALT); } /* compression algorithms */ {hyphen}C { return(F_COMP); } diff --git a/sys/net/pfkeyv2.h b/sys/net/pfkeyv2.h index 4d607a4d8b13..6ac14efaa850 100644 --- a/sys/net/pfkeyv2.h +++ b/sys/net/pfkeyv2.h @@ -372,6 +372,7 @@ _Static_assert(sizeof(struct sadb_x_sa_replay) == 8, "struct size mismatch"); #define SADB_X_AALG_AES128GMAC 11 /* RFC4543 + Errata1821 */ #define SADB_X_AALG_AES192GMAC 12 #define SADB_X_AALG_AES256GMAC 13 +#define SADB_X_AALG_CHACHA20POLY1305 14 #define SADB_X_AALG_MD5 249 /* Keyed MD5 */ #define SADB_X_AALG_SHA 250 /* Keyed SHA */ #define SADB_X_AALG_NULL 251 /* null authentication */ @@ -387,6 +388,7 @@ _Static_assert(sizeof(struct sadb_x_sa_replay) == 8, "struct size mismatch"); #define SADB_X_EALG_AES 12 #define SADB_X_EALG_AESCBC 12 #define SADB_X_EALG_AESCTR 13 +#define SADB_X_EALG_CHACHA20POLY1305 15 #define SADB_X_EALG_AESGCM8 18 /* RFC4106 */ #define SADB_X_EALG_AESGCM12 19 #define SADB_X_EALG_AESGCM16 20 diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c index a7d691f09bb1..b8a47a6a678b 100644 --- a/sys/netipsec/key.c +++ b/sys/netipsec/key.c @@ -592,6 +592,7 @@ static struct supported_ealgs { { SADB_X_EALG_AESCTR, &enc_xform_aes_icm }, { SADB_X_EALG_AESGCM16, &enc_xform_aes_nist_gcm }, { SADB_X_EALG_AESGMAC, &enc_xform_aes_nist_gmac }, + { SADB_X_EALG_CHACHA20POLY1305, &enc_xform_chacha20_poly1305 }, }; static struct supported_aalgs { @@ -606,6 +607,7 @@ static struct supported_aalgs { { SADB_X_AALG_AES128GMAC, &auth_hash_nist_gmac_aes_128 }, { SADB_X_AALG_AES192GMAC, &auth_hash_nist_gmac_aes_192 }, { SADB_X_AALG_AES256GMAC, &auth_hash_nist_gmac_aes_256 }, + { SADB_X_AALG_CHACHA20POLY1305, &auth_hash_poly1305 }, }; static struct supported_calgs { diff --git a/sys/netipsec/keydb.h b/sys/netipsec/keydb.h index a2da0da613e2..4e55a9abc34b 100644 --- a/sys/netipsec/keydb.h +++ b/sys/netipsec/keydb.h @@ -200,6 +200,8 @@ struct secasvar { (_sav)->alg_enc == SADB_X_EALG_AESGCM12 || \ (_sav)->alg_enc == SADB_X_EALG_AESGCM16) #define SAV_ISCTR(_sav) ((_sav)->alg_enc == SADB_X_EALG_AESCTR) +#define SAV_ISCHACHA(_sav) \ + ((_sav)->alg_enc == SADB_X_EALG_CHACHA20POLY1305) #define SAV_ISCTRORGCM(_sav) (SAV_ISCTR((_sav)) || SAV_ISGCM((_sav))) #define IPSEC_SEQH_SHIFT 32 diff --git a/sys/netipsec/xform_ah.c b/sys/netipsec/xform_ah.c index 2600a49ebcdf..a504225ab929 100644 --- a/sys/netipsec/xform_ah.c +++ b/sys/netipsec/xform_ah.c @@ -131,6 +131,7 @@ xform_ah_authsize(const struct auth_hash *esph) alen = esph->hashsize / 2; /* RFC4868 2.3 */ break; + case CRYPTO_POLY1305: case CRYPTO_AES_NIST_GMAC: alen = esph->hashsize; break; diff --git a/sys/netipsec/xform_esp.c b/sys/netipsec/xform_esp.c index 4a94960fd2e1..4ae081ae7f2a 100644 --- a/sys/netipsec/xform_esp.c +++ b/sys/netipsec/xform_esp.c @@ -169,7 +169,8 @@ esp_init(struct secasvar *sav, struct xformsw *xsp) } /* subtract off the salt, RFC4106, 8.1 and RFC3686, 5.1 */ - keylen = _KEYLEN(sav->key_enc) - SAV_ISCTRORGCM(sav) * 4; + keylen = _KEYLEN(sav->key_enc) - SAV_ISCTRORGCM(sav) * 4 - + SAV_ISCHACHA(sav) * 4; if (txform->minkey > keylen || keylen > txform->maxkey) { DPRINTF(("%s: invalid key length %u, must be in the range " "[%u..%u] for algorithm %s\n", __func__, @@ -178,7 +179,7 @@ esp_init(struct secasvar *sav, struct xformsw *xsp) return EINVAL; } - if (SAV_ISCTRORGCM(sav)) + if (SAV_ISCTRORGCM(sav) || SAV_ISCHACHA(sav)) sav->ivlen = 8; /* RFC4106 3.1 and RFC3686 3.1 */ else sav->ivlen = txform->ivsize; @@ -226,6 +227,12 @@ esp_init(struct secasvar *sav, struct xformsw *xsp) csp.csp_mode = CSP_MODE_AEAD; if (sav->flags & SADB_X_SAFLAGS_ESN) csp.csp_flags |= CSP_F_SEPARATE_AAD; + } else if (sav->alg_enc == SADB_X_EALG_CHACHA20POLY1305) { + sav->alg_auth = SADB_X_AALG_CHACHA20POLY1305; + sav->tdb_authalgxform = &auth_hash_poly1305; + csp.csp_mode = CSP_MODE_AEAD; + if (sav->flags & SADB_X_SAFLAGS_ESN) + csp.csp_flags |= CSP_F_SEPARATE_AAD; } else if (sav->alg_auth != 0) { csp.csp_mode = CSP_MODE_ETA; if (sav->flags & SADB_X_SAFLAGS_ESN) @@ -238,7 +245,7 @@ esp_init(struct secasvar *sav, struct xformsw *xsp) if (csp.csp_cipher_alg != CRYPTO_NULL_CBC) { csp.csp_cipher_key = sav->key_enc->key_data; csp.csp_cipher_klen = _KEYBITS(sav->key_enc) / 8 - - SAV_ISCTRORGCM(sav) * 4; + SAV_ISCTRORGCM(sav) * 4 - SAV_ISCHACHA(sav) * 4; }; csp.csp_ivlen = txform->ivsize; @@ -368,7 +375,7 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) if (esph != NULL) { crp->crp_op = CRYPTO_OP_VERIFY_DIGEST; - if (SAV_ISGCM(sav)) + if (SAV_ISGCM(sav) || SAV_ISCHACHA(sav)) crp->crp_aad_length = 8; /* RFC4106 5, SPI + SN */ else crp->crp_aad_length = hlen; @@ -428,7 +435,7 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) crp->crp_payload_length = m->m_pkthdr.len - (skip + hlen + alen); /* Generate or read cipher IV. */ - if (SAV_ISCTRORGCM(sav)) { + if (SAV_ISCTRORGCM(sav) || SAV_ISCHACHA(sav)) { ivp = &crp->crp_iv[0]; /* @@ -811,7 +818,7 @@ esp_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav, SECREPLAY_UNLOCK(sav->replay); } cryptoid = sav->tdb_cryptoid; - if (SAV_ISCTRORGCM(sav)) + if (SAV_ISCTRORGCM(sav) || SAV_ISCHACHA(sav)) cntr = sav->cntr++; SECASVAR_RUNLOCK(sav); @@ -878,7 +885,7 @@ esp_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav, /* Generate cipher and ESP IVs. */ ivp = &crp->crp_iv[0]; - if (SAV_ISCTRORGCM(sav)) { + if (SAV_ISCTRORGCM(sav) || SAV_ISCHACHA(sav)) { /* * See comment in esp_input() for details on the * cipher IV. A simple per-SA counter stored in @@ -914,7 +921,7 @@ esp_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav, if (esph) { /* Authentication descriptor. */ crp->crp_op |= CRYPTO_OP_COMPUTE_DIGEST; - if (SAV_ISGCM(sav)) + if (SAV_ISGCM(sav) || SAV_ISCHACHA(sav)) crp->crp_aad_length = 8; /* RFC4106 5, SPI + SN */ else crp->crp_aad_length = hlen; |