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