knx
ETS configurable knx-stack
secure_application_layer.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "application_layer.h"
4 #include <stdint.h>
5 #include "knx_types.h"
6 #include "apdu.h"
7 #include "bits.h"
8 #include "simple_map.h"
9 
10 class DeviceObject;
13 class AddressTableObject;
14 class BusAccessUnit;
23 {
24  public:
31 
32  void groupAddressTable(AddressTableObject& addrTable);
33 
34  // from transport layer
35  void dataGroupIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu) override;
36  void dataGroupConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap,
37  APDU& apdu, bool status) override;
38  void dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) override;
39  void dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, bool status) override;
40  void dataSystemBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) override;
41  void dataSystemBroadcastConfirm(HopCountType hopType, Priority priority, APDU& apdu, bool status) override;
42  void dataIndividualIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) override;
43  void dataIndividualConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, bool status) override;
44  void dataConnectedIndication(Priority priority, uint16_t tsap, APDU& apdu) override;
45  void dataConnectedConfirm(uint16_t tsap) override;
46 
47  void loop();
48 
49  protected:
50  // to transport layer
51  void dataGroupRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, const SecurityControl& secCtrl) override;
52  void dataBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, const SecurityControl& secCtrl) override;
53  void dataSystemBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, const SecurityControl& secCtrl) override;
54  void dataIndividualRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t destination, APDU& apdu, const SecurityControl& secCtrl) override;
55  void dataConnectedRequest(uint16_t tsap, Priority priority, APDU& apdu, const SecurityControl& secCtrl) override; // apdu must be valid until it was confirmed
56 
57  private:
58  enum class AddrType : uint8_t
59  {
60  group,
61  individual,
62  unknown
63  };
64 
65  struct Addr
66  {
67  Addr() = default;
68  Addr(uint8_t addr) : addr{addr} {}
69 
70  uint16_t addr;
71  AddrType addrType{AddrType::unknown};
72 
73  bool operator ==(const Addr& cmpAddr) const
74  {
75  if ((cmpAddr.addrType == AddrType::unknown) || (addrType == AddrType::unknown))
76  {
77  println("Unknown address type detected!");
78  return false;
79  }
80 
81  return (cmpAddr.addr == addr) && (cmpAddr.addrType == addrType);
82  }
83  };
84 
85  struct GrpAddr : Addr
86  {
87  GrpAddr()
88  {
89  addrType = AddrType::group;
90  }
91  GrpAddr(uint8_t addr) : Addr{addr}
92  {
93  addrType = AddrType::group;
94  }
95  };
96 
97  struct IndAddr : Addr
98  {
99  IndAddr()
100  {
101  addrType = AddrType::individual;
102  }
103  IndAddr(uint8_t addr) : Addr{addr}
104  {
105  addrType = AddrType::individual;
106  }
107  };
108 
109  uint32_t calcAuthOnlyMac(uint8_t* apdu, uint8_t apduLength, const uint8_t* key, uint8_t* iv, uint8_t* ctr0);
110  uint32_t calcConfAuthMac(uint8_t* associatedData, uint16_t associatedDataLength, uint8_t* apdu, uint8_t apduLength, const uint8_t* key, uint8_t* iv);
111 
112  void block0(uint8_t* buffer, uint8_t* seqNum, uint16_t indSrcAddr, uint16_t dstAddr, bool dstAddrIsGroupAddr, uint8_t extFrameFormat, uint8_t tpci, uint8_t apci, uint8_t payloadLength);
113  void blockCtr0(uint8_t* buffer, uint8_t* seqNum, uint16_t indSrcAddr, uint16_t dstAddr);
114 
115  const uint8_t* securityKey(uint16_t addr, bool isGroupAddress);
116 
117  uint16_t groupAddressIndex(uint16_t groupAddr); // returns 1-based index of address in group address table
118  uint16_t groupObjectIndex(uint16_t groupAddrIndex); // returns 1-based index of object in association table
119 
120  uint8_t groupObjectSecurity(uint16_t groupObjectIndex);
121 
122  uint64_t nextSequenceNumber(bool toolAccess);
123  void updateSequenceNumber(bool toolAccess, uint64_t seqNum);
124 
125  uint64_t lastValidSequenceNumber(bool toolAcces, uint16_t srcAddr);
126  void updateLastValidSequence(bool toolAccess, uint16_t remoteAddr, uint64_t seqNo);
127 
128  uint64_t getRandomNumber();
129 
130  bool isSyncService(APDU& secureAsdu);
131 
132  void sendSyncRequest(uint16_t dstAddr, bool dstAddrIsGroupAddr, const SecurityControl& secCtrl, bool systemBcast);
133  void sendSyncResponse(uint16_t dstAddr, bool dstAddrIsGroupAddr, const SecurityControl& secCtrl, uint64_t remoteNextSeqNum, bool systemBcast);
134  void receivedSyncRequest(uint16_t srcAddr, uint16_t dstAddr, bool dstAddrIsGroupAddr, const SecurityControl& secCtrl, uint8_t* seq, uint64_t challenge, bool systemBcast);
135  void receivedSyncResponse(uint16_t remoteAddr, const SecurityControl& secCtrl, uint8_t* plainApdu);
136 
137  bool decrypt(uint8_t* plainApdu, uint16_t plainapduLength, uint16_t srcAddr, uint16_t dstAddr, bool dstAddrIsGroupAddr, uint8_t tpci, uint8_t* secureAsdu, SecurityControl& secCtrl, bool systemBcast);
138  bool secure(uint8_t* buffer, uint16_t service, uint16_t srcAddr, uint16_t dstAddr, bool dstAddrIsGroupAddr, uint8_t tpci, uint8_t* apdu, uint16_t apduLength, const SecurityControl& secCtrl, bool systemBcast);
139 
140  bool decodeSecureApdu(APDU& secureApdu, APDU& plainApdu, SecurityControl& secCtrl);
141  bool createSecureApdu(APDU& plainApdu, APDU& secureApdu, const SecurityControl& secCtrl);
142 
143  void encryptAesCbc(uint8_t* buffer, uint16_t bufLen, const uint8_t* iv, const uint8_t* key);
144  void xcryptAesCtr(uint8_t* buffer, uint16_t bufLen, const uint8_t* iv, const uint8_t* key);
145 
146  bool _syncReqBroadcastIncoming{false};
147  bool _syncReqBroadcastOutgoing{false};
148  uint32_t _lastSyncRes;
149 
150  Map<Addr, uint64_t, 1> _pendingOutgoingSyncRequests; // Store challenges for outgoing sync requests
151  Map<Addr, uint64_t, 1> _pendingIncomingSyncRequests; // Store challenges for incoming sync requests
152 
153  uint64_t _sequenceNumberToolAccess = 50;
154  uint64_t _sequenceNumber = 0;
155 
156  uint64_t _lastValidSequenceNumberTool = 0;
157  uint64_t _lastValidSequenceNumber = 0;
158 
159  SecurityInterfaceObject& _secIfObj;
160  DeviceObject& _deviceObj;
161  AddressTableObject* _addrTab = nullptr;
162 };
void println(const char *s)
This class represents an Application Protocol Data Unit.
Definition: apdu.h:12
This class represents the group address table.
This is an implementation of the application layer as specified in .
This is an implementation of the application layer as specified in .
void dataConnectedRequest(uint16_t tsap, Priority priority, APDU &apdu, const SecurityControl &secCtrl) override
void dataGroupRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU &apdu, const SecurityControl &secCtrl) override
void dataIndividualConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU &apdu, bool status) override
void dataSystemBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU &apdu, const SecurityControl &secCtrl) override
void dataGroupIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU &apdu) override
Somebody send us an APDU via multicast communication.
void dataSystemBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU &apdu) override
void dataConnectedIndication(Priority priority, uint16_t tsap, APDU &apdu) override
void dataConnectedConfirm(uint16_t tsap) override
void dataSystemBroadcastConfirm(HopCountType hopType, Priority priority, APDU &apdu, bool status) override
SecureApplicationLayer(DeviceObject &deviceObj, SecurityInterfaceObject &secIfObj, BusAccessUnit &bau)
The constructor.
void groupAddressTable(AddressTableObject &addrTable)
void dataGroupConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU &apdu, bool status) override
Report the status of an APDU that we sent via multicast communication back to us.
void dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU &apdu) override
void dataIndividualIndication(HopCountType hopType, Priority priority, uint16_t source, APDU &apdu) override
void dataIndividualRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t destination, APDU &apdu, const SecurityControl &secCtrl) override
void dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, APDU &apdu, bool status) override
void dataBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU &apdu, const SecurityControl &secCtrl) override
HopCountType
Definition: knx_types.h:124
Priority
Definition: knx_types.h:10
AckType
Definition: knx_types.h:18