all repos — circe-vpn @ development

Circe VPN

core/peer_table.h (view raw)

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
#ifndef CIRCE_CORE_PEER_TABLE_H
#define CIRCE_CORE_PEER_TABLE_H

#include "mldsa/mldsa_native.h"
#include "mlkem/mlkem_native.h"
#include "proto_circe.h"
#include "tinycrypt/kangarootwelve128.h"
#include <stdbool.h>
#include <stdint.h>

struct circe_location
{
  enum
  {
    CIRCE_ADDRESS_IPV4,
    CIRCE_ADDRESS_IPV6,
  } ip_type;
  uint16_t port;
  union
  {
    uint8_t ipv4[4];
    uint8_t ipv6[16];
  } ip_addr;
};

#define CIRCE_PEER_TABLE_LEN 64
#define CIRCE_IDENTITY_LEN 64  // SHA-512 hash of hostname || island name
#define CIRCE_TUNNEL_ID_LEN 64 // Random bytes

enum circe_handshake_stage
{
  CIRCE_HANDSHAKE_STAGE_OPEN,
  CIRCE_HANDSHAKE_STAGE_ACK,
  CIRCE_HANDSHAKE_STAGE_ID,
  CIRCE_HANDSHAKE_STAGE_DONE,
};

struct circe_peer
{
  bool double_lan; // lan1 is not valid if false
  struct circe_location lan0_loc;
  struct circe_location lan1_loc;
  struct circe_location wan_loc;
  uint8_t relay_server_identity[CIRCE_IDENTITY_LEN]; // SERVERS DON'T USE THIS,
                                                     // ONLY CLIENTS DO

  uint8_t lan0_hash[32]; // SHA-256
  uint8_t lan1_hash[32];

  enum
  {
    CIRCE_ROUTE_LAN0,
    CIRCE_ROUTE_LAN1,
    CIRCE_ROUTE_WAN,
    CIRCE_ROUTE_RELAY,
  } current_route;

  uint8_t identity[CIRCE_IDENTITY_LEN];
  uint8_t mldsa_pubkey[MLDSA_PUBLICKEYBYTES (44)];

  uint8_t rx_key[32];
  uint8_t tx_key[32];

  uint8_t tunnel_id[64];

  uint64_t next_heartbeat_ms;
  uint64_t next_kex_ms;

  uint64_t last_seqn_tx;
  uint64_t last_seqn_rx;

  enum circe_handshake_stage last_handshake_stage;

  uint8_t dgram_rx_buffer[PROTO_CIRCE_V1_MAX_MSG_LEN];
  uint8_t dgram_tx_buffer[PROTO_CIRCE_V1_MAX_MSG_LEN];
  size_t dgram_tx_len;
  proto_circe_v1_rx_t dgram_rx_state;
  proto_circe_v1_tx_t dgram_tx_state;

  // ZERO ALL OF THESE AFTER KEY EXCHANGE IS COMPLETE
  uint8_t my_th2[64]; // SHA-512
  uint8_t my_th3[64]; // SHA-512
  uint8_t my_ecdh_privkey[32];
  uint8_t my_mlkem_privkey[MLKEM_SECRETKEYBYTES (768)];
  uint8_t prk[TCT_TURBOSHAKE128_STATE_LEN];

  enum
  {
    CIRCE_ROLE_EURYLOCHUS,
    CIRCE_ROLE_POLITES,
  } my_role;
};

#endif