Further cleanup.

This commit is contained in:
Nanosonde 2020-07-05 16:18:59 +02:00
parent 24b4a8d8a6
commit e8645dc5ad
5 changed files with 56 additions and 57 deletions

View File

@ -83,25 +83,23 @@ void BauSystemB::sendNextGroupTelegram()
continue; continue;
SecurityControl goSecurity; SecurityControl goSecurity;
goSecurity.toolAccess = false; goSecurity.toolAccess = false; // Secured group communication never uses the toolkey. ETS knows all keys, also the group keys.
#ifdef USE_DATASECURE
// Get security flags from Security Interface Object for this group object
goSecurity.dataSecurity = _secIfObj.getGroupObjectSecurity(asap);
#else
goSecurity.dataSecurity = DataSecurity::none; goSecurity.dataSecurity = DataSecurity::none;
#endif
if (flag == WriteRequest && go.transmitEnable()) if (flag == WriteRequest && go.transmitEnable())
{ {
#ifdef USE_DATASECURE
// Get security flags from Security Interface Object for this group object
goSecurity.dataSecurity = _secIfObj.getGroupObjectSecurity(asap, true);
#endif
uint8_t* data = go.valueRef(); uint8_t* data = go.valueRef();
_appLayer.groupValueWriteRequest(AckRequested, asap, go.priority(), NetworkLayerParameter, goSecurity, data, _appLayer.groupValueWriteRequest(AckRequested, asap, go.priority(), NetworkLayerParameter, goSecurity, data,
go.sizeInTelegram()); go.sizeInTelegram());
} }
else if (flag == ReadRequest) else if (flag == ReadRequest)
{ {
#ifdef USE_DATASECURE
// Get security flags from Security Interface Object for this group object
goSecurity.dataSecurity = _secIfObj.getGroupObjectSecurity(asap, false);
#endif
_appLayer.groupValueReadRequest(AckRequested, asap, go.priority(), NetworkLayerParameter, goSecurity); _appLayer.groupValueReadRequest(AckRequested, asap, go.priority(), NetworkLayerParameter, goSecurity);
} }
@ -215,8 +213,10 @@ uint8_t BauSystemB::masterReset(EraseCode eraseCode, uint8_t channel)
println(eraseCode == EraseCode::FactoryReset ? "FactoryReset with IA" : "FactoryReset without IA"); println(eraseCode == EraseCode::FactoryReset ? "FactoryReset with IA" : "FactoryReset without IA");
#ifdef USE_DATASECURE #ifdef USE_DATASECURE
// If erase code is FactoryReset or FactoryResetWithoutIA, set FDSK as toolkey again // If erase code is FactoryReset or FactoryResetWithoutIA, set FDSK as toolkey again
// and disable security mode // and disable security mode.
_secIfObj.factoryReset(); // FIXME: the A_RestartResponse PDU has still to be sent with the current toolkey.
// Idea: use local confirmation of sent A_RestartResponse PDU to trigger writing the FDSK afterwards
_secIfObj.masterReset(eraseCode);
#endif #endif
return successCode; return successCode;
} }
@ -609,7 +609,7 @@ void BauSystemB::groupValueReadIndication(uint16_t asap, Priority priority, HopC
DataSecurity requiredGoSecurity; DataSecurity requiredGoSecurity;
// Get security flags from Security Interface Object for this group object // Get security flags from Security Interface Object for this group object
requiredGoSecurity = _secIfObj.getGroupObjectSecurity(asap, false); requiredGoSecurity = _secIfObj.getGroupObjectSecurity(asap);
if (secCtrl.dataSecurity != requiredGoSecurity) if (secCtrl.dataSecurity != requiredGoSecurity)
{ {
@ -644,7 +644,7 @@ void BauSystemB::groupValueWriteIndication(uint16_t asap, Priority priority, Hop
DataSecurity requiredGoSecurity; DataSecurity requiredGoSecurity;
// Get security flags from Security Interface Object for this group object // Get security flags from Security Interface Object for this group object
requiredGoSecurity = _secIfObj.getGroupObjectSecurity(asap, true); requiredGoSecurity = _secIfObj.getGroupObjectSecurity(asap);
if (secCtrl.dataSecurity != requiredGoSecurity) if (secCtrl.dataSecurity != requiredGoSecurity)
{ {

View File

@ -782,8 +782,8 @@ bool SecureApplicationLayer::decrypt(uint8_t* plainApdu, uint16_t plainApduLengt
bool syncReq = service == kSecureSyncRequest; bool syncReq = service == kSecureSyncRequest;
bool syncRes = service == kSecureSyncResponse; bool syncRes = service == kSecureSyncResponse;
//const uint8_t* key = dstAddrIsGroupAddr ? securityKey(dstAddr, dstAddrIsGroupAddr) : toolAccess ? toolKey(srcAddr == _deviceObj.induvidualAddress() ? dstAddr : srcAddr) : securityKey(srcAddr, false); //const uint8_t* key = dstAddrIsGroupAddr ? securityKey(dstAddr, dstAddrIsGroupAddr) : toolAccess ? toolKey() : securityKey(srcAddr, false);
const uint8_t* key = dstAddrIsGroupAddr && (dstAddr != 0) ? securityKey(dstAddr, dstAddrIsGroupAddr) : toolAccess ? _secIfObj.toolKey(srcAddr == _deviceObj.induvidualAddress() ? dstAddr : srcAddr) : securityKey(srcAddr, false); const uint8_t* key = dstAddrIsGroupAddr && (dstAddr != 0) ? securityKey(dstAddr, dstAddrIsGroupAddr) : toolAccess ? _secIfObj.toolKey() : securityKey(srcAddr, false);
if (key == nullptr) if (key == nullptr)
{ {
print("Error: No key found. toolAccess: "); print("Error: No key found. toolAccess: ");
@ -1047,7 +1047,7 @@ bool SecureApplicationLayer::secure(uint8_t* buffer, uint16_t service, uint16_t
} }
} }
const uint8_t* key = toolAccess ? _secIfObj.toolKey(_syncReqBroadcastIncoming ? _deviceObj.induvidualAddress() : dstAddr) : securityKey(dstAddr, dstAddrIsGroupAddr); const uint8_t* key = toolAccess ? _secIfObj.toolKey() : securityKey(dstAddr, dstAddrIsGroupAddr);
if (key == nullptr) if (key == nullptr)
{ {
print("Error: No key found. toolAccess: "); print("Error: No key found. toolAccess: ");
@ -1231,16 +1231,6 @@ bool SecureApplicationLayer::createSecureApdu(APDU& plainApdu, APDU& secureApdu,
return false; return false;
} }
void SecureApplicationLayer::setSecurityMode(bool enabled)
{
_securityModeEnabled = enabled;
}
bool SecureApplicationLayer::isSecurityModeEnabled()
{
return _securityModeEnabled;
}
void SecureApplicationLayer::clearFailureLog() void SecureApplicationLayer::clearFailureLog()
{ {
println("clearFailureLog()"); println("clearFailureLog()");

View File

@ -30,8 +30,6 @@ class SecureApplicationLayer : public ApplicationLayer
*/ */
SecureApplicationLayer(DeviceObject& deviceObj, SecurityInterfaceObject& secIfObj, AssociationTableObject& assocTable, AddressTableObject& addrTab, BusAccessUnit& bau); SecureApplicationLayer(DeviceObject& deviceObj, SecurityInterfaceObject& secIfObj, AssociationTableObject& assocTable, AddressTableObject& addrTab, BusAccessUnit& bau);
void setSecurityMode(bool enabled);
bool isSecurityModeEnabled();
void clearFailureLog(); void clearFailureLog();
void getFailureCounters(uint8_t* data); void getFailureCounters(uint8_t* data);
uint8_t getFromFailureLogByIndex(uint8_t index, uint8_t* data, uint8_t maxDataLen); uint8_t getFromFailureLogByIndex(uint8_t index, uint8_t* data, uint8_t maxDataLen);
@ -137,8 +135,6 @@ class SecureApplicationLayer : public ApplicationLayer
void encryptAesCbc(uint8_t* buffer, uint16_t bufLen, const uint8_t* iv, const uint8_t* key); void encryptAesCbc(uint8_t* buffer, uint16_t bufLen, const uint8_t* iv, const uint8_t* key);
void xcryptAesCtr(uint8_t* buffer, uint16_t bufLen, const uint8_t* iv, const uint8_t* key); void xcryptAesCtr(uint8_t* buffer, uint16_t bufLen, const uint8_t* iv, const uint8_t* key);
bool _securityModeEnabled {false};
bool _syncReqBroadcastIncoming{false}; bool _syncReqBroadcastIncoming{false};
bool _syncReqBroadcastOutgoing{false}; bool _syncReqBroadcastOutgoing{false};
uint32_t _lastSyncRes; uint32_t _lastSyncRes;

View File

@ -52,7 +52,7 @@ SecurityInterfaceObject::SecurityInterfaceObject()
resultLength = 1; resultLength = 1;
return; return;
} }
obj->_secAppLayer->setSecurityMode(mode == 1); obj->setSecurityMode(mode == 1);
resultData[0] = ReturnCodes::Success; resultData[0] = ReturnCodes::Success;
resultData[1] = serviceId; resultData[1] = serviceId;
resultLength = 2; resultLength = 2;
@ -74,7 +74,7 @@ SecurityInterfaceObject::SecurityInterfaceObject()
{ {
resultData[0] = ReturnCodes::Success; resultData[0] = ReturnCodes::Success;
resultData[1] = serviceId; resultData[1] = serviceId;
resultData[2] = obj->_secAppLayer->isSecurityModeEnabled() ? 1 : 0; resultData[2] = obj->isSecurityModeEnabled() ? 1 : 0;
resultLength = 3; resultLength = 3;
return; return;
} }
@ -171,6 +171,7 @@ void SecurityInterfaceObject::secureApplicationLayer(SecureApplicationLayer& sec
uint8_t* SecurityInterfaceObject::save(uint8_t* buffer) uint8_t* SecurityInterfaceObject::save(uint8_t* buffer)
{ {
buffer = pushByte(_state, buffer); buffer = pushByte(_state, buffer);
buffer = pushByte(_securityModeEnabled, buffer);
return InterfaceObject::save(buffer); return InterfaceObject::save(buffer);
} }
@ -181,12 +182,28 @@ const uint8_t* SecurityInterfaceObject::restore(const uint8_t* buffer)
buffer = popByte(state, buffer); buffer = popByte(state, buffer);
_state = (LoadState)state; _state = (LoadState)state;
uint8_t securityModeEnabled = 0;
buffer = popByte(securityModeEnabled, buffer);
_securityModeEnabled = securityModeEnabled;
return InterfaceObject::restore(buffer); return InterfaceObject::restore(buffer);
} }
uint16_t SecurityInterfaceObject::saveSize() uint16_t SecurityInterfaceObject::saveSize()
{ {
return 1 + InterfaceObject::saveSize(); return 2 + InterfaceObject::saveSize();
}
void SecurityInterfaceObject::setSecurityMode(bool enabled)
{
print("Security mode set to: ");
println(enabled ? "enabled" : "disabled");
_securityModeEnabled = enabled;
}
bool SecurityInterfaceObject::isSecurityModeEnabled()
{
return _securityModeEnabled;
} }
bool SecurityInterfaceObject::isLoaded() bool SecurityInterfaceObject::isLoaded()
@ -314,16 +331,17 @@ void SecurityInterfaceObject::errorCode(ErrorCode errorCode)
prop->write(data); prop->write(data);
} }
void SecurityInterfaceObject::factoryReset() void SecurityInterfaceObject::masterReset(EraseCode eraseCode)
{ {
// TODO handle different erase codes
println("Factory reset of security interface object requested."); println("Factory reset of security interface object requested.");
_secAppLayer->setSecurityMode(false); setSecurityMode(false);
property(PID_TOOL_KEY)->write(1, 1, _fdsk); property(PID_TOOL_KEY)->write(1, 1, _fdsk);
} }
const uint8_t* SecurityInterfaceObject::toolKey(uint16_t devAddr) const uint8_t* SecurityInterfaceObject::toolKey()
{ {
//TODO: check if multiple tool keys possible, leave it for now // There is only one tool key
const uint8_t* toolKey = propertyData(PID_TOOL_KEY); const uint8_t* toolKey = propertyData(PID_TOOL_KEY);
return toolKey; return toolKey;
} }
@ -341,7 +359,7 @@ const uint8_t* SecurityInterfaceObject::p2pKey(uint16_t addressIndex)
uint8_t elementSize = propertySize(PID_P2P_KEY_TABLE); uint8_t elementSize = propertySize(PID_P2P_KEY_TABLE);
// Search for address index // Search for address index
uint8_t entry[elementSize]; // 2 bytes index + keysize (16 bytes) + 2 bytes(for what?) = 20 bytes uint8_t entry[elementSize]; // 2 bytes index + keysize (16 bytes) + 2 bytes(roles) = 20 bytes
for (int i = 1; i <= numElements; i++) for (int i = 1; i <= numElements; i++)
{ {
property(PID_P2P_KEY_TABLE)->read(i, 1, entry); property(PID_P2P_KEY_TABLE)->read(i, 1, entry);
@ -498,7 +516,7 @@ void SecurityInterfaceObject::setLastValidSequenceNumber(uint16_t deviceAddr, ui
} }
} }
DataSecurity SecurityInterfaceObject::getGroupObjectSecurity(uint16_t index, bool isWrite) DataSecurity SecurityInterfaceObject::getGroupObjectSecurity(uint16_t index)
{ {
// security table uses same index as group object table // security table uses same index as group object table
@ -508,20 +526,9 @@ DataSecurity SecurityInterfaceObject::getGroupObjectSecurity(uint16_t index, boo
if (count > 0) if (count > 0)
{ {
bool conf; // write access flags, approved spec. AN158, p.97
bool auth; bool conf = (data[0] & 2) == 2;
if (isWrite) bool auth = (data[0] & 1) == 1;
{
// write access flags, draft spec. p.68
conf = (data[0] & 2) == 2;
auth = (data[0] & 1) == 1;
}
else
{
// Read access flags, draft spec. p.68
conf = (data[0] & 8) == 8;
auth = (data[0] & 4) == 4;
}
return conf ? DataSecurity::authConf : auth ? DataSecurity::auth : DataSecurity::none; return conf ? DataSecurity::authConf : auth ? DataSecurity::auth : DataSecurity::none;
} }

View File

@ -15,11 +15,13 @@ public:
void secureApplicationLayer(SecureApplicationLayer& secAppLayer); void secureApplicationLayer(SecureApplicationLayer& secAppLayer);
void factoryReset(); void masterReset(EraseCode eraseCode);
bool isSecurityModeEnabled();
bool isLoaded(); bool isLoaded();
const uint8_t* toolKey(uint16_t devAddr); // returns single tool key (ETS) const uint8_t* toolKey(); // returns single tool key (ETS)
const uint8_t* p2pKey(uint16_t addressIndex); // returns p2p key for IA index const uint8_t* p2pKey(uint16_t addressIndex); // returns p2p key for IA index
const uint8_t* groupKey(uint16_t addressIndex); // returns group key for group address index const uint8_t* groupKey(uint16_t addressIndex); // returns group key for group address index
@ -29,7 +31,7 @@ public:
uint64_t getLastValidSequenceNumber(uint16_t deviceAddr); uint64_t getLastValidSequenceNumber(uint16_t deviceAddr);
void setLastValidSequenceNumber(uint16_t deviceAddr, uint64_t seqNum); void setLastValidSequenceNumber(uint16_t deviceAddr, uint64_t seqNum);
DataSecurity getGroupObjectSecurity(uint16_t index, bool isWrite); DataSecurity getGroupObjectSecurity(uint16_t index);
LoadState loadState(); LoadState loadState();
uint8_t* save(uint8_t* buffer) override; uint8_t* save(uint8_t* buffer) override;
@ -39,6 +41,8 @@ public:
private: private:
SecureApplicationLayer* _secAppLayer = nullptr; SecureApplicationLayer* _secAppLayer = nullptr;
void setSecurityMode(bool enabled);
void errorCode(ErrorCode errorCode); void errorCode(ErrorCode errorCode);
void loadEvent(const uint8_t* data); void loadEvent(const uint8_t* data);
@ -50,6 +54,8 @@ private:
void loadState(LoadState newState); void loadState(LoadState newState);
LoadState _state = LS_UNLOADED; LoadState _state = LS_UNLOADED;
bool _securityModeEnabled {false};
uint16_t getNumberOfElements(PropertyID propId); uint16_t getNumberOfElements(PropertyID propId);
// Our FDSK // Our FDSK