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
This commit is contained in:
parent
e1274b5b26
commit
9f8f3a8e9a
@ -149,6 +149,9 @@ static struct val2str str_alg_auth[] = {
|
||||
#endif
|
||||
#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, },
|
||||
};
|
||||
@ -170,6 +173,9 @@ static struct val2str str_alg_enc[] = {
|
||||
#endif
|
||||
#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, },
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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); }
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user