PcapPlusPlus  Next
WireGuardLayer.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "Layer.h"
4 #include "IpAddress.h"
5 #include "MacAddress.h"
6 
8 
11 namespace pcpp
12 {
15  class WireGuardLayer : public Layer
16  {
17  protected:
18 #pragma pack(push, 1)
22  {
24  uint8_t messageType;
26  uint8_t reserved[3];
27  };
28 #pragma pack(pop)
29  static_assert(sizeof(wg_common_header) == 4, "wg_common_header size is not 4 bytes");
30 
31  wg_common_header* getBasicHeader() const
32  {
33  return reinterpret_cast<wg_common_header*>(m_Data);
34  }
35 
36  WireGuardLayer() = default;
37 
38  public:
41  {
43  Unknown = 0,
49  CookieReply = 3,
51  TransportData = 4
52  };
53 
59  WireGuardLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
60  : Layer(data, dataLen, prevLayer, packet, WireGuard)
61  {}
62 
67  static bool isWireGuardPorts(uint16_t portSrc, uint16_t portDst)
68  {
69  return (portSrc == 51820 || portDst == 51820);
70  }
71 
76  static bool isDataValid(const uint8_t* data, size_t dataLen);
77 
84  static WireGuardLayer* parseWireGuardLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
85 
87  std::string getMessageTypeAsString() const;
88 
90  uint8_t getMessageType() const;
91 
93  uint32_t getReserved() const;
94 
96  void setReserved(const std::array<uint8_t, 3>& reserved);
97 
99  void parseNextLayer() override
100  {}
101 
103  size_t getHeaderLen() const override;
104 
106  void computeCalculateFields() override
107  {}
108 
111  std::string toString() const override;
112 
115  {
116  return OsiModelNetworkLayer;
117  }
118 
121  {
123  }
124 
129  {
131  static std::vector<FieldDescriptor> all()
132  {
133  auto result = Layer::SerializedFields::all();
134  std::initializer_list<FieldDescriptor> extra{ MessageType, MessageTypeName };
135  std::copy(extra.begin(), extra.end(), std::back_inserter(result));
136  return result;
137  }
138 
141 
144 
145  // cppcheck-suppress duplInheritedMember
147  static constexpr uint16_t MaxID = Layer::SerializedFields::MaxID + 2;
148  };
149 
150  protected:
151  void serializeLayer(ObjectScope& serializer) const override;
152  };
153 
157  {
158  private:
159 #pragma pack(push, 1)
162  typedef struct wg_handshake_initiation : wg_common_header
163  {
165  uint32_t senderIndex;
167  uint8_t initiatorEphemeral[32];
169  uint8_t encryptedInitiatorStatic[48];
171  uint8_t encryptedTimestamp[28];
173  uint8_t mac1[16];
175  uint8_t mac2[16];
176  } wg_handshake_initiation;
177 #pragma pack(pop)
178  wg_handshake_initiation* getHandshakeInitiationHeader() const
179  {
180  return reinterpret_cast<wg_handshake_initiation*>(getBasicHeader());
181  }
182 
183  public:
189  WireGuardHandshakeInitiationLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
190  : WireGuardLayer(data, dataLen, prevLayer, packet)
191  {}
192 
198  static bool isDataValid(const uint8_t* data, size_t dataLen)
199  {
200  return data != nullptr && dataLen >= sizeof(wg_handshake_initiation);
201  }
202 
210  WireGuardHandshakeInitiationLayer(uint32_t senderIndex, const uint8_t initiatorEphemeral[32],
211  const uint8_t encryptedInitiatorStatic[48],
212  const uint8_t encryptedTimestamp[28], const uint8_t mac1[16],
213  const uint8_t mac2[16]);
214 
216  uint32_t getSenderIndex() const;
217 
219  std::array<uint8_t, 32> getInitiatorEphemeral() const;
220 
222  std::array<uint8_t, 48> getEncryptedInitiatorStatic() const;
223 
225  std::array<uint8_t, 28> getEncryptedTimestamp() const;
226 
228  std::array<uint8_t, 16> getMac1() const;
229 
231  std::array<uint8_t, 16> getMac2() const;
232 
234  void setSenderIndex(uint32_t senderIndex);
235 
237  void setInitiatorEphemeral(const std::array<uint8_t, 32>& initiatorEphemeral);
238 
240  void setEncryptedInitiatorStatic(const std::array<uint8_t, 48>& encryptedInitiatorStatic);
241 
243  void setEncryptedTimestamp(const std::array<uint8_t, 28>& encryptedTimestamp);
244 
246  void setMac1(const std::array<uint8_t, 16>& mac1);
247 
249  void setMac2(const std::array<uint8_t, 16>& mac2);
250 
251  // implement abstract methods
252 
255  {
257  }
258 
263  {
265  static std::vector<FieldDescriptor> all()
266  {
268  std::initializer_list<FieldDescriptor> extra{
270  };
271  std::copy(extra.begin(), extra.end(), std::back_inserter(result));
272  return result;
273  }
274 
277 
281 
285 
288 
290  static const FieldDescriptor Mac1;
291 
293  static const FieldDescriptor Mac2;
294  };
295 
296  protected:
297  void serializeLayer(ObjectScope& serializer) const override;
298  };
299 
303  {
304  private:
305 #pragma pack(push, 1)
308  typedef struct wg_handshake_response : wg_common_header
309  {
311  uint32_t senderIndex;
313  uint32_t receiverIndex;
315  uint8_t responderEphemeral[32];
317  uint8_t encryptedEmpty[16];
319  uint8_t mac1[16];
321  uint8_t mac2[16];
322  } wg_handshake_response;
323 #pragma pack(pop)
324 
325  wg_handshake_response* getHandshakeResponseHeader() const
326  {
327  return reinterpret_cast<wg_handshake_response*>(getBasicHeader());
328  }
329 
330  public:
336  WireGuardHandshakeResponseLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
337  : WireGuardLayer(data, dataLen, prevLayer, packet)
338  {}
339 
345  static bool isDataValid(const uint8_t* data, size_t dataLen)
346  {
347  return data != nullptr && dataLen >= sizeof(wg_handshake_response);
348  }
349 
357  WireGuardHandshakeResponseLayer(uint32_t senderIndex, uint32_t receiverIndex,
358  const uint8_t responderEphemeral[32], const uint8_t encryptedEmpty[16],
359  const uint8_t mac1[16], const uint8_t mac2[16]);
360 
362  uint32_t getSenderIndex() const;
363 
365  uint32_t getReceiverIndex() const;
366 
368  std::array<uint8_t, 32> getResponderEphemeral() const;
369 
371  std::array<uint8_t, 16> getEncryptedEmpty() const;
372 
374  std::array<uint8_t, 16> getMac1() const;
375 
377  std::array<uint8_t, 16> getMac2() const;
378 
380  void setSenderIndex(uint32_t senderIndex);
381 
383  void setReceiverIndex(uint32_t receiverIndex);
384 
386  void setResponderEphemeral(const std::array<uint8_t, 32>& responderEphemeral);
387 
389  void setEncryptedEmpty(const std::array<uint8_t, 16>& encryptedEmpty);
390 
392  void setMac1(const std::array<uint8_t, 16>& mac1);
393 
395  void setMac2(const std::array<uint8_t, 16>& mac2);
396 
397  // implement abstract methods
398 
401  {
403  }
404 
409  {
411  static std::vector<FieldDescriptor> all()
412  {
414  std::initializer_list<FieldDescriptor> extra{ SenderIndex, ReceiverIndex, ResponderEphemeral,
416  std::copy(extra.begin(), extra.end(), std::back_inserter(result));
417  return result;
418  }
419 
422 
425 
429 
433 
435  static const FieldDescriptor Mac1;
436 
438  static const FieldDescriptor Mac2;
439  };
440 
441  protected:
442  void serializeLayer(ObjectScope& serializer) const override;
443  };
444 
448  {
449  private:
450 #pragma pack(push, 1)
453  typedef struct wg_cookie_reply : wg_common_header
454  {
456  uint32_t receiverIndex;
458  uint8_t nonce[24];
460  uint8_t encryptedCookie[32];
461  } wg_cookie_reply;
462 #pragma pack(pop)
463 
464  wg_cookie_reply* getCookieReplyHeader() const
465  {
466  return reinterpret_cast<wg_cookie_reply*>(getBasicHeader());
467  }
468 
469  public:
475  WireGuardCookieReplyLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
476  : WireGuardLayer(data, dataLen, prevLayer, packet)
477  {}
478 
483  static bool isDataValid(const uint8_t* data, size_t dataLen)
484  {
485  return data != nullptr && dataLen >= sizeof(wg_cookie_reply);
486  }
487 
492  WireGuardCookieReplyLayer(uint32_t receiverIndex, const uint8_t nonce[24], const uint8_t encryptedCookie[32]);
493 
495  uint32_t getReceiverIndex() const;
496 
498  std::array<uint8_t, 24> getNonce() const;
499 
501  std::array<uint8_t, 32> getEncryptedCookie() const;
502 
504  void setReceiverIndex(uint32_t receiverIndex);
505 
507  void setNonce(const std::array<uint8_t, 24>& nonce);
508 
510  void setEncryptedCookie(const std::array<uint8_t, 32>& encryptedCookie);
511 
512  // implement abstract methods
513 
516  {
518  }
519 
524  {
526  static std::vector<FieldDescriptor> all()
527  {
529  std::initializer_list<FieldDescriptor> extra{ ReceiverIndex, Nonce, EncryptedCookie };
530  std::copy(extra.begin(), extra.end(), std::back_inserter(result));
531  return result;
532  }
533 
536 
538  static const FieldDescriptor Nonce;
539 
542  };
543 
544  protected:
545  void serializeLayer(ObjectScope& serializer) const override;
546  };
547 
551  {
552  private:
553 #pragma pack(push, 1)
556  typedef struct wg_transport_data : wg_common_header
557  {
559  uint32_t receiverIndex;
561  uint64_t counter;
563  uint8_t encryptedData[0];
564  } wg_transport_data;
565 #pragma pack(pop)
566 
567  wg_transport_data* getTransportHeader() const
568  {
569  return reinterpret_cast<wg_transport_data*>(getBasicHeader());
570  }
571 
572  public:
578  WireGuardTransportDataLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
579  : WireGuardLayer(data, dataLen, prevLayer, packet)
580  {}
581 
586  static bool isDataValid(const uint8_t* data, size_t dataLen)
587  {
588  return data != nullptr && dataLen >= sizeof(wg_transport_data);
589  }
590 
596  WireGuardTransportDataLayer(uint32_t receiverIndex, uint64_t counter, const uint8_t* encryptedData,
597  size_t encryptedDataLen);
598 
600  uint32_t getReceiverIndex() const;
601 
603  uint64_t getCounter() const;
604 
606  const uint8_t* getEncryptedData() const;
607 
609  void setReceiverIndex(uint32_t receiverIndex);
610 
612  void setCounter(uint64_t counter);
613 
617  void setEncryptedData(const uint8_t* encryptedData, size_t encryptedDataLen);
618 
619  // implement abstract methods
620 
623  {
625  }
626 
631  {
633  static std::vector<FieldDescriptor> all()
634  {
636  std::initializer_list<FieldDescriptor> extra{ ReceiverIndex, Counter };
637  std::copy(extra.begin(), extra.end(), std::back_inserter(result));
638  return result;
639  }
640 
643 
645  static const FieldDescriptor Counter;
646  };
647 
648  protected:
649  void serializeLayer(ObjectScope& serializer) const override;
650  };
651 } // namespace pcpp
Definition: Layer.h:117
Definition: Serializers.h:230
Definition: Packet.h:49
Definition: WireGuardLayer.h:157
void serializeLayer(ObjectScope &serializer) const override
void setMac2(const std::array< uint8_t, 16 > &mac2)
WireGuardMessageType getWireGuardMessageType() const override
Definition: WireGuardLayer.h:254
void setMac1(const std::array< uint8_t, 16 > &mac1)
std::array< uint8_t, 48 > getEncryptedInitiatorStatic() const
std::array< uint8_t, 16 > getMac1() const
WireGuardHandshakeInitiationLayer(uint32_t senderIndex, const uint8_t initiatorEphemeral[32], const uint8_t encryptedInitiatorStatic[48], const uint8_t encryptedTimestamp[28], const uint8_t mac1[16], const uint8_t mac2[16])
std::array< uint8_t, 16 > getMac2() const
static bool isDataValid(const uint8_t *data, size_t dataLen)
Definition: WireGuardLayer.h:198
std::array< uint8_t, 28 > getEncryptedTimestamp() const
void setEncryptedInitiatorStatic(const std::array< uint8_t, 48 > &encryptedInitiatorStatic)
WireGuardHandshakeInitiationLayer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet)
Definition: WireGuardLayer.h:189
void setEncryptedTimestamp(const std::array< uint8_t, 28 > &encryptedTimestamp)
std::array< uint8_t, 32 > getInitiatorEphemeral() const
void setInitiatorEphemeral(const std::array< uint8_t, 32 > &initiatorEphemeral)
void setSenderIndex(uint32_t senderIndex)
Definition: WireGuardLayer.h:303
void serializeLayer(ObjectScope &serializer) const override
std::array< uint8_t, 16 > getMac1() const
WireGuardHandshakeResponseLayer(uint32_t senderIndex, uint32_t receiverIndex, const uint8_t responderEphemeral[32], const uint8_t encryptedEmpty[16], const uint8_t mac1[16], const uint8_t mac2[16])
void setResponderEphemeral(const std::array< uint8_t, 32 > &responderEphemeral)
void setMac2(const std::array< uint8_t, 16 > &mac2)
void setReceiverIndex(uint32_t receiverIndex)
WireGuardMessageType getWireGuardMessageType() const override
Definition: WireGuardLayer.h:400
void setEncryptedEmpty(const std::array< uint8_t, 16 > &encryptedEmpty)
WireGuardHandshakeResponseLayer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet)
Definition: WireGuardLayer.h:336
void setMac1(const std::array< uint8_t, 16 > &mac1)
std::array< uint8_t, 16 > getMac2() const
void setSenderIndex(uint32_t senderIndex)
std::array< uint8_t, 32 > getResponderEphemeral() const
static bool isDataValid(const uint8_t *data, size_t dataLen)
Definition: WireGuardLayer.h:345
std::array< uint8_t, 16 > getEncryptedEmpty() const
Definition: WireGuardLayer.h:16
void setReserved(const std::array< uint8_t, 3 > &reserved)
OsiModelLayer getOsiModelLayer() const override
Definition: WireGuardLayer.h:114
size_t getHeaderLen() const override
static bool isWireGuardPorts(uint16_t portSrc, uint16_t portDst)
Definition: WireGuardLayer.h:67
virtual WireGuardMessageType getWireGuardMessageType() const
Definition: WireGuardLayer.h:120
WireGuardMessageType
WireGuard message types.
Definition: WireGuardLayer.h:41
@ HandshakeInitiation
Handshake Initiation message.
@ HandshakeResponse
Handshake Response message.
@ TransportData
Transport Data message.
@ Unknown
Unknown Initiation message.
static bool isDataValid(const uint8_t *data, size_t dataLen)
std::string toString() const override
uint32_t getReserved() const
std::string getMessageTypeAsString() const
static WireGuardLayer * parseWireGuardLayer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet)
void parseNextLayer() override
Does nothing for this layer (WireGuard layer is always last)
Definition: WireGuardLayer.h:99
void computeCalculateFields() override
No fields to compute or update, so this method is left empty.
Definition: WireGuardLayer.h:106
WireGuardLayer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet)
Definition: WireGuardLayer.h:59
uint8_t getMessageType() const
void serializeLayer(ObjectScope &serializer) const override
Definition: WireGuardLayer.h:551
void setEncryptedData(const uint8_t *encryptedData, size_t encryptedDataLen)
void setCounter(uint64_t counter)
static bool isDataValid(const uint8_t *data, size_t dataLen)
Definition: WireGuardLayer.h:586
void serializeLayer(ObjectScope &serializer) const override
WireGuardTransportDataLayer(uint32_t receiverIndex, uint64_t counter, const uint8_t *encryptedData, size_t encryptedDataLen)
WireGuardTransportDataLayer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet)
Definition: WireGuardLayer.h:578
const uint8_t * getEncryptedData() const
void setReceiverIndex(uint32_t receiverIndex)
WireGuardMessageType getWireGuardMessageType() const override
Definition: WireGuardLayer.h:622
const ProtocolType WireGuard
WireGuard protocol.
Definition: ProtocolType.h:240
The main namespace for the PcapPlusPlus lib.
Definition: AssertionUtils.h:19
OsiModelLayer
An enum representing OSI model layers.
Definition: ProtocolType.h:425
@ OsiModelNetworkLayer
Network layer (layer 3)
Definition: ProtocolType.h:431
Definition: Serializers.h:18
Definition: Layer.h:212
static std::vector< FieldDescriptor > all()
Definition: Layer.h:214
static constexpr uint16_t MaxID
Maximum field ID used by the layer.
Definition: Layer.h:229
static std::vector< FieldDescriptor > all()
Definition: WireGuardLayer.h:265
static const FieldDescriptor Mac2
Field descriptor for the 16-byte MAC2, written as a hex string with no separators.
Definition: WireGuardLayer.h:293
static const FieldDescriptor EncryptedTimestamp
Field descriptor for the 28-byte encrypted timestamp, written as a hex string with no separators.
Definition: WireGuardLayer.h:287
static const FieldDescriptor SenderIndex
Field descriptor for the sender index, written as a hex value.
Definition: WireGuardLayer.h:276
static const FieldDescriptor InitiatorEphemeral
Field descriptor for the 32-byte initiator ephemeral public key, written as a hex string with no sepa...
Definition: WireGuardLayer.h:280
static const FieldDescriptor Mac1
Field descriptor for the 16-byte MAC1, written as a hex string with no separators.
Definition: WireGuardLayer.h:290
static const FieldDescriptor EncryptedInitiatorStatic
Field descriptor for the 48-byte encrypted initiator static key, written as a hex string with no sepa...
Definition: WireGuardLayer.h:284
static const FieldDescriptor SenderIndex
Field descriptor for the sender index, written as a hex value.
Definition: WireGuardLayer.h:421
static const FieldDescriptor EncryptedEmpty
Field descriptor for the 16-byte encrypted empty field, written as a hex string with no separators.
Definition: WireGuardLayer.h:432
static const FieldDescriptor Mac1
Field descriptor for the 16-byte MAC1, written as a hex string with no separators.
Definition: WireGuardLayer.h:435
static std::vector< FieldDescriptor > all()
Definition: WireGuardLayer.h:411
static const FieldDescriptor ResponderEphemeral
Field descriptor for the 32-byte responder ephemeral public key, written as a hex string with no sepa...
Definition: WireGuardLayer.h:428
static const FieldDescriptor Mac2
Field descriptor for the 16-byte MAC2, written as a hex string with no separators.
Definition: WireGuardLayer.h:438
static const FieldDescriptor ReceiverIndex
Field descriptor for the receiver index, written as a hex value.
Definition: WireGuardLayer.h:424
Definition: WireGuardLayer.h:129
static constexpr uint16_t MaxID
Maximum field ID used by WireGuardLayer.
Definition: WireGuardLayer.h:147
static const FieldDescriptor MessageTypeName
Field descriptor for the message type name, written as a string.
Definition: WireGuardLayer.h:143
static const FieldDescriptor MessageType
Field descriptor for the raw message type value, written as a number.
Definition: WireGuardLayer.h:140
static std::vector< FieldDescriptor > all()
Definition: WireGuardLayer.h:131
Definition: WireGuardLayer.h:22
uint8_t reserved[3]
Reserved field (3 bytes)
Definition: WireGuardLayer.h:26
uint8_t messageType
Message type field.
Definition: WireGuardLayer.h:24
static const FieldDescriptor ReceiverIndex
Field descriptor for the receiver index, written as a hex value.
Definition: WireGuardLayer.h:642
static std::vector< FieldDescriptor > all()
Definition: WireGuardLayer.h:633
static const FieldDescriptor Counter
Field descriptor for the counter (nonce), written as a number.
Definition: WireGuardLayer.h:645