bool signerAtsha204SoftSignMsg(MyMessage &msg) { // If we cannot fit any signature in the message, refuse to sign it if (mGetLength(msg) > MAX_PAYLOAD-2) { DEBUG_SIGNING_PRINTBUF(F("Message too large"), NULL, 0); return false; } // Calculate signature of message mSetSigned(msg, 1); // make sure signing flag is set before signature is calculated signerCalculateSignature(msg); if (DO_WHITELIST(msg.destination)) { // Salt the signature with the senders nodeId and the (hopefully) unique serial The Creator has provided _signing_sha256.init(); for (int i=0; i<32; i++) _signing_sha256.write(_signing_hmac[i]); _signing_sha256.write(msg.sender); for (int i=0; i<SHA204_SERIAL_SZ; i++) _signing_sha256.write(_signing_node_serial_info[i]); memcpy(_signing_hmac, _signing_sha256.result(), 32); DEBUG_SIGNING_PRINTBUF(F("SHA256: "), _signing_hmac, 32); DEBUG_SIGNING_PRINTBUF(F("Signature salted with serial"), NULL, 0); } // Overwrite the first byte in the signature with the signing identifier _signing_hmac[0] = SIGNING_IDENTIFIER; // Transfer as much signature data as the remaining space in the message permits memcpy(&msg.data[mGetLength(msg)], _signing_hmac, MAX_PAYLOAD-mGetLength(msg)); DEBUG_SIGNING_PRINTBUF(F("Signature in message: "), (uint8_t*)&msg.data[mGetLength(msg)], MAX_PAYLOAD-mGetLength(msg)); return true; }
// Helper to process presentation mesages static bool signerInternalProcessPresentation(MyMessage &msg) { const uint8_t sender = msg.sender; #if defined(MY_SIGNING_FEATURE) if (msg.data[0] != SIGNING_PRESENTATION_VERSION_1) { SIGN_DEBUG(PSTR("Unsupported signing presentation version (%d)!\n"), msg.data[0]); return true; // Just drop this presentation message } // We only handle version 1 here... if (msg.data[1] & SIGNING_PRESENTATION_REQUIRE_SIGNATURES) { // We received an indicator that the sender require us to sign all messages we send to it SIGN_DEBUG(PSTR("Mark node %d as one that require signed messages\n"), sender); SET_SIGN(sender); } else { // We received an indicator that the sender does not require us to sign all messages we send to it SIGN_DEBUG(PSTR("Mark node %d as one that do not require signed messages\n"), sender); CLEAR_SIGN(sender); } if (msg.data[1] & SIGNING_PRESENTATION_REQUIRE_WHITELISTING) { // We received an indicator that the sender require us to salt signatures with serial SIGN_DEBUG(PSTR("Mark node %d as one that require whitelisting\n"), sender); SET_WHITELIST(sender); } else { // We received an indicator that the sender does not require us to sign all messages we send to it SIGN_DEBUG(PSTR("Mark node %d as one that do not require whitelisting\n"), sender); CLEAR_WHITELIST(sender); } // Save updated tables hwWriteConfigBlock((void*)_doSign, (void*)EEPROM_SIGNING_REQUIREMENT_TABLE_ADDRESS, sizeof(_doSign)); hwWriteConfigBlock((void*)_doWhitelist, (void*)EEPROM_WHITELIST_REQUIREMENT_TABLE_ADDRESS, sizeof(_doWhitelist)); // Inform sender about our preference if we are a gateway, but only require signing if the sender // required signing unless we explicitly configure it to #if defined(MY_GATEWAY_FEATURE) prepareSigningPresentation(msg, sender); #if defined(MY_SIGNING_REQUEST_SIGNATURES) #if defined(MY_SIGNING_GW_REQUEST_SIGNATURES_FROM_ALL) msg.data[1] |= SIGNING_PRESENTATION_REQUIRE_SIGNATURES; #else if (DO_SIGN(sender)) { msg.data[1] |= SIGNING_PRESENTATION_REQUIRE_SIGNATURES; } #endif #endif // MY_SIGNING_REQUEST_SIGNATURES #if defined(MY_SIGNING_NODE_WHITELISTING) #if defined(MY_SIGNING_GW_REQUEST_SIGNATURES_FROM_ALL) msg.data[1] |= SIGNING_PRESENTATION_REQUIRE_WHITELISTING; #else if (DO_WHITELIST(sender)) { msg.data[1] |= SIGNING_PRESENTATION_REQUIRE_WHITELISTING; } #endif #endif // MY_SIGNING_NODE_WHITELISTING if (msg.data[1] & SIGNING_PRESENTATION_REQUIRE_SIGNATURES) { SIGN_DEBUG(PSTR("Informing node %d that we require signatures\n"), sender); } else { SIGN_DEBUG(PSTR("Informing node %d that we do not require signatures\n"), sender); } if (msg.data[1] & SIGNING_PRESENTATION_REQUIRE_WHITELISTING) { SIGN_DEBUG(PSTR("Informing node %d that we require whitelisting\n"), sender); } else { SIGN_DEBUG(PSTR("Informing node %d that we do not require whitelisting\n"), sender); } if (!_sendRoute(msg)) { SIGN_DEBUG(PSTR("Failed to transmit signing presentation!\n")); } #endif // MY_GATEWAY_FEATURE #else // not MY_SIGNING_FEATURE #if defined(MY_GATEWAY_FEATURE) // If we act as gateway and do not have the signing feature and receive a signing request we still // need to do make sure the requester does not believe the gateway still require signatures prepareSigningPresentation(msg, sender); SIGN_DEBUG( PSTR("Informing node %d that we do not require signatures because we do not support it\n"), sender); if (!_sendRoute(msg)) { SIGN_DEBUG(PSTR("Failed to transmit signing presentation!\n")); } #else // not MY_GATEWAY_FEATURE // If we act as a node and do not have the signing feature then we just silently drop any signing // presentation messages received (void)msg; (void)sender; SIGN_DEBUG(PSTR("Received signing presentation, but signing is not supported (message ignored)\n")); #endif // not MY_GATEWAY_FEATURE #endif // not MY_SIGNING_FEATURE return true; // No need to further process I_SIGNING_PRESENTATION }