LCOV - code coverage report
Current view: top level - plugins/wireguard - wireguard_chachapoly.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 47 47 100.0 %
Date: 2023-07-05 22:20:52 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*
       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:
       6             :  *
       7             :  *     http://www.apache.org/licenses/LICENSE-2.0
       8             :  *
       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.
      14             :  */
      15             : 
      16             : #include <wireguard/wireguard.h>
      17             : #include <wireguard/wireguard_chachapoly.h>
      18             : #include <wireguard/wireguard_hchacha20.h>
      19             : 
      20             : bool
      21        1745 : 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)
      25             : {
      26        1745 :   vnet_crypto_op_t _op, *op = &_op;
      27             :   u8 iv[12];
      28        1745 :   u8 tag_[NOISE_AUTHTAG_LEN] = {};
      29        1745 :   u8 src_[] = {};
      30             : 
      31        1745 :   clib_memset (iv, 0, 12);
      32        1745 :   clib_memcpy (iv + 4, &nonce, sizeof (nonce));
      33             : 
      34        1745 :   vnet_crypto_op_init (op, op_id);
      35             : 
      36        1745 :   op->tag_len = NOISE_AUTHTAG_LEN;
      37        1745 :   if (op_id == VNET_CRYPTO_OP_CHACHA20_POLY1305_DEC)
      38             :     {
      39        1313 :       op->tag = src + src_len - NOISE_AUTHTAG_LEN;
      40        1313 :       src_len -= NOISE_AUTHTAG_LEN;
      41        1313 :       op->flags |= VNET_CRYPTO_OP_FLAG_HMAC_CHECK;
      42             :     }
      43             :   else
      44         432 :     op->tag = tag_;
      45             : 
      46        1745 :   op->src = !src ? src_ : src;
      47        1745 :   op->len = src_len;
      48             : 
      49        1745 :   op->dst = dst;
      50        1745 :   op->key_index = key_index;
      51        1745 :   op->aad = aad;
      52        1745 :   op->aad_len = aad_len;
      53        1745 :   op->iv = iv;
      54             : 
      55        1745 :   vnet_crypto_process_ops (vm, op, 1);
      56        1745 :   if (op_id == VNET_CRYPTO_OP_CHACHA20_POLY1305_ENC)
      57             :     {
      58         432 :       clib_memcpy (dst + src_len, op->tag, NOISE_AUTHTAG_LEN);
      59             :     }
      60             : 
      61        1745 :   return (op->status == VNET_CRYPTO_OP_STATUS_COMPLETED);
      62             : }
      63             : 
      64             : void
      65          28 : wg_xchacha20poly1305_encrypt (vlib_main_t *vm, u8 *src, u32 src_len, u8 *dst,
      66             :                               u8 *aad, u32 aad_len,
      67             :                               u8 nonce[XCHACHA20POLY1305_NONCE_SIZE],
      68             :                               u8 key[CHACHA20POLY1305_KEY_SIZE])
      69             : {
      70             :   int i;
      71             :   u32 derived_key[CHACHA20POLY1305_KEY_SIZE / sizeof (u32)];
      72             :   u64 h_nonce;
      73             : 
      74          28 :   clib_memcpy (&h_nonce, nonce + 16, sizeof (h_nonce));
      75          28 :   h_nonce = le64toh (h_nonce);
      76          28 :   hchacha20 (derived_key, nonce, key);
      77             : 
      78         252 :   for (i = 0; i < (sizeof (derived_key) / sizeof (derived_key[0])); i++)
      79         224 :     (derived_key[i]) = htole32 ((derived_key[i]));
      80             : 
      81             :   uint32_t key_idx;
      82             : 
      83             :   key_idx =
      84          28 :     vnet_crypto_key_add (vm, VNET_CRYPTO_ALG_CHACHA20_POLY1305,
      85             :                          (uint8_t *) derived_key, CHACHA20POLY1305_KEY_SIZE);
      86             : 
      87          28 :   wg_chacha20poly1305_calc (vm, src, src_len, dst, aad, aad_len, h_nonce,
      88             :                             VNET_CRYPTO_OP_CHACHA20_POLY1305_ENC, key_idx);
      89             : 
      90          28 :   vnet_crypto_key_del (vm, key_idx);
      91          28 :   wg_secure_zero_memory (derived_key, CHACHA20POLY1305_KEY_SIZE);
      92          28 : }
      93             : 
      94             : bool
      95          16 : wg_xchacha20poly1305_decrypt (vlib_main_t *vm, u8 *src, u32 src_len, u8 *dst,
      96             :                               u8 *aad, u32 aad_len,
      97             :                               u8 nonce[XCHACHA20POLY1305_NONCE_SIZE],
      98             :                               u8 key[CHACHA20POLY1305_KEY_SIZE])
      99             : {
     100             :   int ret, i;
     101             :   u32 derived_key[CHACHA20POLY1305_KEY_SIZE / sizeof (u32)];
     102             :   u64 h_nonce;
     103             : 
     104          16 :   clib_memcpy (&h_nonce, nonce + 16, sizeof (h_nonce));
     105          16 :   h_nonce = le64toh (h_nonce);
     106          16 :   hchacha20 (derived_key, nonce, key);
     107             : 
     108         144 :   for (i = 0; i < (sizeof (derived_key) / sizeof (derived_key[0])); i++)
     109         128 :     (derived_key[i]) = htole32 ((derived_key[i]));
     110             : 
     111             :   uint32_t key_idx;
     112             : 
     113             :   key_idx =
     114          16 :     vnet_crypto_key_add (vm, VNET_CRYPTO_ALG_CHACHA20_POLY1305,
     115             :                          (uint8_t *) derived_key, CHACHA20POLY1305_KEY_SIZE);
     116             : 
     117          16 :   ret =
     118          16 :     wg_chacha20poly1305_calc (vm, src, src_len, dst, aad, aad_len, h_nonce,
     119             :                               VNET_CRYPTO_OP_CHACHA20_POLY1305_DEC, key_idx);
     120             : 
     121          16 :   vnet_crypto_key_del (vm, key_idx);
     122          16 :   wg_secure_zero_memory (derived_key, CHACHA20POLY1305_KEY_SIZE);
     123             : 
     124          16 :   return ret;
     125             : }
     126             : 
     127             : /*
     128             :  * fd.io coding-style-patch-verification: ON
     129             :  *
     130             :  * Local Variables:
     131             :  * eval: (c-set-style "gnu")
     132             :  * End:
     133             :  */

Generated by: LCOV version 1.14