diff --git a/sys/apps/network/transport.lua b/sys/apps/network/transport.lua index 2732d12..c8cc035 100644 --- a/sys/apps/network/transport.lua +++ b/sys/apps/network/transport.lua @@ -7,6 +7,7 @@ local Crypto = require('opus.crypto.chacha20') local Event = require('opus.event') +local SHA = require('opus.crypto.sha2') local network = _G.network local os = _G.os @@ -35,7 +36,19 @@ function transport.read(socket) local data = table.remove(socket.messages, 1) if data then if socket.options.ENCRYPT then - return table.unpack(Crypto.decrypt(data[1], socket.enckey)), data[2] + local ciphertext = data[1] + -- Verify HMAC if present (new protocol) + if socket.hmackey and type(ciphertext) == 'table' and ciphertext.hmac then + local expected = SHA.hmac( + ciphertext[1] .. ciphertext[2], + socket.hmackey + ):toHex() + if expected ~= ciphertext.hmac then + _G._syslog('transport: HMAC verification failed on port ' .. socket.sport) + return nil + end + end + return table.unpack(Crypto.decrypt(ciphertext, socket.enckey)), data[2] end return table.unpack(data) end @@ -78,7 +91,15 @@ Event.on('transport_encrypt', function() if socket and socket.connected then local msg = entry[2] - msg.data = Crypto.encrypt({ msg.data }, socket.enckey) + local encrypted = Crypto.encrypt({ msg.data }, socket.enckey) + -- Attach HMAC if key is available + if socket.hmackey then + encrypted.hmac = SHA.hmac( + encrypted[1] .. encrypted[2], + socket.hmackey + ):toHex() + end + msg.data = encrypted socket.transmit(socket.dport, socket.dhost, msg) end end