From ef5567ad463dd5752d371b8e40b8ffbe339fa495 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Sun, 11 Jun 2023 18:26:55 +0000 Subject: [PATCH] #51 hmac verification --- lockbox/cipher/aes128.lua | 415 --------------------------- lockbox/cipher/aes192.lua | 462 ------------------------------ lockbox/cipher/aes256.lua | 498 --------------------------------- lockbox/cipher/mode/cbc.lua | 164 ----------- lockbox/cipher/mode/cfb.lua | 163 ----------- lockbox/cipher/mode/ctr.lua | 248 ---------------- lockbox/cipher/mode/ofb.lua | 164 ----------- lockbox/digest/md5.lua | 201 +++++++++++++ lockbox/padding/ansix923.lua | 22 -- lockbox/padding/isoiec7816.lua | 22 -- lockbox/padding/pkcs7.lua | 18 -- lockbox/padding/zero.lua | 19 -- lockbox/util/bit.lua | 22 +- scada-common/comms.lua | 43 ++- scada-common/crypto.lua | 186 ++++-------- 15 files changed, 286 insertions(+), 2361 deletions(-) delete mode 100644 lockbox/cipher/aes128.lua delete mode 100644 lockbox/cipher/aes192.lua delete mode 100644 lockbox/cipher/aes256.lua delete mode 100644 lockbox/cipher/mode/cbc.lua delete mode 100644 lockbox/cipher/mode/cfb.lua delete mode 100644 lockbox/cipher/mode/ctr.lua delete mode 100644 lockbox/cipher/mode/ofb.lua create mode 100644 lockbox/digest/md5.lua delete mode 100644 lockbox/padding/ansix923.lua delete mode 100644 lockbox/padding/isoiec7816.lua delete mode 100644 lockbox/padding/pkcs7.lua delete mode 100644 lockbox/padding/zero.lua diff --git a/lockbox/cipher/aes128.lua b/lockbox/cipher/aes128.lua deleted file mode 100644 index 0726ac4..0000000 --- a/lockbox/cipher/aes128.lua +++ /dev/null @@ -1,415 +0,0 @@ -local Array = require("lockbox.util.array"); -local Bit = require("lockbox.util.bit"); - -local XOR = Bit.bxor; - -local SBOX = { - [0] = 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, - 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, - 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, - 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, - 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, - 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, - 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, - 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, - 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, - 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, - 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, - 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, - 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, - 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, - 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, - 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16}; - -local ISBOX = { - [0] = 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, - 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, - 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, - 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, - 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, - 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, - 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, - 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, - 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, - 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, - 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, - 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, - 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, - 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, - 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D}; - -local ROW_SHIFT = { 1, 6, 11, 16, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, }; -local IROW_SHIFT = { 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3, 16, 13, 10, 7, 4, }; - -local ETABLE = { - [0] = 0x01, 0x03, 0x05, 0x0F, 0x11, 0x33, 0x55, 0xFF, 0x1A, 0x2E, 0x72, 0x96, 0xA1, 0xF8, 0x13, 0x35, - 0x5F, 0xE1, 0x38, 0x48, 0xD8, 0x73, 0x95, 0xA4, 0xF7, 0x02, 0x06, 0x0A, 0x1E, 0x22, 0x66, 0xAA, - 0xE5, 0x34, 0x5C, 0xE4, 0x37, 0x59, 0xEB, 0x26, 0x6A, 0xBE, 0xD9, 0x70, 0x90, 0xAB, 0xE6, 0x31, - 0x53, 0xF5, 0x04, 0x0C, 0x14, 0x3C, 0x44, 0xCC, 0x4F, 0xD1, 0x68, 0xB8, 0xD3, 0x6E, 0xB2, 0xCD, - 0x4C, 0xD4, 0x67, 0xA9, 0xE0, 0x3B, 0x4D, 0xD7, 0x62, 0xA6, 0xF1, 0x08, 0x18, 0x28, 0x78, 0x88, - 0x83, 0x9E, 0xB9, 0xD0, 0x6B, 0xBD, 0xDC, 0x7F, 0x81, 0x98, 0xB3, 0xCE, 0x49, 0xDB, 0x76, 0x9A, - 0xB5, 0xC4, 0x57, 0xF9, 0x10, 0x30, 0x50, 0xF0, 0x0B, 0x1D, 0x27, 0x69, 0xBB, 0xD6, 0x61, 0xA3, - 0xFE, 0x19, 0x2B, 0x7D, 0x87, 0x92, 0xAD, 0xEC, 0x2F, 0x71, 0x93, 0xAE, 0xE9, 0x20, 0x60, 0xA0, - 0xFB, 0x16, 0x3A, 0x4E, 0xD2, 0x6D, 0xB7, 0xC2, 0x5D, 0xE7, 0x32, 0x56, 0xFA, 0x15, 0x3F, 0x41, - 0xC3, 0x5E, 0xE2, 0x3D, 0x47, 0xC9, 0x40, 0xC0, 0x5B, 0xED, 0x2C, 0x74, 0x9C, 0xBF, 0xDA, 0x75, - 0x9F, 0xBA, 0xD5, 0x64, 0xAC, 0xEF, 0x2A, 0x7E, 0x82, 0x9D, 0xBC, 0xDF, 0x7A, 0x8E, 0x89, 0x80, - 0x9B, 0xB6, 0xC1, 0x58, 0xE8, 0x23, 0x65, 0xAF, 0xEA, 0x25, 0x6F, 0xB1, 0xC8, 0x43, 0xC5, 0x54, - 0xFC, 0x1F, 0x21, 0x63, 0xA5, 0xF4, 0x07, 0x09, 0x1B, 0x2D, 0x77, 0x99, 0xB0, 0xCB, 0x46, 0xCA, - 0x45, 0xCF, 0x4A, 0xDE, 0x79, 0x8B, 0x86, 0x91, 0xA8, 0xE3, 0x3E, 0x42, 0xC6, 0x51, 0xF3, 0x0E, - 0x12, 0x36, 0x5A, 0xEE, 0x29, 0x7B, 0x8D, 0x8C, 0x8F, 0x8A, 0x85, 0x94, 0xA7, 0xF2, 0x0D, 0x17, - 0x39, 0x4B, 0xDD, 0x7C, 0x84, 0x97, 0xA2, 0xFD, 0x1C, 0x24, 0x6C, 0xB4, 0xC7, 0x52, 0xF6, 0x01}; - -local LTABLE = { - [0] = 0x00, 0x00, 0x19, 0x01, 0x32, 0x02, 0x1A, 0xC6, 0x4B, 0xC7, 0x1B, 0x68, 0x33, 0xEE, 0xDF, 0x03, - 0x64, 0x04, 0xE0, 0x0E, 0x34, 0x8D, 0x81, 0xEF, 0x4C, 0x71, 0x08, 0xC8, 0xF8, 0x69, 0x1C, 0xC1, - 0x7D, 0xC2, 0x1D, 0xB5, 0xF9, 0xB9, 0x27, 0x6A, 0x4D, 0xE4, 0xA6, 0x72, 0x9A, 0xC9, 0x09, 0x78, - 0x65, 0x2F, 0x8A, 0x05, 0x21, 0x0F, 0xE1, 0x24, 0x12, 0xF0, 0x82, 0x45, 0x35, 0x93, 0xDA, 0x8E, - 0x96, 0x8F, 0xDB, 0xBD, 0x36, 0xD0, 0xCE, 0x94, 0x13, 0x5C, 0xD2, 0xF1, 0x40, 0x46, 0x83, 0x38, - 0x66, 0xDD, 0xFD, 0x30, 0xBF, 0x06, 0x8B, 0x62, 0xB3, 0x25, 0xE2, 0x98, 0x22, 0x88, 0x91, 0x10, - 0x7E, 0x6E, 0x48, 0xC3, 0xA3, 0xB6, 0x1E, 0x42, 0x3A, 0x6B, 0x28, 0x54, 0xFA, 0x85, 0x3D, 0xBA, - 0x2B, 0x79, 0x0A, 0x15, 0x9B, 0x9F, 0x5E, 0xCA, 0x4E, 0xD4, 0xAC, 0xE5, 0xF3, 0x73, 0xA7, 0x57, - 0xAF, 0x58, 0xA8, 0x50, 0xF4, 0xEA, 0xD6, 0x74, 0x4F, 0xAE, 0xE9, 0xD5, 0xE7, 0xE6, 0xAD, 0xE8, - 0x2C, 0xD7, 0x75, 0x7A, 0xEB, 0x16, 0x0B, 0xF5, 0x59, 0xCB, 0x5F, 0xB0, 0x9C, 0xA9, 0x51, 0xA0, - 0x7F, 0x0C, 0xF6, 0x6F, 0x17, 0xC4, 0x49, 0xEC, 0xD8, 0x43, 0x1F, 0x2D, 0xA4, 0x76, 0x7B, 0xB7, - 0xCC, 0xBB, 0x3E, 0x5A, 0xFB, 0x60, 0xB1, 0x86, 0x3B, 0x52, 0xA1, 0x6C, 0xAA, 0x55, 0x29, 0x9D, - 0x97, 0xB2, 0x87, 0x90, 0x61, 0xBE, 0xDC, 0xFC, 0xBC, 0x95, 0xCF, 0xCD, 0x37, 0x3F, 0x5B, 0xD1, - 0x53, 0x39, 0x84, 0x3C, 0x41, 0xA2, 0x6D, 0x47, 0x14, 0x2A, 0x9E, 0x5D, 0x56, 0xF2, 0xD3, 0xAB, - 0x44, 0x11, 0x92, 0xD9, 0x23, 0x20, 0x2E, 0x89, 0xB4, 0x7C, 0xB8, 0x26, 0x77, 0x99, 0xE3, 0xA5, - 0x67, 0x4A, 0xED, 0xDE, 0xC5, 0x31, 0xFE, 0x18, 0x0D, 0x63, 0x8C, 0x80, 0xC0, 0xF7, 0x70, 0x07}; - -local MIXTABLE = { - 0x02, 0x03, 0x01, 0x01, - 0x01, 0x02, 0x03, 0x01, - 0x01, 0x01, 0x02, 0x03, - 0x03, 0x01, 0x01, 0x02}; - -local IMIXTABLE = { - 0x0E, 0x0B, 0x0D, 0x09, - 0x09, 0x0E, 0x0B, 0x0D, - 0x0D, 0x09, 0x0E, 0x0B, - 0x0B, 0x0D, 0x09, 0x0E}; - -local RCON = { -[0] = 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, -0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, -0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, -0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, -0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, -0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, -0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, -0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, -0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, -0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, -0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, -0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, -0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, -0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, -0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, -0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d}; - - -local GMUL = function(A, B) - if(A == 0x01) then return B; end - if(B == 0x01) then return A; end - if(A == 0x00) then return 0; end - if(B == 0x00) then return 0; end - - local LA = LTABLE[A]; - local LB = LTABLE[B]; - - local sum = LA + LB; - if (sum > 0xFF) then sum = sum - 0xFF; end - - return ETABLE[sum]; -end - -local byteSub = Array.substitute; - -local shiftRow = Array.permute; - -local mixCol = function(i, mix) - local out = {}; - - local a, b, c, d; - - a = GMUL(i[ 1], mix[ 1]); - b = GMUL(i[ 2], mix[ 2]); - c = GMUL(i[ 3], mix[ 3]); - d = GMUL(i[ 4], mix[ 4]); - out[ 1] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 1], mix[ 5]); - b = GMUL(i[ 2], mix[ 6]); - c = GMUL(i[ 3], mix[ 7]); - d = GMUL(i[ 4], mix[ 8]); - out[ 2] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 1], mix[ 9]); - b = GMUL(i[ 2], mix[10]); - c = GMUL(i[ 3], mix[11]); - d = GMUL(i[ 4], mix[12]); - out[ 3] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 1], mix[13]); - b = GMUL(i[ 2], mix[14]); - c = GMUL(i[ 3], mix[15]); - d = GMUL(i[ 4], mix[16]); - out[ 4] = XOR(XOR(a, b), XOR(c, d)); - - - a = GMUL(i[ 5], mix[ 1]); - b = GMUL(i[ 6], mix[ 2]); - c = GMUL(i[ 7], mix[ 3]); - d = GMUL(i[ 8], mix[ 4]); - out[ 5] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 5], mix[ 5]); - b = GMUL(i[ 6], mix[ 6]); - c = GMUL(i[ 7], mix[ 7]); - d = GMUL(i[ 8], mix[ 8]); - out[ 6] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 5], mix[ 9]); - b = GMUL(i[ 6], mix[10]); - c = GMUL(i[ 7], mix[11]); - d = GMUL(i[ 8], mix[12]); - out[ 7] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 5], mix[13]); - b = GMUL(i[ 6], mix[14]); - c = GMUL(i[ 7], mix[15]); - d = GMUL(i[ 8], mix[16]); - out[ 8] = XOR(XOR(a, b), XOR(c, d)); - - - a = GMUL(i[ 9], mix[ 1]); - b = GMUL(i[10], mix[ 2]); - c = GMUL(i[11], mix[ 3]); - d = GMUL(i[12], mix[ 4]); - out[ 9] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 9], mix[ 5]); - b = GMUL(i[10], mix[ 6]); - c = GMUL(i[11], mix[ 7]); - d = GMUL(i[12], mix[ 8]); - out[10] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 9], mix[ 9]); - b = GMUL(i[10], mix[10]); - c = GMUL(i[11], mix[11]); - d = GMUL(i[12], mix[12]); - out[11] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 9], mix[13]); - b = GMUL(i[10], mix[14]); - c = GMUL(i[11], mix[15]); - d = GMUL(i[12], mix[16]); - out[12] = XOR(XOR(a, b), XOR(c, d)); - - - a = GMUL(i[13], mix[ 1]); - b = GMUL(i[14], mix[ 2]); - c = GMUL(i[15], mix[ 3]); - d = GMUL(i[16], mix[ 4]); - out[13] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[13], mix[ 5]); - b = GMUL(i[14], mix[ 6]); - c = GMUL(i[15], mix[ 7]); - d = GMUL(i[16], mix[ 8]); - out[14] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[13], mix[ 9]); - b = GMUL(i[14], mix[10]); - c = GMUL(i[15], mix[11]); - d = GMUL(i[16], mix[12]); - out[15] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[13], mix[13]); - b = GMUL(i[14], mix[14]); - c = GMUL(i[15], mix[15]); - d = GMUL(i[16], mix[16]); - out[16] = XOR(XOR(a, b), XOR(c, d)); - - return out; -end - -local keyRound = function(key, round) - local out = {}; - - out[ 1] = XOR(key[ 1], XOR(SBOX[key[14]], RCON[round])); - out[ 2] = XOR(key[ 2], SBOX[key[15]]); - out[ 3] = XOR(key[ 3], SBOX[key[16]]); - out[ 4] = XOR(key[ 4], SBOX[key[13]]); - - out[ 5] = XOR(out[ 1], key[ 5]); - out[ 6] = XOR(out[ 2], key[ 6]); - out[ 7] = XOR(out[ 3], key[ 7]); - out[ 8] = XOR(out[ 4], key[ 8]); - - out[ 9] = XOR(out[ 5], key[ 9]); - out[10] = XOR(out[ 6], key[10]); - out[11] = XOR(out[ 7], key[11]); - out[12] = XOR(out[ 8], key[12]); - - out[13] = XOR(out[ 9], key[13]); - out[14] = XOR(out[10], key[14]); - out[15] = XOR(out[11], key[15]); - out[16] = XOR(out[12], key[16]); - - return out; -end - -local keyExpand = function(key) - local keys = {}; - - local temp = key; - - keys[1] = temp; - - for i = 1, 10 do - temp = keyRound(temp, i); - keys[i + 1] = temp; - end - - return keys; - -end - -local addKey = Array.XOR; - - - -local AES = {}; - -AES.blockSize = 16; - -AES.encrypt = function(_key, block) - - local key = keyExpand(_key); - - --round 0 - block = addKey(block, key[1]); - - --round 1 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[2]); - - --round 2 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[3]); - - --round 3 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[4]); - - --round 4 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[5]); - - --round 5 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[6]); - - --round 6 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[7]); - - --round 7 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[8]); - - --round 8 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[9]); - - --round 9 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[10]); - - --round 10 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = addKey(block, key[11]); - - return block; - -end - -AES.decrypt = function(_key, block) - - local key = keyExpand(_key); - - --round 0 - block = addKey(block, key[11]); - - --round 1 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[10]); - block = mixCol(block, IMIXTABLE); - - --round 2 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[9]); - block = mixCol(block, IMIXTABLE); - - --round 3 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[8]); - block = mixCol(block, IMIXTABLE); - - --round 4 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[7]); - block = mixCol(block, IMIXTABLE); - - --round 5 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[6]); - block = mixCol(block, IMIXTABLE); - - --round 6 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[5]); - block = mixCol(block, IMIXTABLE); - - --round 7 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[4]); - block = mixCol(block, IMIXTABLE); - - --round 8 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[3]); - block = mixCol(block, IMIXTABLE); - - --round 9 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[2]); - block = mixCol(block, IMIXTABLE); - - --round 10 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[1]); - - return block; -end - -return AES; diff --git a/lockbox/cipher/aes192.lua b/lockbox/cipher/aes192.lua deleted file mode 100644 index 5f55b0e..0000000 --- a/lockbox/cipher/aes192.lua +++ /dev/null @@ -1,462 +0,0 @@ - -local Array = require("lockbox.util.array"); -local Bit = require("lockbox.util.bit"); - -local XOR = Bit.bxor; - -local SBOX = { - [0] = 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, - 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, - 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, - 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, - 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, - 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, - 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, - 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, - 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, - 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, - 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, - 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, - 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, - 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, - 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, - 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16}; - -local ISBOX = { - [0] = 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, - 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, - 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, - 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, - 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, - 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, - 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, - 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, - 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, - 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, - 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, - 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, - 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, - 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, - 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D}; - -local ROW_SHIFT = { 1, 6, 11, 16, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, }; -local IROW_SHIFT = { 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3, 16, 13, 10, 7, 4, }; - -local ETABLE = { - [0] = 0x01, 0x03, 0x05, 0x0F, 0x11, 0x33, 0x55, 0xFF, 0x1A, 0x2E, 0x72, 0x96, 0xA1, 0xF8, 0x13, 0x35, - 0x5F, 0xE1, 0x38, 0x48, 0xD8, 0x73, 0x95, 0xA4, 0xF7, 0x02, 0x06, 0x0A, 0x1E, 0x22, 0x66, 0xAA, - 0xE5, 0x34, 0x5C, 0xE4, 0x37, 0x59, 0xEB, 0x26, 0x6A, 0xBE, 0xD9, 0x70, 0x90, 0xAB, 0xE6, 0x31, - 0x53, 0xF5, 0x04, 0x0C, 0x14, 0x3C, 0x44, 0xCC, 0x4F, 0xD1, 0x68, 0xB8, 0xD3, 0x6E, 0xB2, 0xCD, - 0x4C, 0xD4, 0x67, 0xA9, 0xE0, 0x3B, 0x4D, 0xD7, 0x62, 0xA6, 0xF1, 0x08, 0x18, 0x28, 0x78, 0x88, - 0x83, 0x9E, 0xB9, 0xD0, 0x6B, 0xBD, 0xDC, 0x7F, 0x81, 0x98, 0xB3, 0xCE, 0x49, 0xDB, 0x76, 0x9A, - 0xB5, 0xC4, 0x57, 0xF9, 0x10, 0x30, 0x50, 0xF0, 0x0B, 0x1D, 0x27, 0x69, 0xBB, 0xD6, 0x61, 0xA3, - 0xFE, 0x19, 0x2B, 0x7D, 0x87, 0x92, 0xAD, 0xEC, 0x2F, 0x71, 0x93, 0xAE, 0xE9, 0x20, 0x60, 0xA0, - 0xFB, 0x16, 0x3A, 0x4E, 0xD2, 0x6D, 0xB7, 0xC2, 0x5D, 0xE7, 0x32, 0x56, 0xFA, 0x15, 0x3F, 0x41, - 0xC3, 0x5E, 0xE2, 0x3D, 0x47, 0xC9, 0x40, 0xC0, 0x5B, 0xED, 0x2C, 0x74, 0x9C, 0xBF, 0xDA, 0x75, - 0x9F, 0xBA, 0xD5, 0x64, 0xAC, 0xEF, 0x2A, 0x7E, 0x82, 0x9D, 0xBC, 0xDF, 0x7A, 0x8E, 0x89, 0x80, - 0x9B, 0xB6, 0xC1, 0x58, 0xE8, 0x23, 0x65, 0xAF, 0xEA, 0x25, 0x6F, 0xB1, 0xC8, 0x43, 0xC5, 0x54, - 0xFC, 0x1F, 0x21, 0x63, 0xA5, 0xF4, 0x07, 0x09, 0x1B, 0x2D, 0x77, 0x99, 0xB0, 0xCB, 0x46, 0xCA, - 0x45, 0xCF, 0x4A, 0xDE, 0x79, 0x8B, 0x86, 0x91, 0xA8, 0xE3, 0x3E, 0x42, 0xC6, 0x51, 0xF3, 0x0E, - 0x12, 0x36, 0x5A, 0xEE, 0x29, 0x7B, 0x8D, 0x8C, 0x8F, 0x8A, 0x85, 0x94, 0xA7, 0xF2, 0x0D, 0x17, - 0x39, 0x4B, 0xDD, 0x7C, 0x84, 0x97, 0xA2, 0xFD, 0x1C, 0x24, 0x6C, 0xB4, 0xC7, 0x52, 0xF6, 0x01}; - -local LTABLE = { - [0] = 0x00, 0x00, 0x19, 0x01, 0x32, 0x02, 0x1A, 0xC6, 0x4B, 0xC7, 0x1B, 0x68, 0x33, 0xEE, 0xDF, 0x03, - 0x64, 0x04, 0xE0, 0x0E, 0x34, 0x8D, 0x81, 0xEF, 0x4C, 0x71, 0x08, 0xC8, 0xF8, 0x69, 0x1C, 0xC1, - 0x7D, 0xC2, 0x1D, 0xB5, 0xF9, 0xB9, 0x27, 0x6A, 0x4D, 0xE4, 0xA6, 0x72, 0x9A, 0xC9, 0x09, 0x78, - 0x65, 0x2F, 0x8A, 0x05, 0x21, 0x0F, 0xE1, 0x24, 0x12, 0xF0, 0x82, 0x45, 0x35, 0x93, 0xDA, 0x8E, - 0x96, 0x8F, 0xDB, 0xBD, 0x36, 0xD0, 0xCE, 0x94, 0x13, 0x5C, 0xD2, 0xF1, 0x40, 0x46, 0x83, 0x38, - 0x66, 0xDD, 0xFD, 0x30, 0xBF, 0x06, 0x8B, 0x62, 0xB3, 0x25, 0xE2, 0x98, 0x22, 0x88, 0x91, 0x10, - 0x7E, 0x6E, 0x48, 0xC3, 0xA3, 0xB6, 0x1E, 0x42, 0x3A, 0x6B, 0x28, 0x54, 0xFA, 0x85, 0x3D, 0xBA, - 0x2B, 0x79, 0x0A, 0x15, 0x9B, 0x9F, 0x5E, 0xCA, 0x4E, 0xD4, 0xAC, 0xE5, 0xF3, 0x73, 0xA7, 0x57, - 0xAF, 0x58, 0xA8, 0x50, 0xF4, 0xEA, 0xD6, 0x74, 0x4F, 0xAE, 0xE9, 0xD5, 0xE7, 0xE6, 0xAD, 0xE8, - 0x2C, 0xD7, 0x75, 0x7A, 0xEB, 0x16, 0x0B, 0xF5, 0x59, 0xCB, 0x5F, 0xB0, 0x9C, 0xA9, 0x51, 0xA0, - 0x7F, 0x0C, 0xF6, 0x6F, 0x17, 0xC4, 0x49, 0xEC, 0xD8, 0x43, 0x1F, 0x2D, 0xA4, 0x76, 0x7B, 0xB7, - 0xCC, 0xBB, 0x3E, 0x5A, 0xFB, 0x60, 0xB1, 0x86, 0x3B, 0x52, 0xA1, 0x6C, 0xAA, 0x55, 0x29, 0x9D, - 0x97, 0xB2, 0x87, 0x90, 0x61, 0xBE, 0xDC, 0xFC, 0xBC, 0x95, 0xCF, 0xCD, 0x37, 0x3F, 0x5B, 0xD1, - 0x53, 0x39, 0x84, 0x3C, 0x41, 0xA2, 0x6D, 0x47, 0x14, 0x2A, 0x9E, 0x5D, 0x56, 0xF2, 0xD3, 0xAB, - 0x44, 0x11, 0x92, 0xD9, 0x23, 0x20, 0x2E, 0x89, 0xB4, 0x7C, 0xB8, 0x26, 0x77, 0x99, 0xE3, 0xA5, - 0x67, 0x4A, 0xED, 0xDE, 0xC5, 0x31, 0xFE, 0x18, 0x0D, 0x63, 0x8C, 0x80, 0xC0, 0xF7, 0x70, 0x07}; - -local MIXTABLE = { - 0x02, 0x03, 0x01, 0x01, - 0x01, 0x02, 0x03, 0x01, - 0x01, 0x01, 0x02, 0x03, - 0x03, 0x01, 0x01, 0x02}; - -local IMIXTABLE = { - 0x0E, 0x0B, 0x0D, 0x09, - 0x09, 0x0E, 0x0B, 0x0D, - 0x0D, 0x09, 0x0E, 0x0B, - 0x0B, 0x0D, 0x09, 0x0E}; - -local RCON = { -[0] = 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, -0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, -0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, -0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, -0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, -0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, -0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, -0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, -0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, -0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, -0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, -0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, -0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, -0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, -0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, -0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d}; - - -local GMUL = function(A, B) - if(A == 0x01) then return B; end - if(B == 0x01) then return A; end - if(A == 0x00) then return 0; end - if(B == 0x00) then return 0; end - - local LA = LTABLE[A]; - local LB = LTABLE[B]; - - local sum = LA + LB; - if (sum > 0xFF) then sum = sum - 0xFF; end - - return ETABLE[sum]; -end - -local byteSub = Array.substitute; - -local shiftRow = Array.permute; - -local mixCol = function(i, mix) - local out = {}; - - local a, b, c, d; - - a = GMUL(i[ 1], mix[ 1]); - b = GMUL(i[ 2], mix[ 2]); - c = GMUL(i[ 3], mix[ 3]); - d = GMUL(i[ 4], mix[ 4]); - out[ 1] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 1], mix[ 5]); - b = GMUL(i[ 2], mix[ 6]); - c = GMUL(i[ 3], mix[ 7]); - d = GMUL(i[ 4], mix[ 8]); - out[ 2] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 1], mix[ 9]); - b = GMUL(i[ 2], mix[10]); - c = GMUL(i[ 3], mix[11]); - d = GMUL(i[ 4], mix[12]); - out[ 3] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 1], mix[13]); - b = GMUL(i[ 2], mix[14]); - c = GMUL(i[ 3], mix[15]); - d = GMUL(i[ 4], mix[16]); - out[ 4] = XOR(XOR(a, b), XOR(c, d)); - - - a = GMUL(i[ 5], mix[ 1]); - b = GMUL(i[ 6], mix[ 2]); - c = GMUL(i[ 7], mix[ 3]); - d = GMUL(i[ 8], mix[ 4]); - out[ 5] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 5], mix[ 5]); - b = GMUL(i[ 6], mix[ 6]); - c = GMUL(i[ 7], mix[ 7]); - d = GMUL(i[ 8], mix[ 8]); - out[ 6] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 5], mix[ 9]); - b = GMUL(i[ 6], mix[10]); - c = GMUL(i[ 7], mix[11]); - d = GMUL(i[ 8], mix[12]); - out[ 7] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 5], mix[13]); - b = GMUL(i[ 6], mix[14]); - c = GMUL(i[ 7], mix[15]); - d = GMUL(i[ 8], mix[16]); - out[ 8] = XOR(XOR(a, b), XOR(c, d)); - - - a = GMUL(i[ 9], mix[ 1]); - b = GMUL(i[10], mix[ 2]); - c = GMUL(i[11], mix[ 3]); - d = GMUL(i[12], mix[ 4]); - out[ 9] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 9], mix[ 5]); - b = GMUL(i[10], mix[ 6]); - c = GMUL(i[11], mix[ 7]); - d = GMUL(i[12], mix[ 8]); - out[10] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 9], mix[ 9]); - b = GMUL(i[10], mix[10]); - c = GMUL(i[11], mix[11]); - d = GMUL(i[12], mix[12]); - out[11] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 9], mix[13]); - b = GMUL(i[10], mix[14]); - c = GMUL(i[11], mix[15]); - d = GMUL(i[12], mix[16]); - out[12] = XOR(XOR(a, b), XOR(c, d)); - - - a = GMUL(i[13], mix[ 1]); - b = GMUL(i[14], mix[ 2]); - c = GMUL(i[15], mix[ 3]); - d = GMUL(i[16], mix[ 4]); - out[13] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[13], mix[ 5]); - b = GMUL(i[14], mix[ 6]); - c = GMUL(i[15], mix[ 7]); - d = GMUL(i[16], mix[ 8]); - out[14] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[13], mix[ 9]); - b = GMUL(i[14], mix[10]); - c = GMUL(i[15], mix[11]); - d = GMUL(i[16], mix[12]); - out[15] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[13], mix[13]); - b = GMUL(i[14], mix[14]); - c = GMUL(i[15], mix[15]); - d = GMUL(i[16], mix[16]); - out[16] = XOR(XOR(a, b), XOR(c, d)); - - return out; -end - -local keyRound = function(key, round) - local i = (round - 1) * 24; - local out = key; - - out[25 + i] = XOR(key[ 1 + i], XOR(SBOX[key[22 + i]], RCON[round])); - out[26 + i] = XOR(key[ 2 + i], SBOX[key[23 + i]]); - out[27 + i] = XOR(key[ 3 + i], SBOX[key[24 + i]]); - out[28 + i] = XOR(key[ 4 + i], SBOX[key[21 + i]]); - - out[29 + i] = XOR(out[25 + i], key[ 5 + i]); - out[30 + i] = XOR(out[26 + i], key[ 6 + i]); - out[31 + i] = XOR(out[27 + i], key[ 7 + i]); - out[32 + i] = XOR(out[28 + i], key[ 8 + i]); - - out[33 + i] = XOR(out[29 + i], key[ 9 + i]); - out[34 + i] = XOR(out[30 + i], key[10 + i]); - out[35 + i] = XOR(out[31 + i], key[11 + i]); - out[36 + i] = XOR(out[32 + i], key[12 + i]); - - out[37 + i] = XOR(out[33 + i], key[13 + i]); - out[38 + i] = XOR(out[34 + i], key[14 + i]); - out[39 + i] = XOR(out[35 + i], key[15 + i]); - out[40 + i] = XOR(out[36 + i], key[16 + i]); - - out[41 + i] = XOR(out[37 + i], key[17 + i]); - out[42 + i] = XOR(out[38 + i], key[18 + i]); - out[43 + i] = XOR(out[39 + i], key[19 + i]); - out[44 + i] = XOR(out[40 + i], key[20 + i]); - - out[45 + i] = XOR(out[41 + i], key[21 + i]); - out[46 + i] = XOR(out[42 + i], key[22 + i]); - out[47 + i] = XOR(out[43 + i], key[23 + i]); - out[48 + i] = XOR(out[44 + i], key[24 + i]); - - return out; -end - -local keyExpand = function(key) - local bytes = Array.copy(key); - - for i = 1, 8 do - keyRound(bytes, i); - end - - local keys = {}; - - keys[ 1] = Array.slice(bytes, 1, 16); - keys[ 2] = Array.slice(bytes, 17, 32); - keys[ 3] = Array.slice(bytes, 33, 48); - keys[ 4] = Array.slice(bytes, 49, 64); - keys[ 5] = Array.slice(bytes, 65, 80); - keys[ 6] = Array.slice(bytes, 81, 96); - keys[ 7] = Array.slice(bytes, 97, 112); - keys[ 8] = Array.slice(bytes, 113, 128); - keys[ 9] = Array.slice(bytes, 129, 144); - keys[10] = Array.slice(bytes, 145, 160); - keys[11] = Array.slice(bytes, 161, 176); - keys[12] = Array.slice(bytes, 177, 192); - keys[13] = Array.slice(bytes, 193, 208); - - return keys; - -end - -local addKey = Array.XOR; - - - -local AES = {}; - -AES.blockSize = 16; - -AES.encrypt = function(_key, block) - - local key = keyExpand(_key); - - --round 0 - block = addKey(block, key[1]); - - --round 1 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[2]); - - --round 2 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[3]); - - --round 3 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[4]); - - --round 4 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[5]); - - --round 5 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[6]); - - --round 6 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[7]); - - --round 7 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[8]); - - --round 8 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[9]); - - --round 9 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[10]); - - --round 10 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[11]); - - --round 11 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[12]); - - --round 12 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = addKey(block, key[13]); - - return block; - -end - -AES.decrypt = function(_key, block) - - local key = keyExpand(_key); - - --round 0 - block = addKey(block, key[13]); - - --round 1 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[12]); - block = mixCol(block, IMIXTABLE); - - --round 2 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[11]); - block = mixCol(block, IMIXTABLE); - - --round 3 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[10]); - block = mixCol(block, IMIXTABLE); - - --round 4 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[9]); - block = mixCol(block, IMIXTABLE); - - --round 5 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[8]); - block = mixCol(block, IMIXTABLE); - - --round 6 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[7]); - block = mixCol(block, IMIXTABLE); - - --round 7 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[6]); - block = mixCol(block, IMIXTABLE); - - --round 8 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[5]); - block = mixCol(block, IMIXTABLE); - - --round 9 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[4]); - block = mixCol(block, IMIXTABLE); - - --round 10 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[3]); - block = mixCol(block, IMIXTABLE); - - --round 11 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[2]); - block = mixCol(block, IMIXTABLE); - - --round 12 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[1]); - - return block; -end - -return AES; diff --git a/lockbox/cipher/aes256.lua b/lockbox/cipher/aes256.lua deleted file mode 100644 index 854bae9..0000000 --- a/lockbox/cipher/aes256.lua +++ /dev/null @@ -1,498 +0,0 @@ -local Array = require("lockbox.util.array"); -local Bit = require("lockbox.util.bit"); - -local XOR = Bit.bxor; - -local SBOX = { - [0] = 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, - 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, - 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, - 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, - 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, - 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, - 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, - 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, - 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, - 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, - 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, - 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, - 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, - 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, - 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, - 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16}; - -local ISBOX = { - [0] = 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, - 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, - 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, - 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, - 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, - 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, - 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, - 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, - 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, - 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, - 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, - 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, - 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, - 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, - 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D}; - -local ROW_SHIFT = { 1, 6, 11, 16, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, }; -local IROW_SHIFT = { 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3, 16, 13, 10, 7, 4, }; - -local ETABLE = { - [0] = 0x01, 0x03, 0x05, 0x0F, 0x11, 0x33, 0x55, 0xFF, 0x1A, 0x2E, 0x72, 0x96, 0xA1, 0xF8, 0x13, 0x35, - 0x5F, 0xE1, 0x38, 0x48, 0xD8, 0x73, 0x95, 0xA4, 0xF7, 0x02, 0x06, 0x0A, 0x1E, 0x22, 0x66, 0xAA, - 0xE5, 0x34, 0x5C, 0xE4, 0x37, 0x59, 0xEB, 0x26, 0x6A, 0xBE, 0xD9, 0x70, 0x90, 0xAB, 0xE6, 0x31, - 0x53, 0xF5, 0x04, 0x0C, 0x14, 0x3C, 0x44, 0xCC, 0x4F, 0xD1, 0x68, 0xB8, 0xD3, 0x6E, 0xB2, 0xCD, - 0x4C, 0xD4, 0x67, 0xA9, 0xE0, 0x3B, 0x4D, 0xD7, 0x62, 0xA6, 0xF1, 0x08, 0x18, 0x28, 0x78, 0x88, - 0x83, 0x9E, 0xB9, 0xD0, 0x6B, 0xBD, 0xDC, 0x7F, 0x81, 0x98, 0xB3, 0xCE, 0x49, 0xDB, 0x76, 0x9A, - 0xB5, 0xC4, 0x57, 0xF9, 0x10, 0x30, 0x50, 0xF0, 0x0B, 0x1D, 0x27, 0x69, 0xBB, 0xD6, 0x61, 0xA3, - 0xFE, 0x19, 0x2B, 0x7D, 0x87, 0x92, 0xAD, 0xEC, 0x2F, 0x71, 0x93, 0xAE, 0xE9, 0x20, 0x60, 0xA0, - 0xFB, 0x16, 0x3A, 0x4E, 0xD2, 0x6D, 0xB7, 0xC2, 0x5D, 0xE7, 0x32, 0x56, 0xFA, 0x15, 0x3F, 0x41, - 0xC3, 0x5E, 0xE2, 0x3D, 0x47, 0xC9, 0x40, 0xC0, 0x5B, 0xED, 0x2C, 0x74, 0x9C, 0xBF, 0xDA, 0x75, - 0x9F, 0xBA, 0xD5, 0x64, 0xAC, 0xEF, 0x2A, 0x7E, 0x82, 0x9D, 0xBC, 0xDF, 0x7A, 0x8E, 0x89, 0x80, - 0x9B, 0xB6, 0xC1, 0x58, 0xE8, 0x23, 0x65, 0xAF, 0xEA, 0x25, 0x6F, 0xB1, 0xC8, 0x43, 0xC5, 0x54, - 0xFC, 0x1F, 0x21, 0x63, 0xA5, 0xF4, 0x07, 0x09, 0x1B, 0x2D, 0x77, 0x99, 0xB0, 0xCB, 0x46, 0xCA, - 0x45, 0xCF, 0x4A, 0xDE, 0x79, 0x8B, 0x86, 0x91, 0xA8, 0xE3, 0x3E, 0x42, 0xC6, 0x51, 0xF3, 0x0E, - 0x12, 0x36, 0x5A, 0xEE, 0x29, 0x7B, 0x8D, 0x8C, 0x8F, 0x8A, 0x85, 0x94, 0xA7, 0xF2, 0x0D, 0x17, - 0x39, 0x4B, 0xDD, 0x7C, 0x84, 0x97, 0xA2, 0xFD, 0x1C, 0x24, 0x6C, 0xB4, 0xC7, 0x52, 0xF6, 0x01}; - -local LTABLE = { - [0] = 0x00, 0x00, 0x19, 0x01, 0x32, 0x02, 0x1A, 0xC6, 0x4B, 0xC7, 0x1B, 0x68, 0x33, 0xEE, 0xDF, 0x03, - 0x64, 0x04, 0xE0, 0x0E, 0x34, 0x8D, 0x81, 0xEF, 0x4C, 0x71, 0x08, 0xC8, 0xF8, 0x69, 0x1C, 0xC1, - 0x7D, 0xC2, 0x1D, 0xB5, 0xF9, 0xB9, 0x27, 0x6A, 0x4D, 0xE4, 0xA6, 0x72, 0x9A, 0xC9, 0x09, 0x78, - 0x65, 0x2F, 0x8A, 0x05, 0x21, 0x0F, 0xE1, 0x24, 0x12, 0xF0, 0x82, 0x45, 0x35, 0x93, 0xDA, 0x8E, - 0x96, 0x8F, 0xDB, 0xBD, 0x36, 0xD0, 0xCE, 0x94, 0x13, 0x5C, 0xD2, 0xF1, 0x40, 0x46, 0x83, 0x38, - 0x66, 0xDD, 0xFD, 0x30, 0xBF, 0x06, 0x8B, 0x62, 0xB3, 0x25, 0xE2, 0x98, 0x22, 0x88, 0x91, 0x10, - 0x7E, 0x6E, 0x48, 0xC3, 0xA3, 0xB6, 0x1E, 0x42, 0x3A, 0x6B, 0x28, 0x54, 0xFA, 0x85, 0x3D, 0xBA, - 0x2B, 0x79, 0x0A, 0x15, 0x9B, 0x9F, 0x5E, 0xCA, 0x4E, 0xD4, 0xAC, 0xE5, 0xF3, 0x73, 0xA7, 0x57, - 0xAF, 0x58, 0xA8, 0x50, 0xF4, 0xEA, 0xD6, 0x74, 0x4F, 0xAE, 0xE9, 0xD5, 0xE7, 0xE6, 0xAD, 0xE8, - 0x2C, 0xD7, 0x75, 0x7A, 0xEB, 0x16, 0x0B, 0xF5, 0x59, 0xCB, 0x5F, 0xB0, 0x9C, 0xA9, 0x51, 0xA0, - 0x7F, 0x0C, 0xF6, 0x6F, 0x17, 0xC4, 0x49, 0xEC, 0xD8, 0x43, 0x1F, 0x2D, 0xA4, 0x76, 0x7B, 0xB7, - 0xCC, 0xBB, 0x3E, 0x5A, 0xFB, 0x60, 0xB1, 0x86, 0x3B, 0x52, 0xA1, 0x6C, 0xAA, 0x55, 0x29, 0x9D, - 0x97, 0xB2, 0x87, 0x90, 0x61, 0xBE, 0xDC, 0xFC, 0xBC, 0x95, 0xCF, 0xCD, 0x37, 0x3F, 0x5B, 0xD1, - 0x53, 0x39, 0x84, 0x3C, 0x41, 0xA2, 0x6D, 0x47, 0x14, 0x2A, 0x9E, 0x5D, 0x56, 0xF2, 0xD3, 0xAB, - 0x44, 0x11, 0x92, 0xD9, 0x23, 0x20, 0x2E, 0x89, 0xB4, 0x7C, 0xB8, 0x26, 0x77, 0x99, 0xE3, 0xA5, - 0x67, 0x4A, 0xED, 0xDE, 0xC5, 0x31, 0xFE, 0x18, 0x0D, 0x63, 0x8C, 0x80, 0xC0, 0xF7, 0x70, 0x07}; - -local MIXTABLE = { - 0x02, 0x03, 0x01, 0x01, - 0x01, 0x02, 0x03, 0x01, - 0x01, 0x01, 0x02, 0x03, - 0x03, 0x01, 0x01, 0x02}; - -local IMIXTABLE = { - 0x0E, 0x0B, 0x0D, 0x09, - 0x09, 0x0E, 0x0B, 0x0D, - 0x0D, 0x09, 0x0E, 0x0B, - 0x0B, 0x0D, 0x09, 0x0E}; - -local RCON = { -[0] = 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, -0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, -0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, -0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, -0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, -0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, -0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, -0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, -0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, -0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, -0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, -0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, -0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, -0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, -0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, -0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d}; - - -local GMUL = function(A, B) - if(A == 0x01) then return B; end - if(B == 0x01) then return A; end - if(A == 0x00) then return 0; end - if(B == 0x00) then return 0; end - - local LA = LTABLE[A]; - local LB = LTABLE[B]; - - local sum = LA + LB; - if (sum > 0xFF) then sum = sum - 0xFF; end - - return ETABLE[sum]; -end - -local byteSub = Array.substitute; - -local shiftRow = Array.permute; - -local mixCol = function(i, mix) - local out = {}; - - local a, b, c, d; - - a = GMUL(i[ 1], mix[ 1]); - b = GMUL(i[ 2], mix[ 2]); - c = GMUL(i[ 3], mix[ 3]); - d = GMUL(i[ 4], mix[ 4]); - out[ 1] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 1], mix[ 5]); - b = GMUL(i[ 2], mix[ 6]); - c = GMUL(i[ 3], mix[ 7]); - d = GMUL(i[ 4], mix[ 8]); - out[ 2] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 1], mix[ 9]); - b = GMUL(i[ 2], mix[10]); - c = GMUL(i[ 3], mix[11]); - d = GMUL(i[ 4], mix[12]); - out[ 3] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 1], mix[13]); - b = GMUL(i[ 2], mix[14]); - c = GMUL(i[ 3], mix[15]); - d = GMUL(i[ 4], mix[16]); - out[ 4] = XOR(XOR(a, b), XOR(c, d)); - - - a = GMUL(i[ 5], mix[ 1]); - b = GMUL(i[ 6], mix[ 2]); - c = GMUL(i[ 7], mix[ 3]); - d = GMUL(i[ 8], mix[ 4]); - out[ 5] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 5], mix[ 5]); - b = GMUL(i[ 6], mix[ 6]); - c = GMUL(i[ 7], mix[ 7]); - d = GMUL(i[ 8], mix[ 8]); - out[ 6] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 5], mix[ 9]); - b = GMUL(i[ 6], mix[10]); - c = GMUL(i[ 7], mix[11]); - d = GMUL(i[ 8], mix[12]); - out[ 7] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 5], mix[13]); - b = GMUL(i[ 6], mix[14]); - c = GMUL(i[ 7], mix[15]); - d = GMUL(i[ 8], mix[16]); - out[ 8] = XOR(XOR(a, b), XOR(c, d)); - - - a = GMUL(i[ 9], mix[ 1]); - b = GMUL(i[10], mix[ 2]); - c = GMUL(i[11], mix[ 3]); - d = GMUL(i[12], mix[ 4]); - out[ 9] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 9], mix[ 5]); - b = GMUL(i[10], mix[ 6]); - c = GMUL(i[11], mix[ 7]); - d = GMUL(i[12], mix[ 8]); - out[10] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 9], mix[ 9]); - b = GMUL(i[10], mix[10]); - c = GMUL(i[11], mix[11]); - d = GMUL(i[12], mix[12]); - out[11] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[ 9], mix[13]); - b = GMUL(i[10], mix[14]); - c = GMUL(i[11], mix[15]); - d = GMUL(i[12], mix[16]); - out[12] = XOR(XOR(a, b), XOR(c, d)); - - - a = GMUL(i[13], mix[ 1]); - b = GMUL(i[14], mix[ 2]); - c = GMUL(i[15], mix[ 3]); - d = GMUL(i[16], mix[ 4]); - out[13] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[13], mix[ 5]); - b = GMUL(i[14], mix[ 6]); - c = GMUL(i[15], mix[ 7]); - d = GMUL(i[16], mix[ 8]); - out[14] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[13], mix[ 9]); - b = GMUL(i[14], mix[10]); - c = GMUL(i[15], mix[11]); - d = GMUL(i[16], mix[12]); - out[15] = XOR(XOR(a, b), XOR(c, d)); - a = GMUL(i[13], mix[13]); - b = GMUL(i[14], mix[14]); - c = GMUL(i[15], mix[15]); - d = GMUL(i[16], mix[16]); - out[16] = XOR(XOR(a, b), XOR(c, d)); - - return out; -end - -local keyRound = function(key, round) - local i = (round - 1) * 32; - local out = key; - - out[33 + i] = XOR(key[ 1 + i], XOR(SBOX[key[30 + i]], RCON[round])); - out[34 + i] = XOR(key[ 2 + i], SBOX[key[31 + i]]); - out[35 + i] = XOR(key[ 3 + i], SBOX[key[32 + i]]); - out[36 + i] = XOR(key[ 4 + i], SBOX[key[29 + i]]); - - out[37 + i] = XOR(out[33 + i], key[ 5 + i]); - out[38 + i] = XOR(out[34 + i], key[ 6 + i]); - out[39 + i] = XOR(out[35 + i], key[ 7 + i]); - out[40 + i] = XOR(out[36 + i], key[ 8 + i]); - - out[41 + i] = XOR(out[37 + i], key[ 9 + i]); - out[42 + i] = XOR(out[38 + i], key[10 + i]); - out[43 + i] = XOR(out[39 + i], key[11 + i]); - out[44 + i] = XOR(out[40 + i], key[12 + i]); - - out[45 + i] = XOR(out[41 + i], key[13 + i]); - out[46 + i] = XOR(out[42 + i], key[14 + i]); - out[47 + i] = XOR(out[43 + i], key[15 + i]); - out[48 + i] = XOR(out[44 + i], key[16 + i]); - - - out[49 + i] = XOR(SBOX[out[45 + i]], key[17 + i]); - out[50 + i] = XOR(SBOX[out[46 + i]], key[18 + i]); - out[51 + i] = XOR(SBOX[out[47 + i]], key[19 + i]); - out[52 + i] = XOR(SBOX[out[48 + i]], key[20 + i]); - - out[53 + i] = XOR(out[49 + i], key[21 + i]); - out[54 + i] = XOR(out[50 + i], key[22 + i]); - out[55 + i] = XOR(out[51 + i], key[23 + i]); - out[56 + i] = XOR(out[52 + i], key[24 + i]); - - out[57 + i] = XOR(out[53 + i], key[25 + i]); - out[58 + i] = XOR(out[54 + i], key[26 + i]); - out[59 + i] = XOR(out[55 + i], key[27 + i]); - out[60 + i] = XOR(out[56 + i], key[28 + i]); - - out[61 + i] = XOR(out[57 + i], key[29 + i]); - out[62 + i] = XOR(out[58 + i], key[30 + i]); - out[63 + i] = XOR(out[59 + i], key[31 + i]); - out[64 + i] = XOR(out[60 + i], key[32 + i]); - - return out; -end - -local keyExpand = function(key) - local bytes = Array.copy(key); - - for i = 1, 7 do - keyRound(bytes, i); - end - - local keys = {}; - - keys[ 1] = Array.slice(bytes, 1, 16); - keys[ 2] = Array.slice(bytes, 17, 32); - keys[ 3] = Array.slice(bytes, 33, 48); - keys[ 4] = Array.slice(bytes, 49, 64); - keys[ 5] = Array.slice(bytes, 65, 80); - keys[ 6] = Array.slice(bytes, 81, 96); - keys[ 7] = Array.slice(bytes, 97, 112); - keys[ 8] = Array.slice(bytes, 113, 128); - keys[ 9] = Array.slice(bytes, 129, 144); - keys[10] = Array.slice(bytes, 145, 160); - keys[11] = Array.slice(bytes, 161, 176); - keys[12] = Array.slice(bytes, 177, 192); - keys[13] = Array.slice(bytes, 193, 208); - keys[14] = Array.slice(bytes, 209, 224); - keys[15] = Array.slice(bytes, 225, 240); - - return keys; - -end - -local addKey = Array.XOR; - - - -local AES = {}; - -AES.blockSize = 16; - -AES.encrypt = function(_key, block) - - local key = keyExpand(_key); - - --round 0 - block = addKey(block, key[1]); - - --round 1 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[2]); - - --round 2 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[3]); - - --round 3 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[4]); - - --round 4 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[5]); - - --round 5 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[6]); - - --round 6 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[7]); - - --round 7 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[8]); - - --round 8 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[9]); - - --round 9 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[10]); - - --round 10 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[11]); - - --round 11 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[12]); - - --round 12 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[13]); - - --round 13 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = mixCol(block, MIXTABLE); - block = addKey(block, key[14]); - - --round 14 - block = byteSub(block, SBOX); - block = shiftRow(block, ROW_SHIFT); - block = addKey(block, key[15]); - - return block; - -end - -AES.decrypt = function(_key, block) - - local key = keyExpand(_key); - - --round 0 - block = addKey(block, key[15]); - - --round 1 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[14]); - block = mixCol(block, IMIXTABLE); - - --round 2 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[13]); - block = mixCol(block, IMIXTABLE); - - --round 3 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[12]); - block = mixCol(block, IMIXTABLE); - - --round 4 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[11]); - block = mixCol(block, IMIXTABLE); - - --round 5 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[10]); - block = mixCol(block, IMIXTABLE); - - --round 6 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[9]); - block = mixCol(block, IMIXTABLE); - - --round 7 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[8]); - block = mixCol(block, IMIXTABLE); - - --round 8 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[7]); - block = mixCol(block, IMIXTABLE); - - --round 9 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[6]); - block = mixCol(block, IMIXTABLE); - - --round 10 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[5]); - block = mixCol(block, IMIXTABLE); - - --round 11 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[4]); - block = mixCol(block, IMIXTABLE); - - --round 12 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[3]); - block = mixCol(block, IMIXTABLE); - - --round 13 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[2]); - block = mixCol(block, IMIXTABLE); - - --round 14 - block = shiftRow(block, IROW_SHIFT); - block = byteSub(block, ISBOX); - block = addKey(block, key[1]); - - return block; -end - -return AES; diff --git a/lockbox/cipher/mode/cbc.lua b/lockbox/cipher/mode/cbc.lua deleted file mode 100644 index a02ff2e..0000000 --- a/lockbox/cipher/mode/cbc.lua +++ /dev/null @@ -1,164 +0,0 @@ -local Array = require("lockbox.util.array"); -local Stream = require("lockbox.util.stream"); -local Queue = require("lockbox.util.queue"); - -local CBC = {}; - -CBC.Cipher = function() - - local public = {}; - - local key; - local blockCipher; - local padding; - local inputQueue; - local outputQueue; - local iv; - - public.setKey = function(keyBytes) - key = keyBytes; - return public; - end - - public.setBlockCipher = function(cipher) - blockCipher = cipher; - return public; - end - - public.setPadding = function(paddingMode) - padding = paddingMode; - return public; - end - - public.init = function() - inputQueue = Queue(); - outputQueue = Queue(); - iv = nil; - return public; - end - - public.update = function(messageStream) - local byte = messageStream(); - while (byte ~= nil) do - inputQueue.push(byte); - if(inputQueue.size() >= blockCipher.blockSize) then - local block = Array.readFromQueue(inputQueue, blockCipher.blockSize); - - if(iv == nil) then - iv = block; - else - local out = Array.XOR(iv, block); - out = blockCipher.encrypt(key, out); - Array.writeToQueue(outputQueue, out); - iv = out; - end - end - byte = messageStream(); - end - return public; - end - - public.finish = function() - local paddingStream = padding(blockCipher.blockSize, inputQueue.getHead()); - public.update(paddingStream); - - return public; - end - - public.getOutputQueue = function() - return outputQueue; - end - - public.asHex = function() - return Stream.toHex(outputQueue.pop); - end - - public.asBytes = function() - return Stream.toArray(outputQueue.pop); - end - - return public; - -end - - -CBC.Decipher = function() - - local public = {}; - - local key; - local blockCipher; - local padding; - local inputQueue; - local outputQueue; - local iv; - - public.setKey = function(keyBytes) - key = keyBytes; - return public; - end - - public.setBlockCipher = function(cipher) - blockCipher = cipher; - return public; - end - - public.setPadding = function(paddingMode) - padding = paddingMode; - return public; - end - - public.init = function() - inputQueue = Queue(); - outputQueue = Queue(); - iv = nil; - return public; - end - - public.update = function(messageStream) - local byte = messageStream(); - while (byte ~= nil) do - inputQueue.push(byte); - if(inputQueue.size() >= blockCipher.blockSize) then - local block = Array.readFromQueue(inputQueue, blockCipher.blockSize); - - if(iv == nil) then - iv = block; - else - local out = block; - out = blockCipher.decrypt(key, out); - out = Array.XOR(iv, out); - Array.writeToQueue(outputQueue, out); - iv = block; - end - end - byte = messageStream(); - end - return public; - end - - public.finish = function() - local paddingStream = padding(blockCipher.blockSize, inputQueue.getHead()); - public.update(paddingStream); - - return public; - end - - public.getOutputQueue = function() - return outputQueue; - end - - public.asHex = function() - return Stream.toHex(outputQueue.pop); - end - - public.asBytes = function() - return Stream.toArray(outputQueue.pop); - end - - return public; - -end - -return CBC; - diff --git a/lockbox/cipher/mode/cfb.lua b/lockbox/cipher/mode/cfb.lua deleted file mode 100644 index c736d52..0000000 --- a/lockbox/cipher/mode/cfb.lua +++ /dev/null @@ -1,163 +0,0 @@ -local Array = require("lockbox.util.array"); -local Stream = require("lockbox.util.stream"); -local Queue = require("lockbox.util.queue"); - -local CFB = {}; - -CFB.Cipher = function() - - local public = {}; - - local key; - local blockCipher; - local padding; - local inputQueue; - local outputQueue; - local iv; - - public.setKey = function(keyBytes) - key = keyBytes; - return public; - end - - public.setBlockCipher = function(cipher) - blockCipher = cipher; - return public; - end - - public.setPadding = function(paddingMode) - padding = paddingMode; - return public; - end - - public.init = function() - inputQueue = Queue(); - outputQueue = Queue(); - iv = nil; - return public; - end - - public.update = function(messageStream) - local byte = messageStream(); - while (byte ~= nil) do - inputQueue.push(byte); - if(inputQueue.size() >= blockCipher.blockSize) then - local block = Array.readFromQueue(inputQueue, blockCipher.blockSize); - - if(iv == nil) then - iv = block; - else - local out = iv; - out = blockCipher.encrypt(key, out); - out = Array.XOR(out, block); - Array.writeToQueue(outputQueue, out); - iv = out; - end - end - byte = messageStream(); - end - return public; - end - - public.finish = function() - local paddingStream = padding(blockCipher.blockSize, inputQueue.getHead()); - public.update(paddingStream); - - return public; - end - - public.getOutputQueue = function() - return outputQueue; - end - - public.asHex = function() - return Stream.toHex(outputQueue.pop); - end - - public.asBytes = function() - return Stream.toArray(outputQueue.pop); - end - - return public; - -end - -CFB.Decipher = function() - - local public = {}; - - local key; - local blockCipher; - local padding; - local inputQueue; - local outputQueue; - local iv; - - public.setKey = function(keyBytes) - key = keyBytes; - return public; - end - - public.setBlockCipher = function(cipher) - blockCipher = cipher; - return public; - end - - public.setPadding = function(paddingMode) - padding = paddingMode; - return public; - end - - public.init = function() - inputQueue = Queue(); - outputQueue = Queue(); - iv = nil; - return public; - end - - public.update = function(messageStream) - local byte = messageStream(); - while (byte ~= nil) do - inputQueue.push(byte); - if(inputQueue.size() >= blockCipher.blockSize) then - local block = Array.readFromQueue(inputQueue, blockCipher.blockSize); - - if(iv == nil) then - iv = block; - else - local out = iv; - out = blockCipher.encrypt(key, out); - out = Array.XOR(out, block); - Array.writeToQueue(outputQueue, out); - iv = block; - end - end - byte = messageStream(); - end - return public; - end - - public.finish = function() - local paddingStream = padding(blockCipher.blockSize, inputQueue.getHead()); - public.update(paddingStream); - - return public; - end - - public.getOutputQueue = function() - return outputQueue; - end - - public.asHex = function() - return Stream.toHex(outputQueue.pop); - end - - public.asBytes = function() - return Stream.toArray(outputQueue.pop); - end - - return public; - -end - -return CFB; diff --git a/lockbox/cipher/mode/ctr.lua b/lockbox/cipher/mode/ctr.lua deleted file mode 100644 index beb8ef0..0000000 --- a/lockbox/cipher/mode/ctr.lua +++ /dev/null @@ -1,248 +0,0 @@ -local Array = require("lockbox.util.array"); -local Stream = require("lockbox.util.stream"); -local Queue = require("lockbox.util.queue"); - -local Bit = require("lockbox.util.bit"); - -local AND = Bit.band; - -local CTR = {}; - -CTR.Cipher = function() - - local public = {}; - - local key; - local blockCipher; - local padding; - local inputQueue; - local outputQueue; - local iv; - - public.setKey = function(keyBytes) - key = keyBytes; - return public; - end - - public.setBlockCipher = function(cipher) - blockCipher = cipher; - return public; - end - - public.setPadding = function(paddingMode) - padding = paddingMode; - return public; - end - - public.init = function() - inputQueue = Queue(); - outputQueue = Queue(); - iv = nil; - return public; - end - - local updateIV = function() - iv[16] = iv[16] + 1; - if iv[16] <= 0xFF then return; end - iv[16] = AND(iv[16], 0xFF); - - iv[15] = iv[15] + 1; - if iv[15] <= 0xFF then return; end - iv[15] = AND(iv[15], 0xFF); - - iv[14] = iv[14] + 1; - if iv[14] <= 0xFF then return; end - iv[14] = AND(iv[14], 0xFF); - - iv[13] = iv[13] + 1; - if iv[13] <= 0xFF then return; end - iv[13] = AND(iv[13], 0xFF); - - iv[12] = iv[12] + 1; - if iv[12] <= 0xFF then return; end - iv[12] = AND(iv[12], 0xFF); - - iv[11] = iv[11] + 1; - if iv[11] <= 0xFF then return; end - iv[11] = AND(iv[11], 0xFF); - - iv[10] = iv[10] + 1; - if iv[10] <= 0xFF then return; end - iv[10] = AND(iv[10], 0xFF); - - iv[9] = iv[9] + 1; - if iv[9] <= 0xFF then return; end - iv[9] = AND(iv[9], 0xFF); - - return; - end - - public.update = function(messageStream) - local byte = messageStream(); - while (byte ~= nil) do - inputQueue.push(byte); - - if(inputQueue.size() >= blockCipher.blockSize) then - local block = Array.readFromQueue(inputQueue, blockCipher.blockSize); - - if(iv == nil) then - iv = block; - else - local out = iv; - out = blockCipher.encrypt(key, out); - - out = Array.XOR(out, block); - Array.writeToQueue(outputQueue, out); - updateIV(); - end - end - byte = messageStream(); - end - return public; - end - - public.finish = function() - local paddingStream = padding(blockCipher.blockSize, inputQueue.getHead()); - public.update(paddingStream); - - return public; - end - - public.getOutputQueue = function() - return outputQueue; - end - - public.asHex = function() - return Stream.toHex(outputQueue.pop); - end - - public.asBytes = function() - return Stream.toArray(outputQueue.pop); - end - - return public; - -end - - -CTR.Decipher = function() - - local public = {}; - - local key; - local blockCipher; - local padding; - local inputQueue; - local outputQueue; - local iv; - - public.setKey = function(keyBytes) - key = keyBytes; - return public; - end - - public.setBlockCipher = function(cipher) - blockCipher = cipher; - return public; - end - - public.setPadding = function(paddingMode) - padding = paddingMode; - return public; - end - - public.init = function() - inputQueue = Queue(); - outputQueue = Queue(); - iv = nil; - return public; - end - - local updateIV = function() - iv[16] = iv[16] + 1; - if iv[16] <= 0xFF then return; end - iv[16] = AND(iv[16], 0xFF); - - iv[15] = iv[15] + 1; - if iv[15] <= 0xFF then return; end - iv[15] = AND(iv[15], 0xFF); - - iv[14] = iv[14] + 1; - if iv[14] <= 0xFF then return; end - iv[14] = AND(iv[14], 0xFF); - - iv[13] = iv[13] + 1; - if iv[13] <= 0xFF then return; end - iv[13] = AND(iv[13], 0xFF); - - iv[12] = iv[12] + 1; - if iv[12] <= 0xFF then return; end - iv[12] = AND(iv[12], 0xFF); - - iv[11] = iv[11] + 1; - if iv[11] <= 0xFF then return; end - iv[11] = AND(iv[11], 0xFF); - - iv[10] = iv[10] + 1; - if iv[10] <= 0xFF then return; end - iv[10] = AND(iv[10], 0xFF); - - iv[9] = iv[9] + 1; - if iv[9] <= 0xFF then return; end - iv[9] = AND(iv[9], 0xFF); - - return; - end - - public.update = function(messageStream) - local byte = messageStream(); - while (byte ~= nil) do - inputQueue.push(byte); - - if(inputQueue.size() >= blockCipher.blockSize) then - local block = Array.readFromQueue(inputQueue, blockCipher.blockSize); - - if(iv == nil) then - iv = block; - else - local out = iv; - out = blockCipher.encrypt(key, out); - - out = Array.XOR(out, block); - Array.writeToQueue(outputQueue, out); - updateIV(); - end - end - byte = messageStream(); - end - return public; - end - - public.finish = function() - local paddingStream = padding(blockCipher.blockSize, inputQueue.getHead()); - public.update(paddingStream); - - return public; - end - - public.getOutputQueue = function() - return outputQueue; - end - - public.asHex = function() - return Stream.toHex(outputQueue.pop); - end - - public.asBytes = function() - return Stream.toArray(outputQueue.pop); - end - - return public; - -end - - - - -return CTR; - diff --git a/lockbox/cipher/mode/ofb.lua b/lockbox/cipher/mode/ofb.lua deleted file mode 100644 index a824846..0000000 --- a/lockbox/cipher/mode/ofb.lua +++ /dev/null @@ -1,164 +0,0 @@ -local Array = require("lockbox.util.array"); -local Stream = require("lockbox.util.stream"); -local Queue = require("lockbox.util.queue"); - -local OFB = {}; - -OFB.Cipher = function() - - local public = {}; - - local key; - local blockCipher; - local padding; - local inputQueue; - local outputQueue; - local iv; - - public.setKey = function(keyBytes) - key = keyBytes; - return public; - end - - public.setBlockCipher = function(cipher) - blockCipher = cipher; - return public; - end - - public.setPadding = function(paddingMode) - padding = paddingMode; - return public; - end - - public.init = function() - inputQueue = Queue(); - outputQueue = Queue(); - iv = nil; - return public; - end - - public.update = function(messageStream) - local byte = messageStream(); - while (byte ~= nil) do - inputQueue.push(byte); - if(inputQueue.size() >= blockCipher.blockSize) then - local block = Array.readFromQueue(inputQueue, blockCipher.blockSize); - - if(iv == nil) then - iv = block; - else - local out = iv; - out = blockCipher.encrypt(key, out); - iv = out; - out = Array.XOR(out, block); - Array.writeToQueue(outputQueue, out); - end - end - byte = messageStream(); - end - return public; - end - - public.finish = function() - local paddingStream = padding(blockCipher.blockSize, inputQueue.getHead()); - public.update(paddingStream); - - return public; - end - - public.getOutputQueue = function() - return outputQueue; - end - - public.asHex = function() - return Stream.toHex(outputQueue.pop); - end - - public.asBytes = function() - return Stream.toArray(outputQueue.pop); - end - - return public; - -end - -OFB.Decipher = function() - - local public = {}; - - local key; - local blockCipher; - local padding; - local inputQueue; - local outputQueue; - local iv; - - public.setKey = function(keyBytes) - key = keyBytes; - return public; - end - - public.setBlockCipher = function(cipher) - blockCipher = cipher; - return public; - end - - public.setPadding = function(paddingMode) - padding = paddingMode; - return public; - end - - public.init = function() - inputQueue = Queue(); - outputQueue = Queue(); - iv = nil; - return public; - end - - public.update = function(messageStream) - local byte = messageStream(); - while (byte ~= nil) do - inputQueue.push(byte); - if(inputQueue.size() >= blockCipher.blockSize) then - local block = Array.readFromQueue(inputQueue, blockCipher.blockSize); - - if(iv == nil) then - iv = block; - else - local out = iv; - out = blockCipher.encrypt(key, out); - iv = out; - out = Array.XOR(out, block); - Array.writeToQueue(outputQueue, out); - end - end - byte = messageStream(); - end - return public; - end - - public.finish = function() - local paddingStream = padding(blockCipher.blockSize, inputQueue.getHead()); - public.update(paddingStream); - - return public; - end - - public.getOutputQueue = function() - return outputQueue; - end - - public.asHex = function() - return Stream.toHex(outputQueue.pop); - end - - public.asBytes = function() - return Stream.toArray(outputQueue.pop); - end - - return public; - -end - - -return OFB; diff --git a/lockbox/digest/md5.lua b/lockbox/digest/md5.lua new file mode 100644 index 0000000..6ce1df2 --- /dev/null +++ b/lockbox/digest/md5.lua @@ -0,0 +1,201 @@ +require("lockbox").insecure(); + +local Bit = require("lockbox.util.bit"); +local String = require("string"); +local Math = require("math"); +local Queue = require("lockbox.util.queue"); + +local SHIFT = { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21}; + +local CONSTANTS = { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391}; + +local AND = Bit.band; +local OR = Bit.bor; +local NOT = Bit.bnot; +local XOR = Bit.bxor; +local LROT = Bit.lrotate; +local LSHIFT = Bit.lshift; +local RSHIFT = Bit.rshift; + +--MD5 is little-endian +local bytes2word = function(b0, b1, b2, b3) + local i = b3; i = LSHIFT(i, 8); + i = OR(i, b2); i = LSHIFT(i, 8); + i = OR(i, b1); i = LSHIFT(i, 8); + i = OR(i, b0); + return i; +end + +local word2bytes = function(word) + local b0, b1, b2, b3; + b0 = AND(word, 0xFF); word = RSHIFT(word, 8); + b1 = AND(word, 0xFF); word = RSHIFT(word, 8); + b2 = AND(word, 0xFF); word = RSHIFT(word, 8); + b3 = AND(word, 0xFF); + return b0, b1, b2, b3; +end + +local dword2bytes = function(i) + local b4, b5, b6, b7 = word2bytes(Math.floor(i / 0x100000000)); + local b0, b1, b2, b3 = word2bytes(i); + return b0, b1, b2, b3, b4, b5, b6, b7; +end + +local F = function(x, y, z) return OR(AND(x, y), AND(NOT(x), z)); end +local G = function(x, y, z) return OR(AND(x, z), AND(y, NOT(z))); end +local H = function(x, y, z) return XOR(x, XOR(y, z)); end +local I = function(x, y, z) return XOR(y, OR(x, NOT(z))); end + +local MD5 = function() + + local queue = Queue(); + + local A = 0x67452301; + local B = 0xefcdab89; + local C = 0x98badcfe; + local D = 0x10325476; + local public = {}; + + local processBlock = function() + local a = A; + local b = B; + local c = C; + local d = D; + + local X = {}; + + for i = 1, 16 do + X[i] = bytes2word(queue.pop(), queue.pop(), queue.pop(), queue.pop()); + end + + for i = 0, 63 do + local f, g, temp; + + if (0 <= i) and (i <= 15) then + f = F(b, c, d); + g = i; + elseif (16 <= i) and (i <= 31) then + f = G(b, c, d); + g = (5 * i + 1) % 16; + elseif (32 <= i) and (i <= 47) then + f = H(b, c, d); + g = (3 * i + 5) % 16; + elseif (48 <= i) and (i <= 63) then + f = I(b, c, d); + g = (7 * i) % 16; + end + temp = d; + d = c; + c = b; + b = b + LROT((a + f + CONSTANTS[i + 1] + X[g + 1]), SHIFT[i + 1]); + a = temp; + end + + A = AND(A + a, 0xFFFFFFFF); + B = AND(B + b, 0xFFFFFFFF); + C = AND(C + c, 0xFFFFFFFF); + D = AND(D + d, 0xFFFFFFFF); + end + + public.init = function() + queue.reset(); + + A = 0x67452301; + B = 0xefcdab89; + C = 0x98badcfe; + D = 0x10325476; + + return public; + end + + public.update = function(bytes) + for b in bytes do + queue.push(b); + if(queue.size() >= 64) then processBlock(); end + end + + return public; + end + + public.finish = function() + local bits = queue.getHead() * 8; + + queue.push(0x80); + while ((queue.size() + 7) % 64) < 63 do + queue.push(0x00); + end + + local b0, b1, b2, b3, b4, b5, b6, b7 = dword2bytes(bits); + + queue.push(b0); + queue.push(b1); + queue.push(b2); + queue.push(b3); + queue.push(b4); + queue.push(b5); + queue.push(b6); + queue.push(b7); + + while queue.size() > 0 do + processBlock(); + end + + return public; + end + + public.asBytes = function() + local b0, b1, b2, b3 = word2bytes(A); + local b4, b5, b6, b7 = word2bytes(B); + local b8, b9, b10, b11 = word2bytes(C); + local b12, b13, b14, b15 = word2bytes(D); + + return {b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15}; + end + + public.asHex = function() + local b0, b1, b2, b3 = word2bytes(A); + local b4, b5, b6, b7 = word2bytes(B); + local b8, b9, b10, b11 = word2bytes(C); + local b12, b13, b14, b15 = word2bytes(D); + + return String.format("%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15); + end + + public.asString = function() + local b0, b1, b2, b3 = word2bytes(A); + local b4, b5, b6, b7 = word2bytes(B); + local b8, b9, b10, b11 = word2bytes(C); + local b12, b13, b14, b15 = word2bytes(D); + + return string.pack(string.rep('B', 16), + b0, b1, b2, b3, b4, b5, b6, b7, b8, + b9, b10, b11, b12, b13, b14, b15 + ) + end + + return public; + +end + +return MD5; diff --git a/lockbox/padding/ansix923.lua b/lockbox/padding/ansix923.lua deleted file mode 100644 index 83702c6..0000000 --- a/lockbox/padding/ansix923.lua +++ /dev/null @@ -1,22 +0,0 @@ -local ANSIX923Padding = function(blockSize, byteCount) - - local paddingCount = blockSize - (byteCount % blockSize); - local bytesLeft = paddingCount; - - local stream = function() - if bytesLeft > 1 then - bytesLeft = bytesLeft - 1; - return 0x00; - elseif bytesLeft > 0 then - bytesLeft = bytesLeft - 1; - return paddingCount; - else - return nil; - end - end - - return stream; - -end - -return ANSIX923Padding; diff --git a/lockbox/padding/isoiec7816.lua b/lockbox/padding/isoiec7816.lua deleted file mode 100644 index 3dc255d..0000000 --- a/lockbox/padding/isoiec7816.lua +++ /dev/null @@ -1,22 +0,0 @@ -local ISOIEC7816Padding = function(blockSize, byteCount) - - local paddingCount = blockSize - (byteCount % blockSize); - local bytesLeft = paddingCount; - - local stream = function() - if bytesLeft == paddingCount then - bytesLeft = bytesLeft - 1; - return 0x80; - elseif bytesLeft > 0 then - bytesLeft = bytesLeft - 1; - return 0x00; - else - return nil; - end - end - - return stream; - -end - -return ISOIEC7816Padding; diff --git a/lockbox/padding/pkcs7.lua b/lockbox/padding/pkcs7.lua deleted file mode 100644 index 3b635ab..0000000 --- a/lockbox/padding/pkcs7.lua +++ /dev/null @@ -1,18 +0,0 @@ -local PKCS7Padding = function(blockSize, byteCount) - - local paddingCount = blockSize - ((byteCount -1) % blockSize) + 1; - local bytesLeft = paddingCount; - - local stream = function() - if bytesLeft > 0 then - bytesLeft = bytesLeft - 1; - return paddingCount; - else - return nil; - end - end - - return stream; -end - -return PKCS7Padding; diff --git a/lockbox/padding/zero.lua b/lockbox/padding/zero.lua deleted file mode 100644 index d42a9b7..0000000 --- a/lockbox/padding/zero.lua +++ /dev/null @@ -1,19 +0,0 @@ -local ZeroPadding = function(blockSize, byteCount) - - local paddingCount = blockSize - ((byteCount -1) % blockSize) + 1; - local bytesLeft = paddingCount; - - local stream = function() - if bytesLeft > 0 then - bytesLeft = bytesLeft - 1; - return 0x00; - else - return nil; - end - end - - return stream; - -end - -return ZeroPadding; diff --git a/lockbox/util/bit.lua b/lockbox/util/bit.lua index b17238e..1de5f8b 100644 --- a/lockbox/util/bit.lua +++ b/lockbox/util/bit.lua @@ -1,25 +1,19 @@ -local ok, e -ok = nil -if not ok then - ok, e = pcall(require, "bit") -- the LuaJIT one ? -end +-- modified (simplified) for ComputerCraft + +local ok, e = nil, nil + if not ok then ok, e = pcall(require, "bit32") -- Lua 5.2 end + if not ok then - ok, e = pcall(require, "bit.numberlua") -- for Lua 5.1, https://github.com/tst2005/lua-bit-numberlua/ + ok, e = pcall(require, "bit") end + if not ok then error("no bitwise support found", 2) end + assert(type(e) == "table", "invalid bit module") --- Workaround to support Lua 5.2 bit32 API with the LuaJIT bit one -if e.rol and not e.lrotate then - e.lrotate = e.rol -end -if e.ror and not e.rrotate then - e.rrotate = e.ror -end - return e diff --git a/scada-common/comms.lua b/scada-common/comms.lua index c5e9fd2..bd43706 100644 --- a/scada-common/comms.lua +++ b/scada-common/comms.lua @@ -7,14 +7,14 @@ local log = require("scada-common.log") local insert = table.insert ---@diagnostic disable-next-line: undefined-field -local C_ID = os.getComputerID() ---@type integer computer ID +local COMPUTER_ID = os.getComputerID() ---@type integer computer ID -local max_distance = nil ---@type number|nil maximum acceptable transmission distance +local max_distance = nil ---@type number|nil maximum acceptable transmission distance ---@class comms local comms = {} -comms.version = "2.0.0" +comms.version = "2.1.0" ---@enum PROTOCOL local PROTOCOL = { @@ -149,6 +149,7 @@ function comms.scada_packet() dest_addr = comms.BROADCAST, seq_num = -1, protocol = PROTOCOL.SCADA_MGMT, + mac = "", length = 0, payload = {} } @@ -163,14 +164,13 @@ function comms.scada_packet() ---@param payload table function public.make(dest_addr, seq_num, protocol, payload) self.valid = true ----@diagnostic disable-next-line: undefined-field - self.src_addr = C_ID + self.src_addr = COMPUTER_ID self.dest_addr = dest_addr self.seq_num = seq_num self.protocol = protocol self.length = #payload self.payload = payload - self.raw = { self.src_addr, self.dest_addr, self.seq_num, self.protocol, self.payload } + self.raw = { self.src_addr, self.dest_addr, self.seq_num, self.protocol, self.mac, self.payload } end -- parse in a modem message as a SCADA packet @@ -198,43 +198,58 @@ function comms.scada_packet() -- log.debug("comms.scada_packet.receive(): discarding packet with distance " .. distance .. " outside of trusted range") else if type(self.raw) == "table" then - if #self.raw == 5 then + if #self.raw == 6 then self.src_addr = self.raw[1] self.dest_addr = self.raw[2] self.seq_num = self.raw[3] self.protocol = self.raw[4] + self.mac = self.raw[5] -- element 5 must be a table - if type(self.raw[5]) == "table" then - self.length = #self.raw[5] - self.payload = self.raw[5] + if type(self.raw[6]) == "table" then + self.length = #self.raw[6] + self.payload = self.raw[6] end else self.src_addr = nil self.dest_addr = nil self.seq_num = nil self.protocol = nil + self.mac = "" self.length = 0 self.payload = {} end -- check if this packet is destined for this device - local is_destination = (self.dest_addr == comms.BROADCAST) or (self.dest_addr == C_ID) + local is_destination = (self.dest_addr == comms.BROADCAST) or (self.dest_addr == COMPUTER_ID) - self.valid = is_destination and type(self.src_addr) == "number" and type(self.dest_addr) == "number" and - type(self.seq_num) == "number" and type(self.protocol) == "number" and type(self.payload) == "table" + self.valid = is_destination and + type(self.src_addr) == "number" and + type(self.dest_addr) == "number" and + type(self.seq_num) == "number" and + type(self.protocol) == "number" and + type(self.mac) == "string" and + type(self.payload) == "table" end end return self.valid end + -- set message authentication code + function public.set_mac(code) + self.mac = code + self.raw = { self.src_addr, self.dest_addr, self.seq_num, self.protocol, self.mac, self.payload } + end + -- public accessors -- ---@nodiscard function public.modem_event() return self.modem_msg_in end ---@nodiscard function public.raw_sendable() return self.raw end + ---@nodiscard + function public.raw_verifiable() return { self.src_addr, self.dest_addr, self.seq_num, self.protocol, "", self.payload } end ---@nodiscard function public.local_channel() return self.modem_msg_in.s_channel end @@ -253,6 +268,8 @@ function comms.scada_packet() ---@nodiscard function public.protocol() return self.protocol end ---@nodiscard + function public.mac() return self.mac end + ---@nodiscard function public.length() return self.length end ---@nodiscard function public.data() return self.payload end diff --git a/scada-common/crypto.lua b/scada-common/crypto.lua index 4417ae3..0dae940 100644 --- a/scada-common/crypto.lua +++ b/scada-common/crypto.lua @@ -2,15 +2,13 @@ -- Cryptographic Communications Engine -- -local aes128 = require("lockbox.cipher.aes128") -local ctr_mode = require("lockbox.cipher.mode.ctr") -local sha1 = require("lockbox.digest.sha1") +local md5 = require("lockbox.digest.md5") local sha2_256 = require("lockbox.digest.sha2_256") local pbkdf2 = require("lockbox.kdf.pbkdf2") local hmac = require("lockbox.mac.hmac") -local zero_pad = require("lockbox.padding.zero") local stream = require("lockbox.util.stream") local array = require("lockbox.util.array") +local comms = require("scada-common.comms") local log = require("scada-common.log") local util = require("scada-common.util") @@ -19,136 +17,56 @@ local crypto = {} local c_eng = { key = nil, - cipher = nil, - decipher = nil, hmac = nil } ----@alias hex string - -- initialize cryptographic system -function crypto.init(password, server_port) +function crypto.init(password) local key_deriv = pbkdf2() -- setup PBKDF2 - -- the primary goal is to just turn our password into a 16 byte key key_deriv.setPassword(password) - key_deriv.setSalt("salty_salt_at_" .. server_port) + key_deriv.setSalt("pepper") key_deriv.setIterations(32) key_deriv.setBlockLen(8) key_deriv.setDKeyLen(16) - local start = util.time() + local start = util.time_ms() key_deriv.setPRF(hmac().setBlockSize(64).setDigest(sha2_256)) key_deriv.finish() - log.dmesg("pbkdf2: key derivation took " .. (util.time() - start) .. "ms", "CRYPTO", colors.yellow) + local message = "pbkdf2 key derivation took " .. (util.time_ms() - start) .. "ms" + log.dmesg(message, "CRYPTO", colors.yellow) + log.info("crypto.init: " .. message) c_eng.key = array.fromHex(key_deriv.asHex()) - -- initialize cipher - c_eng.cipher = ctr_mode.Cipher() - c_eng.cipher.setKey(c_eng.key) - c_eng.cipher.setBlockCipher(aes128) - c_eng.cipher.setPadding(zero_pad) - - -- initialize decipher - c_eng.decipher = ctr_mode.Decipher() - c_eng.decipher.setKey(c_eng.key) - c_eng.decipher.setBlockCipher(aes128) - c_eng.decipher.setPadding(zero_pad) - -- initialize HMAC c_eng.hmac = hmac() c_eng.hmac.setBlockSize(64) - c_eng.hmac.setDigest(sha1) + c_eng.hmac.setDigest(md5) c_eng.hmac.setKey(c_eng.key) - log.dmesg("init: completed in " .. (util.time() - start) .. "ms", "CRYPTO", colors.yellow) -end - --- encrypt plaintext ----@nodiscard ----@param plaintext string ----@return table initial_value, string ciphertext -function crypto.encrypt(plaintext) - local start = util.time() - - -- initial value - local iv = { - math.random(0, 255), - math.random(0, 255), - math.random(0, 255), - math.random(0, 255), - math.random(0, 255), - math.random(0, 255), - math.random(0, 255), - math.random(0, 255), - math.random(0, 255), - math.random(0, 255), - math.random(0, 255), - math.random(0, 255), - math.random(0, 255), - math.random(0, 255), - math.random(0, 255), - math.random(0, 255) - } - - log.debug("crypto.random: iv random took " .. (util.time() - start) .. "ms") - - start = util.time() - - c_eng.cipher.init() - c_eng.cipher.update(stream.fromArray(iv)) - c_eng.cipher.update(stream.fromString(plaintext)) - c_eng.cipher.finish() - - local ciphertext = c_eng.cipher.asHex() ---@type hex - - log.debug("crypto.encrypt: aes128-ctr-mode took " .. (util.time() - start) .. "ms") - log.debug("ciphertext: " .. util.strval(ciphertext)) - - return iv, ciphertext -end - --- decrypt ciphertext ----@nodiscard ----@param iv string CTR initial value ----@param ciphertext string ciphertext hex ----@return string plaintext -function crypto.decrypt(iv, ciphertext) - local start = util.time() - - c_eng.decipher.init() - c_eng.decipher.update(stream.fromArray(iv)) - c_eng.decipher.update(stream.fromHex(ciphertext)) - c_eng.decipher.finish() - - local plaintext_hex = c_eng.decipher.asHex() ---@type hex - - local plaintext = stream.toString(stream.fromHex(plaintext_hex)) - - log.debug("crypto.decrypt: aes128-ctr-mode took " .. (util.time() - start) .. "ms") - log.debug("plaintext: " .. util.strval(plaintext)) - - return plaintext + message = "init: completed in " .. (util.time_ms() - start) .. "ms" + log.dmesg(message, "CRYPTO", colors.yellow) + log.info("crypto." .. message) end -- generate HMAC of message ---@nodiscard ----@param message_hex string initial value concatenated with ciphertext -function crypto.hmac(message_hex) - local start = util.time() +---@param message string initial value concatenated with ciphertext +function crypto.hmac(message) + local start = util.time_ms() c_eng.hmac.init() - c_eng.hmac.update(stream.fromHex(message_hex)) + c_eng.hmac.update(stream.fromString(message)) c_eng.hmac.finish() - local hash = c_eng.hmac.asHex() ---@type hex + local hash = c_eng.hmac.asHex() - log.debug("crypto.hmac: hmac-sha1 took " .. (util.time() - start) .. "ms") - log.debug("hmac: " .. util.strval(hash)) + log.debug("crypto.hmac: hmac-md5 took " .. (util.time_ms() - start) .. "ms") + log.debug("crypto.hmac: hmac = " .. util.strval(hash)) return hash end @@ -173,7 +91,6 @@ function crypto.secure_modem(modem) -- wrap a modem ---@param reconnected_modem table ----@diagnostic disable-next-line: redefined-local function public.wrap(reconnected_modem) modem = reconnected_modem for key, func in pairs(modem) do @@ -184,58 +101,49 @@ function crypto.secure_modem(modem) -- wrap modem functions, then we replace transmit public.wrap(modem) - -- send a packet with encryption - ---@param channel integer - ---@param reply_channel integer - ---@param payload table packet raw_sendable - function public.transmit(channel, reply_channel, payload) - local plaintext = textutils.serialize(payload, { allow_repetitions = true, compact = true }) + -- send a packet with message authentication + ---@param packet scada_packet packet raw_sendable + function public.transmit(packet) + local start = util.time_ms() + local message = textutils.serialize(packet.raw_verifiable(), { allow_repetitions = true, compact = true }) + local computed_hmac = crypto.hmac(message) - local iv, ciphertext = crypto.encrypt(plaintext) ----@diagnostic disable-next-line: redefined-local - local computed_hmac = crypto.hmac(iv .. ciphertext) + packet.set_mac(computed_hmac) - modem.transmit(channel, reply_channel, { computed_hmac, iv, ciphertext }) + log.debug("crypto.transmit: data processing took " .. (util.time_ms() - start) .. "ms") + + modem.transmit(packet.remote_channel(), packet.local_channel(), packet.raw_sendable()) end -- parse in a modem message as a network packet ---@nodiscard ---@param side string modem side - ---@param sender integer sender port - ---@param reply_to integer reply port - ---@param message any encrypted packet sent with secure_modem.transmit + ---@param sender integer sender channel + ---@param reply_to integer reply channel + ---@param message any packet sent with message authentication ---@param distance integer transmission distance - ---@return string side, integer sender, integer reply_to, any plaintext_message, integer distance + ---@return scada_packet|nil packet received packet if valid and passed authentication check function public.receive(side, sender, reply_to, message, distance) - local body = "" + local packet = nil + local s_packet = comms.scada_packet() - if type(message) == "table" then - if #message == 3 then ----@diagnostic disable-next-line: redefined-local - local rx_hmac = message[1] - local iv = message[2] - local ciphertext = message[3] + -- parse packet as generic SCADA packet + s_packet.receive(side, sender, reply_to, message, distance) - local computed_hmac = crypto.hmac(iv .. ciphertext) + if s_packet.is_valid() then + local start = util.time_ms() + local packet_hmac = s_packet.mac() + local computed_hmac = crypto.hmac(textutils.serialize(s_packet.raw_verifiable(), { allow_repetitions = true, compact = true })) - if rx_hmac == computed_hmac then - -- message intact - local plaintext = crypto.decrypt(iv, ciphertext) - body = textutils.unserialize(plaintext) - - if body == nil then - -- failed decryption - log.debug("crypto.secure_modem: decryption failed") - body = "" - end - else - -- something went wrong - log.debug("crypto.secure_modem: hmac mismatch violation") - end + if packet_hmac == computed_hmac then + log.debug("crypto.secure_modem.receive: HMAC verified in " .. (util.time_ms() - start) .. "ms") + packet = s_packet + else + log.debug("crypto.secure_modem.receive: HMAC failed verification in " .. (util.time_ms() - start) .. "ms") end end - return side, sender, reply_to, body, distance + return packet end return public