From 1c291979835ab976298c3d9f41dcffc2f4a317a2 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Sat, 29 Jun 2019 22:02:00 -0400 Subject: [PATCH] security - final round? --- sys/apps/network/transport.lua | 6 ++--- sys/modules/opus/crypto/chacha20.lua | 31 ++++++++++++++++++++++++- sys/modules/opus/socket.lua | 34 ++++++++++++---------------- 3 files changed, 47 insertions(+), 24 deletions(-) diff --git a/sys/apps/network/transport.lua b/sys/apps/network/transport.lua index 316f46a..3858383 100644 --- a/sys/apps/network/transport.lua +++ b/sys/apps/network/transport.lua @@ -6,7 +6,6 @@ ]]-- local Event = require('opus.event') -local SHA = require('opus.crypto.sha2') local network = _G.network local os = _G.os @@ -39,7 +38,7 @@ end function transport.write(socket, data) socket.transmit(socket.dport, socket.dhost, data) - socket.wseq = SHA.digest(socket.wseq):toHex() + socket.wseq = socket.wrng:nextInt(5) end function transport.ping(socket) @@ -113,7 +112,8 @@ Event.on('modem_message', function(_, _, dport, dhost, msg, distance) _syslog('got ' .. msg.seq) else socket.activityTimer = os.clock() - socket.rseq = SHA.digest(socket.rseq):toHex() + socket.rseq = socket.rrng:nextInt(5) + table.insert(socket.messages, { msg.data, distance }) if not socket.messages[2] then -- table size is 1 diff --git a/sys/modules/opus/crypto/chacha20.lua b/sys/modules/opus/crypto/chacha20.lua index 3b3569a..c99a854 100644 --- a/sys/modules/opus/crypto/chacha20.lua +++ b/sys/modules/opus/crypto/chacha20.lua @@ -10,12 +10,13 @@ local bxor = bit32.bxor local band = bit32.band local blshift = bit32.lshift local brshift = bit32.arshift -local os = _G.os local textutils = _G.textutils local mod = 2^32 local tau = {("expand 16-byte k"):byte(1,-1)} local sigma = {("expand 32-byte k"):byte(1,-1)} +local null32 = {("A"):rep(32):byte(1,-1)} +local null12 = {("A"):rep(12):byte(1,-1)} local function rotl(n, b) local s = n/(2^(32-b)) @@ -164,7 +165,35 @@ local function decrypt(data, key) return textutils.unserialise(tostring(ptx)) end +local obj = {} +local mt = {['__index'] = obj} + +function obj:nextInt(byte) + if byte < 1 or byte > 6 then error("Can only return 1-6 bytes", 2) end + local output = 0 + for i = 0, byte-1 do + if #self.block == 0 then + self.cnt = self.cnt + 1 + self.block = crypt(null32, self.seed, null12, self.cnt) + end + + local newByte = table.remove(self.block) + output = output + (newByte * (2^(8*i))) + end + return output +end + +local function newRNG(seed) + local o = {} + o.seed = seed + o.cnt = 0 + o.block = {} + + return setmetatable(o, mt) +end + return { encrypt = encrypt, decrypt = decrypt, + newRNG = newRNG, } diff --git a/sys/modules/opus/socket.lua b/sys/modules/opus/socket.lua index 721f8e4..c1518fb 100644 --- a/sys/modules/opus/socket.lua +++ b/sys/modules/opus/socket.lua @@ -64,13 +64,16 @@ function socketClass:ping() end function socketClass:setupEncryption(x) -local timer = Util.timer() + self.rrng = Crypto.newRNG( + SHA.pbkdf2(self.sharedKey, x and "3rseed" or "4sseed", 1)) + self.wrng = Crypto.newRNG( + SHA.pbkdf2(self.sharedKey, x and "4sseed" or "3rseed", 1)) + self.sharedKey = ECC.exchange(self.privKey, self.remotePubKey) - self.enckey = SHA.pbkdf2(self.sharedKey, "1enc", 1) - self.hmackey = SHA.pbkdf2(self.sharedKey, "2hmac", 1) - self.rseq = SHA.pbkdf2(self.sharedKey, x and "3rseed" or "4sseed", 1):toHex() - self.wseq = SHA.pbkdf2(self.sharedKey, x and "4sseed" or "3rseed", 1):toHex() -_syslog('shared in ' .. timer()) + --self.enckey = SHA.pbkdf2(self.sharedKey, "1enc", 1) + --self.hmackey = SHA.pbkdf2(self.sharedKey, "2hmac", 1) + self.rseq = self.rrng:nextInt(5) + self.wseq = self.wrng:nextInt(5) end function socketClass:close() @@ -99,8 +102,6 @@ local function newSocket(isLoopback) shost = os.getComputerID(), sport = i, transmit = device.wireless_modem.transmit, - wseq = math.random(100, 100000), - rseq = math.random(100, 100000), timers = { }, messages = { }, } @@ -121,7 +122,7 @@ function Socket.connect(host, port, options) if not device.wireless_modem then return false, 'Wireless modem not found', 'NOMODEM' end -local timer = Util.timer() + local socket = newSocket(host == os.getComputerID()) socket.dhost = tonumber(host) socket.privKey, socket.pubKey = network.getKeyPair() @@ -143,7 +144,8 @@ local timer = Util.timer() if e == 'modem_message' and sport == socket.sport and type(msg) == 'table' and - msg.dhost == socket.shost then + msg.dhost == socket.shost and + type(msg.pk) == 'string' then os.cancelTimer(timerId) @@ -152,10 +154,7 @@ local timer = Util.timer() socket.connected = true socket.remotePubKey = Util.hexToByteArray(msg.pk) socket:setupEncryption(true) - -- Logger.log('socket', 'connection established to %d %d->%d', - -- host, socket.sport, socket.dport) network.getTransport().open(socket) -_syslog('connection in ' .. timer()) return socket elseif msg.type == 'NOPASS' then @@ -181,24 +180,23 @@ local function trusted(socket, msg, options) local identifier = options and options.identifier or getIdentifier() - if identifier and msg.t and type(msg.t) == 'table' then + if identifier and type(msg.t) == 'table' then local data = Crypto.decrypt(msg.t, Util.hexToByteArray(identifier)) if data and data.ts and tonumber(data.ts) then -_G._syslog('time diff ' .. math.abs(os.epoch('utc') - data.ts)) if math.abs(os.epoch('utc') - data.ts) < 4096 then socket.remotePubKey = Util.hexToByteArray(data.pk) socket.privKey, socket.pubKey = network.getKeyPair() socket:setupEncryption() return true end + _G._syslog('time diff ' .. math.abs(os.epoch('utc') - data.ts)) end end end function Socket.server(port, options) device.wireless_modem.open(port) - -- Logger.log('socket', 'Waiting for connections on port ' .. port) while true do local _, _, sport, dport, msg = os.pullEvent('modem_message') @@ -212,8 +210,6 @@ function Socket.server(port, options) local socket = newSocket(msg.shost == os.getComputerID()) socket.dport = dport socket.dhost = msg.shost - socket.wseq = msg.wseq - socket.rseq = msg.rseq socket.options = options if not Security.hasPassword() then @@ -233,8 +229,6 @@ function Socket.server(port, options) pk = Util.byteArrayToHex(socket.pubKey), }) - -- Logger.log('socket', 'Connection established %d->%d', socket.sport, socket.dport) - network.getTransport().open(socket) return socket