3a7feca0b02e0cc0e82ac807d92c766447f455e7
[platform/upstream/connectedhomeip.git] / src / transport / raw / MessageHeader.h
1 /*
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *
5  *    Licensed under the Apache License, Version 2.0 (the "License");
6  *    you may not use this file except in compliance with the License.
7  *    You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *    Unless required by applicable law or agreed to in writing, software
12  *    distributed under the License is distributed on an "AS IS" BASIS,
13  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *    See the License for the specific language governing permissions and
15  *    limitations under the License.
16  */
17
18 /**
19  * @file
20  * This file defines CHIP binary header encode/decode.
21  */
22
23 #pragma once
24
25 #include <cstddef>
26 #include <cstdint>
27 #include <string.h>
28
29 #include <type_traits>
30
31 #include <core/CHIPError.h>
32 #include <core/Optional.h>
33 #include <protocols/Protocols.h>
34 #include <support/BitFlags.h>
35 #include <system/SystemPacketBuffer.h>
36
37 namespace chip {
38
39 /// Convenience type to make it clear a number represents a node id.
40 typedef uint64_t NodeId;
41
42 static constexpr NodeId kUndefinedNodeId = 0ULL;
43 static constexpr NodeId kAnyNodeId       = 0xFFFFFFFFFFFFFFFFULL;
44 static constexpr size_t kMaxTagLen       = 16;
45
46 typedef int PacketHeaderFlags;
47
48 namespace Header {
49
50 enum class EncryptionType
51 {
52     kAESCCMTagLen8  = 0,
53     kAESCCMTagLen12 = 1,
54     kAESCCMTagLen16 = 2,
55 };
56
57 /**
58  *  @brief
59  *    The CHIP Exchange header flag bits.
60  */
61 enum class ExFlagValues : uint8_t
62 {
63     /// Set when current message is sent by the initiator of an exchange.
64     kExchangeFlag_Initiator = 0x01,
65
66     /// Set when current message is an acknowledgment for a previously received message.
67     kExchangeFlag_AckMsg = 0x02,
68
69     /// Set when current message is requesting an acknowledgment from the recipient.
70     kExchangeFlag_NeedsAck = 0x04,
71
72     /// Set when a vendor id is prepended to the Message Protocol Id field.
73     kExchangeFlag_VendorIdPresent = 0x10,
74 };
75
76 enum class InternalFlagValues : uint8_t
77 {
78     // Header flag indicates that the peer's group key message counter is not synchronized.
79     kPeerGroupMsgIdNotSynchronized = 0x01,
80 };
81
82 enum class FlagValues : uint16_t
83 {
84     /// Header flag specifying that a destination node id is included in the header.
85     kDestinationNodeIdPresent = 0x0100,
86
87     /// Header flag specifying that a source node id is included in the header.
88     kSourceNodeIdPresent = 0x0200,
89
90     /// Header flag specifying that it is a control message for secure session.
91     kSecureSessionControlMessage = 0x0800,
92
93     /// Header flag specifying that it is a encrypted message.
94     kSecure = 0x0001,
95
96 };
97
98 using Flags         = BitFlags<uint16_t, FlagValues>;
99 using ExFlags       = BitFlags<uint8_t, ExFlagValues>;
100 using InternalFlags = BitFlags<uint8_t, InternalFlagValues>;
101
102 // Header is a 16-bit value of the form
103 //  |  4 bit  | 4 bit |8 bit Security Flags|
104 //  +---------+-------+--------------------|
105 //  | version | Flags | P | C |Reserved| E |
106 //                      |   |            +---Encrypted
107 //                      |   +----------------Control message (TODO: Implement this)
108 //                      +--------------------Privacy enhancements (TODO: Implement this)
109 static constexpr uint16_t kFlagsMask = 0x0F01;
110
111 } // namespace Header
112
113 /**
114  * Handles encoding/decoding of CHIP packet message headers.
115  *
116  * Packet headers are **UNENCRYPTED** and are placed at the start of
117  * a message buffer.
118  */
119 class PacketHeader
120 {
121 public:
122     /**
123      * Gets the message id set in the header.
124      *
125      * Message IDs are expecte to monotonically increase by one for each mesage
126      * that has been sent.
127      */
128     uint32_t GetMessageId() const { return mMessageId; }
129
130     /**
131      * Gets the source node id in the current message.
132      *
133      * NOTE: the source node id is optional and may be missing.
134      */
135     const Optional<NodeId> & GetSourceNodeId() const { return mSourceNodeId; }
136
137     /**
138      * Gets the destination node id in the current message.
139      *
140      * NOTE: the destination node id is optional and may be missing.
141      */
142     const Optional<NodeId> & GetDestinationNodeId() const { return mDestinationNodeId; }
143
144     uint16_t GetEncryptionKeyID() const { return mEncryptionKeyID; }
145
146     Header::Flags & GetFlags() { return mFlags; }
147     const Header::Flags & GetFlags() const { return mFlags; }
148
149     /** Check if it's a secure session control message. */
150     bool IsSecureSessionControlMsg() const { return mFlags.Has(Header::FlagValues::kSecureSessionControlMessage); }
151
152     /** Check if the peer's group key message counter is not synchronized. */
153     bool IsPeerGroupMsgIdNotSynchronized() const
154     {
155         return mInternalFlags.Has(Header::InternalFlagValues::kPeerGroupMsgIdNotSynchronized);
156     }
157
158     Header::EncryptionType GetEncryptionType() const { return mEncryptionType; }
159
160     PacketHeader & SetSecureSessionControlMsg(bool value)
161     {
162         mFlags.Set(Header::FlagValues::kSecureSessionControlMessage, value);
163         return *this;
164     }
165
166     PacketHeader & SetPeerGroupMsgIdNotSynchronized(bool value)
167     {
168         mInternalFlags.Set(Header::InternalFlagValues::kPeerGroupMsgIdNotSynchronized, value);
169         return *this;
170     }
171
172     PacketHeader & SetSourceNodeId(NodeId id)
173     {
174         mSourceNodeId.SetValue(id);
175         mFlags.Set(Header::FlagValues::kSourceNodeIdPresent);
176         return *this;
177     }
178
179     PacketHeader & SetSourceNodeId(Optional<NodeId> id)
180     {
181         mSourceNodeId = id;
182         mFlags.Set(Header::FlagValues::kSourceNodeIdPresent, id.HasValue());
183         return *this;
184     }
185
186     PacketHeader & ClearSourceNodeId()
187     {
188         mSourceNodeId.ClearValue();
189         mFlags.Clear(Header::FlagValues::kSourceNodeIdPresent);
190         return *this;
191     }
192
193     PacketHeader & SetDestinationNodeId(NodeId id)
194     {
195         mDestinationNodeId.SetValue(id);
196         mFlags.Set(Header::FlagValues::kDestinationNodeIdPresent);
197         return *this;
198     }
199
200     PacketHeader & SetDestinationNodeId(Optional<NodeId> id)
201     {
202         mDestinationNodeId = id;
203         mFlags.Set(Header::FlagValues::kDestinationNodeIdPresent, id.HasValue());
204         return *this;
205     }
206
207     PacketHeader & ClearDestinationNodeId()
208     {
209         mDestinationNodeId.ClearValue();
210         mFlags.Clear(Header::FlagValues::kDestinationNodeIdPresent);
211         return *this;
212     }
213
214     PacketHeader & SetEncryptionKeyID(uint16_t id)
215     {
216         mEncryptionKeyID = id;
217         return *this;
218     }
219
220     PacketHeader & SetMessageId(uint32_t id)
221     {
222         mMessageId = id;
223         return *this;
224     }
225
226     PacketHeader & SetEncryptionType(Header::EncryptionType type)
227     {
228         mEncryptionType = type;
229         return *this;
230     }
231
232     /**
233      * A call to `Encode` will require at least this many bytes on the current
234      * object to be successful.
235      *
236      * @return the number of bytes needed in a buffer to be able to Encode.
237      */
238     uint16_t EncodeSizeBytes() const;
239
240     /**
241      * Decodes a header from the given buffer.
242      *
243      * @param data - the buffer to read from
244      * @param size - bytes available in the buffer
245      * @param decode_size - number of bytes read from the buffer to decode the
246      *                      object
247      *
248      * @return CHIP_NO_ERROR on success.
249      *
250      * Possible failures:
251      *    CHIP_ERROR_INVALID_ARGUMENT on insufficient buffer size
252      *    CHIP_ERROR_VERSION_MISMATCH if header version is not supported.
253      */
254     CHIP_ERROR Decode(const uint8_t * data, uint16_t size, uint16_t * decode_size);
255
256     /**
257      * A version of Decode that uses the type system to determine available
258      * space.
259      */
260     template <uint16_t N>
261     inline CHIP_ERROR Decode(const uint8_t (&data)[N], uint16_t * decode_size)
262     {
263         return Decode(data, N, decode_size);
264     }
265
266     /**
267      * A version of Decode that decodes from the start of a PacketBuffer and
268      * consumes the bytes we decoded from.
269      */
270     CHIP_ERROR DecodeAndConsume(const System::PacketBufferHandle & buf);
271
272     /**
273      * Encodes a header into the given buffer.
274      *
275      * @param data - the buffer to write to
276      * @param size - space available in the buffer (in bytes)
277      * @param encode_size - number of bytes written to the buffer.
278      *
279      * @return CHIP_NO_ERROR on success.
280      *
281      * Possible failures:
282      *    CHIP_ERROR_INVALID_ARGUMENT on insufficient buffer size
283      */
284     CHIP_ERROR Encode(uint8_t * data, uint16_t size, uint16_t * encode_size) const;
285
286     /**
287      * A version of Encode that uses the type system to determine available
288      * space.
289      */
290     template <int N>
291     inline CHIP_ERROR Encode(uint8_t (&data)[N], uint16_t * encode_size) const
292     {
293         return Encode(data, N, encode_size);
294     }
295
296     /**
297      * A version of Encode that encodes into a PacketBuffer before the
298      * PacketBuffer's current data.
299      */
300     CHIP_ERROR EncodeBeforeData(const System::PacketBufferHandle & buf) const;
301
302     /**
303      * A version of Encode that encodes into a PacketBuffer at the start of the
304      * current data space.  This assumes that someone has already preallocated
305      * space for the header.
306      */
307     inline CHIP_ERROR EncodeAtStart(const System::PacketBufferHandle & buf, uint16_t * encode_size) const
308     {
309         return Encode(buf->Start(), buf->DataLength(), encode_size);
310     }
311
312 private:
313     /// Represents the current encode/decode header version
314     static constexpr int kHeaderVersion = 2;
315
316     /// Value expected to be incremented for each message sent.
317     uint32_t mMessageId = 0;
318
319     /// What node the message originated from
320     Optional<NodeId> mSourceNodeId;
321
322     /// Intended recipient of the message.
323     Optional<NodeId> mDestinationNodeId;
324
325     /// Encryption Key ID
326     uint16_t mEncryptionKeyID = 0;
327
328     /// Message flags read from the message.
329     Header::Flags mFlags;
330
331     /// Message flags not encoded into the packet sent over wire.
332     Header::InternalFlags mInternalFlags;
333
334     /// Represents encryption type used for encrypting current packet
335     Header::EncryptionType mEncryptionType = Header::EncryptionType::kAESCCMTagLen16;
336 };
337
338 /**
339  * Handles encoding/decoding of CHIP payload headers.
340  *
341  * Payload headers are **ENCRYPTED** and are placed at the start of
342  * an encrypted message payload.
343  */
344 class PayloadHeader
345 {
346 public:
347     PayloadHeader & operator=(const PayloadHeader &) = default;
348
349     /**
350      * Gets the vendor id in the current message.
351      *
352      * NOTE: the vendor id is optional and may be missing.
353      */
354     const Optional<uint16_t> & GetVendorId() const { return mVendorId; }
355
356     /** Get the Session ID from this header. */
357     uint16_t GetExchangeID() const { return mExchangeID; }
358
359     /** Get the Protocol ID from this header. */
360     uint16_t GetProtocolID() const { return mProtocolID; }
361
362     /** Get the secure msg type from this header. */
363     uint8_t GetMessageType() const { return mMessageType; }
364
365     /** Check whether the header has a given secure message type */
366     bool HasMessageType(uint8_t type) const { return mMessageType == type; }
367     template <typename MessageType, typename = std::enable_if_t<std::is_enum<MessageType>::value>>
368     bool HasMessageType(MessageType type) const
369     {
370         static_assert(std::is_same<std::underlying_type_t<MessageType>, uint8_t>::value, "Enum is wrong size; cast is not safe");
371         return mProtocolID == Protocols::MessageTypeTraits<MessageType>::ProtocolId && HasMessageType(static_cast<uint8_t>(type));
372     }
373
374     /**
375      * Gets the Acknowledged Message Counter from this header.
376      *
377      * NOTE: the Acknowledged Message Counter is optional and may be missing.
378      */
379     const Optional<uint32_t> & GetAckId() const { return mAckId; }
380
381     /** Set the vendor id for this header. */
382     PayloadHeader & SetVendorId(uint16_t id)
383     {
384         mVendorId.SetValue(id);
385         mExchangeFlags.Set(Header::ExFlagValues::kExchangeFlag_VendorIdPresent);
386
387         return *this;
388     }
389
390     /** Set the vendor id for this header. */
391     PayloadHeader & SetVendorId(Optional<uint16_t> id)
392     {
393         mVendorId = id;
394         mExchangeFlags.Set(Header::ExFlagValues::kExchangeFlag_VendorIdPresent, id.HasValue());
395
396         return *this;
397     }
398
399     /** Clear the vendor id for this header. */
400     PayloadHeader & ClearVendorId()
401     {
402         mVendorId.ClearValue();
403
404         return *this;
405     }
406
407     /**
408      * Set the message type for this header.  This requires setting the protocol
409      * id as well, because the meaning of a message type is only relevant given
410      * a specific protocol.
411      *
412      * This should only be used for cases when we don't have a strongly typed
413      * message type and hence can't automatically determine the protocol from
414      * the message type.
415      */
416     PayloadHeader & SetMessageType(uint16_t protocol, uint8_t type)
417     {
418         mProtocolID  = protocol;
419         mMessageType = type;
420         return *this;
421     }
422
423     /** Set the secure message type, with the protocol id derived from the
424         message type. */
425     template <typename MessageType, typename = std::enable_if_t<std::is_enum<MessageType>::value>>
426     PayloadHeader & SetMessageType(MessageType type)
427     {
428         static_assert(std::is_same<std::underlying_type_t<MessageType>, uint8_t>::value, "Enum is wrong size; cast is not safe");
429         mMessageType = static_cast<uint8_t>(type);
430         mProtocolID  = Protocols::MessageTypeTraits<MessageType>::ProtocolId;
431         return *this;
432     }
433
434     /** Set the security session ID for this header. */
435     PayloadHeader & SetExchangeID(uint16_t id)
436     {
437         mExchangeID = id;
438         return *this;
439     }
440
441     /** Set the Initiator flag bit. */
442     PayloadHeader & SetInitiator(bool inInitiator)
443     {
444         mExchangeFlags.Set(Header::ExFlagValues::kExchangeFlag_Initiator, inInitiator);
445         return *this;
446     }
447
448     PayloadHeader & SetAckId(uint32_t id)
449     {
450         mAckId.SetValue(id);
451         mExchangeFlags.Set(Header::ExFlagValues::kExchangeFlag_AckMsg);
452         return *this;
453     }
454
455     /** Set the AckMsg flag bit. */
456     PayloadHeader & SetAckId(Optional<uint32_t> id)
457     {
458         mAckId = id;
459         mExchangeFlags.Set(Header::ExFlagValues::kExchangeFlag_AckMsg, id.HasValue());
460         return *this;
461     }
462
463     /** Set the NeedsAck flag bit. */
464     PayloadHeader & SetNeedsAck(bool inNeedsAck)
465     {
466         mExchangeFlags.Set(Header::ExFlagValues::kExchangeFlag_NeedsAck, inNeedsAck);
467         return *this;
468     }
469
470     /**
471      *  Determine whether the initiator of the exchange.
472      *
473      *  @return Returns 'true' if it is the initiator, else 'false'.
474      *
475      */
476     bool IsInitiator() const { return mExchangeFlags.Has(Header::ExFlagValues::kExchangeFlag_Initiator); }
477
478     /**
479      *  Determine whether the current message is an acknowledgment for a previously received message.
480      *
481      *  @return Returns 'true' if current message is an acknowledgment, else 'false'.
482      *
483      */
484     bool IsAckMsg() const { return mExchangeFlags.Has(Header::ExFlagValues::kExchangeFlag_AckMsg); }
485
486     /**
487      *  Determine whether current message is requesting an acknowledgment from the recipient.
488      *
489      *  @return Returns 'true' if the current message is requesting an acknowledgment from the recipient, else 'false'.
490      *
491      */
492     bool NeedsAck() const { return mExchangeFlags.Has(Header::ExFlagValues::kExchangeFlag_NeedsAck); }
493
494     /**
495      * A call to `Encode` will require at least this many bytes on the current
496      * object to be successful.
497      *
498      * @return the number of bytes needed in a buffer to be able to Encode.
499      */
500     uint16_t EncodeSizeBytes() const;
501
502     /**
503      * Decodes the encrypted header fields from the given buffer.
504      *
505      * @param data - the buffer to read from
506      * @param size - bytes available in the buffer
507      * @param decode_size - number of bytes read from the buffer to decode the
508      *                      object
509      *
510      * @return CHIP_NO_ERROR on success.
511      *
512      * Possible failures:
513      *    CHIP_ERROR_INVALID_ARGUMENT on insufficient buffer size
514      *    CHIP_ERROR_VERSION_MISMATCH if header version is not supported.
515      */
516     CHIP_ERROR Decode(const uint8_t * data, uint16_t size, uint16_t * decode_size);
517
518     /**
519      * A version of Decode that uses the type system to determine available
520      * space.
521      */
522     template <uint16_t N>
523     inline CHIP_ERROR Decode(const uint8_t (&data)[N], uint16_t * decode_size)
524     {
525         return Decode(data, N, decode_size);
526     }
527
528     /**
529      * A version of Decode that decodes from the start of a PacketBuffer and
530      * consumes the bytes we decoded from.
531      */
532     CHIP_ERROR DecodeAndConsume(const System::PacketBufferHandle & buf);
533
534     /**
535      * Encodes the encrypted part of the header into the given buffer.
536      *
537      * @param data - the buffer to write to
538      * @param size - space available in the buffer (in bytes)
539      * @param encode_size - number of bytes written to the buffer.
540      *
541      * @return CHIP_NO_ERROR on success.
542      *
543      * Possible failures:
544      *    CHIP_ERROR_INVALID_ARGUMENT on insufficient buffer size
545      */
546     CHIP_ERROR Encode(uint8_t * data, uint16_t size, uint16_t * encode_size) const;
547
548     /**
549      * A version of Encode that uses the type system to determine available
550      * space.
551      */
552     template <uint16_t N>
553     inline CHIP_ERROR Encode(uint8_t (&data)[N], uint16_t * decode_size) const
554     {
555         return Encode(data, N, decode_size);
556     }
557
558     /**
559      * A version of Encode that encodes into a PacketBuffer before the
560      * PacketBuffer's current data.
561      */
562     CHIP_ERROR EncodeBeforeData(const System::PacketBufferHandle & buf) const;
563
564     /**
565      * A version of Encode that encodes into a PacketBuffer at the start of the
566      * current data space.  This assumes that someone has already preallocated
567      * space for the header.
568      */
569     inline CHIP_ERROR EncodeAtStart(const System::PacketBufferHandle & buf, uint16_t * encode_size) const
570     {
571         return Encode(buf->Start(), buf->DataLength(), encode_size);
572     }
573
574 private:
575     /// Packet type (application data, security control packets, e.g. pairing,
576     /// configuration, rekey etc)
577     uint8_t mMessageType = 0;
578
579     /// Security session identifier
580     uint16_t mExchangeID = 0;
581
582     /// Vendor identifier
583     Optional<uint16_t> mVendorId;
584
585     /// Protocol identifier
586     uint16_t mProtocolID = 0;
587
588     /// Bit flag indicators for CHIP Exchange header
589     Header::ExFlags mExchangeFlags;
590
591     /// Message counter of a previous message that is being acknowledged by the current message
592     Optional<uint32_t> mAckId;
593 };
594
595 /** Handles encoding/decoding of CHIP message headers */
596 class MessageAuthenticationCode
597 {
598 public:
599     const uint8_t * GetTag() const { return &mTag[0]; }
600
601     /** Set the message auth tag for this header. */
602     MessageAuthenticationCode & SetTag(PacketHeader * header, Header::EncryptionType encType, uint8_t * tag, size_t len)
603     {
604         const size_t tagLen = TagLenForEncryptionType(encType);
605         if (tagLen > 0 && tagLen <= kMaxTagLen && len == tagLen)
606         {
607             header->SetEncryptionType(encType);
608             memcpy(&mTag, tag, tagLen);
609         }
610
611         return *this;
612     }
613
614     /**
615      * Decodes the Message Authentication Tag from the given buffer.
616      *
617      * @param packetHeader - header containing encryption information
618      * @param data - the buffer to read from
619      * @param size - bytes available in the buffer
620      * @param decode_size - number of bytes read from the buffer to decode the
621      *                      object
622      *
623      * @return CHIP_NO_ERROR on success.
624      *
625      * Possible failures:
626      *    CHIP_ERROR_INVALID_ARGUMENT on insufficient buffer size
627      *    CHIP_ERROR_VERSION_MISMATCH if header version is not supported.
628      */
629     CHIP_ERROR Decode(const PacketHeader & packetHeader, const uint8_t * data, uint16_t size, uint16_t * decode_size);
630
631     /**
632      * Encodes the Messae Authentication Tag into the given buffer.
633      *
634      * @param packetHeader - header containing encryption information
635      * @param data - the buffer to write to
636      * @param size - space available in the buffer (in bytes)
637      * @param encode_size - number of bytes written to the buffer.
638      *
639      * @return CHIP_NO_ERROR on success.
640      *
641      * Possible failures:
642      *    CHIP_ERROR_INVALID_ARGUMENT on insufficient buffer size
643      */
644     CHIP_ERROR Encode(const PacketHeader & packetHeader, uint8_t * data, uint16_t size, uint16_t * encode_size) const;
645
646     static uint16_t TagLenForEncryptionType(Header::EncryptionType encType);
647
648 private:
649     /// Message authentication tag generated at encryption of the message.
650     uint8_t mTag[kMaxTagLen];
651 };
652
653 } // namespace chip