2 * Copyright (c) 2022 Rubicon Communications, LLC.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 #include <wireguard/wireguard.h>
17 #include <wireguard/wireguard_chachapoly.h>
18 #include <wireguard/wireguard_hchacha20.h>
21 wg_chacha20poly1305_calc (vlib_main_t *vm, u8 *src, u32 src_len, u8 *dst,
22 u8 *aad, u32 aad_len, u64 nonce,
23 vnet_crypto_op_id_t op_id,
24 vnet_crypto_key_index_t key_index)
26 vnet_crypto_op_t _op, *op = &_op;
28 u8 tag_[NOISE_AUTHTAG_LEN] = {};
31 clib_memset (iv, 0, 12);
32 clib_memcpy (iv + 4, &nonce, sizeof (nonce));
34 vnet_crypto_op_init (op, op_id);
36 op->tag_len = NOISE_AUTHTAG_LEN;
37 if (op_id == VNET_CRYPTO_OP_CHACHA20_POLY1305_DEC)
39 op->tag = src + src_len - NOISE_AUTHTAG_LEN;
40 src_len -= NOISE_AUTHTAG_LEN;
41 op->flags |= VNET_CRYPTO_OP_FLAG_HMAC_CHECK;
46 op->src = !src ? src_ : src;
50 op->key_index = key_index;
52 op->aad_len = aad_len;
55 vnet_crypto_process_ops (vm, op, 1);
56 if (op_id == VNET_CRYPTO_OP_CHACHA20_POLY1305_ENC)
58 clib_memcpy (dst + src_len, op->tag, NOISE_AUTHTAG_LEN);
61 return (op->status == VNET_CRYPTO_OP_STATUS_COMPLETED);
65 wg_xchacha20poly1305_decrypt (vlib_main_t *vm, u8 *src, u32 src_len, u8 *dst,
67 u8 nonce[XCHACHA20POLY1305_NONCE_SIZE],
68 u8 key[CHACHA20POLY1305_KEY_SIZE])
71 u32 derived_key[CHACHA20POLY1305_KEY_SIZE / sizeof (u32)];
74 clib_memcpy (&h_nonce, nonce + 16, sizeof (h_nonce));
75 h_nonce = le64toh (h_nonce);
76 hchacha20 (derived_key, nonce, key);
78 for (i = 0; i < (sizeof (derived_key) / sizeof (derived_key[0])); i++)
79 (derived_key[i]) = htole32 ((derived_key[i]));
84 vnet_crypto_key_add (vm, VNET_CRYPTO_ALG_CHACHA20_POLY1305,
85 (uint8_t *) derived_key, CHACHA20POLY1305_KEY_SIZE);
88 wg_chacha20poly1305_calc (vm, src, src_len, dst, aad, aad_len, h_nonce,
89 VNET_CRYPTO_OP_CHACHA20_POLY1305_DEC, key_idx);
91 vnet_crypto_key_del (vm, key_idx);
92 wg_secure_zero_memory (derived_key, CHACHA20POLY1305_KEY_SIZE);
98 * fd.io coding-style-patch-verification: ON
101 * eval: (c-set-style "gnu")