crypto: use OCF to encrypt/decrypt packets when supported
This requires the the recent changes in FreeBSD to support the Chacha20-Poly1305 AEAD cipher with support for an 8 byte nonce (vs the 12 byte nonce used by TLS and IPsec). Signed-off-by: John Baldwin <jhb@FreeBSD.org>
This commit is contained in:
parent
b7441e3154
commit
a6354a1436
93
src/crypto.c
93
src/crypto.c
|
@ -5,10 +5,16 @@
|
|||
|
||||
#include <sys/types.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/systm.h>
|
||||
#include <opencrypto/cryptodev.h>
|
||||
|
||||
#include "crypto.h"
|
||||
|
||||
#ifdef OCF_CHACHA20_POLY1305
|
||||
static crypto_session_t chacha20_poly1305_sid;
|
||||
#endif
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#endif
|
||||
|
@ -587,6 +593,63 @@ chacha20poly1305_decrypt(uint8_t *dst, const uint8_t *src, const size_t src_len,
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef OCF_CHACHA20_POLY1305
|
||||
static int
|
||||
crypto_callback(struct cryptop *crp)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
chacha20poly1305_encrypt_mbuf(struct mbuf *m, const uint64_t nonce,
|
||||
const uint8_t key[CHACHA20POLY1305_KEY_SIZE])
|
||||
{
|
||||
static char blank_tag[POLY1305_HASH_LEN];
|
||||
struct cryptop crp;
|
||||
int error;
|
||||
|
||||
if (!m_append(m, POLY1305_HASH_LEN, blank_tag))
|
||||
return (ENOMEM);
|
||||
crypto_initreq(&crp, chacha20_poly1305_sid);
|
||||
crp.crp_op = CRYPTO_OP_ENCRYPT | CRYPTO_OP_COMPUTE_DIGEST;
|
||||
crp.crp_flags = CRYPTO_F_IV_SEPARATE | CRYPTO_F_CBIMM;
|
||||
crypto_use_mbuf(&crp, m);
|
||||
crp.crp_payload_length = m->m_pkthdr.len - POLY1305_HASH_LEN;
|
||||
crp.crp_digest_start = crp.crp_payload_length;
|
||||
le64enc(crp.crp_iv, nonce);
|
||||
crp.crp_cipher_key = key;
|
||||
crp.crp_callback = crypto_callback;
|
||||
error = crypto_dispatch(&crp);
|
||||
crypto_destroyreq(&crp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
chacha20poly1305_decrypt_mbuf(struct mbuf *m, const uint64_t nonce,
|
||||
const uint8_t key[CHACHA20POLY1305_KEY_SIZE])
|
||||
{
|
||||
struct cryptop crp;
|
||||
int error;
|
||||
|
||||
if (m->m_pkthdr.len < POLY1305_HASH_LEN)
|
||||
return (EMSGSIZE);
|
||||
crypto_initreq(&crp, chacha20_poly1305_sid);
|
||||
crp.crp_op = CRYPTO_OP_DECRYPT | CRYPTO_OP_VERIFY_DIGEST;
|
||||
crp.crp_flags = CRYPTO_F_IV_SEPARATE | CRYPTO_F_CBIMM;
|
||||
crypto_use_mbuf(&crp, m);
|
||||
crp.crp_payload_length = m->m_pkthdr.len - POLY1305_HASH_LEN;
|
||||
crp.crp_digest_start = crp.crp_payload_length;
|
||||
le64enc(crp.crp_iv, nonce);
|
||||
crp.crp_cipher_key = key;
|
||||
crp.crp_callback = crypto_callback;
|
||||
error = crypto_dispatch(&crp);
|
||||
crypto_destroyreq(&crp);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
m_adj(m, -POLY1305_HASH_LEN);
|
||||
return (0);
|
||||
}
|
||||
#else
|
||||
static inline int
|
||||
chacha20poly1305_crypt_mbuf(struct mbuf *m0, uint64_t nonce,
|
||||
const uint8_t key[CHACHA20POLY1305_KEY_SIZE], bool encrypt)
|
||||
|
@ -678,6 +741,7 @@ chacha20poly1305_decrypt_mbuf(struct mbuf *m, const uint64_t nonce,
|
|||
{
|
||||
return chacha20poly1305_crypt_mbuf(m, nonce, key, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
xchacha20poly1305_encrypt(uint8_t *dst, const uint8_t *src,
|
||||
|
@ -1784,3 +1848,32 @@ bool curve25519(uint8_t out[CURVE25519_KEY_SIZE],
|
|||
|
||||
return timingsafe_bcmp(out, curve25519_null_point, CURVE25519_KEY_SIZE) != 0;
|
||||
}
|
||||
|
||||
int
|
||||
crypto_init(void)
|
||||
{
|
||||
#ifdef OCF_CHACHA20_POLY1305
|
||||
struct crypto_session_params csp;
|
||||
int error;
|
||||
|
||||
memset(&csp, 0, sizeof(csp));
|
||||
csp.csp_mode = CSP_MODE_AEAD;
|
||||
csp.csp_ivlen = sizeof(uint64_t);
|
||||
csp.csp_cipher_alg = CRYPTO_CHACHA20_POLY1305;
|
||||
csp.csp_cipher_klen = CHACHA20POLY1305_KEY_SIZE;
|
||||
csp.csp_flags = CSP_F_SEPARATE_AAD | CSP_F_SEPARATE_OUTPUT;
|
||||
error = crypto_newsession(&chacha20_poly1305_sid, &csp,
|
||||
CRYPTOCAP_F_SOFTWARE);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
crypto_deinit(void)
|
||||
{
|
||||
#ifdef OCF_CHACHA20_POLY1305
|
||||
crypto_freesession(chacha20_poly1305_sid);
|
||||
#endif
|
||||
}
|
||||
|
|
10
src/crypto.h
10
src/crypto.h
|
@ -6,9 +6,14 @@
|
|||
#ifndef _WG_CRYPTO
|
||||
#define _WG_CRYPTO
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/mbuf.h>
|
||||
|
||||
#if __FreeBSD_version >= 1400036 || \
|
||||
(__FreeBSD_version < 1400000 && __FreeBSD_version >= 1300519)
|
||||
#define OCF_CHACHA20_POLY1305
|
||||
#endif
|
||||
|
||||
enum chacha20poly1305_lengths {
|
||||
XCHACHA20POLY1305_NONCE_SIZE = 24,
|
||||
CHACHA20POLY1305_KEY_SIZE = 32,
|
||||
|
@ -109,4 +114,7 @@ static inline void curve25519_generate_secret(uint8_t secret[CURVE25519_KEY_SIZE
|
|||
curve25519_clamp_secret(secret);
|
||||
}
|
||||
|
||||
int crypto_init(void);
|
||||
void crypto_deinit(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2980,8 +2980,11 @@ wg_module_init(void)
|
|||
if ((wg_packet_zone = uma_zcreate("wg packet", sizeof(struct wg_packet),
|
||||
NULL, NULL, NULL, NULL, 0, 0)) == NULL)
|
||||
goto free_none;
|
||||
if (cookie_init() != 0)
|
||||
ret = crypto_init();
|
||||
if (ret != 0)
|
||||
goto free_zone;
|
||||
if (cookie_init() != 0)
|
||||
goto free_crypto;
|
||||
|
||||
wg_osd_jail_slot = osd_jail_register(NULL, methods);
|
||||
|
||||
|
@ -2994,6 +2997,8 @@ wg_module_init(void)
|
|||
free_all:
|
||||
osd_jail_deregister(wg_osd_jail_slot);
|
||||
cookie_deinit();
|
||||
free_crypto:
|
||||
crypto_deinit();
|
||||
free_zone:
|
||||
uma_zdestroy(wg_packet_zone);
|
||||
free_none:
|
||||
|
@ -3017,6 +3022,7 @@ wg_module_deinit(void)
|
|||
MPASS(LIST_EMPTY(&wg_list));
|
||||
osd_jail_deregister(wg_osd_jail_slot);
|
||||
cookie_deinit();
|
||||
crypto_deinit();
|
||||
uma_zdestroy(wg_packet_zone);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue