xref: /freebsd/sys/dev/wg/crypto.h (revision 744bfb213144c63cbaf38d91a1c4f7aebb9b9fbc)
1 /* SPDX-License-Identifier: MIT
2  *
3  * Copyright (C) 2015-2021 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
4  * Copyright (c) 2022 The FreeBSD Foundation
5  */
6 
7 #ifndef _WG_CRYPTO
8 #define _WG_CRYPTO
9 
10 #include <sys/param.h>
11 
12 struct mbuf;
13 
14 int crypto_init(void);
15 void crypto_deinit(void);
16 
17 enum chacha20poly1305_lengths {
18 	XCHACHA20POLY1305_NONCE_SIZE = 24,
19 	CHACHA20POLY1305_KEY_SIZE = 32,
20 	CHACHA20POLY1305_AUTHTAG_SIZE = 16
21 };
22 
23 #ifdef COMPAT_NEED_CHACHA20POLY1305
24 void
25 chacha20poly1305_encrypt(uint8_t *dst, const uint8_t *src, const size_t src_len,
26 			 const uint8_t *ad, const size_t ad_len,
27 			 const uint64_t nonce,
28 			 const uint8_t key[CHACHA20POLY1305_KEY_SIZE]);
29 
30 bool
31 chacha20poly1305_decrypt(uint8_t *dst, const uint8_t *src, const size_t src_len,
32 			 const uint8_t *ad, const size_t ad_len,
33 			 const uint64_t nonce,
34 			 const uint8_t key[CHACHA20POLY1305_KEY_SIZE]);
35 
36 void
37 xchacha20poly1305_encrypt(uint8_t *dst, const uint8_t *src,
38 			  const size_t src_len, const uint8_t *ad,
39 			  const size_t ad_len,
40 			  const uint8_t nonce[XCHACHA20POLY1305_NONCE_SIZE],
41 			  const uint8_t key[CHACHA20POLY1305_KEY_SIZE]);
42 
43 bool
44 xchacha20poly1305_decrypt(uint8_t *dst, const uint8_t *src,
45 			  const size_t src_len,  const uint8_t *ad,
46 			  const size_t ad_len,
47 			  const uint8_t nonce[XCHACHA20POLY1305_NONCE_SIZE],
48 			  const uint8_t key[CHACHA20POLY1305_KEY_SIZE]);
49 #else
50 #include <sys/endian.h>
51 #include <crypto/chacha20_poly1305.h>
52 
53 static inline void
54 chacha20poly1305_encrypt(uint8_t *dst, const uint8_t *src, const size_t src_len,
55 			 const uint8_t *ad, const size_t ad_len,
56 			 const uint64_t nonce,
57 			 const uint8_t key[CHACHA20POLY1305_KEY_SIZE])
58 {
59 	uint8_t nonce_bytes[8];
60 
61 	le64enc(nonce_bytes, nonce);
62 	chacha20_poly1305_encrypt(dst, src, src_len, ad, ad_len,
63 				  nonce_bytes, sizeof(nonce_bytes), key);
64 }
65 
66 static inline bool
67 chacha20poly1305_decrypt(uint8_t *dst, const uint8_t *src, const size_t src_len,
68 			 const uint8_t *ad, const size_t ad_len,
69 			 const uint64_t nonce,
70 			 const uint8_t key[CHACHA20POLY1305_KEY_SIZE])
71 {
72 	uint8_t nonce_bytes[8];
73 
74 	le64enc(nonce_bytes, nonce);
75 	return (chacha20_poly1305_decrypt(dst, src, src_len, ad, ad_len,
76 					  nonce_bytes, sizeof(nonce_bytes), key));
77 }
78 
79 static inline void
80 xchacha20poly1305_encrypt(uint8_t *dst, const uint8_t *src,
81 			  const size_t src_len, const uint8_t *ad,
82 			  const size_t ad_len,
83 			  const uint8_t nonce[XCHACHA20POLY1305_NONCE_SIZE],
84 			  const uint8_t key[CHACHA20POLY1305_KEY_SIZE])
85 {
86 	xchacha20_poly1305_encrypt(dst, src, src_len, ad, ad_len, nonce, key);
87 }
88 
89 static inline bool
90 xchacha20poly1305_decrypt(uint8_t *dst, const uint8_t *src,
91 			  const size_t src_len,  const uint8_t *ad,
92 			  const size_t ad_len,
93 			  const uint8_t nonce[XCHACHA20POLY1305_NONCE_SIZE],
94 			  const uint8_t key[CHACHA20POLY1305_KEY_SIZE])
95 {
96 	return (xchacha20_poly1305_decrypt(dst, src, src_len, ad, ad_len, nonce, key));
97 }
98 #endif
99 
100 int
101 chacha20poly1305_encrypt_mbuf(struct mbuf *, const uint64_t nonce,
102 			      const uint8_t key[CHACHA20POLY1305_KEY_SIZE]);
103 
104 int
105 chacha20poly1305_decrypt_mbuf(struct mbuf *, const uint64_t nonce,
106 			      const uint8_t key[CHACHA20POLY1305_KEY_SIZE]);
107 
108 
109 enum blake2s_lengths {
110 	BLAKE2S_BLOCK_SIZE = 64,
111 	BLAKE2S_HASH_SIZE = 32,
112 	BLAKE2S_KEY_SIZE = 32
113 };
114 
115 #ifdef COMPAT_NEED_BLAKE2S
116 struct blake2s_state {
117 	uint32_t h[8];
118 	uint32_t t[2];
119 	uint32_t f[2];
120 	uint8_t buf[BLAKE2S_BLOCK_SIZE];
121 	unsigned int buflen;
122 	unsigned int outlen;
123 };
124 
125 void blake2s_init(struct blake2s_state *state, const size_t outlen);
126 
127 void blake2s_init_key(struct blake2s_state *state, const size_t outlen,
128 		      const uint8_t *key, const size_t keylen);
129 
130 void blake2s_update(struct blake2s_state *state, const uint8_t *in, size_t inlen);
131 
132 void blake2s_final(struct blake2s_state *state, uint8_t *out);
133 
134 static inline void blake2s(uint8_t *out, const uint8_t *in, const uint8_t *key,
135 			   const size_t outlen, const size_t inlen, const size_t keylen)
136 {
137 	struct blake2s_state state;
138 
139 	if (keylen)
140 		blake2s_init_key(&state, outlen, key, keylen);
141 	else
142 		blake2s_init(&state, outlen);
143 
144 	blake2s_update(&state, in, inlen);
145 	blake2s_final(&state, out);
146 }
147 #endif
148 
149 #ifdef COMPAT_NEED_CURVE25519
150 enum curve25519_lengths {
151         CURVE25519_KEY_SIZE = 32
152 };
153 
154 bool curve25519(uint8_t mypublic[static CURVE25519_KEY_SIZE],
155 		const uint8_t secret[static CURVE25519_KEY_SIZE],
156 		const uint8_t basepoint[static CURVE25519_KEY_SIZE]);
157 
158 static inline bool
159 curve25519_generate_public(uint8_t pub[static CURVE25519_KEY_SIZE],
160 			   const uint8_t secret[static CURVE25519_KEY_SIZE])
161 {
162 	static const uint8_t basepoint[CURVE25519_KEY_SIZE] = { 9 };
163 
164 	return curve25519(pub, secret, basepoint);
165 }
166 
167 static inline void curve25519_clamp_secret(uint8_t secret[static CURVE25519_KEY_SIZE])
168 {
169         secret[0] &= 248;
170         secret[31] = (secret[31] & 127) | 64;
171 }
172 
173 static inline void curve25519_generate_secret(uint8_t secret[CURVE25519_KEY_SIZE])
174 {
175 	arc4random_buf(secret, CURVE25519_KEY_SIZE);
176 	curve25519_clamp_secret(secret);
177 }
178 #else
179 #include <crypto/curve25519.h>
180 #endif
181 
182 #endif
183