From a4be6a6ddec852bc1c5b1957137dc7a65c579242 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Thu, 8 Jun 2023 10:41:44 -0400 Subject: [PATCH 01/34] #244 luadoc in github actions --- .github/workflows/{manifest.yml => pages.yml} | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) rename .github/workflows/{manifest.yml => pages.yml} (91%) diff --git a/.github/workflows/manifest.yml b/.github/workflows/pages.yml similarity index 91% rename from .github/workflows/manifest.yml rename to .github/workflows/pages.yml index 73586d1..6675757 100644 --- a/.github/workflows/manifest.yml +++ b/.github/workflows/pages.yml @@ -1,5 +1,5 @@ # Simple workflow for deploying static content to GitHub Pages -name: Deploy Installation Manifests and Versions +name: Deploy Install Data and LuaDoc on: workflow_dispatch: @@ -51,6 +51,14 @@ jobs: - name: Save main's manifest if: ${{ (success() || failure()) && steps.manifest-main.outcome == 'success' }} run: mv install_manifest.json deploy/manifests/main + - name: Switch to deploy directory + if: success() || failure() + shell: bash + run: cd deploy + - name: Generate LuaDoc + uses: lunarmodules/ldoc@v0 + with: + args: ../coordinator ../graphics ../pocket ../reactor-plc ../rtu ../scada-common ../supervisor # Generate manifest for latest branch - name: Checkout latest id: checkout-latest From 8d76c86309e60ebeb90d6b5a2a1b5a485e4844cd Mon Sep 17 00:00:00 2001 From: Mikayla Date: Thu, 8 Jun 2023 10:42:49 -0400 Subject: [PATCH 02/34] fixed pages.yml format error --- .github/workflows/pages.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 6675757..87c1b71 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -57,8 +57,8 @@ jobs: run: cd deploy - name: Generate LuaDoc uses: lunarmodules/ldoc@v0 - with: - args: ../coordinator ../graphics ../pocket ../reactor-plc ../rtu ../scada-common ../supervisor + with: + args: ../coordinator ../graphics ../pocket ../reactor-plc ../rtu ../scada-common ../supervisor # Generate manifest for latest branch - name: Checkout latest id: checkout-latest From 7f19f76c0b2f1e764ef3ccdac2b3eebb2c1c027a Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Thu, 8 Jun 2023 10:46:35 -0400 Subject: [PATCH 03/34] update comment to force re-run --- .github/workflows/pages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 87c1b71..5ac8a73 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -1,4 +1,4 @@ -# Simple workflow for deploying static content to GitHub Pages +# Deploy installation manifests, shields versions, and documentation to GitHub Pages name: Deploy Install Data and LuaDoc on: From 543ac8c9fea2a3324d65e5c0635cfa45b066f896 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Thu, 8 Jun 2023 10:50:39 -0400 Subject: [PATCH 04/34] updated ldoc version --- .github/workflows/pages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 5ac8a73..289a7ab 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -56,7 +56,7 @@ jobs: shell: bash run: cd deploy - name: Generate LuaDoc - uses: lunarmodules/ldoc@v0 + uses: lunarmodules/ldoc@v1.5.0 with: args: ../coordinator ../graphics ../pocket ../reactor-plc ../rtu ../scada-common ../supervisor # Generate manifest for latest branch From 650b9c1811c07d002075cb97828a4962ce3e45cf Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Thu, 8 Jun 2023 10:58:06 -0400 Subject: [PATCH 05/34] #244 luadoc actions fixes --- .github/workflows/pages.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 289a7ab..4121e65 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -51,14 +51,15 @@ jobs: - name: Save main's manifest if: ${{ (success() || failure()) && steps.manifest-main.outcome == 'success' }} run: mv install_manifest.json deploy/manifests/main - - name: Switch to deploy directory - if: success() || failure() - shell: bash - run: cd deploy - name: Generate LuaDoc + if: success() || failure() uses: lunarmodules/ldoc@v1.5.0 with: - args: ../coordinator ../graphics ../pocket ../reactor-plc ../rtu ../scada-common ../supervisor + args: ./coordinator ./graphics ./pocket ./reactor-plc ./rtu ./scada-common ./supervisor + - name: Save doc directory + if: success() || failure() + shell: bash + run: mv doc deploy/ # Generate manifest for latest branch - name: Checkout latest id: checkout-latest From 302f3d913f12f9f971b36de69226de95da2cba6e Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Thu, 8 Jun 2023 11:39:07 -0400 Subject: [PATCH 06/34] unlikely to use ldoc due to incompatibilities with vscode lua extension luadocs --- .github/workflows/{pages.yml => manifest.yml} | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) rename .github/workflows/{pages.yml => manifest.yml} (88%) diff --git a/.github/workflows/pages.yml b/.github/workflows/manifest.yml similarity index 88% rename from .github/workflows/pages.yml rename to .github/workflows/manifest.yml index 4121e65..a631058 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/manifest.yml @@ -1,5 +1,5 @@ -# Deploy installation manifests, shields versions, and documentation to GitHub Pages -name: Deploy Install Data and LuaDoc +# Deploy installation manifests and shields versions +name: Deploy Installation Data on: workflow_dispatch: @@ -51,15 +51,6 @@ jobs: - name: Save main's manifest if: ${{ (success() || failure()) && steps.manifest-main.outcome == 'success' }} run: mv install_manifest.json deploy/manifests/main - - name: Generate LuaDoc - if: success() || failure() - uses: lunarmodules/ldoc@v1.5.0 - with: - args: ./coordinator ./graphics ./pocket ./reactor-plc ./rtu ./scada-common ./supervisor - - name: Save doc directory - if: success() || failure() - shell: bash - run: mv doc deploy/ # Generate manifest for latest branch - name: Checkout latest id: checkout-latest From ef5567ad463dd5752d371b8e40b8ffbe339fa495 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Sun, 11 Jun 2023 18:26:55 +0000 Subject: [PATCH 07/34] #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 From 9266d7d8e1fa9e7e7ac669e56c938507e3327949 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sun, 18 Jun 2023 00:40:01 -0400 Subject: [PATCH 08/34] #258 versioned graphics component --- ccmsi.lua | 267 ++++++++++++++++++++---------------------- graphics/core.lua | 2 + imgen.py | 7 +- install_manifest.json | 2 +- 4 files changed, 137 insertions(+), 141 deletions(-) diff --git a/ccmsi.lua b/ccmsi.lua index a8fff8a..b3bc16d 100644 --- a/ccmsi.lua +++ b/ccmsi.lua @@ -20,7 +20,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. local function println(message) print(tostring(message)) end local function print(message) term.write(tostring(message)) end -local CCMSI_VERSION = "v1.2" +local CCMSI_VERSION = "v1.3" local install_dir = "/.install-cache" local manifest_path = "https://mikaylafischler.github.io/cc-mek-scada/manifests/" @@ -54,6 +54,68 @@ local function write_install_manifest(manifest, dependencies) imfile.close() end +-- ask the user yes or no +---@nodiscard +---@param question string +---@param default boolean +---@return boolean|nil +local function ask_y_n(question, default) + print(question) + + if default == true then + print(" (Y/n)? ") + else + print(" (y/N)? ") + end + + local response = read(nil, nil) + + if response == "" then + return default + elseif response == "Y" or response == "y" then + return true + elseif response == "N" or response == "n" then + return false + else + return nil + end +end + +-- print out a white + blue text message
+-- automatically adds a space +---@param message string message +---@param package string dependency/package/version +local function pkg_message(message, package) + term.setTextColor(colors.white) + print(message .. " ") + term.setTextColor(colors.blue) + println(package) + term.setTextColor(colors.white) +end + +-- indicate actions to be taken based on package differences for installs/updates +---@param name string package name +---@param _local_v string|nil local version +---@param _remote_v string remote version +local function show_pkg_change(name, _local_v, _remote_v) + if _local_v ~= nil then + if _local_v ~= _remote_v then + print("[" .. name .. "] updating ") + term.setTextColor(colors.blue) + print(_local_v) + term.setTextColor(colors.white) + print(" \xbb ") + term.setTextColor(colors.blue) + println(_local_v) + term.setTextColor(colors.white) + elseif mode == "install" then + pkg_message("[" .. name .. "] reinstalling", _local_v) + end + else + pkg_message("[" .. name .. "] new install of", _remote_v) + end +end + -- -- get and validate command line options -- @@ -230,6 +292,13 @@ elseif mode == "install" or mode == "update" then -- GET LOCAL MANIFEST -- ------------------------ + local ver = { + app = { v_local = nil, v_remote = nil, changed = false }, + boot = { v_local = nil, v_remote = nil, changed = false }, + comms = { v_local = nil, v_remote = nil, changed = false }, + graphics = { v_local = nil, v_remote = nil, changed = false } + } + local imfile = fs.open("install_manifest.json", "r") local local_ok = false local local_manifest = {} @@ -239,10 +308,6 @@ elseif mode == "install" or mode == "update" then imfile.close() end - local local_app_version = nil - local local_comms_version = nil - local local_boot_version = nil - -- try to find local versions if not local_ok then if mode == "update" then @@ -252,9 +317,10 @@ elseif mode == "install" or mode == "update" then return end else - local_app_version = local_manifest.versions[app] - local_comms_version = local_manifest.versions.comms - local_boot_version = local_manifest.versions.bootloader + ver.boot.v_local = local_manifest.versions.bootloader + ver.app.v_local = local_manifest.versions[app] + ver.comms.v_local = local_manifest.versions.comms + ver.graphics.v_local = local_manifest.versions.graphics if local_manifest.versions[app] == nil then term.setTextColor(colors.red) @@ -271,93 +337,43 @@ elseif mode == "install" or mode == "update" then end end - local remote_app_version = manifest.versions[app] - local remote_comms_version = manifest.versions.comms - local remote_boot_version = manifest.versions.bootloader + ver.boot.v_remote = manifest.versions.bootloader + ver.app.v_remote = manifest.versions[app] + ver.comms.v_remote = manifest.versions.comms + ver.graphics.v_remote = manifest.versions.graphics term.setTextColor(colors.green) if mode == "install" then - println("installing " .. app .. " files...") + println("Installing " .. app .. " files...") elseif mode == "update" then - println("updating " .. app .. " files... (keeping old config.lua)") + println("Updating " .. app .. " files... (keeping old config.lua)") end term.setTextColor(colors.white) -- display bootloader version change information - if local_boot_version ~= nil then - if local_boot_version ~= remote_boot_version then - print("[bootldr] updating ") - term.setTextColor(colors.blue) - print(local_boot_version) - term.setTextColor(colors.white) - print(" \xbb ") - term.setTextColor(colors.blue) - println(remote_boot_version) - term.setTextColor(colors.white) - elseif mode == "install" then - print("[bootldr] reinstalling ") - term.setTextColor(colors.blue) - println(local_boot_version) - term.setTextColor(colors.white) - end - else - print("[bootldr] new install of ") - term.setTextColor(colors.blue) - println(remote_boot_version) - term.setTextColor(colors.white) - end + show_pkg_change("bootldr", ver.boot.v_local, ver.boot.v_remote) + ver.boot.changed = ver.boot.v_local ~= ver.boot.v_remote -- display app version change information - if local_app_version ~= nil then - if local_app_version ~= remote_app_version then - print("[" .. app .. "] updating ") - term.setTextColor(colors.blue) - print(local_app_version) - term.setTextColor(colors.white) - print(" \xbb ") - term.setTextColor(colors.blue) - println(remote_app_version) - term.setTextColor(colors.white) - elseif mode == "install" then - print("[" .. app .. "] reinstalling ") - term.setTextColor(colors.blue) - println(local_app_version) - term.setTextColor(colors.white) - end - else - print("[" .. app .. "] new install of ") - term.setTextColor(colors.blue) - println(remote_app_version) + show_pkg_change(app, ver.app.v_local, ver.app.v_remote) + ver.app.changed = ver.app.v_local ~= ver.app.v_remote + + -- display comms version change information + show_pkg_change("comms", ver.comms.v_local, ver.comms.v_remote) + ver.comms.changed = ver.comms.v_local ~= ver.comms.v_remote + if ver.comms.changed then + print("[comms] ") + term.setTextColor(colors.yellow) + println("other devices on the network will require an update") term.setTextColor(colors.white) end - -- display comms version change information - if local_comms_version ~= nil then - if local_comms_version ~= remote_comms_version then - print("[comms] updating ") - term.setTextColor(colors.blue) - print(local_comms_version) - term.setTextColor(colors.white) - print(" \xbb ") - term.setTextColor(colors.blue) - println(remote_comms_version) - term.setTextColor(colors.white) - print("[comms] ") - term.setTextColor(colors.yellow) - println("other devices on the network will require an update") - term.setTextColor(colors.white) - elseif mode == "install" then - print("[comms] reinstalling ") - term.setTextColor(colors.blue) - println(local_comms_version) - term.setTextColor(colors.white) - end - else - print("[comms] new install of ") - term.setTextColor(colors.blue) - println(remote_comms_version) - term.setTextColor(colors.white) - end + -- display graphics version change information + show_pkg_change("graphics", ver.graphics.v_local, ver.graphics.v_remote) + ver.graphics.changed = ver.graphics.v_local ~= ver.graphics.v_remote + + -- ask for confirmation + if not ask_y_n("Continue?", false) then return end -------------------------- -- START INSTALL/UPDATE -- @@ -386,18 +402,13 @@ elseif mode == "install" or mode == "update" then println("WARNING: Insufficient space available for a full download!") term.setTextColor(colors.white) println("Files can be downloaded one by one, so if you are replacing a current install this will not be a problem unless installation fails.") - println("Do you wish to continue? (y/N)") - - local confirm = read() - if confirm ~= "y" and confirm ~= "Y" then - println("installation cancelled") + if mode == "update" then println("If installation still fails, delete this device's log file and try again.") end + if not ask_y_n("Do you wish to continue?", false) then + println("Operation cancelled.") return end end ----@diagnostic disable-next-line: undefined-field - os.sleep(2) - local success = true if not single_file_mode then @@ -408,20 +419,14 @@ elseif mode == "install" or mode == "update" then -- download all dependencies for _, dependency in pairs(dependencies) do - if mode == "update" and ((dependency == "system" and local_boot_version == remote_boot_version) or (local_app_version == remote_app_version)) then - -- skip system package if unchanged, skip app package if not changed - -- skip packages that have no version if app version didn't change - term.setTextColor(colors.white) - print("skipping download of unchanged package ") - term.setTextColor(colors.blue) - println(dependency) + if mode == "update" and ((dependency == "system" and ver.boot.changed) or + (dependency == "graphics" and ver.graphics.changed) or + (ver.changed.app)) then + pkg_message("skipping download of unchanged package", dependency) else - term.setTextColor(colors.white) - print("downloading package ") - term.setTextColor(colors.blue) - println(dependency) - + pkg_message("downloading package", dependency) term.setTextColor(colors.lightGray) + local files = file_list[dependency] for _, file in pairs(files) do println("GET " .. file) @@ -444,20 +449,14 @@ elseif mode == "install" or mode == "update" then -- copy in downloaded files (installation) if success then for _, dependency in pairs(dependencies) do - if mode == "update" and ((dependency == "system" and local_boot_version == remote_boot_version) or (local_app_version == remote_app_version)) then - -- skip system package if unchanged, skip app package if not changed - -- skip packages that have no version if app version didn't change - term.setTextColor(colors.white) - print("skipping install of unchanged package ") - term.setTextColor(colors.blue) - println(dependency) + if mode == "update" and ((dependency == "system" and ver.boot.changed) or + (dependency == "graphics" and ver.graphics.changed) or + (ver.changed.app)) then + pkg_message("skipping install of unchanged package", dependency) else - term.setTextColor(colors.white) - print("installing package ") - term.setTextColor(colors.blue) - println(dependency) - + pkg_message("installing package", dependency) term.setTextColor(colors.lightGray) + local files = file_list[dependency] for _, file in pairs(files) do if mode == "install" or file ~= config_file then @@ -478,36 +477,30 @@ elseif mode == "install" or mode == "update" then write_install_manifest(manifest, dependencies) term.setTextColor(colors.green) if mode == "install" then - println("installation completed successfully") + println("Installation completed successfully.") else - println("update completed successfully") + println("Update completed successfully.") end else if mode == "install" then term.setTextColor(colors.red) - println("installation failed") + println("Installation failed.") else term.setTextColor(colors.orange) - println("update failed, existing files unmodified") + println("Update failed, existing files unmodified.") end end else -- go through all files and replace one by one for _, dependency in pairs(dependencies) do - if mode == "update" and ((dependency == "system" and local_boot_version == remote_boot_version) or (local_app_version == remote_app_version)) then - -- skip system package if unchanged, skip app package if not changed - -- skip packages that have no version if app version didn't change - term.setTextColor(colors.white) - print("skipping install of unchanged package ") - term.setTextColor(colors.blue) - println(dependency) + if mode == "update" and ((dependency == "system" and ver.boot.changed) or + (dependency == "graphics" and ver.graphics.changed) or + (ver.changed.app)) then + pkg_message("skipping install of unchanged package", dependency) else - term.setTextColor(colors.white) - print("installing package ") - term.setTextColor(colors.blue) - println(dependency) - + pkg_message("installing package", dependency) term.setTextColor(colors.lightGray) + local files = file_list[dependency] for _, file in pairs(files) do if mode == "install" or file ~= config_file then @@ -534,16 +527,16 @@ elseif mode == "install" or mode == "update" then write_install_manifest(manifest, dependencies) term.setTextColor(colors.green) if mode == "install" then - println("installation completed successfully") + println("Installation completed successfully.") else - println("update completed successfully") + println("Update completed successfully.") end else term.setTextColor(colors.red) if mode == "install" then - println("installation failed, files may have been skipped") + println("Installation failed, files may have been skipped.") else - println("update failed, files may have been skipped") + println("Update failed, files may have been skipped.") end end end @@ -576,8 +569,8 @@ elseif mode == "remove" or mode == "purge" then println("purging all " .. app .. " files...") end ----@diagnostic disable-next-line: undefined-field - os.sleep(2) + -- ask for confirmation + if not ask_y_n("Continue?", false) then return end local file_list = manifest.files local dependencies = manifest.depends[app] @@ -666,7 +659,7 @@ elseif mode == "remove" or mode == "purge" then end term.setTextColor(colors.green) - println("done!") + println("Done!") end term.setTextColor(colors.white) diff --git a/graphics/core.lua b/graphics/core.lua index 58b6b8c..d99ef3b 100644 --- a/graphics/core.lua +++ b/graphics/core.lua @@ -7,6 +7,8 @@ local flasher = require("graphics.flasher") local core = {} +core.version = "1.0.0" + core.flasher = flasher core.events = events diff --git a/imgen.py b/imgen.py index bd34822..63f28cf 100644 --- a/imgen.py +++ b/imgen.py @@ -23,11 +23,11 @@ def dir_size(path): return total # get the version of an application at the provided path -def get_version(path, is_comms = False): +def get_version(path, is_lib = False): ver = "" - string = "comms.version = \"" + string = ".version = \"" - if not is_comms: + if not is_lib: string = "_VERSION = \"" f = open(path, "r") @@ -49,6 +49,7 @@ def make_manifest(size): "installer" : get_version("./ccmsi.lua"), "bootloader" : get_version("./startup.lua"), "comms" : get_version("./scada-common/comms.lua", True), + "graphics" : get_version("./graphics/core.lua", True), "reactor-plc" : get_version("./reactor-plc/startup.lua"), "rtu" : get_version("./rtu/startup.lua"), "supervisor" : get_version("./supervisor/startup.lua"), diff --git a/install_manifest.json b/install_manifest.json index c75c072..62b1edc 100644 --- a/install_manifest.json +++ b/install_manifest.json @@ -1 +1 @@ -{"versions": {"installer": "v1.2", "bootloader": "0.2", "comms": "2.0.0", "reactor-plc": "v1.4.6", "rtu": "v1.3.6", "supervisor": "v0.17.7", "coordinator": "v0.16.1", "pocket": "alpha-v0.4.5"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/tcd.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/events.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/listbox.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/tabbar.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/renderer.lua", "supervisor/databus.lua", "supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/panel/pgi.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/style.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/panel/components/pdg_entry.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/pocket.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/conn_waiting.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/boiler_page.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common", "graphics"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5781, "system": 1991, "common": 92736, "graphics": 144532, "lockbox": 100797, "reactor-plc": 97335, "rtu": 102240, "supervisor": 315402, "coordinator": 197991, "pocket": 37581}} \ No newline at end of file +{"versions": {"installer": "v1.3", "bootloader": "0.2", "comms": "2.0.0", "graphics": "1.0.0", "reactor-plc": "v1.4.6", "rtu": "v1.3.6", "supervisor": "v0.17.7", "coordinator": "v0.16.1", "pocket": "alpha-v0.4.5"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/tcd.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/events.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/listbox.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/tabbar.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/renderer.lua", "supervisor/databus.lua", "supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/panel/pgi.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/style.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/panel/components/pdg_entry.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/pocket.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/conn_waiting.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/boiler_page.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common", "graphics"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5802, "system": 1991, "common": 92736, "graphics": 144556, "lockbox": 100797, "reactor-plc": 97335, "rtu": 102240, "supervisor": 315402, "coordinator": 197991, "pocket": 37581}} \ No newline at end of file From bc8703049161c2a9b439311e35700714592357c1 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sun, 18 Jun 2023 00:48:06 -0400 Subject: [PATCH 09/34] #258 installer improvements and test change to graphics version --- ccmsi.lua | 31 +++++++++++++++---------------- graphics/core.lua | 2 +- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/ccmsi.lua b/ccmsi.lua index b3bc16d..0c62acf 100644 --- a/ccmsi.lua +++ b/ccmsi.lua @@ -20,7 +20,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. local function println(message) print(tostring(message)) end local function print(message) term.write(tostring(message)) end -local CCMSI_VERSION = "v1.3" +local CCMSI_VERSION = "v1.4" local install_dir = "/.install-cache" local manifest_path = "https://mikaylafischler.github.io/cc-mek-scada/manifests/" @@ -95,24 +95,24 @@ end -- indicate actions to be taken based on package differences for installs/updates ---@param name string package name ----@param _local_v string|nil local version ----@param _remote_v string remote version -local function show_pkg_change(name, _local_v, _remote_v) - if _local_v ~= nil then - if _local_v ~= _remote_v then +---@param v_local string|nil local version +---@param v_remote string remote version +local function show_pkg_change(name, v_local, v_remote) + if v_local ~= nil then + if v_local ~= v_remote then print("[" .. name .. "] updating ") term.setTextColor(colors.blue) - print(_local_v) + print(v_local) term.setTextColor(colors.white) print(" \xbb ") term.setTextColor(colors.blue) - println(_local_v) + println(v_local) term.setTextColor(colors.white) elseif mode == "install" then - pkg_message("[" .. name .. "] reinstalling", _local_v) + pkg_message("[" .. name .. "] reinstalling", v_local) end else - pkg_message("[" .. name .. "] new install of", _remote_v) + pkg_message("[" .. name .. "] new install of", v_remote) end end @@ -123,12 +123,12 @@ end println("-- CC Mekanism SCADA Installer " .. CCMSI_VERSION .. " --") if #opts == 0 or opts[1] == "help" then - println("usage: ccmsi ") + println("usage: ccmsi ") println("") term.setTextColor(colors.lightGray) println(" check - check latest versions avilable") term.setTextColor(colors.yellow) - println(" ccmsi check for target") + println(" ccmsi check for target") term.setTextColor(colors.lightGray) println(" install - fresh install, overwrites config") println(" update - update files EXCEPT for config/logs") @@ -143,12 +143,11 @@ if #opts == 0 or opts[1] == "help" then println(" coordinator - coordinator application") println(" pocket - pocket application") term.setTextColor(colors.white) - println("") + println("") term.setTextColor(colors.yellow) println(" second parameter when used with check") term.setTextColor(colors.lightGray) - println(" note: defaults to main") - println(" target GitHub tag or branch name") + println(" main (default) | latest | devel") return else for _, v in pairs({ "check", "install", "update", "remove", "purge" }) do @@ -361,7 +360,7 @@ elseif mode == "install" or mode == "update" then -- display comms version change information show_pkg_change("comms", ver.comms.v_local, ver.comms.v_remote) ver.comms.changed = ver.comms.v_local ~= ver.comms.v_remote - if ver.comms.changed then + if ver.comms.changed and mode == "update" then print("[comms] ") term.setTextColor(colors.yellow) println("other devices on the network will require an update") diff --git a/graphics/core.lua b/graphics/core.lua index d99ef3b..657bc0d 100644 --- a/graphics/core.lua +++ b/graphics/core.lua @@ -7,7 +7,7 @@ local flasher = require("graphics.flasher") local core = {} -core.version = "1.0.0" +core.version = "1.0.0-test" core.flasher = flasher core.events = events From 49db75f34db4a36cb0f05875351fca45d8dc421a Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sun, 18 Jun 2023 01:04:40 -0400 Subject: [PATCH 10/34] #258 installer bugfix --- ccmsi.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ccmsi.lua b/ccmsi.lua index 0c62acf..dd66062 100644 --- a/ccmsi.lua +++ b/ccmsi.lua @@ -20,7 +20,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. local function println(message) print(tostring(message)) end local function print(message) term.write(tostring(message)) end -local CCMSI_VERSION = "v1.4" +local CCMSI_VERSION = "v1.4a" local install_dir = "/.install-cache" local manifest_path = "https://mikaylafischler.github.io/cc-mek-scada/manifests/" @@ -38,13 +38,13 @@ local function write_install_manifest(manifest, dependencies) for key, value in pairs(manifest.versions) do local is_dependency = false for _, dependency in pairs(dependencies) do - if key == "bootloader" and dependency == "system" then + if (key == "bootloader" and dependency == "system") or key == dependency then is_dependency = true break end end - if key == app or key == "comms" or is_dependency then versions[key] = value end + if key == app or is_dependency then versions[key] = value end end manifest.versions = versions @@ -420,7 +420,7 @@ elseif mode == "install" or mode == "update" then for _, dependency in pairs(dependencies) do if mode == "update" and ((dependency == "system" and ver.boot.changed) or (dependency == "graphics" and ver.graphics.changed) or - (ver.changed.app)) then + (ver.app.changed)) then pkg_message("skipping download of unchanged package", dependency) else pkg_message("downloading package", dependency) @@ -450,7 +450,7 @@ elseif mode == "install" or mode == "update" then for _, dependency in pairs(dependencies) do if mode == "update" and ((dependency == "system" and ver.boot.changed) or (dependency == "graphics" and ver.graphics.changed) or - (ver.changed.app)) then + (ver.app.changed)) then pkg_message("skipping install of unchanged package", dependency) else pkg_message("installing package", dependency) @@ -494,7 +494,7 @@ elseif mode == "install" or mode == "update" then for _, dependency in pairs(dependencies) do if mode == "update" and ((dependency == "system" and ver.boot.changed) or (dependency == "graphics" and ver.graphics.changed) or - (ver.changed.app)) then + (ver.app.changed)) then pkg_message("skipping install of unchanged package", dependency) else pkg_message("installing package", dependency) From d42327a20d5f7ce57283e76687b19dfb093c9694 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sun, 18 Jun 2023 01:09:46 -0400 Subject: [PATCH 11/34] #258 bugfixes --- ccmsi.lua | 22 +++++++++++----------- graphics/core.lua | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ccmsi.lua b/ccmsi.lua index dd66062..7fefba7 100644 --- a/ccmsi.lua +++ b/ccmsi.lua @@ -20,7 +20,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. local function println(message) print(tostring(message)) end local function print(message) term.write(tostring(message)) end -local CCMSI_VERSION = "v1.4a" +local CCMSI_VERSION = "v1.4b" local install_dir = "/.install-cache" local manifest_path = "https://mikaylafischler.github.io/cc-mek-scada/manifests/" @@ -44,7 +44,7 @@ local function write_install_manifest(manifest, dependencies) end end - if key == app or is_dependency then versions[key] = value end + if key == app or key == "comms" or is_dependency then versions[key] = value end end manifest.versions = versions @@ -418,9 +418,9 @@ elseif mode == "install" or mode == "update" then -- download all dependencies for _, dependency in pairs(dependencies) do - if mode == "update" and ((dependency == "system" and ver.boot.changed) or - (dependency == "graphics" and ver.graphics.changed) or - (ver.app.changed)) then + if mode == "update" and ((dependency == "system" and not ver.boot.changed) or + (dependency == "graphics" and not ver.graphics.changed) or + (not ver.app.changed)) then pkg_message("skipping download of unchanged package", dependency) else pkg_message("downloading package", dependency) @@ -448,9 +448,9 @@ elseif mode == "install" or mode == "update" then -- copy in downloaded files (installation) if success then for _, dependency in pairs(dependencies) do - if mode == "update" and ((dependency == "system" and ver.boot.changed) or - (dependency == "graphics" and ver.graphics.changed) or - (ver.app.changed)) then + if mode == "update" and ((dependency == "system" and not ver.boot.changed) or + (dependency == "graphics" and not ver.graphics.changed) or + (not ver.app.changed)) then pkg_message("skipping install of unchanged package", dependency) else pkg_message("installing package", dependency) @@ -492,9 +492,9 @@ elseif mode == "install" or mode == "update" then else -- go through all files and replace one by one for _, dependency in pairs(dependencies) do - if mode == "update" and ((dependency == "system" and ver.boot.changed) or - (dependency == "graphics" and ver.graphics.changed) or - (ver.app.changed)) then + if mode == "update" and ((dependency == "system" and not ver.boot.changed) or + (dependency == "graphics" and not ver.graphics.changed) or + (not ver.app.changed)) then pkg_message("skipping install of unchanged package", dependency) else pkg_message("installing package", dependency) diff --git a/graphics/core.lua b/graphics/core.lua index 657bc0d..c343308 100644 --- a/graphics/core.lua +++ b/graphics/core.lua @@ -7,7 +7,7 @@ local flasher = require("graphics.flasher") local core = {} -core.version = "1.0.0-test" +core.version = "1.0.0-test2" core.flasher = flasher core.events = events From aef8281ad66186be6cf4b82430859ac9469beae2 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sun, 18 Jun 2023 01:19:00 -0400 Subject: [PATCH 12/34] #258 more installer fixes --- ccmsi.lua | 25 +++++++++++++++---------- graphics/core.lua | 2 +- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/ccmsi.lua b/ccmsi.lua index 7fefba7..0b42bd9 100644 --- a/ccmsi.lua +++ b/ccmsi.lua @@ -20,7 +20,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. local function println(message) print(tostring(message)) end local function print(message) term.write(tostring(message)) end -local CCMSI_VERSION = "v1.4b" +local CCMSI_VERSION = "v1.4c" local install_dir = "/.install-cache" local manifest_path = "https://mikaylafischler.github.io/cc-mek-scada/manifests/" @@ -410,6 +410,17 @@ elseif mode == "install" or mode == "update" then local success = true + -- helper function to check if a dependency is unchanged + ---@nodiscard + ---@param dependency string + ---@return boolean + local function unchanged(dependency) + if dependency == "system" then return not ver.boot.changed + elseif dependency == "graphics" then return not ver.graphics.changed + elseif dependency == app then return not ver.app.changed + else return true end + end + if not single_file_mode then if fs.exists(install_dir) then fs.delete(install_dir) @@ -418,9 +429,7 @@ elseif mode == "install" or mode == "update" then -- download all dependencies for _, dependency in pairs(dependencies) do - if mode == "update" and ((dependency == "system" and not ver.boot.changed) or - (dependency == "graphics" and not ver.graphics.changed) or - (not ver.app.changed)) then + if mode == "update" and unchanged(dependency) then pkg_message("skipping download of unchanged package", dependency) else pkg_message("downloading package", dependency) @@ -448,9 +457,7 @@ elseif mode == "install" or mode == "update" then -- copy in downloaded files (installation) if success then for _, dependency in pairs(dependencies) do - if mode == "update" and ((dependency == "system" and not ver.boot.changed) or - (dependency == "graphics" and not ver.graphics.changed) or - (not ver.app.changed)) then + if mode == "update" and unchanged(dependency) then pkg_message("skipping install of unchanged package", dependency) else pkg_message("installing package", dependency) @@ -492,9 +499,7 @@ elseif mode == "install" or mode == "update" then else -- go through all files and replace one by one for _, dependency in pairs(dependencies) do - if mode == "update" and ((dependency == "system" and not ver.boot.changed) or - (dependency == "graphics" and not ver.graphics.changed) or - (not ver.app.changed)) then + if mode == "update" and unchanged(dependency) then pkg_message("skipping install of unchanged package", dependency) else pkg_message("installing package", dependency) diff --git a/graphics/core.lua b/graphics/core.lua index c343308..27ede11 100644 --- a/graphics/core.lua +++ b/graphics/core.lua @@ -7,7 +7,7 @@ local flasher = require("graphics.flasher") local core = {} -core.version = "1.0.0-test2" +core.version = "1.0.0-test3" core.flasher = flasher core.events = events From a2fa6570dcfbca1f53486aab7382fed52911b4c8 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sun, 18 Jun 2023 13:12:34 -0400 Subject: [PATCH 13/34] #258 installer improvement --- ccmsi.lua | 17 ++++++++++++----- graphics/core.lua | 2 +- install_manifest.json | 2 +- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/ccmsi.lua b/ccmsi.lua index 0b42bd9..1f8c886 100644 --- a/ccmsi.lua +++ b/ccmsi.lua @@ -20,7 +20,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. local function println(message) print(tostring(message)) end local function print(message) term.write(tostring(message)) end -local CCMSI_VERSION = "v1.4c" +local CCMSI_VERSION = "v1.4d" local install_dir = "/.install-cache" local manifest_path = "https://mikaylafischler.github.io/cc-mek-scada/manifests/" @@ -29,6 +29,7 @@ local repo_path = "http://raw.githubusercontent.com/MikaylaFischler/cc-mek-scada local opts = { ... } local mode = nil local app = nil +local target = "main" -- record the local installation manifest ---@param manifest table @@ -173,6 +174,12 @@ else println("unrecognized application") return end + + -- determine target + if mode == "check" then target = opts[2] else target = opts[3] end + if target ~= "main" or target ~= "latest" or target ~= "devel" then + target = "main" + end end -- @@ -184,7 +191,7 @@ if mode == "check" then -- GET REMOTE MANIFEST -- ------------------------- - if opts[2] then manifest_path = manifest_path .. opts[2] .. "/" else manifest_path = manifest_path .. "main/" end + manifest_path = manifest_path .. target .. "/" local install_manifest = manifest_path .. "install_manifest.json" local response, error = http.get(install_manifest) @@ -264,8 +271,8 @@ elseif mode == "install" or mode == "update" then -- GET REMOTE MANIFEST -- ------------------------- - if opts[3] then repo_path = repo_path .. opts[3] .. "/" else repo_path = repo_path .. "main/" end - if opts[3] then manifest_path = manifest_path .. opts[3] .. "/" else manifest_path = manifest_path .. "main/" end + repo_path = repo_path .. target .. "/" + manifest_path = manifest_path .. target .. "/" local install_manifest = manifest_path .. "install_manifest.json" local response, error = http.get(install_manifest) @@ -360,7 +367,7 @@ elseif mode == "install" or mode == "update" then -- display comms version change information show_pkg_change("comms", ver.comms.v_local, ver.comms.v_remote) ver.comms.changed = ver.comms.v_local ~= ver.comms.v_remote - if ver.comms.changed and mode == "update" then + if ver.comms.changed and ver.comms.v_local ~= nil then print("[comms] ") term.setTextColor(colors.yellow) println("other devices on the network will require an update") diff --git a/graphics/core.lua b/graphics/core.lua index 27ede11..d99ef3b 100644 --- a/graphics/core.lua +++ b/graphics/core.lua @@ -7,7 +7,7 @@ local flasher = require("graphics.flasher") local core = {} -core.version = "1.0.0-test3" +core.version = "1.0.0" core.flasher = flasher core.events = events diff --git a/install_manifest.json b/install_manifest.json index 62b1edc..ca507ff 100644 --- a/install_manifest.json +++ b/install_manifest.json @@ -1 +1 @@ -{"versions": {"installer": "v1.3", "bootloader": "0.2", "comms": "2.0.0", "graphics": "1.0.0", "reactor-plc": "v1.4.6", "rtu": "v1.3.6", "supervisor": "v0.17.7", "coordinator": "v0.16.1", "pocket": "alpha-v0.4.5"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/tcd.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/events.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/listbox.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/tabbar.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/renderer.lua", "supervisor/databus.lua", "supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/panel/pgi.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/style.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/panel/components/pdg_entry.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/pocket.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/conn_waiting.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/boiler_page.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common", "graphics"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5802, "system": 1991, "common": 92736, "graphics": 144556, "lockbox": 100797, "reactor-plc": 97335, "rtu": 102240, "supervisor": 315402, "coordinator": 197991, "pocket": 37581}} \ No newline at end of file +{"versions": {"installer": "v1.4d", "bootloader": "0.2", "comms": "2.0.0", "graphics": "1.0.0", "reactor-plc": "v1.4.6", "rtu": "v1.3.6", "supervisor": "v0.17.7", "coordinator": "v0.16.1", "pocket": "alpha-v0.4.5"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/tcd.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/events.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/listbox.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/tabbar.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/renderer.lua", "supervisor/databus.lua", "supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/panel/pgi.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/style.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/panel/components/pdg_entry.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/pocket.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/conn_waiting.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/boiler_page.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common", "graphics"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5803, "system": 1991, "common": 92736, "graphics": 144556, "lockbox": 100797, "reactor-plc": 97335, "rtu": 102240, "supervisor": 315402, "coordinator": 197991, "pocket": 37581}} \ No newline at end of file From 4a3455fa608505971a0591f537a2df6091531c6d Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sun, 18 Jun 2023 13:13:34 -0400 Subject: [PATCH 14/34] #258 luacheck fix --- ccmsi.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ccmsi.lua b/ccmsi.lua index 1f8c886..bacba6f 100644 --- a/ccmsi.lua +++ b/ccmsi.lua @@ -29,7 +29,7 @@ local repo_path = "http://raw.githubusercontent.com/MikaylaFischler/cc-mek-scada local opts = { ... } local mode = nil local app = nil -local target = "main" +local target = nil -- record the local installation manifest ---@param manifest table From 75dfa3ae7381dc2224ca8ee56f08c34eb2d5902c Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sun, 18 Jun 2023 13:16:28 -0400 Subject: [PATCH 15/34] #258 luacheck fix --- ccmsi.lua | 5 +++-- install_manifest.json | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ccmsi.lua b/ccmsi.lua index bacba6f..3a00542 100644 --- a/ccmsi.lua +++ b/ccmsi.lua @@ -20,7 +20,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. local function println(message) print(tostring(message)) end local function print(message) term.write(tostring(message)) end -local CCMSI_VERSION = "v1.4d" +local CCMSI_VERSION = "v1.4e" local install_dir = "/.install-cache" local manifest_path = "https://mikaylafischler.github.io/cc-mek-scada/manifests/" @@ -29,7 +29,7 @@ local repo_path = "http://raw.githubusercontent.com/MikaylaFischler/cc-mek-scada local opts = { ... } local mode = nil local app = nil -local target = nil +local target -- record the local installation manifest ---@param manifest table @@ -179,6 +179,7 @@ else if mode == "check" then target = opts[2] else target = opts[3] end if target ~= "main" or target ~= "latest" or target ~= "devel" then target = "main" + println("unknown target, defaulting to 'main'") end end diff --git a/install_manifest.json b/install_manifest.json index ca507ff..e3fc79d 100644 --- a/install_manifest.json +++ b/install_manifest.json @@ -1 +1 @@ -{"versions": {"installer": "v1.4d", "bootloader": "0.2", "comms": "2.0.0", "graphics": "1.0.0", "reactor-plc": "v1.4.6", "rtu": "v1.3.6", "supervisor": "v0.17.7", "coordinator": "v0.16.1", "pocket": "alpha-v0.4.5"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/tcd.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/events.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/listbox.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/tabbar.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/renderer.lua", "supervisor/databus.lua", "supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/panel/pgi.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/style.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/panel/components/pdg_entry.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/pocket.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/conn_waiting.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/boiler_page.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common", "graphics"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5803, "system": 1991, "common": 92736, "graphics": 144556, "lockbox": 100797, "reactor-plc": 97335, "rtu": 102240, "supervisor": 315402, "coordinator": 197991, "pocket": 37581}} \ No newline at end of file +{"versions": {"installer": "v1.4e", "bootloader": "0.2", "comms": "2.0.0", "graphics": "1.0.0", "reactor-plc": "v1.4.6", "rtu": "v1.3.6", "supervisor": "v0.17.7", "coordinator": "v0.16.1", "pocket": "alpha-v0.4.5"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/tcd.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/events.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/listbox.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/tabbar.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/renderer.lua", "supervisor/databus.lua", "supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/panel/pgi.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/style.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/panel/components/pdg_entry.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/pocket.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/conn_waiting.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/boiler_page.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common", "graphics"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5803, "system": 1991, "common": 92736, "graphics": 144556, "lockbox": 100797, "reactor-plc": 97335, "rtu": 102240, "supervisor": 315402, "coordinator": 197991, "pocket": 37581}} \ No newline at end of file From b28e4d1e9574d67a03587b57fe34281910c4fd31 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sun, 18 Jun 2023 14:04:49 -0400 Subject: [PATCH 16/34] #258 installer bugfix --- ccmsi.lua | 4 ++-- install_manifest.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ccmsi.lua b/ccmsi.lua index 3a00542..f3f74d1 100644 --- a/ccmsi.lua +++ b/ccmsi.lua @@ -20,7 +20,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. local function println(message) print(tostring(message)) end local function print(message) term.write(tostring(message)) end -local CCMSI_VERSION = "v1.4e" +local CCMSI_VERSION = "v1.4f" local install_dir = "/.install-cache" local manifest_path = "https://mikaylafischler.github.io/cc-mek-scada/manifests/" @@ -177,7 +177,7 @@ else -- determine target if mode == "check" then target = opts[2] else target = opts[3] end - if target ~= "main" or target ~= "latest" or target ~= "devel" then + if (target ~= "main") and (target ~= "latest") and (target ~= "devel") then target = "main" println("unknown target, defaulting to 'main'") end diff --git a/install_manifest.json b/install_manifest.json index e3fc79d..5cec2b8 100644 --- a/install_manifest.json +++ b/install_manifest.json @@ -1 +1 @@ -{"versions": {"installer": "v1.4e", "bootloader": "0.2", "comms": "2.0.0", "graphics": "1.0.0", "reactor-plc": "v1.4.6", "rtu": "v1.3.6", "supervisor": "v0.17.7", "coordinator": "v0.16.1", "pocket": "alpha-v0.4.5"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/tcd.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/events.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/listbox.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/tabbar.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/renderer.lua", "supervisor/databus.lua", "supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/panel/pgi.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/style.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/panel/components/pdg_entry.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/pocket.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/conn_waiting.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/boiler_page.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common", "graphics"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5803, "system": 1991, "common": 92736, "graphics": 144556, "lockbox": 100797, "reactor-plc": 97335, "rtu": 102240, "supervisor": 315402, "coordinator": 197991, "pocket": 37581}} \ No newline at end of file +{"versions": {"installer": "v1.4f", "bootloader": "0.2", "comms": "2.0.0", "graphics": "1.0.0", "reactor-plc": "v1.4.6", "rtu": "v1.3.6", "supervisor": "v0.17.7", "coordinator": "v0.16.1", "pocket": "alpha-v0.4.5"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/tcd.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/events.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/listbox.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/tabbar.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/renderer.lua", "supervisor/databus.lua", "supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/panel/pgi.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/style.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/panel/components/pdg_entry.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/pocket.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/conn_waiting.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/boiler_page.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common", "graphics"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5803, "system": 1991, "common": 92736, "graphics": 144556, "lockbox": 100797, "reactor-plc": 97335, "rtu": 102240, "supervisor": 315402, "coordinator": 197991, "pocket": 37581}} \ No newline at end of file From af38025f501f3aaebfaf574ed77e7b7744d9bfaa Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sun, 18 Jun 2023 14:26:38 -0400 Subject: [PATCH 17/34] #262 don't ever abort RTU unit parsing on error, just skip --- install_manifest.json | 2 +- supervisor/session/rtu.lua | 10 ++++------ supervisor/startup.lua | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/install_manifest.json b/install_manifest.json index 5cec2b8..dc82370 100644 --- a/install_manifest.json +++ b/install_manifest.json @@ -1 +1 @@ -{"versions": {"installer": "v1.4f", "bootloader": "0.2", "comms": "2.0.0", "graphics": "1.0.0", "reactor-plc": "v1.4.6", "rtu": "v1.3.6", "supervisor": "v0.17.7", "coordinator": "v0.16.1", "pocket": "alpha-v0.4.5"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/tcd.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/events.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/listbox.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/tabbar.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/renderer.lua", "supervisor/databus.lua", "supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/panel/pgi.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/style.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/panel/components/pdg_entry.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/pocket.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/conn_waiting.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/boiler_page.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common", "graphics"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5803, "system": 1991, "common": 92736, "graphics": 144556, "lockbox": 100797, "reactor-plc": 97335, "rtu": 102240, "supervisor": 315402, "coordinator": 197991, "pocket": 37581}} \ No newline at end of file +{"versions": {"installer": "v1.4f", "bootloader": "0.2", "comms": "2.0.0", "graphics": "1.0.0", "reactor-plc": "v1.4.6", "rtu": "v1.3.6", "supervisor": "v0.17.8", "coordinator": "v0.16.1", "pocket": "alpha-v0.4.5"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/tcd.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/events.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/listbox.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/tabbar.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/renderer.lua", "supervisor/databus.lua", "supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/panel/pgi.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/style.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/panel/components/pdg_entry.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/pocket.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/conn_waiting.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/boiler_page.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common", "graphics"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5803, "system": 1991, "common": 92736, "graphics": 144556, "lockbox": 100797, "reactor-plc": 97335, "rtu": 102240, "supervisor": 315388, "coordinator": 197991, "pocket": 37581}} \ No newline at end of file diff --git a/supervisor/session/rtu.lua b/supervisor/session/rtu.lua index d1fbaec..69ba796 100644 --- a/supervisor/session/rtu.lua +++ b/supervisor/session/rtu.lua @@ -120,7 +120,7 @@ function rtu.new_session(id, s_addr, in_queue, out_queue, timeout, advertisement if u_type == false then -- validation fail - log.debug(log_header .. "advertisement unit validation failure") + log.debug(log_header .. "_handle_advertisement(): advertisement unit validation failure") else if unit_advert.reactor > 0 then local target_unit = self.fac_units[unit_advert.reactor] ---@type reactor_unit @@ -146,7 +146,7 @@ function rtu.new_session(id, s_addr, in_queue, out_queue, timeout, advertisement -- skip virtual units log.debug(util.c(log_header, "skipping virtual RTU unit #", i)) else - log.error(util.c(log_header, "bad advertisement: encountered unsupported reactor-specific RTU type ", type_string)) + log.warning(util.c(log_header, "_handle_advertisement(): encountered unsupported reactor-specific RTU type ", type_string)) end else -- facility RTUs @@ -172,7 +172,7 @@ function rtu.new_session(id, s_addr, in_queue, out_queue, timeout, advertisement -- skip virtual units log.debug(util.c(log_header, "skipping virtual RTU unit #", i)) else - log.error(util.c(log_header, "bad advertisement: encountered unsupported reactor-independent RTU type ", type_string)) + log.warning(util.c(log_header, "_handle_advertisement(): encountered unsupported facility RTU type ", type_string)) end end end @@ -181,9 +181,7 @@ function rtu.new_session(id, s_addr, in_queue, out_queue, timeout, advertisement self.units[i] = unit unit_count = unit_count + 1 elseif u_type ~= RTU_UNIT_TYPE.VIRTUAL then - _reset_config() - log.error(util.c(log_header, "bad advertisement: error occured while creating a unit (type is ", type_string, ")")) - break + log.warning(util.c(log_header, "_handle_advertisement(): problem occured while creating a unit (type is ", type_string, ")")) end end diff --git a/supervisor/startup.lua b/supervisor/startup.lua index f03fe1e..3ec55cc 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -20,7 +20,7 @@ local supervisor = require("supervisor.supervisor") local svsessions = require("supervisor.session.svsessions") -local SUPERVISOR_VERSION = "v0.17.7" +local SUPERVISOR_VERSION = "v0.17.8" local println = util.println local println_ts = util.println_ts From a02529b9f703dd00d5fe9c085edad58e9c8a36bf Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sun, 18 Jun 2023 15:19:01 -0400 Subject: [PATCH 18/34] #263 fixed bug with supervisor group map length not matching number of reactors --- .gitignore | 2 +- supervisor/facility.lua | 5 +++-- supervisor/startup.lua | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 17ae161..0688a64 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ _notes/ -program.sh \ No newline at end of file +/*program.sh \ No newline at end of file diff --git a/supervisor/facility.lua b/supervisor/facility.lua index e3b8059..5864ea5 100644 --- a/supervisor/facility.lua +++ b/supervisor/facility.lua @@ -75,7 +75,7 @@ function facility.new(num_reactors, cooling_conf) burn_target = 0.1, -- burn rate target for aggregate burn mode charge_setpoint = 0, -- FE charge target setpoint gen_rate_setpoint = 0, -- FE/t charge rate target setpoint - group_map = { 0, 0, 0, 0 }, -- units -> group IDs + group_map = {}, -- units -> group IDs prio_defs = { {}, {}, {}, {} }, -- priority definitions (each level is a table of units) at_max_burn = false, ascram = false, @@ -109,6 +109,7 @@ function facility.new(num_reactors, cooling_conf) -- create units for i = 1, num_reactors do table.insert(self.units, unit.new(i, cooling_conf[i].BOILERS, cooling_conf[i].TURBINES)) + table.insert(self.group_map, 0) end -- init redstone RTU I/O controller @@ -790,7 +791,7 @@ function facility.new(num_reactors, cooling_conf) ---@param unit_id integer unit ID ---@param group integer group ID or 0 for independent function public.set_group(unit_id, group) - if group >= 0 and group <= 4 and self.mode == PROCESS.INACTIVE then + if (group >= 0 and group <= 4) and (unit_id > 0 and unit_id <= num_reactors) and self.mode == PROCESS.INACTIVE then -- remove from old group if previously assigned local old_group = self.group_map[unit_id] if old_group ~= 0 then diff --git a/supervisor/startup.lua b/supervisor/startup.lua index 3ec55cc..0949573 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -20,7 +20,7 @@ local supervisor = require("supervisor.supervisor") local svsessions = require("supervisor.session.svsessions") -local SUPERVISOR_VERSION = "v0.17.8" +local SUPERVISOR_VERSION = "v0.17.9" local println = util.println local println_ts = util.println_ts From 1cdf66a8c35bd7e148f9b1ac22ea2ab2f03100df Mon Sep 17 00:00:00 2001 From: Mikayla Date: Wed, 21 Jun 2023 23:04:39 +0000 Subject: [PATCH 19/34] #51 WIP network interface controller --- coordinator/coordinator.lua | 30 ++-- coordinator/session/apisessions.lua | 18 +-- coordinator/startup.lua | 25 ++-- lockbox/init.lua | 3 + pocket/pocket.lua | 27 +--- pocket/startup.lua | 8 +- scada-common/comms.lua | 2 +- scada-common/crypto.lua | 152 ------------------- scada-common/network.lua | 225 ++++++++++++++++++++++++++++ 9 files changed, 270 insertions(+), 220 deletions(-) delete mode 100644 scada-common/crypto.lua create mode 100644 scada-common/network.lua diff --git a/coordinator/coordinator.lua b/coordinator/coordinator.lua index f6e8038..59661da 100644 --- a/coordinator/coordinator.lua +++ b/coordinator/coordinator.lua @@ -212,13 +212,13 @@ end -- coordinator communications ---@nodiscard ---@param version string coordinator version ----@param modem table modem device +---@param nic nic network interface device ---@param crd_channel integer port of configured supervisor ---@param svr_channel integer listening port for supervisor replys ---@param pkt_channel integer listening port for pocket API ---@param range integer trusted device connection range ---@param sv_watchdog watchdog -function coordinator.comms(version, modem, crd_channel, svr_channel, pkt_channel, range, sv_watchdog) +function coordinator.comms(version, nic, crd_channel, svr_channel, pkt_channel, range, sv_watchdog) local self = { sv_linked = false, sv_addr = comms.BROADCAST, @@ -234,16 +234,12 @@ function coordinator.comms(version, modem, crd_channel, svr_channel, pkt_channel -- PRIVATE FUNCTIONS -- - -- configure modem channels - local function _conf_channels() - modem.closeAll() - modem.open(crd_channel) - end + -- configure network channels + nic.closeAll() + nic.open(crd_channel) - _conf_channels() - - -- link modem to apisessions - apisessions.init(modem) + -- link nic to apisessions + apisessions.init(nic) -- send a packet to the supervisor ---@param msg_type SCADA_MGMT_TYPE|SCADA_CRDN_TYPE @@ -263,7 +259,7 @@ function coordinator.comms(version, modem, crd_channel, svr_channel, pkt_channel pkt.make(msg_type, msg) s_pkt.make(self.sv_addr, self.sv_seq_num, protocol, pkt.raw_sendable()) - modem.transmit(svr_channel, crd_channel, s_pkt.raw_sendable()) + nic.transmit(svr_channel, crd_channel, s_pkt) self.sv_seq_num = self.sv_seq_num + 1 end @@ -277,7 +273,7 @@ function coordinator.comms(version, modem, crd_channel, svr_channel, pkt_channel m_pkt.make(SCADA_MGMT_TYPE.ESTABLISH, { ack }) s_pkt.make(packet.src_addr(), packet.seq_num() + 1, PROTOCOL.SCADA_MGMT, m_pkt.raw_sendable()) - modem.transmit(pkt_channel, crd_channel, s_pkt.raw_sendable()) + nic.transmit(pkt_channel, crd_channel, s_pkt) self.last_api_est_acks[packet.src_addr()] = ack end @@ -297,14 +293,6 @@ function coordinator.comms(version, modem, crd_channel, svr_channel, pkt_channel ---@class coord_comms local public = {} - -- reconnect a newly connected modem - ---@param new_modem table - function public.reconnect_modem(new_modem) - modem = new_modem - apisessions.relink_modem(new_modem) - _conf_channels() - end - -- close the connection to the server function public.close() sv_watchdog.cancel() diff --git a/coordinator/session/apisessions.lua b/coordinator/session/apisessions.lua index 17988f5..1ea1beb 100644 --- a/coordinator/session/apisessions.lua +++ b/coordinator/session/apisessions.lua @@ -10,7 +10,7 @@ local pocket = require("coordinator.session.pocket") local apisessions = {} local self = { - modem = nil, + nic = nil, next_id = 0, sessions = {} } @@ -31,7 +31,7 @@ local function _api_handle_outq(session) if msg ~= nil then if msg.qtype == mqueue.TYPE.PACKET then -- handle a packet to be sent - self.modem.transmit(config.PKT_CHANNEL, config.CRD_CHANNEL, msg.message.raw_sendable()) + self.nic.transmit(config.PKT_CHANNEL, config.CRD_CHANNEL, msg.message) elseif msg.qtype == mqueue.TYPE.COMMAND then -- handle instruction/notification elseif msg.qtype == mqueue.TYPE.DATA then @@ -58,7 +58,7 @@ local function _shutdown(session) while session.out_queue.ready() do local msg = session.out_queue.pop() if msg ~= nil and msg.qtype == mqueue.TYPE.PACKET then - self.modem.transmit(config.PKT_CHANNEL, config.CRD_CHANNEL, msg.message.raw_sendable()) + self.nic.transmit(config.PKT_CHANNEL, config.CRD_CHANNEL, msg.message) end end @@ -68,15 +68,9 @@ end -- PUBLIC FUNCTIONS -- -- initialize apisessions ----@param modem table -function apisessions.init(modem) - self.modem = modem -end - --- re-link the modem ----@param modem table -function apisessions.relink_modem(modem) - self.modem = modem +---@param nic nic +function apisessions.init(nic) + self.nic = nic end -- find a session by remote port diff --git a/coordinator/startup.lua b/coordinator/startup.lua index 5a68afc..52b790c 100644 --- a/coordinator/startup.lua +++ b/coordinator/startup.lua @@ -6,6 +6,7 @@ require("/initenv").init_env() local crash = require("scada-common.crash") local log = require("scada-common.log") +local network = require("scada-common.network") local ppm = require("scada-common.ppm") local tcd = require("scada-common.tcd") local util = require("scada-common.util") @@ -20,7 +21,7 @@ local sounder = require("coordinator.sounder") local apisessions = require("coordinator.session.apisessions") -local COORDINATOR_VERSION = "v0.16.1" +local COORDINATOR_VERSION = "v0.17.0" local println = util.println local println_ts = util.println_ts @@ -147,8 +148,9 @@ local function main() conn_watchdog.cancel() log.debug("startup> conn watchdog created") - -- start comms, open all channels - local coord_comms = coordinator.comms(COORDINATOR_VERSION, modem, config.CRD_CHANNEL, config.SVR_CHANNEL, + -- init network interface then start comms + local nic = network.nic(modem) + local coord_comms = coordinator.comms(COORDINATOR_VERSION, nic, config.CRD_CHANNEL, config.SVR_CHANNEL, config.PKT_CHANNEL, config.TRUSTED_RANGE, conn_watchdog) log.debug("startup> comms init") log_comms("comms initialized") @@ -218,8 +220,6 @@ local function main() local date_format = util.trinary(config.TIME_24_HOUR, "%X \x04 %A, %B %d %Y", "%r \x04 %A, %B %d %Y") - local no_modem = false - if ui_ok then -- start connection watchdog conn_watchdog.feed() @@ -239,8 +239,9 @@ local function main() if type ~= nil and device ~= nil then if type == "modem" then -- we only really care if this is our wireless modem - if device == modem then - no_modem = true + -- if it is another modem, handle other peripheral losses separately + if nic.is_modem(device) then + nic.disconnect() log_sys("comms modem disconnected") println_ts("wireless modem disconnected!") @@ -254,6 +255,7 @@ local function main() end elseif type == "monitor" then if renderer.is_monitor_used(device) then + ---@todo will be handled properly in #249 -- "halt and catch fire" style handling local msg = "lost a configured monitor, system will now exit" println_ts(msg) @@ -275,9 +277,7 @@ local function main() if type == "modem" then if device.isWireless() then -- reconnected modem - no_modem = false - modem = device - coord_comms.reconnect_modem(modem) + nic.connect(device) log_sys("comms modem reconnected") println_ts("wireless modem reconnected.") @@ -289,6 +289,7 @@ local function main() log_sys("wired modem reconnected") end -- elseif type == "monitor" then + ---@todo will be handled properly in #249 -- not supported, system will exit on loss of in-use monitors elseif type == "speaker" then local msg = "alarm sounder speaker reconnected" @@ -322,7 +323,7 @@ local function main() renderer.close_ui() sounder.stop() - if not no_modem then + if nic.connected() then -- try to re-connect to the supervisor if not init_connect_sv() then break end ui_ok = init_start_ui() @@ -350,7 +351,7 @@ local function main() renderer.close_ui() sounder.stop() - if not no_modem then + if nic.connected() then -- try to re-connect to the supervisor if not init_connect_sv() then break end ui_ok = init_start_ui() diff --git a/lockbox/init.lua b/lockbox/init.lua index 0031a50..9323451 100644 --- a/lockbox/init.lua +++ b/lockbox/init.lua @@ -1,5 +1,8 @@ local Lockbox = {}; +-- cc-mek-scada lockbox version +Lockbox.VERSION = "1.0" + --[[ package.path = "./?.lua;" .. "./cipher/?.lua;" diff --git a/pocket/pocket.lua b/pocket/pocket.lua index 0281e92..c0b5f77 100644 --- a/pocket/pocket.lua +++ b/pocket/pocket.lua @@ -17,14 +17,14 @@ local pocket = {} -- pocket coordinator + supervisor communications ---@nodiscard ---@param version string pocket version ----@param modem table modem device +---@param nic nic network interface device ---@param pkt_channel integer pocket comms channel ---@param svr_channel integer supervisor access channel ---@param crd_channel integer coordinator access channel ---@param range integer trusted device connection range ---@param sv_watchdog watchdog ---@param api_watchdog watchdog -function pocket.comms(version, modem, pkt_channel, svr_channel, crd_channel, range, sv_watchdog, api_watchdog) +function pocket.comms(version, nic, pkt_channel, svr_channel, crd_channel, range, sv_watchdog, api_watchdog) local self = { sv = { linked = false, @@ -47,13 +47,9 @@ function pocket.comms(version, modem, pkt_channel, svr_channel, crd_channel, ran -- PRIVATE FUNCTIONS -- - -- configure modem channels - local function _conf_channels() - modem.closeAll() - modem.open(pkt_channel) - end - - _conf_channels() + -- configure network channels + nic.closeAll() + nic.open(pkt_channel) -- send a management packet to the supervisor ---@param msg_type SCADA_MGMT_TYPE @@ -65,7 +61,7 @@ function pocket.comms(version, modem, pkt_channel, svr_channel, crd_channel, ran pkt.make(msg_type, msg) s_pkt.make(self.sv.addr, self.sv.seq_num, PROTOCOL.SCADA_MGMT, pkt.raw_sendable()) - modem.transmit(svr_channel, pkt_channel, s_pkt.raw_sendable()) + nic.transmit(svr_channel, pkt_channel, s_pkt) self.sv.seq_num = self.sv.seq_num + 1 end @@ -79,7 +75,7 @@ function pocket.comms(version, modem, pkt_channel, svr_channel, crd_channel, ran pkt.make(msg_type, msg) s_pkt.make(self.api.addr, self.api.seq_num, PROTOCOL.SCADA_MGMT, pkt.raw_sendable()) - modem.transmit(crd_channel, pkt_channel, s_pkt.raw_sendable()) + nic.transmit(crd_channel, pkt_channel, s_pkt) self.api.seq_num = self.api.seq_num + 1 end @@ -93,7 +89,7 @@ function pocket.comms(version, modem, pkt_channel, svr_channel, crd_channel, ran -- pkt.make(msg_type, msg) -- s_pkt.make(self.api.addr, self.api.seq_num, PROTOCOL.COORD_API, pkt.raw_sendable()) - -- modem.transmit(crd_channel, pkt_channel, s_pkt.raw_sendable()) + -- nic.transmit(crd_channel, pkt_channel, s_pkt) -- self.api.seq_num = self.api.seq_num + 1 -- end @@ -124,13 +120,6 @@ function pocket.comms(version, modem, pkt_channel, svr_channel, crd_channel, ran ---@class pocket_comms local public = {} - -- reconnect a newly connected modem - ---@param new_modem table - function public.reconnect_modem(new_modem) - modem = new_modem - _conf_channels() - end - -- close connection to the supervisor function public.close_sv() sv_watchdog.cancel() diff --git a/pocket/startup.lua b/pocket/startup.lua index 7afd208..7b2e493 100644 --- a/pocket/startup.lua +++ b/pocket/startup.lua @@ -6,6 +6,7 @@ require("/initenv").init_env() local crash = require("scada-common.crash") local log = require("scada-common.log") +local network = require("scada-common.network") local ppm = require("scada-common.ppm") local tcd = require("scada-common.tcd") local util = require("scada-common.util") @@ -17,7 +18,7 @@ local coreio = require("pocket.coreio") local pocket = require("pocket.pocket") local renderer = require("pocket.renderer") -local POCKET_VERSION = "alpha-v0.4.5" +local POCKET_VERSION = "alpha-v0.5.0" local println = util.println local println_ts = util.println_ts @@ -88,8 +89,9 @@ local function main() log.debug("startup> conn watchdogs created") - -- start comms, open all channels - local pocket_comms = pocket.comms(POCKET_VERSION, modem, config.PKT_CHANNEL, config.SVR_CHANNEL, + -- init network interface then start comms + local nic = network.nic(modem) + local pocket_comms = pocket.comms(POCKET_VERSION, nic, config.PKT_CHANNEL, config.SVR_CHANNEL, config.CRD_CHANNEL, config.TRUSTED_RANGE, conn_wd.sv, conn_wd.api) log.debug("startup> comms init") diff --git a/scada-common/comms.lua b/scada-common/comms.lua index bd43706..99a3c7c 100644 --- a/scada-common/comms.lua +++ b/scada-common/comms.lua @@ -205,7 +205,7 @@ function comms.scada_packet() self.protocol = self.raw[4] self.mac = self.raw[5] - -- element 5 must be a table + -- element 6 must be a table if type(self.raw[6]) == "table" then self.length = #self.raw[6] self.payload = self.raw[6] diff --git a/scada-common/crypto.lua b/scada-common/crypto.lua deleted file mode 100644 index 0dae940..0000000 --- a/scada-common/crypto.lua +++ /dev/null @@ -1,152 +0,0 @@ --- --- Cryptographic Communications Engine --- - -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 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") - -local crypto = {} - -local c_eng = { - key = nil, - hmac = nil -} - --- initialize cryptographic system -function crypto.init(password) - local key_deriv = pbkdf2() - - -- setup PBKDF2 - key_deriv.setPassword(password) - key_deriv.setSalt("pepper") - key_deriv.setIterations(32) - key_deriv.setBlockLen(8) - key_deriv.setDKeyLen(16) - - local start = util.time_ms() - - key_deriv.setPRF(hmac().setBlockSize(64).setDigest(sha2_256)) - key_deriv.finish() - - 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 HMAC - c_eng.hmac = hmac() - c_eng.hmac.setBlockSize(64) - c_eng.hmac.setDigest(md5) - c_eng.hmac.setKey(c_eng.key) - - 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 string initial value concatenated with ciphertext -function crypto.hmac(message) - local start = util.time_ms() - - c_eng.hmac.init() - c_eng.hmac.update(stream.fromString(message)) - c_eng.hmac.finish() - - local hash = c_eng.hmac.asHex() - - log.debug("crypto.hmac: hmac-md5 took " .. (util.time_ms() - start) .. "ms") - log.debug("crypto.hmac: hmac = " .. util.strval(hash)) - - return hash -end - --- wrap a modem as a secure modem to send encrypted traffic ----@param modem table modem to wrap -function crypto.secure_modem(modem) - ---@class secure_modem - ---@field open function - ---@field isOpen function - ---@field close function - ---@field closeAll function - ---@field isWireless function - ---@field getNamesRemote function - ---@field isPresentRemote function - ---@field getTypeRemote function - ---@field hasTypeRemote function - ---@field getMethodsRemote function - ---@field callRemote function - ---@field getNameLocal function - local public = {} - - -- wrap a modem - ---@param reconnected_modem table - function public.wrap(reconnected_modem) - modem = reconnected_modem - for key, func in pairs(modem) do - public[key] = func - end - end - - -- wrap modem functions, then we replace transmit - public.wrap(modem) - - -- 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) - - packet.set_mac(computed_hmac) - - 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 channel - ---@param reply_to integer reply channel - ---@param message any packet sent with message authentication - ---@param distance integer transmission distance - ---@return scada_packet|nil packet received packet if valid and passed authentication check - function public.receive(side, sender, reply_to, message, distance) - local packet = nil - local s_packet = comms.scada_packet() - - -- parse packet as generic SCADA packet - s_packet.receive(side, sender, reply_to, message, distance) - - 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 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 packet - end - - return public -end - -return crypto diff --git a/scada-common/network.lua b/scada-common/network.lua new file mode 100644 index 0000000..fbc4750 --- /dev/null +++ b/scada-common/network.lua @@ -0,0 +1,225 @@ +-- +-- Network Communications +-- + +local md5 = require("lockbox.digest.md5") +local sha256 = require("lockbox.digest.sha2_256") +local pbkdf2 = require("lockbox.kdf.pbkdf2") +local hmac = require("lockbox.mac.hmac") +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") + +local network = {} + +local c_eng = { + key = nil, + hmac = nil +} + +-- initialize message authentication system +---@param passkey string facility passkey +---@return integer init_time milliseconds init took +function network.init_mac(passkey) + local start = util.time_ms() + + local key_deriv = pbkdf2() + + -- setup PBKDF2 + key_deriv.setPassword(passkey) + key_deriv.setSalt("pepper") + key_deriv.setIterations(32) + key_deriv.setBlockLen(8) + key_deriv.setDKeyLen(16) + key_deriv.setPRF(hmac().setBlockSize(64).setDigest(sha256)) + key_deriv.finish() + + c_eng.key = array.fromHex(key_deriv.asHex()) + + -- initialize HMAC + c_eng.hmac = hmac() + c_eng.hmac.setBlockSize(64) + c_eng.hmac.setDigest(md5) + c_eng.hmac.setKey(c_eng.key) + + local init_time = util.time_ms() - start + log.info("network.init_mac completed in " .. init_time .. "ms") + + return init_time +end + +-- generate HMAC of message +---@nodiscard +---@param message string initial value concatenated with ciphertext +local function compute_hmac(message) + local start = util.time_ms() + + c_eng.hmac.init() + c_eng.hmac.update(stream.fromString(message)) + c_eng.hmac.finish() + + local hash = c_eng.hmac.asHex() + + log.debug("compute_hmac(): hmac-md5 = " .. util.strval(hash) .. " (took " .. (util.time_ms() - start) .. "ms)") + + return hash +end + +-- NIC: Network Interface Controller
+-- utilizes HMAC-MD5 for message authentication, if enabled +---@param modem table modem to use +function network.nic(modem) + local self = { + connected = (modem ~= nil), + channels = {} + } + + ---@class nic + ---@field open function + ---@field isOpen function + ---@field close function + ---@field closeAll function + ---@field isWireless function + ---@field getNameLocal function + ---@field getNamesRemote function + ---@field isPresentRemote function + ---@field getTypeRemote function + ---@field hasTypeRemote function + ---@field getMethodsRemote function + ---@field callRemote function + local public = {} + + -- connect to a modem peripheral + ---@param reconnected_modem table + function public.connect(reconnected_modem) + modem = reconnected_modem + self.connected = true + + -- open previously opened channels + for _, channel in ipairs(self.channels) do + modem.open(channel) + end + + -- link all public functions except for transmit + for key, func in pairs(modem) do + if key ~= "transmit" and key ~= "open" and key ~= "close" and key ~= "closeAll" then public[key] = func end + end + end + + -- flag this NIC as no longer having a connected modem (usually do to peripheral disconnect) + function public.disconnect() self.connected = false end + + -- check if this NIC has a connected modem + ---@nodiscard + function public.connected() return self.connected end + + -- check if a peripheral is this modem + ---@nodiscard + ---@param device table + function public.is_modem(device) return device == modem end + + -- wrap modem functions, then create custom transmit + public.connect(modem) + + function public.open(channel) + if self.connected then + modem.open(channel) + + local already_open = false + for i = 1, #self.channels do + if self.channels[i] == channel then + already_open = true + break + end + end + + if not already_open then + table.insert(self.channels, channel) + end + end + end + + function public.close(channel) + if self.connected then + modem.close(channel) + for i = 1, #self.channels do + if self.channels[i] == channel then + table.remove(self.channels, i) + return + end + end + end + end + + function public.closeAll() + if self.connected then + modem.closeAll() + self.channels = {} + end + end + + -- send a packet, with message authentication if configured + ---@param dest_channel integer destination channel + ---@param local_channel integer local channel + ---@param packet scada_packet packet raw_sendable + function public.transmit(dest_channel, local_channel, packet) + if self.connected then + if c_eng.hmac ~= nil then + local start = util.time_ms() + local message = textutils.serialize(packet.raw_verifiable(), { allow_repetitions = true, compact = true }) + local computed_hmac = compute_hmac(message) + + packet.set_mac(computed_hmac) + + log.debug("crypto.modem.transmit: data processing took " .. (util.time_ms() - start) .. "ms") + end + + modem.transmit(dest_channel, local_channel, packet.raw_sendable()) + end + end + + -- parse in a modem message as a network packet + ---@nodiscard + ---@param side string modem side + ---@param sender integer sender channel + ---@param reply_to integer reply channel + ---@param message any packet sent with or without message authentication + ---@param distance integer transmission distance + ---@return scada_packet|nil packet received packet if valid and passed authentication check + function public.receive(side, sender, reply_to, message, distance) + local packet = nil + + if self.connected then + local s_packet = comms.scada_packet() + + -- parse packet as generic SCADA packet + s_packet.receive(side, sender, reply_to, message, distance) + + if s_packet.is_valid() then + if c_eng.hmac ~= nil then + local start = util.time_ms() + local packet_hmac = s_packet.mac() + local computed_hmac = compute_hmac(textutils.serialize(s_packet.raw_verifiable(), { allow_repetitions = true, compact = true })) + + if packet_hmac == computed_hmac then + log.debug("crypto.modem.receive: HMAC verified in " .. (util.time_ms() - start) .. "ms") + packet = s_packet + else + log.debug("crypto.modem.receive: HMAC failed verification in " .. (util.time_ms() - start) .. "ms") + end + else + packet = s_packet + end + end + end + + return packet + end + + return public +end + +return network From d69796b6072d722cd07efb758721d091fbe20516 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Thu, 22 Jun 2023 14:21:00 +0000 Subject: [PATCH 20/34] lockbox benchmark cleanup --- test/lockbox-benchmark.lua | 81 ++++++++++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 20 deletions(-) diff --git a/test/lockbox-benchmark.lua b/test/lockbox-benchmark.lua index 7c6ae55..6bb1c37 100644 --- a/test/lockbox-benchmark.lua +++ b/test/lockbox-benchmark.lua @@ -1,23 +1,24 @@ require("/initenv").init_env() -local pbkdf2 = require("lockbox.kdf.pbkdf2") -local AES128Cipher = require("lockbox.cipher.aes128") -local HMAC = require("lockbox.mac.hmac") -local SHA1 = require("lockbox.digest.sha1") --- local SHA2_224 = require("lockbox.digest.sha2_224") -local SHA2_256 = require("lockbox.digest.sha2_256") -local Stream = require("lockbox.util.stream") -local Array = require("lockbox.util.array") +local pbkdf2 = require("lockbox.kdf.pbkdf2") +-- local AES128Cipher = require("lockbox.cipher.aes128") +local HMAC = require("lockbox.mac.hmac") +local MD5 = require("lockbox.digest.md5") +local SHA1 = require("lockbox.digest.sha1") +local SHA2_224 = require("lockbox.digest.sha2_224") +local SHA2_256 = require("lockbox.digest.sha2_256") +local Stream = require("lockbox.util.stream") +-- local Array = require("lockbox.util.array") -- local CBCMode = require("lockbox.cipher.mode.cbc") -- local CFBMode = require("lockbox.cipher.mode.cfb") -- local OFBMode = require("lockbox.cipher.mode.ofb") -local CTRMode = require("lockbox.cipher.mode.ctr") +-- local CTRMode = require("lockbox.cipher.mode.ctr") -local ZeroPadding = require("lockbox.padding.zero") +-- local ZeroPadding = require("lockbox.padding.zero") local comms = require("scada-common.comms") -local util = require("scada-common.util") +local util = require("scada-common.util") local start = util.time() @@ -46,6 +47,7 @@ local data = textutils.serialize(spkt.raw_sendable(), { allow_repetitions = true util.println("packet serialize: took " .. (util.time() - start) .. "ms") util.println("message: " .. data) +--[[ start = util.time() local v = { cipher = CTRMode.Cipher, @@ -91,15 +93,54 @@ local b = Stream.toString(a) util.println("plaintext: " .. b) local msg = "000102030405060708090A0B0C0D0E0F" .. cipherOutput +]]-- + +-- local testmsg = "{1,0,42,3,{5,{{},{boilers={},turbines={},rad_mon={},},{TurbineOnline={false,},AutoControl=false,TurbineTrip={false,},HeatingRateLow={false,},HighStartupRate=false,BoilRateMismatch=false,ManualReactorSCRAM=false,FuelInputRateLow=false,PLCHeartbeat=false,MaxWaterReturnFeed=false,RCSFault=false,PLCOnline=false,RadiationMonitor=1,TurbineOverSpeed={false,},CoolantFeedMismatch=false,BoilerOnline={false,},ReactorTempHigh=false,SteamDumpOpen={1,},RCSFlowLow=false,RadiationWarning=false,WasteLineOcclusion=false,SteamFeedMismatch=false,ReactorSCRAM=false,EmergencyCoolant=1,CoolantLevelLow=false,ReactorHighDeltaT=false,AutoReactorSCRAM=false,WaterLevelLow={},RCPTrip=false,GeneratorTrip={false,},},{1,1,1,1,1,1,1,1,1,1,1,1,},{\"REACTOR OFF-LINE\",\"awaiting connection...\",1,false,true,},},{{},{boilers={},turbines={},rad_mon={},},{TurbineOnline={false,},AutoControl=false,TurbineTrip={false,},HeatingRateLow={false,},HighStartupRate=false,BoilRateMismatch=false,ManualReactorSCRAM=false,FuelInputRateLow=false,PLCHeartbeat=false,MaxWaterReturnFeed=false,RCSFault=false,PLCOnline=false,RadiationMonitor=1,TurbineOverSpeed={false,},CoolantFeedMismatch=false,BoilerOnline={false,},ReactorTempHigh=false,SteamDumpOpen={1,},RCSFlowLow=false,RadiationWarning=false,WasteLineOcclusion=false,SteamFeedMismatch=false,ReactorSCRAM=false,EmergencyCoolant=1,CoolantLevelLow=false,ReactorHighDeltaT=false,AutoReactorSCRAM=false,WaterLevelLow={},RCPTrip=false,GeneratorTrip={false,},},{1,1,1,1,1,1,1,1,1,1,1,1,},{\"REACTOR OFF-LINE\",\"awaiting connection...\",1,false,true,},},{{},{boilers={},turbines={},rad_mon={},},{TurbineOnline={false,},AutoControl=false,TurbineTrip={false,},HeatingRateLow={false,},HighStartupRate=false,BoilRateMismatch=false,ManualReactorSCRAM=false,FuelInputRateLow=false,PLCHeartbeat=false,MaxWaterReturnFeed=false,RCSFault=false,PLCOnline=false,RadiationMonitor=1,TurbineOverSpeed={false,},CoolantFeedMismatch=false,BoilerOnline={false,},ReactorTempHigh=false,SteamDumpOpen={1,},RCSFlowLow=false,RadiationWarning=false,WasteLineOcclusion=false,SteamFeedMismatch=false,ReactorSCRAM=false,EmergencyCoolant=1,CoolantLevelLow=false,ReactorHighDeltaT=false,AutoReactorSCRAM=false,WaterLevelLow={},RCPTrip=false,GeneratorTrip={false,},},{1,1,1,1,1,1,1,1,1,1,1,1,},{\"REACTOR OFF-LINE\",\"awaiting connection...\",1,false,true,},},{{},{boilers={},turbines={},rad_mon={},},{TurbineOnline={false,},AutoControl=false,TurbineTrip={false,},HeatingRateLow={false,},HighStartupRate=false,BoilRateMismatch=false,ManualReactorSCRAM=false,FuelInputRateLow=false,PLCHeartbeat=false,MaxWaterReturnFeed=false,RCSFault=false,PLCOnline=false,RadiationMonitor=1,TurbineOverSpeed={false,},CoolantFeedMismatch=false,BoilerOnline={false,},ReactorTempHigh=false,SteamDumpOpen={1,},RCSFlowLow=false,RadiationWarning=false,WasteLineOcclusion=false,SteamFeedMismatch=false,ReactorSCRAM=false,EmergencyCoolant=1,CoolantLevelLow=false,ReactorHighDeltaT=false,AutoReactorSCRAM=false,WaterLevelLow={},RCPTrip=false,GeneratorTrip={false,},},{1,1,1,1,1,1,1,1,1,1,1,1,},{\"REACTOR OFF-LINE\",\"awaiting connection...\",1,false,true,},},},}" +local testmsg = "{1,0,42,3,{5,{{},{boilers={},turbines={},rad_mon={},},{TurbineOnline={false,},AutoControl=false,TurbineTrip={false,},HeatingRateLow={false,},HighStartupRate=false,BoilRateMismatch=false,ManualReactorSCRAM=false,FuelInputRateLow=false}" +local n = 1000 + +---@diagnostic disable: undefined-field +os.sleep(1) + +local hash +local hmac = HMAC().setBlockSize(64).setDigest(MD5).setKey(keyd).init() start = util.time() -local hash = HMAC() - .setBlockSize(64) - .setDigest(SHA1) - .setKey(keyd) - .init() - .update(Stream.fromHex(msg)) - .finish() - .asHex(); -util.println("hmac: took " .. (util.time() - start) .. "ms") +for _ = 1, n do + hash = hmac.update(Stream.fromHex(testmsg)).finish().asHex(); +end +util.println("hmac-md5: took " .. (util.time() - start) .. "ms") +util.println("hash: " .. hash) + +os.sleep(1) + +hmac = HMAC().setBlockSize(64).setDigest(SHA1).setKey(keyd).init() + +start = util.time() +for _ = 1, n do + hash = hmac.update(Stream.fromHex(testmsg)).finish().asHex(); +end +util.println("hmac-sha1: took " .. (util.time() - start) .. "ms") +util.println("hash: " .. hash) + +os.sleep(1) + +hmac = HMAC().setBlockSize(64).setDigest(SHA2_224).setKey(keyd).init() + +start = util.time() +for _ = 1, n do + hash = hmac.update(Stream.fromHex(testmsg)).finish().asHex(); +end +util.println("hmac-sha224: took " .. (util.time() - start) .. "ms") +util.println("hash: " .. hash) + +os.sleep(1) + +hmac = HMAC().setBlockSize(64).setDigest(SHA2_256).setKey(keyd).init() + +start = util.time() +for _ = 1, n do + hash = hmac.update(Stream.fromHex(testmsg)).finish().asHex(); +end +util.println("hmac-sha256: took " .. (util.time() - start) .. "ms") util.println("hash: " .. hash) From 737afe586d5f11a421455cc6fdebcc66316bf21c Mon Sep 17 00:00:00 2001 From: Mikayla Date: Thu, 22 Jun 2023 14:22:32 +0000 Subject: [PATCH 21/34] renamed lockbox benchmark --- test/{lockbox-benchmark.lua => lockbox_benchmark.lua} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{lockbox-benchmark.lua => lockbox_benchmark.lua} (100%) diff --git a/test/lockbox-benchmark.lua b/test/lockbox_benchmark.lua similarity index 100% rename from test/lockbox-benchmark.lua rename to test/lockbox_benchmark.lua From 712c7a8f3b8aa903a788625b921ddd3ecd0ce099 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Thu, 22 Jun 2023 19:46:17 +0000 Subject: [PATCH 22/34] #266 added health check to ppm and strengthened reliability of RTU hw state reporting --- coordinator/startup.lua | 2 +- install_manifest.json | 2 +- pocket/startup.lua | 2 +- reactor-plc/plc.lua | 4 +- reactor-plc/startup.lua | 2 +- rtu/dev/boilerv_rtu.lua | 1 + rtu/dev/envd_rtu.lua | 1 + rtu/dev/imatrix_rtu.lua | 1 + rtu/dev/sna_rtu.lua | 1 + rtu/dev/sps_rtu.lua | 1 + rtu/dev/turbinev_rtu.lua | 1 + rtu/startup.lua | 40 ++++++++-------- rtu/threads.lua | 98 +++++++++++++++++++++------------------- scada-common/ppm.lua | 15 ++++-- supervisor/startup.lua | 2 +- 15 files changed, 99 insertions(+), 74 deletions(-) diff --git a/coordinator/startup.lua b/coordinator/startup.lua index 5a68afc..838d9ec 100644 --- a/coordinator/startup.lua +++ b/coordinator/startup.lua @@ -20,7 +20,7 @@ local sounder = require("coordinator.sounder") local apisessions = require("coordinator.session.apisessions") -local COORDINATOR_VERSION = "v0.16.1" +local COORDINATOR_VERSION = "v0.16.2" local println = util.println local println_ts = util.println_ts diff --git a/install_manifest.json b/install_manifest.json index dc82370..b6c4c60 100644 --- a/install_manifest.json +++ b/install_manifest.json @@ -1 +1 @@ -{"versions": {"installer": "v1.4f", "bootloader": "0.2", "comms": "2.0.0", "graphics": "1.0.0", "reactor-plc": "v1.4.6", "rtu": "v1.3.6", "supervisor": "v0.17.8", "coordinator": "v0.16.1", "pocket": "alpha-v0.4.5"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/tcd.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/events.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/listbox.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/tabbar.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/renderer.lua", "supervisor/databus.lua", "supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/panel/pgi.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/style.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/panel/components/pdg_entry.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/pocket.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/conn_waiting.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/boiler_page.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common", "graphics"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5803, "system": 1991, "common": 92736, "graphics": 144556, "lockbox": 100797, "reactor-plc": 97335, "rtu": 102240, "supervisor": 315388, "coordinator": 197991, "pocket": 37581}} \ No newline at end of file +{"versions": {"installer": "v1.4f", "bootloader": "0.2", "comms": "2.0.0", "graphics": "1.0.0", "reactor-plc": "v1.4.7", "rtu": "v1.3.7", "supervisor": "v0.17.10", "coordinator": "v0.16.2", "pocket": "alpha-v0.4.6"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/constants.lua", "scada-common/crypto.lua", "scada-common/types.lua", "scada-common/comms.lua", "scada-common/mqueue.lua", "scada-common/util.lua", "scada-common/psil.lua", "scada-common/crash.lua", "scada-common/tcd.lua", "scada-common/rsio.lua", "scada-common/ppm.lua", "scada-common/log.lua"], "graphics": ["graphics/core.lua", "graphics/flasher.lua", "graphics/element.lua", "graphics/events.lua", "graphics/elements/div.lua", "graphics/elements/colormap.lua", "graphics/elements/textbox.lua", "graphics/elements/pipenet.lua", "graphics/elements/listbox.lua", "graphics/elements/multipane.lua", "graphics/elements/displaybox.lua", "graphics/elements/rectangle.lua", "graphics/elements/tiling.lua", "graphics/elements/controls/tabbar.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/animations/waiting.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/indicators/alight.lua"], "lockbox": ["lockbox/LICENSE", "lockbox/init.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/digest/sha2_224.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/mac/hmac.lua", "lockbox/kdf/pbkdf2.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/isoiec7816.lua", "lockbox/padding/zero.lua", "lockbox/padding/pkcs7.lua", "lockbox/util/stream.lua", "lockbox/util/bit.lua", "lockbox/util/queue.lua", "lockbox/util/array.lua"], "reactor-plc": ["reactor-plc/config.lua", "reactor-plc/plc.lua", "reactor-plc/renderer.lua", "reactor-plc/databus.lua", "reactor-plc/startup.lua", "reactor-plc/threads.lua", "reactor-plc/panel/style.lua", "reactor-plc/panel/front_panel.lua"], "rtu": ["rtu/modbus.lua", "rtu/rtu.lua", "rtu/config.lua", "rtu/renderer.lua", "rtu/databus.lua", "rtu/startup.lua", "rtu/threads.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/turbinev_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/panel/style.lua", "rtu/panel/front_panel.lua"], "supervisor": ["supervisor/unit.lua", "supervisor/supervisor.lua", "supervisor/config.lua", "supervisor/renderer.lua", "supervisor/databus.lua", "supervisor/startup.lua", "supervisor/facility.lua", "supervisor/unitlogic.lua", "supervisor/panel/style.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/pgi.lua", "supervisor/panel/components/pdg_entry.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/session/coordinator.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/svsessions.lua", "supervisor/session/pocket.lua", "supervisor/session/svqtypes.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/redstone.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/sps.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/iocontrol.lua", "coordinator/config.lua", "coordinator/renderer.lua", "coordinator/startup.lua", "coordinator/sounder.lua", "coordinator/process.lua", "coordinator/session/pocket.lua", "coordinator/session/apisessions.lua", "coordinator/ui/style.lua", "coordinator/ui/dialog.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/turbine.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua"], "pocket": ["pocket/config.lua", "pocket/renderer.lua", "pocket/startup.lua", "pocket/coreio.lua", "pocket/pocket.lua", "pocket/ui/style.lua", "pocket/ui/main.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/boiler_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/components/conn_waiting.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common", "graphics"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5804, "system": 1991, "common": 93200, "graphics": 144556, "lockbox": 100797, "reactor-plc": 97317, "rtu": 102353, "supervisor": 315477, "coordinator": 197991, "pocket": 37581}} \ No newline at end of file diff --git a/pocket/startup.lua b/pocket/startup.lua index 7afd208..3352605 100644 --- a/pocket/startup.lua +++ b/pocket/startup.lua @@ -17,7 +17,7 @@ local coreio = require("pocket.coreio") local pocket = require("pocket.pocket") local renderer = require("pocket.renderer") -local POCKET_VERSION = "alpha-v0.4.5" +local POCKET_VERSION = "alpha-v0.4.6" local println = util.println local println_ts = util.println_ts diff --git a/reactor-plc/plc.lua b/reactor-plc/plc.lua index 02e592a..fc41f80 100644 --- a/reactor-plc/plc.lua +++ b/reactor-plc/plc.lua @@ -639,7 +639,7 @@ function plc.comms(id, version, modem, plc_channel, svr_channel, range, reactor, parallel.waitForAll(table.unpack(tasks)) - if not reactor.__p_is_faulted() then + if reactor.__p_is_ok() then _send(RPLC_TYPE.MEK_STRUCT, mek_data) self.resend_build = false end @@ -836,7 +836,7 @@ function plc.comms(id, version, modem, plc_channel, svr_channel, range, reactor, success = true else reactor.setBurnRate(burn_rate) - success = not reactor.__p_is_faulted() + success = reactor.__p_is_ok() end else log.debug(burn_rate .. " rate outside of 0 < x <= " .. self.max_burn_rate) diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 76185e9..a6a47a6 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -18,7 +18,7 @@ local plc = require("reactor-plc.plc") local renderer = require("reactor-plc.renderer") local threads = require("reactor-plc.threads") -local R_PLC_VERSION = "v1.4.6" +local R_PLC_VERSION = "v1.4.7" local println = util.println local println_ts = util.println_ts diff --git a/rtu/dev/boilerv_rtu.lua b/rtu/dev/boilerv_rtu.lua index 46ac7c2..6815a3c 100644 --- a/rtu/dev/boilerv_rtu.lua +++ b/rtu/dev/boilerv_rtu.lua @@ -10,6 +10,7 @@ function boilerv_rtu.new(boiler) local unit = rtu.init_unit() -- disable auto fault clearing + boiler.__p_clear_fault() boiler.__p_disable_afc() -- discrete inputs -- diff --git a/rtu/dev/envd_rtu.lua b/rtu/dev/envd_rtu.lua index 2894e2c..2d576bc 100644 --- a/rtu/dev/envd_rtu.lua +++ b/rtu/dev/envd_rtu.lua @@ -10,6 +10,7 @@ function envd_rtu.new(envd) local unit = rtu.init_unit() -- disable auto fault clearing + envd.__p_clear_fault() envd.__p_disable_afc() -- discrete inputs -- diff --git a/rtu/dev/imatrix_rtu.lua b/rtu/dev/imatrix_rtu.lua index 3b72a12..a20d1a5 100644 --- a/rtu/dev/imatrix_rtu.lua +++ b/rtu/dev/imatrix_rtu.lua @@ -10,6 +10,7 @@ function imatrix_rtu.new(imatrix) local unit = rtu.init_unit() -- disable auto fault clearing + imatrix.__p_clear_fault() imatrix.__p_disable_afc() -- discrete inputs -- diff --git a/rtu/dev/sna_rtu.lua b/rtu/dev/sna_rtu.lua index 16c0cfd..a3e678e 100644 --- a/rtu/dev/sna_rtu.lua +++ b/rtu/dev/sna_rtu.lua @@ -10,6 +10,7 @@ function sna_rtu.new(sna) local unit = rtu.init_unit() -- disable auto fault clearing + sna.__p_clear_fault() sna.__p_disable_afc() -- discrete inputs -- diff --git a/rtu/dev/sps_rtu.lua b/rtu/dev/sps_rtu.lua index 349550c..428f7bb 100644 --- a/rtu/dev/sps_rtu.lua +++ b/rtu/dev/sps_rtu.lua @@ -10,6 +10,7 @@ function sps_rtu.new(sps) local unit = rtu.init_unit() -- disable auto fault clearing + sps.__p_clear_fault() sps.__p_disable_afc() -- discrete inputs -- diff --git a/rtu/dev/turbinev_rtu.lua b/rtu/dev/turbinev_rtu.lua index 4f2ee48..f8d6d5e 100644 --- a/rtu/dev/turbinev_rtu.lua +++ b/rtu/dev/turbinev_rtu.lua @@ -10,6 +10,7 @@ function turbinev_rtu.new(turbine) local unit = rtu.init_unit() -- disable auto fault clearing + turbine.__p_clear_fault() turbine.__p_disable_afc() -- discrete inputs -- diff --git a/rtu/startup.lua b/rtu/startup.lua index 769e4d7..85f3220 100644 --- a/rtu/startup.lua +++ b/rtu/startup.lua @@ -28,7 +28,7 @@ local sna_rtu = require("rtu.dev.sna_rtu") local sps_rtu = require("rtu.dev.sps_rtu") local turbinev_rtu = require("rtu.dev.turbinev_rtu") -local RTU_VERSION = "v1.3.6" +local RTU_VERSION = "v1.3.7" local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE @@ -236,18 +236,19 @@ local function main() ---@class rtu_unit_registry_entry local unit = { - uid = 0, ---@type integer - name = "redstone_io", ---@type string - type = RTU_UNIT_TYPE.REDSTONE, ---@type RTU_UNIT_TYPE - index = entry_idx, ---@type integer - reactor = io_reactor, ---@type integer - device = capabilities, ---@type table use device field for redstone ports - is_multiblock = false, ---@type boolean - formed = nil, ---@type boolean|nil - rtu = rs_rtu, ---@type rtu_device|rtu_rs_device + uid = 0, ---@type integer + name = "redstone_io", ---@type string + type = RTU_UNIT_TYPE.REDSTONE, ---@type RTU_UNIT_TYPE + index = entry_idx, ---@type integer + reactor = io_reactor, ---@type integer + device = capabilities, ---@type table use device field for redstone ports + is_multiblock = false, ---@type boolean + formed = nil, ---@type boolean|nil + hw_state = RTU_UNIT_HW_STATE.OK, ---@type RTU_UNIT_HW_STATE + rtu = rs_rtu, ---@type rtu_device|rtu_rs_device modbus_io = modbus.new(rs_rtu, false), - pkt_queue = nil, ---@type mqueue|nil - thread = nil ---@type parallel_thread|nil + pkt_queue = nil, ---@type mqueue|nil + thread = nil ---@type parallel_thread|nil } table.insert(units, unit) @@ -261,7 +262,7 @@ local function main() unit.uid = #units - databus.tx_unit_hw_status(unit.uid, RTU_UNIT_HW_STATE.OK) + databus.tx_unit_hw_status(unit.uid, unit.hw_state) end end @@ -403,6 +404,7 @@ local function main() device = device, ---@type table is_multiblock = is_multiblock, ---@type boolean formed = formed, ---@type boolean|nil + hw_state = RTU_UNIT_HW_STATE.OFFLINE, ---@type RTU_UNIT_HW_STATE rtu = rtu_iface, ---@type rtu_device|rtu_rs_device modbus_io = modbus.new(rtu_iface, true), pkt_queue = mqueue.new(), ---@type mqueue|nil @@ -422,19 +424,21 @@ local function main() rtu_unit.uid = #units - -- report hardware status + -- determine hardware status if rtu_unit.type == RTU_UNIT_TYPE.VIRTUAL then - databus.tx_unit_hw_status(rtu_unit.uid, RTU_UNIT_HW_STATE.OFFLINE) + rtu_unit.hw_state = RTU_UNIT_HW_STATE.OFFLINE else if rtu_unit.is_multiblock then - databus.tx_unit_hw_status(rtu_unit.uid, util.trinary(rtu_unit.formed == true, RTU_UNIT_HW_STATE.OK, RTU_UNIT_HW_STATE.UNFORMED)) + rtu_unit.hw_state = util.trinary(rtu_unit.formed == true, RTU_UNIT_HW_STATE.OK, RTU_UNIT_HW_STATE.UNFORMED) elseif faulted then - databus.tx_unit_hw_status(rtu_unit.uid, RTU_UNIT_HW_STATE.FAULTED) + rtu_unit.hw_state = RTU_UNIT_HW_STATE.FAULTED else - databus.tx_unit_hw_status(rtu_unit.uid, RTU_UNIT_HW_STATE.OK) + rtu_unit.hw_state = RTU_UNIT_HW_STATE.OK end end + -- report hardware status + databus.tx_unit_hw_status(rtu_unit.uid, rtu_unit.hw_state) end -- we made it through all that trusting-user-to-write-a-config-file chaos diff --git a/rtu/threads.lua b/rtu/threads.lua index fdb82b3..6d51dec 100644 --- a/rtu/threads.lua +++ b/rtu/threads.lua @@ -105,13 +105,15 @@ function threads.thread__main(smem) for i = 1, #units do -- find disconnected device if units[i].device == device then - -- we are going to let the PPM prevent crashes - -- return fault flags/codes to MODBUS queries + -- will let the PPM prevent crashes, which will indicate failures in MODBUS queries local unit = units[i] ---@type rtu_unit_registry_entry local type_name = types.rtu_type_to_string(unit.type) + println_ts(util.c("lost the ", type_name, " on interface ", unit.name)) log.warning(util.c("lost the ", type_name, " unit peripheral on interface ", unit.name)) - databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.OFFLINE) + + unit.hw_state = UNIT_HW_STATE.OFFLINE + databus.tx_unit_hw_status(unit.uid, unit.hw_state) break end end @@ -144,6 +146,8 @@ function threads.thread__main(smem) -- note: cannot check isFormed as that would yield this coroutine and consume events if unit.name == param1 then local resend_advert = false + local faulted = false + local unknown = false -- found, re-link unit.device = device @@ -177,57 +181,58 @@ function threads.thread__main(smem) end if unit.type == RTU_UNIT_TYPE.BOILER_VALVE then - unit.rtu = boilerv_rtu.new(device) + unit.rtu, faulted = boilerv_rtu.new(device) -- if not formed, indexing the multiblock functions would have resulted in a PPM fault - unit.formed = util.trinary(device.__p_is_faulted(), false, nil) - databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.UNFORMED) + unit.formed = util.trinary(faulted, false, nil) elseif unit.type == RTU_UNIT_TYPE.TURBINE_VALVE then - unit.rtu = turbinev_rtu.new(device) + unit.rtu, faulted = turbinev_rtu.new(device) -- if not formed, indexing the multiblock functions would have resulted in a PPM fault - unit.formed = util.trinary(device.__p_is_faulted(), false, nil) - databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.UNFORMED) + unit.formed = util.trinary(faulted, false, nil) elseif unit.type == RTU_UNIT_TYPE.IMATRIX then - unit.rtu = imatrix_rtu.new(device) + unit.rtu, faulted = imatrix_rtu.new(device) -- if not formed, indexing the multiblock functions would have resulted in a PPM fault - unit.formed = util.trinary(device.__p_is_faulted(), false, nil) - databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.UNFORMED) + unit.formed = util.trinary(faulted, false, nil) elseif unit.type == RTU_UNIT_TYPE.SPS then - unit.rtu = sps_rtu.new(device) + unit.rtu, faulted = sps_rtu.new(device) -- if not formed, indexing the multiblock functions would have resulted in a PPM fault - unit.formed = util.trinary(device.__p_is_faulted(), false, nil) - databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.UNFORMED) + unit.formed = util.trinary(faulted, false, nil) elseif unit.type == RTU_UNIT_TYPE.SNA then - unit.rtu = sna_rtu.new(device) - databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.OK) + unit.rtu, faulted = sna_rtu.new(device) elseif unit.type == RTU_UNIT_TYPE.ENV_DETECTOR then - unit.rtu = envd_rtu.new(device) - databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.OK) + unit.rtu, faulted = envd_rtu.new(device) else + unknown = true log.error(util.c("failed to identify reconnected RTU unit type (", unit.name, ")"), true) end if unit.is_multiblock then - if (unit.formed == false) then + unit.hw_state = UNIT_HW_STATE.UNFORMED + if unit.formed == false then log.info(util.c("assuming ", unit.name, " is not formed due to PPM faults while initializing")) - databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.UNFORMED) end - elseif device.__p_is_faulted() then - databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.FAULTED) + elseif faulted then + unit.hw_state = UNIT_HW_STATE.FAULTED + elseif not unknown then + unit.hw_state = UNIT_HW_STATE.OK else - databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.OK) + unit.hw_state = UNIT_HW_STATE.OFFLINE end - unit.modbus_io = modbus.new(unit.rtu, true) + databus.tx_unit_hw_status(unit.uid, unit.hw_state) - local type_name = types.rtu_type_to_string(unit.type) - local message = util.c("reconnected the ", type_name, " on interface ", unit.name) - println_ts(message) - log.info(message) + if not unknown then + unit.modbus_io = modbus.new(unit.rtu, true) - if resend_advert then - rtu_comms.send_advertisement(units) - else - rtu_comms.send_remounted(unit.uid) + local type_name = types.rtu_type_to_string(unit.type) + local message = util.c("reconnected the ", type_name, " on interface ", unit.name) + println_ts(message) + log.info(message) + + if resend_advert then + rtu_comms.send_advertisement(units) + else + rtu_comms.send_remounted(unit.uid) + end end end end @@ -391,13 +396,6 @@ function threads.thread__unit_comms(smem, unit) -- received a packet local _, reply = unit.modbus_io.handle_packet(msg.message) rtu_comms.send_modbus(reply) - - -- check if there was a problem and update the hardware state if so - local frame = reply.get() - if unit.formed and (bit.band(frame.func_code, types.MODBUS_FCODE.ERROR_FLAG) ~= 0) and - (frame.data[1] == types.MODBUS_EXCODE.SERVER_DEVICE_FAIL) then - databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.FAULTED) - end end end @@ -413,12 +411,10 @@ function threads.thread__unit_comms(smem, unit) if unit.formed == nil then unit.formed = is_formed - if is_formed then databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.OK) end + if is_formed then unit.hw_state = UNIT_HW_STATE.OK end end - if not unit.formed then - databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.UNFORMED) - end + if not unit.formed then unit.hw_state = UNIT_HW_STATE.UNFORMED end if (not unit.formed) and is_formed then -- newly re-formed @@ -463,11 +459,11 @@ function threads.thread__unit_comms(smem, unit) if unit.formed and faulted then -- something is still wrong = can't mark as formed yet unit.formed = false + unit.hw_state = UNIT_HW_STATE.UNFORMED log.info(util.c("assuming ", unit.name, " is not formed due to PPM faults while initializing")) - databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.UNFORMED) else + unit.hw_state = UNIT_HW_STATE.OK rtu_comms.send_remounted(unit.uid) - databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.OK) end local type_name = types.rtu_type_to_string(unit.type) @@ -484,6 +480,16 @@ function threads.thread__unit_comms(smem, unit) unit.formed = is_formed end + -- check hardware status + if unit.device.__p_is_healthy() then + if unit.hw_state == UNIT_HW_STATE.FAULTED then unit.hw_state = UNIT_HW_STATE.OK end + else + if unit.hw_state == UNIT_HW_STATE.OK then unit.hw_state = UNIT_HW_STATE.FAULTED end + end + + -- update hw status + databus.tx_unit_hw_status(unit.uid, unit.hw_state) + -- check for termination request if rtu_state.shutdown then log.info("rtu unit thread exiting -> " .. short_name) diff --git a/scada-common/ppm.lua b/scada-common/ppm.lua index fe9e026..90f0b17 100644 --- a/scada-common/ppm.lua +++ b/scada-common/ppm.lua @@ -101,22 +101,31 @@ local function peri_init(iface) end end - -- fault management functions + -- fault management & monitoring functions local function clear_fault() self.faulted = false end local function get_last_fault() return self.last_fault end local function is_faulted() return self.faulted end local function is_ok() return not self.faulted end + -- check if a peripheral has any faulted functions
+ -- contrasted with is_faulted() and is_ok() as those only check if the last operation failed, + -- unless auto fault clearing is disabled, at which point faults become sticky faults + local function is_healthy() + for _, v in pairs(self.fault_counts) do if v > 0 then return false end end + return true + end + local function enable_afc() self.auto_cf = true end local function disable_afc() self.auto_cf = false end - -- append to device functions + -- append PPM functions to device functions self.device.__p_clear_fault = clear_fault self.device.__p_last_fault = get_last_fault self.device.__p_is_faulted = is_faulted self.device.__p_is_ok = is_ok + self.device.__p_is_healthy = is_healthy self.device.__p_enable_afc = enable_afc self.device.__p_disable_afc = disable_afc @@ -156,7 +165,7 @@ local function peri_init(iface) return { type = self.type, - dev = self.device + dev = self.device } end diff --git a/supervisor/startup.lua b/supervisor/startup.lua index 0949573..d3f2d81 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -20,7 +20,7 @@ local supervisor = require("supervisor.supervisor") local svsessions = require("supervisor.session.svsessions") -local SUPERVISOR_VERSION = "v0.17.9" +local SUPERVISOR_VERSION = "v0.17.10" local println = util.println local println_ts = util.println_ts From ffac6996ed2935a25447e31e6ed817e23306075b Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Fri, 23 Jun 2023 13:52:24 -0400 Subject: [PATCH 23/34] #51 PLC changes for new networking --- reactor-plc/plc.lua | 32 +++++++++----------------------- reactor-plc/startup.lua | 31 ++++++++++++++++++------------- reactor-plc/threads.lua | 25 ++++++++++++------------- 3 files changed, 39 insertions(+), 49 deletions(-) diff --git a/reactor-plc/plc.lua b/reactor-plc/plc.lua index fc41f80..d2991ae 100644 --- a/reactor-plc/plc.lua +++ b/reactor-plc/plc.lua @@ -445,14 +445,14 @@ end ---@nodiscard ---@param id integer reactor ID ---@param version string PLC version ----@param modem table modem device +---@param nic nic network interface device ---@param plc_channel integer PLC comms channel ---@param svr_channel integer supervisor server channel ---@param range integer trusted device connection range ---@param reactor table reactor device ---@param rps rps RPS reference ---@param conn_watchdog watchdog watchdog reference -function plc.comms(id, version, modem, plc_channel, svr_channel, range, reactor, rps, conn_watchdog) +function plc.comms(id, version, nic, plc_channel, svr_channel, range, reactor, rps, conn_watchdog) local self = { sv_addr = comms.BROADCAST, seq_num = 0, @@ -470,13 +470,9 @@ function plc.comms(id, version, modem, plc_channel, svr_channel, range, reactor, -- PRIVATE FUNCTIONS -- - -- configure modem channels - local function _conf_channels() - modem.closeAll() - modem.open(plc_channel) - end - - _conf_channels() + -- configure network channels + nic.closeAll() + nic.open(plc_channel) -- send an RPLC packet ---@param msg_type RPLC_TYPE @@ -488,7 +484,7 @@ function plc.comms(id, version, modem, plc_channel, svr_channel, range, reactor, r_pkt.make(id, msg_type, msg) s_pkt.make(self.sv_addr, self.seq_num, PROTOCOL.RPLC, r_pkt.raw_sendable()) - modem.transmit(svr_channel, plc_channel, s_pkt.raw_sendable()) + nic.transmit(svr_channel, plc_channel, s_pkt) self.seq_num = self.seq_num + 1 end @@ -502,7 +498,7 @@ function plc.comms(id, version, modem, plc_channel, svr_channel, range, reactor, m_pkt.make(msg_type, msg) s_pkt.make(self.sv_addr, self.seq_num, PROTOCOL.SCADA_MGMT, m_pkt.raw_sendable()) - modem.transmit(svr_channel, plc_channel, s_pkt.raw_sendable()) + nic.transmit(svr_channel, plc_channel, s_pkt) self.seq_num = self.seq_num + 1 end @@ -650,13 +646,6 @@ function plc.comms(id, version, modem, plc_channel, svr_channel, range, reactor, ---@class plc_comms local public = {} - -- reconnect a newly connected modem - ---@param new_modem table - function public.reconnect_modem(new_modem) - modem = new_modem - _conf_channels() - end - -- reconnect a newly connected reactor ---@param new_reactor table function public.reconnect_reactor(new_reactor) @@ -744,12 +733,9 @@ function plc.comms(id, version, modem, plc_channel, svr_channel, range, reactor, ---@return rplc_frame|mgmt_frame|nil packet function public.parse_packet(side, sender, reply_to, message, distance) local pkt = nil - local s_pkt = comms.scada_packet() + local s_pkt = nic.receive(side, sender, reply_to, message, distance) - -- parse packet as generic SCADA packet - s_pkt.receive(side, sender, reply_to, message, distance) - - if s_pkt.is_valid() then + if s_pkt and s_pkt.is_valid() then -- get as RPLC packet if s_pkt.protocol() == PROTOCOL.RPLC then local rplc_pkt = comms.rplc_packet() diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index a6a47a6..284008f 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -8,6 +8,7 @@ local comms = require("scada-common.comms") local crash = require("scada-common.crash") local log = require("scada-common.log") local mqueue = require("scada-common.mqueue") +local network = require("scada-common.network") local ppm = require("scada-common.ppm") local rsio = require("scada-common.rsio") local util = require("scada-common.util") @@ -18,7 +19,7 @@ local plc = require("reactor-plc.plc") local renderer = require("reactor-plc.renderer") local threads = require("reactor-plc.threads") -local R_PLC_VERSION = "v1.4.7" +local R_PLC_VERSION = "v1.5.0" local println = util.println local println_ts = util.println_ts @@ -88,13 +89,13 @@ local function main() -- PLC system state flags ---@class plc_state plc_state = { - init_ok = true, - fp_ok = false, - shutdown = false, - degraded = false, + init_ok = true, + fp_ok = false, + shutdown = false, + degraded = true, reactor_formed = true, - no_reactor = false, - no_modem = false + no_reactor = true, + no_modem = true }, -- control setpoints @@ -113,6 +114,7 @@ local function main() -- system objects plc_sys = { rps = nil, ---@type rps + nic = nil, ---@type nic plc_comms = nil, ---@type plc_comms conn_watchdog = nil ---@type watchdog }, @@ -130,14 +132,17 @@ local function main() local plc_state = __shared_memory.plc_state + -- initial state evaluation + plc_state.no_reactor = smem_dev.reactor == nil + plc_state.no_modem = smem_dev.modem == nil + -- we need a reactor, can at least do some things even if it isn't formed though - if smem_dev.reactor == nil then + if plc_state.no_reactor then println("init> fission reactor not found"); log.warning("init> no reactor on startup") plc_state.init_ok = false plc_state.degraded = true - plc_state.no_reactor = true elseif not smem_dev.reactor.isFormed() then println("init> fission reactor not formed"); log.warning("init> reactor logic adapter present, but reactor is not formed") @@ -147,7 +152,7 @@ local function main() end -- modem is required if networked - if __shared_memory.networked and smem_dev.modem == nil then + if __shared_memory.networked and plc_state.no_modem then println("init> wireless modem not found") log.warning("init> no wireless modem on startup") @@ -158,7 +163,6 @@ local function main() plc_state.init_ok = false plc_state.degraded = true - plc_state.no_modem = true end -- print a log message to the terminal as long as the UI isn't running @@ -196,8 +200,9 @@ local function main() smem_sys.conn_watchdog = util.new_watchdog(config.COMMS_TIMEOUT) log.debug("init> conn watchdog started") - -- start comms - smem_sys.plc_comms = plc.comms(config.REACTOR_ID, R_PLC_VERSION, smem_dev.modem, config.PLC_CHANNEL, config.SVR_CHANNEL, + -- init network interface then start comms + smem_sys.nic = network.nic(smem_dev.modem) + smem_sys.plc_comms = plc.comms(config.REACTOR_ID, R_PLC_VERSION, smem_sys.nic, config.PLC_CHANNEL, config.SVR_CHANNEL, config.TRUSTED_RANGE, smem_dev.reactor, smem_sys.rps, smem_sys.conn_watchdog) log.debug("init> comms init") else diff --git a/reactor-plc/threads.lua b/reactor-plc/threads.lua index b9c986d..17f6661 100644 --- a/reactor-plc/threads.lua +++ b/reactor-plc/threads.lua @@ -59,6 +59,7 @@ function threads.thread__main(smem, init) while true do -- get plc_sys fields (may have been set late due to degraded boot) local rps = smem.plc_sys.rps + local nic = smem.plc_sys.nic local plc_comms = smem.plc_sys.plc_comms local conn_watchdog = smem.plc_sys.conn_watchdog @@ -66,6 +67,7 @@ function threads.thread__main(smem, init) -- handle event if event == "timer" and loop_clock.is_clock(param1) then + -- note: loop clock is only running if init_ok = true -- blink heartbeat indicator databus.heartbeat() @@ -75,7 +77,7 @@ function threads.thread__main(smem, init) loop_clock.start() -- send updated data - if not plc_state.no_modem then + if not nic.connected() then if plc_comms.is_linked() then smem.q.mq_comms_tx.push_command(MQ__COMM_CMD.SEND_STATUS) else @@ -114,7 +116,7 @@ function threads.thread__main(smem, init) smem.q.mq_rps.push_command(MQ__RPS_CMD.SCRAM) -- determine if we are still in a degraded state - if not networked or not plc_state.no_modem then + if (not networked) or nic.connected() then plc_state.degraded = false end @@ -144,7 +146,7 @@ function threads.thread__main(smem, init) -- update indicators databus.tx_hw_status(plc_state) - elseif event == "modem_message" and networked and plc_state.init_ok and not plc_state.no_modem then + elseif event == "modem_message" and networked and plc_state.init_ok and nic.connected() then -- got a packet local packet = plc_comms.parse_packet(param1, param2, param3, param4, param5) if packet ~= nil then @@ -171,7 +173,9 @@ function threads.thread__main(smem, init) plc_state.degraded = true elseif networked and type == "modem" then -- we only care if this is our wireless modem - if device == plc_dev.modem then + if nic.is_modem(device) then + nic.disconnect() + println_ts("comms modem disconnected!") log.error("comms modem disconnected") @@ -199,12 +203,11 @@ function threads.thread__main(smem, init) if type == "fissionReactorLogicAdapter" then -- reconnected reactor plc_dev.reactor = device + plc_state.no_reactor = false println_ts("reactor reconnected.") log.info("reactor reconnected") - plc_state.no_reactor = false - -- we need to assume formed here as we cannot check in this main loop -- RPS will identify if it isn't and this will get set false later plc_state.reactor_formed = true @@ -230,14 +233,12 @@ function threads.thread__main(smem, init) if device.isWireless() then -- reconnected modem plc_dev.modem = device + plc_state.no_modem = false - if plc_state.init_ok then - plc_comms.reconnect_modem(plc_dev.modem) - end + if plc_state.init_ok then nic.connect(device) end println_ts("wireless modem reconnected.") log.info("comms modem reconnected") - plc_state.no_modem = false -- determine if we are still in a degraded state if not plc_state.no_reactor then @@ -709,9 +710,7 @@ function threads.thread__setpoint_control(smem) end -- if ramping completed or was aborted, reset last burn setpoint so that if it is requested again it will be re-attempted - if not setpoints.burn_rate_en then - last_burn_sp = 0 - end + if not setpoints.burn_rate_en then last_burn_sp = 0 end end -- check for termination request From 9073009eb02b6c096e84111f861708ef7474d5bb Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Fri, 23 Jun 2023 14:12:41 -0400 Subject: [PATCH 24/34] #51 usage of nic.receive and some cleanup --- coordinator/coordinator.lua | 7 ++----- pocket/pocket.lua | 7 ++----- reactor-plc/plc.lua | 4 ++-- scada-common/network.lua | 18 ++++++++++++------ 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/coordinator/coordinator.lua b/coordinator/coordinator.lua index 59661da..53fda6f 100644 --- a/coordinator/coordinator.lua +++ b/coordinator/coordinator.lua @@ -390,13 +390,10 @@ function coordinator.comms(version, nic, crd_channel, svr_channel, pkt_channel, ---@param distance integer ---@return mgmt_frame|crdn_frame|capi_frame|nil packet function public.parse_packet(side, sender, reply_to, message, distance) + local s_pkt = nic.receive(side, sender, reply_to, message, distance) local pkt = nil - local s_pkt = comms.scada_packet() - -- parse packet as generic SCADA packet - s_pkt.receive(side, sender, reply_to, message, distance) - - if s_pkt.is_valid() then + if s_pkt then -- get as SCADA management packet if s_pkt.protocol() == PROTOCOL.SCADA_MGMT then local mgmt_pkt = comms.mgmt_packet() diff --git a/pocket/pocket.lua b/pocket/pocket.lua index c0b5f77..b0432cf 100644 --- a/pocket/pocket.lua +++ b/pocket/pocket.lua @@ -178,13 +178,10 @@ function pocket.comms(version, nic, pkt_channel, svr_channel, crd_channel, range ---@param distance integer ---@return mgmt_frame|capi_frame|nil packet function public.parse_packet(side, sender, reply_to, message, distance) + local s_pkt = nic.receive(side, sender, reply_to, message, distance) local pkt = nil - local s_pkt = comms.scada_packet() - -- parse packet as generic SCADA packet - s_pkt.receive(side, sender, reply_to, message, distance) - - if s_pkt.is_valid() then + if s_pkt then -- get as SCADA management packet if s_pkt.protocol() == PROTOCOL.SCADA_MGMT then local mgmt_pkt = comms.mgmt_packet() diff --git a/reactor-plc/plc.lua b/reactor-plc/plc.lua index d2991ae..2bba4ee 100644 --- a/reactor-plc/plc.lua +++ b/reactor-plc/plc.lua @@ -732,10 +732,10 @@ function plc.comms(id, version, nic, plc_channel, svr_channel, range, reactor, r ---@param distance integer ---@return rplc_frame|mgmt_frame|nil packet function public.parse_packet(side, sender, reply_to, message, distance) - local pkt = nil local s_pkt = nic.receive(side, sender, reply_to, message, distance) + local pkt = nil - if s_pkt and s_pkt.is_valid() then + if s_pkt then -- get as RPLC packet if s_pkt.protocol() == PROTOCOL.RPLC then local rplc_pkt = comms.rplc_packet() diff --git a/scada-common/network.lua b/scada-common/network.lua index fbc4750..3469413 100644 --- a/scada-common/network.lua +++ b/scada-common/network.lua @@ -73,7 +73,7 @@ end ---@param modem table modem to use function network.nic(modem) local self = { - connected = (modem ~= nil), + connected = true, channels = {} } @@ -92,6 +92,10 @@ function network.nic(modem) ---@field callRemote function local public = {} + -- check if this NIC has a connected modem + ---@nodiscard + function public.connected() return self.connected end + -- connect to a modem peripheral ---@param reconnected_modem table function public.connect(reconnected_modem) @@ -112,18 +116,17 @@ function network.nic(modem) -- flag this NIC as no longer having a connected modem (usually do to peripheral disconnect) function public.disconnect() self.connected = false end - -- check if this NIC has a connected modem - ---@nodiscard - function public.connected() return self.connected end - -- check if a peripheral is this modem ---@nodiscard ---@param device table function public.is_modem(device) return device == modem end - -- wrap modem functions, then create custom transmit + -- wrap modem functions, then create custom functions public.connect(modem) + -- open a channel on the modem
+ -- if disconnected *after* opening, previousy opened channels will be re-opened on reconnection + ---@param channel integer function public.open(channel) if self.connected then modem.open(channel) @@ -142,6 +145,8 @@ function network.nic(modem) end end + -- close a channel on the modem + ---@param channel integer function public.close(channel) if self.connected then modem.close(channel) @@ -154,6 +159,7 @@ function network.nic(modem) end end + -- close all channels on the modem function public.closeAll() if self.connected then modem.closeAll() From 336662de624eb6f75b5c29ca9040b4b39e69cab0 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sun, 25 Jun 2023 12:59:38 -0400 Subject: [PATCH 25/34] #51 nic integration with rtu and supervisor --- coordinator/startup.lua | 2 +- pocket/startup.lua | 2 +- reactor-plc/startup.lua | 2 +- rtu/rtu.lua | 30 ++++++++---------------------- rtu/startup.lua | 29 +++++++++++++---------------- rtu/threads.lua | 9 +++++---- supervisor/session/svsessions.lua | 18 ++++++------------ supervisor/startup.lua | 18 +++++++++++------- supervisor/supervisor.lua | 24 ++++++------------------ 9 files changed, 52 insertions(+), 82 deletions(-) diff --git a/coordinator/startup.lua b/coordinator/startup.lua index ab4f948..d21ec63 100644 --- a/coordinator/startup.lua +++ b/coordinator/startup.lua @@ -148,7 +148,7 @@ local function main() conn_watchdog.cancel() log.debug("startup> conn watchdog created") - -- init network interface then start comms + -- create network interface then setup comms local nic = network.nic(modem) local coord_comms = coordinator.comms(COORDINATOR_VERSION, nic, config.CRD_CHANNEL, config.SVR_CHANNEL, config.PKT_CHANNEL, config.TRUSTED_RANGE, conn_watchdog) diff --git a/pocket/startup.lua b/pocket/startup.lua index 7f08dd4..29fdcb7 100644 --- a/pocket/startup.lua +++ b/pocket/startup.lua @@ -89,7 +89,7 @@ local function main() log.debug("startup> conn watchdogs created") - -- init network interface then start comms + -- create network interface then setup comms local nic = network.nic(modem) local pocket_comms = pocket.comms(POCKET_VERSION, nic, config.PKT_CHANNEL, config.SVR_CHANNEL, config.CRD_CHANNEL, config.TRUSTED_RANGE, conn_wd.sv, conn_wd.api) diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 284008f..31dc600 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -200,7 +200,7 @@ local function main() smem_sys.conn_watchdog = util.new_watchdog(config.COMMS_TIMEOUT) log.debug("init> conn watchdog started") - -- init network interface then start comms + -- create network interface then setup comms smem_sys.nic = network.nic(smem_dev.modem) smem_sys.plc_comms = plc.comms(config.REACTOR_ID, R_PLC_VERSION, smem_sys.nic, config.PLC_CHANNEL, config.SVR_CHANNEL, config.TRUSTED_RANGE, smem_dev.reactor, smem_sys.rps, smem_sys.conn_watchdog) diff --git a/rtu/rtu.lua b/rtu/rtu.lua index 831e231..3832986 100644 --- a/rtu/rtu.lua +++ b/rtu/rtu.lua @@ -158,12 +158,12 @@ end -- RTU Communications ---@nodiscard ---@param version string RTU version ----@param modem table modem device +---@param nic nic network interface device ---@param rtu_channel integer PLC comms channel ---@param svr_channel integer supervisor server channel ---@param range integer trusted device connection range ---@param conn_watchdog watchdog watchdog reference -function rtu.comms(version, modem, rtu_channel, svr_channel, range, conn_watchdog) +function rtu.comms(version, nic, rtu_channel, svr_channel, range, conn_watchdog) local self = { sv_addr = comms.BROADCAST, seq_num = 0, @@ -179,12 +179,8 @@ function rtu.comms(version, modem, rtu_channel, svr_channel, range, conn_watchdo -- PRIVATE FUNCTIONS -- -- configure modem channels - local function _conf_channels() - modem.closeAll() - modem.open(rtu_channel) - end - - _conf_channels() + nic.closeAll() + nic.open(rtu_channel) -- send a scada management packet ---@param msg_type SCADA_MGMT_TYPE @@ -196,7 +192,7 @@ function rtu.comms(version, modem, rtu_channel, svr_channel, range, conn_watchdo m_pkt.make(msg_type, msg) s_pkt.make(self.sv_addr, self.seq_num, PROTOCOL.SCADA_MGMT, m_pkt.raw_sendable()) - modem.transmit(svr_channel, rtu_channel, s_pkt.raw_sendable()) + nic.transmit(svr_channel, rtu_channel, s_pkt) self.seq_num = self.seq_num + 1 end @@ -240,17 +236,10 @@ function rtu.comms(version, modem, rtu_channel, svr_channel, range, conn_watchdo function public.send_modbus(m_pkt) local s_pkt = comms.scada_packet() s_pkt.make(self.sv_addr, self.seq_num, PROTOCOL.MODBUS_TCP, m_pkt.raw_sendable()) - modem.transmit(svr_channel, rtu_channel, s_pkt.raw_sendable()) + nic.transmit(svr_channel, rtu_channel, s_pkt) self.seq_num = self.seq_num + 1 end - -- reconnect a newly connected modem - ---@param new_modem table - function public.reconnect_modem(new_modem) - modem = new_modem - _conf_channels() - end - -- unlink from the server ---@param rtu_state rtu_state function public.unlink(rtu_state) @@ -295,13 +284,10 @@ function rtu.comms(version, modem, rtu_channel, svr_channel, range, conn_watchdo ---@param distance integer ---@return modbus_frame|mgmt_frame|nil packet function public.parse_packet(side, sender, reply_to, message, distance) + local s_pkt = nic.receive(side, sender, reply_to, message, distance) local pkt = nil - local s_pkt = comms.scada_packet() - -- parse packet as generic SCADA packet - s_pkt.receive(side, sender, reply_to, message, distance) - - if s_pkt.is_valid() then + if s_pkt then -- get as MODBUS TCP packet if s_pkt.protocol() == PROTOCOL.MODBUS_TCP then local m_pkt = comms.modbus_packet() diff --git a/rtu/startup.lua b/rtu/startup.lua index 85f3220..085a7b4 100644 --- a/rtu/startup.lua +++ b/rtu/startup.lua @@ -8,6 +8,7 @@ local comms = require("scada-common.comms") local crash = require("scada-common.crash") local log = require("scada-common.log") local mqueue = require("scada-common.mqueue") +local network = require("scada-common.network") local ppm = require("scada-common.ppm") local rsio = require("scada-common.rsio") local types = require("scada-common.types") @@ -28,7 +29,7 @@ local sna_rtu = require("rtu.dev.sna_rtu") local sps_rtu = require("rtu.dev.sps_rtu") local turbinev_rtu = require("rtu.dev.turbinev_rtu") -local RTU_VERSION = "v1.3.7" +local RTU_VERSION = "v1.4.0" local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE @@ -81,6 +82,14 @@ local function main() -- mount connected devices ppm.mount_all() + -- get modem + local modem = ppm.get_wireless_modem() + if modem == nil then + println("boot> wireless modem not found") + log.fatal("no wireless modem on startup") + return + end + ---@class rtu_shared_memory local __shared_memory = { -- RTU system state flags @@ -91,16 +100,12 @@ local function main() shutdown = false }, - -- core RTU devices - rtu_dev = { - modem = ppm.get_wireless_modem() - }, - -- system objects rtu_sys = { + nic = network.nic(modem), rtu_comms = nil, ---@type rtu_comms conn_watchdog = nil, ---@type watchdog - units = {} ---@type table + units = {} }, -- message queues @@ -109,16 +114,8 @@ local function main() } } - local smem_dev = __shared_memory.rtu_dev local smem_sys = __shared_memory.rtu_sys - -- get modem - if smem_dev.modem == nil then - println("boot> wireless modem not found") - log.fatal("no wireless modem on startup") - return - end - databus.tx_hw_modem(true) ---------------------------------------- @@ -471,7 +468,7 @@ local function main() log.debug("startup> conn watchdog started") -- setup comms - smem_sys.rtu_comms = rtu.comms(RTU_VERSION, smem_dev.modem, config.RTU_CHANNEL, config.SVR_CHANNEL, + smem_sys.rtu_comms = rtu.comms(RTU_VERSION, smem_sys.nic, config.RTU_CHANNEL, config.SVR_CHANNEL, config.TRUSTED_RANGE, smem_sys.conn_watchdog) log.debug("startup> comms init") diff --git a/rtu/threads.lua b/rtu/threads.lua index 6d51dec..c27052d 100644 --- a/rtu/threads.lua +++ b/rtu/threads.lua @@ -46,7 +46,7 @@ function threads.thread__main(smem) -- load in from shared memory local rtu_state = smem.rtu_state - local rtu_dev = smem.rtu_dev + local nic = smem.rtu_sys.nic local rtu_comms = smem.rtu_sys.rtu_comms local conn_watchdog = smem.rtu_sys.conn_watchdog local units = smem.rtu_sys.units @@ -93,7 +93,9 @@ function threads.thread__main(smem) if type ~= nil and device ~= nil then if type == "modem" then -- we only care if this is our wireless modem - if device == rtu_dev.modem then + if nic.is_modem(device) then + nic.disconnect() + println_ts("wireless modem disconnected!") log.warning("comms modem disconnected!") @@ -127,8 +129,7 @@ function threads.thread__main(smem) if type == "modem" then if device.isWireless() then -- reconnected modem - rtu_dev.modem = device - rtu_comms.reconnect_modem(rtu_dev.modem) + nic.connect(device) println_ts("wireless modem reconnected.") log.info("comms modem reconnected") diff --git a/supervisor/session/svsessions.lua b/supervisor/session/svsessions.lua index a311ab9..075f090 100644 --- a/supervisor/session/svsessions.lua +++ b/supervisor/session/svsessions.lua @@ -34,7 +34,7 @@ local SESSION_TYPE = { svsessions.SESSION_TYPE = SESSION_TYPE local self = { - modem = nil, ---@type table|nil + nic = nil, ---@type nic|nil fp_ok = false, num_reactors = 0, facility = nil, ---@type facility|nil @@ -60,7 +60,7 @@ local function _sv_handle_outq(session) if msg ~= nil then if msg.qtype == mqueue.TYPE.PACKET then -- handle a packet to be sent - self.modem.transmit(session.r_chan, config.SVR_CHANNEL, msg.message.raw_sendable()) + self.nic.transmit(session.r_chan, config.SVR_CHANNEL, msg.message) elseif msg.qtype == mqueue.TYPE.COMMAND then -- handle instruction/notification elseif msg.qtype == mqueue.TYPE.DATA then @@ -135,7 +135,7 @@ local function _shutdown(session) while session.out_queue.ready() do local msg = session.out_queue.pop() if msg ~= nil and msg.qtype == mqueue.TYPE.PACKET then - self.modem.transmit(session.r_chan, config.SVR_CHANNEL, msg.message.raw_sendable()) + self.nic.transmit(session.r_chan, config.SVR_CHANNEL, msg.message) end end @@ -195,23 +195,17 @@ end -- PUBLIC FUNCTIONS -- -- initialize svsessions ----@param modem table modem device +---@param nic nic network interface device ---@param fp_ok boolean front panel active ---@param num_reactors integer number of reactors ---@param cooling_conf table cooling configuration definition -function svsessions.init(modem, fp_ok, num_reactors, cooling_conf) - self.modem = modem +function svsessions.init(nic, fp_ok, num_reactors, cooling_conf) + self.nic = nic self.fp_ok = fp_ok self.num_reactors = num_reactors self.facility = facility.new(num_reactors, cooling_conf) end --- re-link the modem ----@param modem table -function svsessions.relink_modem(modem) - self.modem = modem -end - -- find an RTU session by the computer ID ---@nodiscard ---@param source_addr integer diff --git a/supervisor/startup.lua b/supervisor/startup.lua index d3f2d81..8fb1897 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -7,6 +7,7 @@ require("/initenv").init_env() local crash = require("scada-common.crash") local comms = require("scada-common.comms") local log = require("scada-common.log") +local network = require("scada-common.network") local ppm = require("scada-common.ppm") local tcd = require("scada-common.tcd") local util = require("scada-common.util") @@ -20,7 +21,7 @@ local supervisor = require("supervisor.supervisor") local svsessions = require("supervisor.session.svsessions") -local SUPERVISOR_VERSION = "v0.17.10" +local SUPERVISOR_VERSION = "v0.18.0" local println = util.println local println_ts = util.println_ts @@ -115,8 +116,9 @@ local function main() println_ts = function (_) end end - -- start comms - local superv_comms = supervisor.comms(SUPERVISOR_VERSION, modem, fp_ok) + -- create network interface then setup comms + local nic = network.nic(modem) + local superv_comms = supervisor.comms(SUPERVISOR_VERSION, nic, fp_ok) -- base loop clock (6.67Hz, 3 ticks) local MAIN_CLOCK = 0.15 @@ -139,9 +141,12 @@ local function main() if type ~= nil and device ~= nil then if type == "modem" then -- we only care if this is our wireless modem - if device == modem then + if nic.is_modem(device) then + nic.disconnect() + println_ts("wireless modem disconnected!") log.warning("comms modem disconnected") + databus.tx_hw_modem(false) else log.warning("non-comms modem disconnected") @@ -153,10 +158,9 @@ local function main() if type ~= nil and device ~= nil then if type == "modem" then - if device.isWireless() then + if device.isWireless() and not nic.connected() then -- reconnected modem - modem = device - superv_comms.reconnect_modem(modem) + nic.connect(device) println_ts("wireless modem reconnected.") log.info("comms modem reconnected") diff --git a/supervisor/supervisor.lua b/supervisor/supervisor.lua index cfc52d8..b9c14ce 100644 --- a/supervisor/supervisor.lua +++ b/supervisor/supervisor.lua @@ -16,10 +16,10 @@ local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE -- supervisory controller communications ---@nodiscard ---@param _version string supervisor version ----@param modem table modem device +---@param nic nic network interface device ---@param fp_ok boolean if the front panel UI is running ---@diagnostic disable-next-line: unused-local -function supervisor.comms(_version, modem, fp_ok) +function supervisor.comms(_version, nic, fp_ok) -- print a log message to the terminal as long as the UI isn't running local function println(message) if not fp_ok then util.println_ts(message) end end @@ -43,15 +43,11 @@ function supervisor.comms(_version, modem, fp_ok) -- PRIVATE FUNCTIONS -- -- configure modem channels - local function _conf_channels() - modem.closeAll() - modem.open(svr_channel) - end - - _conf_channels() + nic.closeAll() + nic.open(svr_channel) -- pass modem, status, and config data to svsessions - svsessions.init(modem, fp_ok, num_reactors, cooling_conf) + svsessions.init(nic, fp_ok, num_reactors, cooling_conf) -- send an establish request response ---@param packet scada_packet @@ -64,7 +60,7 @@ function supervisor.comms(_version, modem, fp_ok) m_pkt.make(SCADA_MGMT_TYPE.ESTABLISH, { ack, data }) s_pkt.make(packet.src_addr(), packet.seq_num() + 1, PROTOCOL.SCADA_MGMT, m_pkt.raw_sendable()) - modem.transmit(packet.remote_channel(), svr_channel, s_pkt.raw_sendable()) + nic.transmit(packet.remote_channel(), svr_channel, s_pkt) self.last_est_acks[packet.src_addr()] = ack end @@ -73,14 +69,6 @@ function supervisor.comms(_version, modem, fp_ok) ---@class superv_comms local public = {} - -- reconnect a newly connected modem - ---@param new_modem table - function public.reconnect_modem(new_modem) - modem = new_modem - svsessions.relink_modem(new_modem) - _conf_channels() - end - -- parse a packet ---@nodiscard ---@param side string From f469754bb73efdac36ae210928c57bed00df7d36 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sun, 25 Jun 2023 13:06:03 -0400 Subject: [PATCH 26/34] #51 network file cleanup --- scada-common/network.lua | 42 ++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/scada-common/network.lua b/scada-common/network.lua index 3469413..5c18eda 100644 --- a/scada-common/network.lua +++ b/scada-common/network.lua @@ -73,7 +73,7 @@ end ---@param modem table modem to use function network.nic(modem) local self = { - connected = true, + connected = true, -- used to avoid costly MAC calculations if modem isn't even present channels = {} } @@ -128,43 +128,39 @@ function network.nic(modem) -- if disconnected *after* opening, previousy opened channels will be re-opened on reconnection ---@param channel integer function public.open(channel) - if self.connected then - modem.open(channel) + modem.open(channel) - local already_open = false - for i = 1, #self.channels do - if self.channels[i] == channel then - already_open = true - break - end + local already_open = false + for i = 1, #self.channels do + if self.channels[i] == channel then + already_open = true + break end + end - if not already_open then - table.insert(self.channels, channel) - end + if not already_open then + table.insert(self.channels, channel) end end -- close a channel on the modem ---@param channel integer function public.close(channel) - if self.connected then - modem.close(channel) - for i = 1, #self.channels do - if self.channels[i] == channel then - table.remove(self.channels, i) - return - end + modem.close(channel) + + for i = 1, #self.channels do + if self.channels[i] == channel then + table.remove(self.channels, i) + return end end end -- close all channels on the modem function public.closeAll() - if self.connected then - modem.closeAll() - self.channels = {} - end + modem.closeAll() + + self.channels = {} end -- send a packet, with message authentication if configured From 57763702ffe89e53f05ea8d6bb483d5c803e1893 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sun, 25 Jun 2023 14:00:18 -0400 Subject: [PATCH 27/34] #51 init mac component from config key --- coordinator/config.lua | 5 +++++ coordinator/coordinator.lua | 4 +++- coordinator/startup.lua | 7 +++++++ pocket/config.lua | 5 +++++ pocket/startup.lua | 5 +++++ reactor-plc/config.lua | 5 +++++ reactor-plc/startup.lua | 5 +++++ rtu/config.lua | 5 +++++ rtu/startup.lua | 5 +++++ supervisor/config.lua | 5 +++++ supervisor/startup.lua | 6 ++++++ 11 files changed, 56 insertions(+), 1 deletion(-) diff --git a/coordinator/config.lua b/coordinator/config.lua index ecb7599..860d297 100644 --- a/coordinator/config.lua +++ b/coordinator/config.lua @@ -11,6 +11,11 @@ config.TRUSTED_RANGE = 0 -- time in seconds (>= 2) before assuming a remote device is no longer active config.SV_TIMEOUT = 5 config.API_TIMEOUT = 5 +-- facility authentication key (do NOT use one of your passwords) +-- this enables verifying that messages are authentic +-- all devices on the same network must use the same key +-- message authentication codes require computing a hash on each message, so this can slow things down +-- config.AUTH_KEY = "SCADAfacility123" -- expected number of reactor units, used only to require that number of unit monitors config.NUM_UNITS = 4 diff --git a/coordinator/coordinator.lua b/coordinator/coordinator.lua index 53fda6f..ff81e5d 100644 --- a/coordinator/coordinator.lua +++ b/coordinator/coordinator.lua @@ -183,7 +183,8 @@ local function log_dmesg(message, dmesg_tag, working) GRAPHICS = colors.green, SYSTEM = colors.cyan, BOOT = colors.blue, - COMMS = colors.purple + COMMS = colors.purple, + CRYPTO = colors.yellow } if working then @@ -197,6 +198,7 @@ function coordinator.log_graphics(message) log_dmesg(message, "GRAPHICS") end function coordinator.log_sys(message) log_dmesg(message, "SYSTEM") end function coordinator.log_boot(message) log_dmesg(message, "BOOT") end function coordinator.log_comms(message) log_dmesg(message, "COMMS") end +function coordinator.log_crypto(message) log_dmesg(message, "CRYPTO") end -- log a message for communications connecting, providing access to progress indication control functions ---@nodiscard diff --git a/coordinator/startup.lua b/coordinator/startup.lua index d21ec63..8bbc550 100644 --- a/coordinator/startup.lua +++ b/coordinator/startup.lua @@ -31,6 +31,7 @@ local log_sys = coordinator.log_sys local log_boot = coordinator.log_boot local log_comms = coordinator.log_comms local log_comms_connecting = coordinator.log_comms_connecting +local log_crypto = coordinator.log_crypto ---------------------------------------- -- config validation @@ -132,6 +133,12 @@ local function main() -- setup communications ---------------------------------------- + -- message authentication init + if type(config.AUTH_KEY) == "string" then + local init_time = network.init_mac(config.AUTH_KEY) + log_crypto("HMAC init took " .. init_time .. "ms") + end + -- get the communications modem local modem = ppm.get_wireless_modem() if modem == nil then diff --git a/pocket/config.lua b/pocket/config.lua index 0c35b59..d7ff5f2 100644 --- a/pocket/config.lua +++ b/pocket/config.lua @@ -10,6 +10,11 @@ config.PKT_CHANNEL = 16244 config.TRUSTED_RANGE = 0 -- time in seconds (>= 2) before assuming a remote device is no longer active config.COMMS_TIMEOUT = 5 +-- facility authentication key (do NOT use one of your passwords) +-- this enables verifying that messages are authentic +-- all devices on the same network must use the same key +-- message authentication codes require computing a hash on each message, so this can slow things down +-- config.AUTH_KEY = "SCADAfacility123" -- log path config.LOG_PATH = "/log.txt" diff --git a/pocket/startup.lua b/pocket/startup.lua index 29fdcb7..843686e 100644 --- a/pocket/startup.lua +++ b/pocket/startup.lua @@ -68,6 +68,11 @@ local function main() -- setup communications & clocks ---------------------------------------- + -- message authentication init + if type(config.AUTH_KEY) == "string" then + network.init_mac(config.AUTH_KEY) + end + coreio.report_link_state(coreio.LINK_STATE.UNLINKED) -- get the communications modem diff --git a/reactor-plc/config.lua b/reactor-plc/config.lua index 3462b2c..64eacc4 100644 --- a/reactor-plc/config.lua +++ b/reactor-plc/config.lua @@ -17,6 +17,11 @@ config.PLC_CHANNEL = 16241 config.TRUSTED_RANGE = 0 -- time in seconds (>= 2) before assuming a remote device is no longer active config.COMMS_TIMEOUT = 5 +-- facility authentication key (do NOT use one of your passwords) +-- this enables verifying that messages are authentic +-- all devices on the same network must use the same key +-- message authentication codes require computing a hash on each message, so this can slow things down +-- config.AUTH_KEY = "SCADAfacility123" -- log path config.LOG_PATH = "/log.txt" diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 31dc600..132c7aa 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -80,6 +80,11 @@ local function main() -- mount connected devices ppm.mount_all() + -- message authentication init + if type(config.AUTH_KEY) == "string" then + network.init_mac(config.AUTH_KEY) + end + -- shared memory across threads ---@class plc_shared_memory local __shared_memory = { diff --git a/rtu/config.lua b/rtu/config.lua index 2279759..6f5796e 100644 --- a/rtu/config.lua +++ b/rtu/config.lua @@ -10,6 +10,11 @@ config.RTU_CHANNEL = 16242 config.TRUSTED_RANGE = 0 -- time in seconds (>= 2) before assuming a remote device is no longer active config.COMMS_TIMEOUT = 5 +-- facility authentication key (do NOT use one of your passwords) +-- this enables verifying that messages are authentic +-- all devices on the same network must use the same key +-- message authentication codes require computing a hash on each message, so this can slow things down +-- config.AUTH_KEY = "SCADAfacility123" -- log path config.LOG_PATH = "/log.txt" diff --git a/rtu/startup.lua b/rtu/startup.lua index 085a7b4..9eecace 100644 --- a/rtu/startup.lua +++ b/rtu/startup.lua @@ -82,6 +82,11 @@ local function main() -- mount connected devices ppm.mount_all() + -- message authentication init + if type(config.AUTH_KEY) == "string" then + network.init_mac(config.AUTH_KEY) + end + -- get modem local modem = ppm.get_wireless_modem() if modem == nil then diff --git a/supervisor/config.lua b/supervisor/config.lua index a4a595b..8d247e1 100644 --- a/supervisor/config.lua +++ b/supervisor/config.lua @@ -17,6 +17,11 @@ config.PLC_TIMEOUT = 5 config.RTU_TIMEOUT = 5 config.CRD_TIMEOUT = 5 config.PKT_TIMEOUT = 5 +-- facility authentication key (do NOT use one of your passwords) +-- this enables verifying that messages are authentic +-- all devices on the same network must use the same key +-- message authentication codes require computing a hash on each message, so this can slow things down +-- config.AUTH_KEY = "SCADAfacility123" -- expected number of reactors config.NUM_REACTORS = 4 diff --git a/supervisor/startup.lua b/supervisor/startup.lua index 8fb1897..3dc850e 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -95,6 +95,12 @@ local function main() -- mount connected devices ppm.mount_all() + -- message authentication init + if type(config.AUTH_KEY) == "string" then + network.init_mac(config.AUTH_KEY) + end + + -- get modem local modem = ppm.get_wireless_modem() if modem == nil then println("startup> wireless modem not found") From bfbbfb164bbca4149e8e0fa5993de05e895c1534 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sun, 25 Jun 2023 17:53:02 -0400 Subject: [PATCH 28/34] #51 include versioned lockbox in installer, reduced installer file size --- ccmsi.lua | 439 ++++++++++++++---------------------------- imgen.py | 11 +- install_manifest.json | 2 +- lockbox/init.lua | 2 +- 4 files changed, 156 insertions(+), 298 deletions(-) diff --git a/ccmsi.lua b/ccmsi.lua index f3f74d1..1ce1e88 100644 --- a/ccmsi.lua +++ b/ccmsi.lua @@ -20,7 +20,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. local function println(message) print(tostring(message)) end local function print(message) term.write(tostring(message)) end -local CCMSI_VERSION = "v1.4f" +local CCMSI_VERSION = "v1.5" local install_dir = "/.install-cache" local manifest_path = "https://mikaylafischler.github.io/cc-mek-scada/manifests/" @@ -29,22 +29,88 @@ local repo_path = "http://raw.githubusercontent.com/MikaylaFischler/cc-mek-scada local opts = { ... } local mode = nil local app = nil -local target +local target = nil +local install_manifest = manifest_path .. "main/install_manifest.json" + +local function red() term.setTextColor(colors.red) end +local function orange() term.setTextColor(colors.orange) end +local function yellow() term.setTextColor(colors.yellow) end +local function green() term.setTextColor(colors.green) end +local function blue() term.setTextColor(colors.blue) end +local function white() term.setTextColor(colors.white) end +local function lgray() term.setTextColor(colors.lightGray) end + +-- get command line option in list +local function get_opt(opt, options) + for _, v in pairs(options) do if opt == v then return v end end + return nil +end + +-- ask the user yes or no +local function ask_y_n(question, default) + print(question) + if default == true then print(" (Y/n)? ") else print(" (y/N)? ") end + local response = read() + if response == "" then return default + elseif response == "Y" or response == "y" then return true + elseif response == "N" or response == "n" then return false + else return nil end +end + +-- print out a white + blue text message +local function pkg_message(message, package) white(); print(message .. " "); blue(); println(package); white() end + +-- indicate actions to be taken based on package differences for installs/updates +local function show_pkg_change(name, v_local, v_remote) + if v_local ~= nil then + if v_local ~= v_remote then + print("[" .. name .. "] updating "); blue(); print(v_local); white(); print(" \xbb "); blue(); println(v_local); white() + elseif mode == "install" then + pkg_message("[" .. name .. "] reinstalling", v_local) + end + else + pkg_message("[" .. name .. "] new install of", v_remote) + end +end + +-- read the local manifest file +local function read_local_manifest() + local local_ok = false + local local_manifest = {} + local imfile = fs.open("install_manifest.json", "r") + if imfile ~= nil then + local_ok, local_manifest = pcall(function () return textutils.unserializeJSON(imfile.readAll()) end) + imfile.close() + end + return local_ok, local_manifest +end + +local function get_remote_manifest() + local response, error = http.get(install_manifest) + if response == nil then + orange(); println("failed to get installation manifest from GitHub, cannot update or install") + red(); println("HTTP error: " .. error); white() + return false, {} + end + + local ok, manifest = pcall(function () return textutils.unserializeJSON(response.readAll()) end) + if not ok then + red(); println("error parsing remote installation manifest"); white() + end + + return ok, manifest +end -- record the local installation manifest ----@param manifest table ----@param dependencies table local function write_install_manifest(manifest, dependencies) local versions = {} for key, value in pairs(manifest.versions) do local is_dependency = false for _, dependency in pairs(dependencies) do if (key == "bootloader" and dependency == "system") or key == dependency then - is_dependency = true - break + is_dependency = true; break end end - if key == app or key == "comms" or is_dependency then versions[key] = value end end @@ -55,184 +121,66 @@ local function write_install_manifest(manifest, dependencies) imfile.close() end --- ask the user yes or no ----@nodiscard ----@param question string ----@param default boolean ----@return boolean|nil -local function ask_y_n(question, default) - print(question) - - if default == true then - print(" (Y/n)? ") - else - print(" (y/N)? ") - end - - local response = read(nil, nil) - - if response == "" then - return default - elseif response == "Y" or response == "y" then - return true - elseif response == "N" or response == "n" then - return false - else - return nil - end -end - --- print out a white + blue text message
--- automatically adds a space ----@param message string message ----@param package string dependency/package/version -local function pkg_message(message, package) - term.setTextColor(colors.white) - print(message .. " ") - term.setTextColor(colors.blue) - println(package) - term.setTextColor(colors.white) -end - --- indicate actions to be taken based on package differences for installs/updates ----@param name string package name ----@param v_local string|nil local version ----@param v_remote string remote version -local function show_pkg_change(name, v_local, v_remote) - if v_local ~= nil then - if v_local ~= v_remote then - print("[" .. name .. "] updating ") - term.setTextColor(colors.blue) - print(v_local) - term.setTextColor(colors.white) - print(" \xbb ") - term.setTextColor(colors.blue) - println(v_local) - term.setTextColor(colors.white) - elseif mode == "install" then - pkg_message("[" .. name .. "] reinstalling", v_local) - end - else - pkg_message("[" .. name .. "] new install of", v_remote) - end -end - --- -- get and validate command line options --- println("-- CC Mekanism SCADA Installer " .. CCMSI_VERSION .. " --") if #opts == 0 or opts[1] == "help" then println("usage: ccmsi ") println("") - term.setTextColor(colors.lightGray) + lgray() println(" check - check latest versions avilable") - term.setTextColor(colors.yellow) + yellow() println(" ccmsi check for target") - term.setTextColor(colors.lightGray) + lgray() println(" install - fresh install, overwrites config") println(" update - update files EXCEPT for config/logs") println(" remove - delete files EXCEPT for config/logs") println(" purge - delete files INCLUDING config/logs") - term.setTextColor(colors.white) - println("") - term.setTextColor(colors.lightGray) + white(); println(""); lgray() println(" reactor-plc - reactor PLC firmware") println(" rtu - RTU firmware") println(" supervisor - supervisor server application") println(" coordinator - coordinator application") println(" pocket - pocket application") - term.setTextColor(colors.white) - println("") - term.setTextColor(colors.yellow) + white(); println(""); yellow() println(" second parameter when used with check") - term.setTextColor(colors.lightGray) - println(" main (default) | latest | devel") + lgray(); println(" main (default) | latest | devel"); white() return else - for _, v in pairs({ "check", "install", "update", "remove", "purge" }) do - if opts[1] == v then - mode = v - break - end - end - + mode = get_opt(opts[1], { "check", "install", "update", "remove", "purge" }) if mode == nil then - println("unrecognized mode") + red(); println("Unrecognized mode."); white() return end - for _, v in pairs({ "reactor-plc", "rtu", "supervisor", "coordinator", "pocket" }) do - if opts[2] == v then - app = v - break - end - end - + app = get_opt(opts[2], { "reactor-plc", "rtu", "supervisor", "coordinator", "pocket" }) if app == nil and mode ~= "check" then - println("unrecognized application") + red(); println("Unrecognized application."); white() return end -- determine target if mode == "check" then target = opts[2] else target = opts[3] end if (target ~= "main") and (target ~= "latest") and (target ~= "devel") then + if target ~= "" then yellow(); println("Unknown target, defaulting to 'main'"); white() end target = "main" - println("unknown target, defaulting to 'main'") end + + -- set paths + install_manifest = manifest_path .. target .. "/install_manifest.json" + repo_path = repo_path .. target .. "/" end --- -- run selected mode --- if mode == "check" then - ------------------------- - -- GET REMOTE MANIFEST -- - ------------------------- - - manifest_path = manifest_path .. target .. "/" - local install_manifest = manifest_path .. "install_manifest.json" - - local response, error = http.get(install_manifest) - - if response == nil then - term.setTextColor(colors.orange) - println("failed to get installation manifest from GitHub, cannot update or install") - term.setTextColor(colors.red) - println("HTTP error: " .. error) - term.setTextColor(colors.white) - return - end - - local ok, manifest = pcall(function () return textutils.unserializeJSON(response.readAll()) end) - - if not ok then - term.setTextColor(colors.red) - println("error parsing remote installation manifest") - term.setTextColor(colors.white) - return - end - - ------------------------ - -- GET LOCAL MANIFEST -- - ------------------------ - - local imfile = fs.open("install_manifest.json", "r") - local local_ok = false - local local_manifest = {} - - if imfile ~= nil then - local_ok, local_manifest = pcall(function () return textutils.unserializeJSON(imfile.readAll()) end) - imfile.close() - end + local ok, manifest = get_remote_manifest() + if not ok then return end + local local_ok, local_manifest = read_local_manifest() if not local_ok then - term.setTextColor(colors.yellow) - println("failed to load local installation information") - term.setTextColor(colors.white) - + yellow(); println("failed to load local installation information"); white() local_manifest = { versions = { installer = CCMSI_VERSION } } else local_manifest.versions.installer = CCMSI_VERSION @@ -243,84 +191,35 @@ if mode == "check" then term.setTextColor(colors.purple) print(string.format("%-14s", "[" .. key .. "]")) if key == "installer" or (local_ok and (local_manifest.versions[key] ~= nil)) then - term.setTextColor(colors.blue) - print(local_manifest.versions[key]) + blue(); print(local_manifest.versions[key]) if value ~= local_manifest.versions[key] then - term.setTextColor(colors.white) - print(" (") + white(); print(" (") term.setTextColor(colors.cyan) - print(value) - term.setTextColor(colors.white) - println(" available)") - else - term.setTextColor(colors.green) - println(" (up to date)") - end + print(value); white(); println(" available)") + else green(); println(" (up to date)") end else - term.setTextColor(colors.lightGray) - print("not installed") - term.setTextColor(colors.white) - print(" (latest ") + lgray(); print("not installed"); white(); print(" (latest ") term.setTextColor(colors.cyan) - print(value) - term.setTextColor(colors.white) - println(")") + print(value); white(); println(")") end end elseif mode == "install" or mode == "update" then - ------------------------- - -- GET REMOTE MANIFEST -- - ------------------------- - - repo_path = repo_path .. target .. "/" - manifest_path = manifest_path .. target .. "/" - local install_manifest = manifest_path .. "install_manifest.json" - - local response, error = http.get(install_manifest) - - if response == nil then - term.setTextColor(colors.orange) - println("failed to get installation manifest from GitHub, cannot update or install") - term.setTextColor(colors.red) - println("HTTP error: " .. error) - term.setTextColor(colors.white) - return - end - - local ok, manifest = pcall(function () return textutils.unserializeJSON(response.readAll()) end) - - if not ok then - term.setTextColor(colors.red) - println("error parsing remote installation manifest") - term.setTextColor(colors.white) - end - - ------------------------ - -- GET LOCAL MANIFEST -- - ------------------------ + local ok, manifest = get_remote_manifest() + if not ok then return end local ver = { app = { v_local = nil, v_remote = nil, changed = false }, boot = { v_local = nil, v_remote = nil, changed = false }, comms = { v_local = nil, v_remote = nil, changed = false }, - graphics = { v_local = nil, v_remote = nil, changed = false } + graphics = { v_local = nil, v_remote = nil, changed = false }, + lockbox = { v_local = nil, v_remote = nil, changed = false } } - local imfile = fs.open("install_manifest.json", "r") - local local_ok = false - local local_manifest = {} - - if imfile ~= nil then - local_ok, local_manifest = pcall(function () return textutils.unserializeJSON(imfile.readAll()) end) - imfile.close() - end - -- try to find local versions + local local_ok, local_manifest = read_local_manifest() if not local_ok then if mode == "update" then - term.setTextColor(colors.red) - println("failed to load local installation information, cannot update") - term.setTextColor(colors.white) + red(); println("failed to load local installation information, cannot update"); white() return end else @@ -328,19 +227,16 @@ elseif mode == "install" or mode == "update" then ver.app.v_local = local_manifest.versions[app] ver.comms.v_local = local_manifest.versions.comms ver.graphics.v_local = local_manifest.versions.graphics + ver.lockbox.v_local = local_manifest.versions.lockbox if local_manifest.versions[app] == nil then - term.setTextColor(colors.red) - println("another application is already installed, please purge it before installing a new application") - term.setTextColor(colors.white) + red(); println("another application is already installed, please purge it before installing a new application"); white() return end local_manifest.versions.installer = CCMSI_VERSION if manifest.versions.installer ~= CCMSI_VERSION then - term.setTextColor(colors.yellow) - println("a newer version of the installer is available, consider downloading it") - term.setTextColor(colors.white) + yellow(); println("a newer version of the installer is available, it is recommended to download it"); white() end end @@ -348,14 +244,15 @@ elseif mode == "install" or mode == "update" then ver.app.v_remote = manifest.versions[app] ver.comms.v_remote = manifest.versions.comms ver.graphics.v_remote = manifest.versions.graphics + ver.lockbox.v_remote = manifest.versions.lockbox - term.setTextColor(colors.green) + green() if mode == "install" then println("Installing " .. app .. " files...") elseif mode == "update" then println("Updating " .. app .. " files... (keeping old config.lua)") end - term.setTextColor(colors.white) + white() -- display bootloader version change information show_pkg_change("bootldr", ver.boot.v_local, ver.boot.v_remote) @@ -369,16 +266,17 @@ elseif mode == "install" or mode == "update" then show_pkg_change("comms", ver.comms.v_local, ver.comms.v_remote) ver.comms.changed = ver.comms.v_local ~= ver.comms.v_remote if ver.comms.changed and ver.comms.v_local ~= nil then - print("[comms] ") - term.setTextColor(colors.yellow) - println("other devices on the network will require an update") - term.setTextColor(colors.white) + print("[comms] "); yellow(); println("other devices on the network will require an update"); white() end -- display graphics version change information show_pkg_change("graphics", ver.graphics.v_local, ver.graphics.v_remote) ver.graphics.changed = ver.graphics.v_local ~= ver.graphics.v_remote + -- display lockbox version change information + show_pkg_change("lockbox", ver.lockbox.v_local, ver.lockbox.v_remote) + ver.lockbox.changed = ver.lockbox.v_local ~= ver.lockbox.v_remote + -- ask for confirmation if not ask_y_n("Continue?", false) then return end @@ -405,11 +303,9 @@ elseif mode == "install" or mode == "update" then -- check space constraints if space_available < space_required then single_file_mode = true - term.setTextColor(colors.yellow) - println("WARNING: Insufficient space available for a full download!") - term.setTextColor(colors.white) + yellow(); println("WARNING: Insufficient space available for a full download!"); white() println("Files can be downloaded one by one, so if you are replacing a current install this will not be a problem unless installation fails.") - if mode == "update" then println("If installation still fails, delete this device's log file and try again.") end + if mode == "update" then println("If installation still fails, delete this device's log file or uninstall the app (not purge) and try again.") end if not ask_y_n("Do you wish to continue?", false) then println("Operation cancelled.") return @@ -419,12 +315,11 @@ elseif mode == "install" or mode == "update" then local success = true -- helper function to check if a dependency is unchanged - ---@nodiscard - ---@param dependency string - ---@return boolean local function unchanged(dependency) if dependency == "system" then return not ver.boot.changed elseif dependency == "graphics" then return not ver.graphics.changed + elseif dependency == "lockbox" then return not ver.lockbox.changed + elseif dependency == "common" then return not (ver.app.changed or ver.comms.changed) elseif dependency == app then return not ver.app.changed else return true end end @@ -441,7 +336,7 @@ elseif mode == "install" or mode == "update" then pkg_message("skipping download of unchanged package", dependency) else pkg_message("downloading package", dependency) - term.setTextColor(colors.lightGray) + lgray() local files = file_list[dependency] for _, file in pairs(files) do @@ -449,8 +344,7 @@ elseif mode == "install" or mode == "update" then local dl, err = http.get(repo_path .. file) if dl == nil then - term.setTextColor(colors.red) - println("GET HTTP Error " .. err) + red(); println("GET HTTP Error " .. err) success = false break else @@ -469,7 +363,7 @@ elseif mode == "install" or mode == "update" then pkg_message("skipping install of unchanged package", dependency) else pkg_message("installing package", dependency) - term.setTextColor(colors.lightGray) + lgray() local files = file_list[dependency] for _, file in pairs(files) do @@ -486,23 +380,15 @@ elseif mode == "install" or mode == "update" then fs.delete(install_dir) if success then - -- if we made it here, then none of the file system functions threw exceptions - -- that means everything is OK write_install_manifest(manifest, dependencies) - term.setTextColor(colors.green) + green() if mode == "install" then println("Installation completed successfully.") - else - println("Update completed successfully.") - end + else println("Update completed successfully.") end else if mode == "install" then - term.setTextColor(colors.red) - println("Installation failed.") - else - term.setTextColor(colors.orange) - println("Update failed, existing files unmodified.") - end + red(); println("Installation failed.") + else orange(); println("Update failed, existing files unmodified.") end end else -- go through all files and replace one by one @@ -511,7 +397,7 @@ elseif mode == "install" or mode == "update" then pkg_message("skipping install of unchanged package", dependency) else pkg_message("installing package", dependency) - term.setTextColor(colors.lightGray) + lgray() local files = file_list[dependency] for _, file in pairs(files) do @@ -520,7 +406,7 @@ elseif mode == "install" or mode == "update" then local dl, err = http.get(repo_path .. file) if dl == nil then - println("GET HTTP Error " .. err) + red(); println("GET HTTP Error " .. err) success = false break else @@ -534,51 +420,33 @@ elseif mode == "install" or mode == "update" then end if success then - -- if we made it here, then none of the file system functions threw exceptions - -- that means everything is OK write_install_manifest(manifest, dependencies) - term.setTextColor(colors.green) + green() if mode == "install" then println("Installation completed successfully.") - else - println("Update completed successfully.") - end + else println("Update completed successfully.") end else - term.setTextColor(colors.red) + red() if mode == "install" then println("Installation failed, files may have been skipped.") - else - println("Update failed, files may have been skipped.") - end + else println("Update failed, files may have been skipped.") end end end elseif mode == "remove" or mode == "purge" then - local imfile = fs.open("install_manifest.json", "r") - local ok = false - local manifest = {} - - if imfile ~= nil then - ok, manifest = pcall(function () return textutils.unserializeJSON(imfile.readAll()) end) - imfile.close() - end - + local ok, manifest = read_local_manifest() if not ok then - term.setTextColor(colors.red) - println("error parsing local installation manifest") - term.setTextColor(colors.white) + red(); println("Error parsing local installation manifest."); white() return elseif mode == "remove" and manifest.versions[app] == nil then - term.setTextColor(colors.red) - println(app .. " is not installed") - term.setTextColor(colors.white) + red(); println(app .. " is not installed, cannot remove."); white() return end - term.setTextColor(colors.orange) + orange() if mode == "remove" then - println("removing all " .. app .. " files except for config.lua and log.txt...") + println("Removing all " .. app .. " files except for config and log...") elseif mode == "purge" then - println("purging all " .. app .. " files...") + println("Purging all " .. app .. " files including config and log...") end -- ask for confirmation @@ -590,9 +458,8 @@ elseif mode == "remove" or mode == "purge" then table.insert(dependencies, app) - term.setTextColor(colors.lightGray) - -- delete log file if purging + lgray() if mode == "purge" and fs.exists(config_file) then local log_deleted = pcall(function () local config = require(app .. ".config") @@ -603,11 +470,9 @@ elseif mode == "remove" or mode == "purge" then end) if not log_deleted then - term.setTextColor(colors.red) - println("failed to delete log file") - term.setTextColor(colors.lightGray) ----@diagnostic disable-next-line: undefined-field - os.sleep(1) + red(); println("failed to delete log file") + white(); println("press enter to continue...") + read(); lgray() end end @@ -628,11 +493,7 @@ elseif mode == "remove" or mode == "purge" then local folder = files[1] while true do local dir = fs.getDir(folder) - if dir == "" or dir == ".." then - break - else - folder = dir - end + if dir == "" or dir == ".." then break else folder = dir end end if fs.isDir(folder) then @@ -640,14 +501,11 @@ elseif mode == "remove" or mode == "purge" then println("deleted directory " .. folder) end elseif dependency == app then + -- delete individual subdirectories so we can leave the config for _, folder in pairs(files) do while true do local dir = fs.getDir(folder) - if dir == "" or dir == ".." or dir == app then - break - else - folder = dir - end + if dir == "" or dir == ".." or dir == app then break else folder = dir end end if folder ~= app and fs.isDir(folder) then @@ -665,13 +523,12 @@ elseif mode == "remove" or mode == "purge" then else -- remove all data from versions list to show nothing is installed manifest.versions = {} - imfile = fs.open("install_manifest.json", "w") + local imfile = fs.open("install_manifest.json", "w") imfile.write(textutils.serializeJSON(manifest)) imfile.close() end - term.setTextColor(colors.green) - println("Done!") + green(); println("Done!") end -term.setTextColor(colors.white) +white() diff --git a/imgen.py b/imgen.py index 63f28cf..046fc36 100644 --- a/imgen.py +++ b/imgen.py @@ -50,6 +50,7 @@ def make_manifest(size): "bootloader" : get_version("./startup.lua"), "comms" : get_version("./scada-common/comms.lua", True), "graphics" : get_version("./graphics/core.lua", True), + "lockbox" : get_version("./lockbox/init.lua", True), "reactor-plc" : get_version("./reactor-plc/startup.lua"), "rtu" : get_version("./rtu/startup.lua"), "supervisor" : get_version("./supervisor/startup.lua"), @@ -70,11 +71,11 @@ def make_manifest(size): "pocket" : list_files("./pocket"), }, "depends" : { - "reactor-plc" : [ "system", "common", "graphics" ], - "rtu" : [ "system", "common", "graphics" ], - "supervisor" : [ "system", "common", "graphics" ], - "coordinator" : [ "system", "common", "graphics" ], - "pocket" : [ "system", "common", "graphics" ] + "reactor-plc" : [ "system", "common", "graphics", "lockbox" ], + "rtu" : [ "system", "common", "graphics", "lockbox" ], + "supervisor" : [ "system", "common", "graphics", "lockbox" ], + "coordinator" : [ "system", "common", "graphics", "lockbox" ], + "pocket" : [ "system", "common", "graphics", "lockbox" ] }, "sizes" : { # manifest file estimate diff --git a/install_manifest.json b/install_manifest.json index 7a6c673..88da63c 100644 --- a/install_manifest.json +++ b/install_manifest.json @@ -1 +1 @@ -{"versions": {"installer": "v1.4f", "bootloader": "0.2", "comms": "2.1.0", "graphics": "1.0.0", "reactor-plc": "v1.4.7", "rtu": "v1.3.7", "supervisor": "v0.17.10", "coordinator": "v0.17.1", "pocket": "alpha-v0.5.1"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/tcd.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua", "scada-common/network.lua"], "graphics": ["graphics/element.lua", "graphics/events.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/listbox.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/tabbar.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/digest/md5.lua", "lockbox/mac/hmac.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/renderer.lua", "supervisor/databus.lua", "supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/panel/pgi.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/style.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/panel/components/pdg_entry.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/pocket.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/conn_waiting.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/boiler_page.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common", "graphics"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5496, "system": 1991, "common": 93516, "graphics": 144556, "lockbox": 34900, "reactor-plc": 97317, "rtu": 102353, "supervisor": 315477, "coordinator": 197703, "pocket": 37373}} \ No newline at end of file +{"versions": {"installer": "v1.5", "bootloader": "0.2", "comms": "2.1.0", "graphics": "1.0.0", "lockbox": "1.0", "reactor-plc": "v1.5.0", "rtu": "v1.4.0", "supervisor": "v0.18.0", "coordinator": "v0.17.1", "pocket": "alpha-v0.5.1"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/tcd.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua", "scada-common/network.lua"], "graphics": ["graphics/element.lua", "graphics/events.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/listbox.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/tabbar.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/digest/md5.lua", "lockbox/mac/hmac.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/renderer.lua", "supervisor/databus.lua", "supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/panel/pgi.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/style.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/panel/components/pdg_entry.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/pocket.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/conn_waiting.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/boiler_page.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics", "lockbox"], "rtu": ["system", "common", "graphics", "lockbox"], "supervisor": ["system", "common", "graphics", "lockbox"], "coordinator": ["system", "common", "graphics", "lockbox"], "pocket": ["system", "common", "graphics", "lockbox"]}, "sizes": {"manifest": 5567, "system": 1991, "common": 93645, "graphics": 144556, "lockbox": 34900, "reactor-plc": 97702, "rtu": 102350, "supervisor": 315619, "coordinator": 198291, "pocket": 37736}} \ No newline at end of file diff --git a/lockbox/init.lua b/lockbox/init.lua index 9323451..caee6c0 100644 --- a/lockbox/init.lua +++ b/lockbox/init.lua @@ -1,7 +1,7 @@ local Lockbox = {}; -- cc-mek-scada lockbox version -Lockbox.VERSION = "1.0" +Lockbox.version = "1.0" --[[ package.path = "./?.lua;" From f6b0a49904263bf801bb4327cd6227e158a9555d Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Mon, 26 Jun 2023 14:03:36 -0400 Subject: [PATCH 29/34] added graphics version to crash dump --- scada-common/crash.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scada-common/crash.lua b/scada-common/crash.lua index 8d02728..45a3874 100644 --- a/scada-common/crash.lua +++ b/scada-common/crash.lua @@ -6,6 +6,8 @@ local comms = require("scada-common.comms") local log = require("scada-common.log") local util = require("scada-common.util") +local core = require("graphics.core") + local crash = {} local app = "unknown" @@ -32,6 +34,7 @@ function crash.handler(error) log.info(util.c("APPLICATION: ", app)) log.info(util.c("FIRMWARE VERSION: ", ver)) log.info(util.c("COMMS VERSION: ", comms.version)) + log.info(util.c("GRAPHICS VERSION: ", core.version)) log.info("----------------------------------") log.info(debug.traceback("--- begin debug trace ---", 1)) log.info("--- end debug trace ---") From fb3c7ded06368f24586f381fbe8f769a4f66c40c Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Mon, 26 Jun 2023 20:44:55 -0400 Subject: [PATCH 30/34] updated lockbox benchmark --- test/lockbox_benchmark.lua | 57 ++++++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/test/lockbox_benchmark.lua b/test/lockbox_benchmark.lua index 6bb1c37..9cdfd73 100644 --- a/test/lockbox_benchmark.lua +++ b/test/lockbox_benchmark.lua @@ -100,30 +100,77 @@ local testmsg = "{1,0,42,3,{5,{{},{boilers={},turbines={},rad_mon={},},{TurbineO local n = 1000 ---@diagnostic disable: undefined-field -os.sleep(1) local hash local hmac = HMAC().setBlockSize(64).setDigest(MD5).setKey(keyd).init() +os.sleep(0) start = util.time() for _ = 1, n do hash = hmac.update(Stream.fromHex(testmsg)).finish().asHex(); end util.println("hmac-md5: took " .. (util.time() - start) .. "ms") util.println("hash: " .. hash) - -os.sleep(1) +os.sleep(0) +start = util.time() +for _ = 1, n do + hash = hmac.update(Stream.fromHex(testmsg)).finish().asHex(); +end +util.println("hmac-md5: took " .. (util.time() - start) .. "ms") +os.sleep(0) +start = util.time() +for _ = 1, n do + hash = hmac.update(Stream.fromHex(testmsg)).finish().asHex(); +end +util.println("hmac-md5: took " .. (util.time() - start) .. "ms") +os.sleep(0) +start = util.time() +for _ = 1, n do + hash = hmac.update(Stream.fromHex(testmsg)).finish().asHex(); +end +util.println("hmac-md5: took " .. (util.time() - start) .. "ms") +os.sleep(0) +start = util.time() +for _ = 1, n do + hash = hmac.update(Stream.fromHex(testmsg)).finish().asHex(); +end +util.println("hmac-md5: took " .. (util.time() - start) .. "ms") hmac = HMAC().setBlockSize(64).setDigest(SHA1).setKey(keyd).init() +os.sleep(0) start = util.time() for _ = 1, n do hash = hmac.update(Stream.fromHex(testmsg)).finish().asHex(); end util.println("hmac-sha1: took " .. (util.time() - start) .. "ms") util.println("hash: " .. hash) +os.sleep(0) +start = util.time() +for _ = 1, n do + hash = hmac.update(Stream.fromHex(testmsg)).finish().asHex(); +end +util.println("hmac-sha1: took " .. (util.time() - start) .. "ms") +os.sleep(0) +start = util.time() +for _ = 1, n do + hash = hmac.update(Stream.fromHex(testmsg)).finish().asHex(); +end +util.println("hmac-sha1: took " .. (util.time() - start) .. "ms") +os.sleep(0) +start = util.time() +for _ = 1, n do + hash = hmac.update(Stream.fromHex(testmsg)).finish().asHex(); +end +util.println("hmac-sha1: took " .. (util.time() - start) .. "ms") +os.sleep(0) +start = util.time() +for _ = 1, n do + hash = hmac.update(Stream.fromHex(testmsg)).finish().asHex(); +end +util.println("hmac-sha1: took " .. (util.time() - start) .. "ms") -os.sleep(1) +os.sleep(0) hmac = HMAC().setBlockSize(64).setDigest(SHA2_224).setKey(keyd).init() @@ -134,7 +181,7 @@ end util.println("hmac-sha224: took " .. (util.time() - start) .. "ms") util.println("hash: " .. hash) -os.sleep(1) +os.sleep(0) hmac = HMAC().setBlockSize(64).setDigest(SHA2_256).setKey(keyd).init() From a8071db08eb2345168a90c8f24948e0c321b41c8 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Tue, 27 Jun 2023 18:36:16 -0400 Subject: [PATCH 31/34] #51 send serialized data to properly MAC --- install_manifest.json | 2 +- reactor-plc/threads.lua | 2 +- scada-common/comms.lua | 132 ++++++++++++++++++++++++++++++++------ scada-common/network.lua | 49 ++++++++------ supervisor/supervisor.lua | 7 +- 5 files changed, 144 insertions(+), 48 deletions(-) diff --git a/install_manifest.json b/install_manifest.json index 88da63c..0d4a88f 100644 --- a/install_manifest.json +++ b/install_manifest.json @@ -1 +1 @@ -{"versions": {"installer": "v1.5", "bootloader": "0.2", "comms": "2.1.0", "graphics": "1.0.0", "lockbox": "1.0", "reactor-plc": "v1.5.0", "rtu": "v1.4.0", "supervisor": "v0.18.0", "coordinator": "v0.17.1", "pocket": "alpha-v0.5.1"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/tcd.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua", "scada-common/network.lua"], "graphics": ["graphics/element.lua", "graphics/events.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/listbox.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/tabbar.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/digest/md5.lua", "lockbox/mac/hmac.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/renderer.lua", "supervisor/databus.lua", "supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/panel/pgi.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/style.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/panel/components/pdg_entry.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/pocket.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/conn_waiting.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/boiler_page.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics", "lockbox"], "rtu": ["system", "common", "graphics", "lockbox"], "supervisor": ["system", "common", "graphics", "lockbox"], "coordinator": ["system", "common", "graphics", "lockbox"], "pocket": ["system", "common", "graphics", "lockbox"]}, "sizes": {"manifest": 5567, "system": 1991, "common": 93645, "graphics": 144556, "lockbox": 34900, "reactor-plc": 97702, "rtu": 102350, "supervisor": 315619, "coordinator": 198291, "pocket": 37736}} \ No newline at end of file +{"versions": {"installer": "v1.5", "bootloader": "0.2", "comms": "2.1.0", "graphics": "1.0.0", "lockbox": "1.0", "reactor-plc": "v1.5.0", "rtu": "v1.4.0", "supervisor": "v0.18.0", "coordinator": "v0.17.1", "pocket": "alpha-v0.5.1"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/tcd.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua", "scada-common/network.lua"], "graphics": ["graphics/element.lua", "graphics/events.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/listbox.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/tabbar.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/digest/md5.lua", "lockbox/mac/hmac.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/renderer.lua", "supervisor/databus.lua", "supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/panel/pgi.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/style.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/panel/components/pdg_entry.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/pocket.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/conn_waiting.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/boiler_page.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics", "lockbox"], "rtu": ["system", "common", "graphics", "lockbox"], "supervisor": ["system", "common", "graphics", "lockbox"], "coordinator": ["system", "common", "graphics", "lockbox"], "pocket": ["system", "common", "graphics", "lockbox"]}, "sizes": {"manifest": 5567, "system": 1991, "common": 97110, "graphics": 144556, "lockbox": 34900, "reactor-plc": 97698, "rtu": 102350, "supervisor": 315528, "coordinator": 198291, "pocket": 37736}} \ No newline at end of file diff --git a/reactor-plc/threads.lua b/reactor-plc/threads.lua index 17f6661..cf18963 100644 --- a/reactor-plc/threads.lua +++ b/reactor-plc/threads.lua @@ -77,7 +77,7 @@ function threads.thread__main(smem, init) loop_clock.start() -- send updated data - if not nic.connected() then + if nic.connected() then if plc_comms.is_linked() then smem.q.mq_comms_tx.push_command(MQ__COMM_CMD.SEND_STATUS) else diff --git a/scada-common/comms.lua b/scada-common/comms.lua index 99a3c7c..88e8631 100644 --- a/scada-common/comms.lua +++ b/scada-common/comms.lua @@ -149,7 +149,6 @@ function comms.scada_packet() dest_addr = comms.BROADCAST, seq_num = -1, protocol = PROTOCOL.SCADA_MGMT, - mac = "", length = 0, payload = {} } @@ -170,7 +169,7 @@ function comms.scada_packet() self.protocol = protocol self.length = #payload self.payload = payload - self.raw = { self.src_addr, self.dest_addr, self.seq_num, self.protocol, self.mac, self.payload } + self.raw = { self.src_addr, self.dest_addr, self.seq_num, self.protocol, self.payload } end -- parse in a modem message as a SCADA packet @@ -198,24 +197,22 @@ 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 == 6 then + if #self.raw == 5 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 6 must be a table - if type(self.raw[6]) == "table" then - self.length = #self.raw[6] - self.payload = self.raw[6] + -- element 5 must be a table + if type(self.raw[5]) == "table" then + self.length = #self.raw[5] + self.payload = self.raw[5] 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 @@ -228,7 +225,6 @@ function comms.scada_packet() 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 @@ -236,20 +232,12 @@ function comms.scada_packet() 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 @@ -268,8 +256,6 @@ 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 @@ -277,6 +263,112 @@ function comms.scada_packet() return public end +-- authenticated SCADA packet object +---@nodiscard +function comms.authd_packet() + local self = { + modem_msg_in = nil, ---@type modem_message|nil + valid = false, + raw = {}, + src_addr = comms.BROADCAST, + dest_addr = comms.BROADCAST, + mac = "", + payload = "" + } + + ---@class authd_packet + local public = {} + + -- make an authenticated SCADA packet + ---@param s_packet scada_packet scada packet to authenticate + ---@param mac function message authentication function + function public.make(s_packet, mac) + self.valid = true + self.src_addr = s_packet.src_addr() + self.dest_addr = s_packet.dest_addr() + self.payload = textutils.serialize(s_packet.raw_sendable(), { allow_repetitions = true, compact = true }) + self.mac = mac(self.payload) + self.raw = { self.src_addr, self.dest_addr, self.mac, self.payload } + end + + -- parse in a modem message as an authenticated SCADA packet + ---@param side string modem side + ---@param sender integer sender channel + ---@param reply_to integer reply channel + ---@param message any message body + ---@param distance integer transmission distance + ---@return boolean valid valid message received + function public.receive(side, sender, reply_to, message, distance) + ---@class modem_message + self.modem_msg_in = { + iface = side, + s_channel = sender, + r_channel = reply_to, + msg = message, + dist = distance + } + + self.valid = false + self.raw = self.modem_msg_in.msg + + if (type(max_distance) == "number") and (distance > max_distance) then + -- outside of maximum allowable transmission distance + -- log.debug("comms.authd_packet.receive(): discarding packet with distance " .. distance .. " outside of trusted range") + else + if type(self.raw) == "table" then + if #self.raw == 4 then + self.src_addr = self.raw[1] + self.dest_addr = self.raw[2] + self.mac = self.raw[3] + self.payload = self.raw[4] + else + self.src_addr = nil + self.dest_addr = nil + self.mac = "" + self.payload = "" + end + + -- check if this packet is destined for this device + 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.mac) == "string" and + type(self.payload) == "string" + end + end + + return self.valid + 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.local_channel() return self.modem_msg_in.s_channel end + ---@nodiscard + function public.remote_channel() return self.modem_msg_in.r_channel end + + ---@nodiscard + function public.is_valid() return self.valid end + + ---@nodiscard + function public.src_addr() return self.src_addr end + ---@nodiscard + function public.dest_addr() return self.dest_addr end + ---@nodiscard + function public.mac() return self.mac end + ---@nodiscard + function public.data() return self.payload end + + return public +end + -- MODBUS packet
-- modeled after MODBUS TCP packet ---@nodiscard diff --git a/scada-common/network.lua b/scada-common/network.lua index 5c18eda..f0a96e2 100644 --- a/scada-common/network.lua +++ b/scada-common/network.lua @@ -55,7 +55,7 @@ end ---@nodiscard ---@param message string initial value concatenated with ciphertext local function compute_hmac(message) - local start = util.time_ms() + -- local start = util.time_ms() c_eng.hmac.init() c_eng.hmac.update(stream.fromString(message)) @@ -63,7 +63,7 @@ local function compute_hmac(message) local hash = c_eng.hmac.asHex() - log.debug("compute_hmac(): hmac-md5 = " .. util.strval(hash) .. " (took " .. (util.time_ms() - start) .. "ms)") + -- log.debug("compute_hmac(): hmac-md5 = " .. util.strval(hash) .. " (took " .. (util.time_ms() - start) .. "ms)") return hash end @@ -166,20 +166,22 @@ function network.nic(modem) -- send a packet, with message authentication if configured ---@param dest_channel integer destination channel ---@param local_channel integer local channel - ---@param packet scada_packet packet raw_sendable + ---@param packet scada_packet packet function public.transmit(dest_channel, local_channel, packet) if self.connected then + local tx_packet = packet ---@type authd_packet|scada_packet + if c_eng.hmac ~= nil then - local start = util.time_ms() - local message = textutils.serialize(packet.raw_verifiable(), { allow_repetitions = true, compact = true }) - local computed_hmac = compute_hmac(message) + -- local start = util.time_ms() + tx_packet = comms.authd_packet() - packet.set_mac(computed_hmac) + ---@cast tx_packet authd_packet + tx_packet.make(packet, compute_hmac) - log.debug("crypto.modem.transmit: data processing took " .. (util.time_ms() - start) .. "ms") + -- log.debug("crypto.modem.transmit: data processing took " .. (util.time_ms() - start) .. "ms") end - modem.transmit(dest_channel, local_channel, packet.raw_sendable()) + modem.transmit(dest_channel, local_channel, tx_packet.raw_sendable()) end end @@ -197,25 +199,30 @@ function network.nic(modem) if self.connected then local s_packet = comms.scada_packet() - -- parse packet as generic SCADA packet - s_packet.receive(side, sender, reply_to, message, distance) + if c_eng.hmac ~= nil then + -- parse packet as an authenticated SCADA packet + local a_packet = comms.authd_packet() + a_packet.receive(side, sender, reply_to, message, distance) - if s_packet.is_valid() then - if c_eng.hmac ~= nil then - local start = util.time_ms() - local packet_hmac = s_packet.mac() - local computed_hmac = compute_hmac(textutils.serialize(s_packet.raw_verifiable(), { allow_repetitions = true, compact = true })) + if a_packet.is_valid() then + -- local start = util.time_ms() + local packet_hmac = a_packet.mac() + local msg = a_packet.data() + local computed_hmac = compute_hmac(msg) if packet_hmac == computed_hmac then - log.debug("crypto.modem.receive: HMAC verified in " .. (util.time_ms() - start) .. "ms") - packet = s_packet + -- log.debug("crypto.modem.receive: HMAC verified in " .. (util.time_ms() - start) .. "ms") + s_packet.receive(side, sender, reply_to, textutils.unserialize(msg), distance) else - log.debug("crypto.modem.receive: HMAC failed verification in " .. (util.time_ms() - start) .. "ms") + -- log.debug("crypto.modem.receive: HMAC failed verification in " .. (util.time_ms() - start) .. "ms") end - else - packet = s_packet end + else + -- parse packet as a generic SCADA packet + s_packet.receive(side, sender, reply_to, message, distance) end + + if s_packet.is_valid() then packet = s_packet end end return packet diff --git a/supervisor/supervisor.lua b/supervisor/supervisor.lua index b9c14ce..fb33b06 100644 --- a/supervisor/supervisor.lua +++ b/supervisor/supervisor.lua @@ -78,13 +78,10 @@ function supervisor.comms(_version, nic, fp_ok) ---@param distance integer ---@return modbus_frame|rplc_frame|mgmt_frame|crdn_frame|nil packet function public.parse_packet(side, sender, reply_to, message, distance) + local s_pkt = nic.receive(side, sender, reply_to, message, distance) local pkt = nil - local s_pkt = comms.scada_packet() - -- parse packet as generic SCADA packet - s_pkt.receive(side, sender, reply_to, message, distance) - - if s_pkt.is_valid() then + if s_pkt then -- get as MODBUS TCP packet if s_pkt.protocol() == PROTOCOL.MODBUS_TCP then local m_pkt = comms.modbus_packet() From 8924ba4e991161e03fcea8157a5cbc3531b3cc3f Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Tue, 27 Jun 2023 19:05:51 -0400 Subject: [PATCH 32/34] cleanup and luacheck fixes --- ccmsi.lua | 5 ++--- scada-common/network.lua | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/ccmsi.lua b/ccmsi.lua index 1ce1e88..c2018ac 100644 --- a/ccmsi.lua +++ b/ccmsi.lua @@ -27,9 +27,7 @@ local manifest_path = "https://mikaylafischler.github.io/cc-mek-scada/manifests/ local repo_path = "http://raw.githubusercontent.com/MikaylaFischler/cc-mek-scada/" local opts = { ... } -local mode = nil -local app = nil -local target = nil +local mode, app, target local install_manifest = manifest_path .. "main/install_manifest.json" local function red() term.setTextColor(colors.red) end @@ -85,6 +83,7 @@ local function read_local_manifest() return local_ok, local_manifest end +-- get the manifest from GitHub local function get_remote_manifest() local response, error = http.get(install_manifest) if response == nil then diff --git a/scada-common/network.lua b/scada-common/network.lua index f0a96e2..dbb3e75 100644 --- a/scada-common/network.lua +++ b/scada-common/network.lua @@ -159,7 +159,6 @@ function network.nic(modem) -- close all channels on the modem function public.closeAll() modem.closeAll() - self.channels = {} end From 0e7ea7102ca78f657737188582ac6e9a555698bf Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Tue, 27 Jun 2023 19:08:33 -0400 Subject: [PATCH 33/34] removed extra verbose comment in configs --- coordinator/config.lua | 1 - pocket/config.lua | 1 - reactor-plc/config.lua | 1 - rtu/config.lua | 1 - supervisor/config.lua | 1 - 5 files changed, 5 deletions(-) diff --git a/coordinator/config.lua b/coordinator/config.lua index 860d297..7ea6ea2 100644 --- a/coordinator/config.lua +++ b/coordinator/config.lua @@ -14,7 +14,6 @@ config.API_TIMEOUT = 5 -- facility authentication key (do NOT use one of your passwords) -- this enables verifying that messages are authentic -- all devices on the same network must use the same key --- message authentication codes require computing a hash on each message, so this can slow things down -- config.AUTH_KEY = "SCADAfacility123" -- expected number of reactor units, used only to require that number of unit monitors diff --git a/pocket/config.lua b/pocket/config.lua index d7ff5f2..72625f4 100644 --- a/pocket/config.lua +++ b/pocket/config.lua @@ -13,7 +13,6 @@ config.COMMS_TIMEOUT = 5 -- facility authentication key (do NOT use one of your passwords) -- this enables verifying that messages are authentic -- all devices on the same network must use the same key --- message authentication codes require computing a hash on each message, so this can slow things down -- config.AUTH_KEY = "SCADAfacility123" -- log path diff --git a/reactor-plc/config.lua b/reactor-plc/config.lua index 64eacc4..066ccf6 100644 --- a/reactor-plc/config.lua +++ b/reactor-plc/config.lua @@ -20,7 +20,6 @@ config.COMMS_TIMEOUT = 5 -- facility authentication key (do NOT use one of your passwords) -- this enables verifying that messages are authentic -- all devices on the same network must use the same key --- message authentication codes require computing a hash on each message, so this can slow things down -- config.AUTH_KEY = "SCADAfacility123" -- log path diff --git a/rtu/config.lua b/rtu/config.lua index 6f5796e..a0d3e68 100644 --- a/rtu/config.lua +++ b/rtu/config.lua @@ -13,7 +13,6 @@ config.COMMS_TIMEOUT = 5 -- facility authentication key (do NOT use one of your passwords) -- this enables verifying that messages are authentic -- all devices on the same network must use the same key --- message authentication codes require computing a hash on each message, so this can slow things down -- config.AUTH_KEY = "SCADAfacility123" -- log path diff --git a/supervisor/config.lua b/supervisor/config.lua index 8d247e1..2373f0d 100644 --- a/supervisor/config.lua +++ b/supervisor/config.lua @@ -20,7 +20,6 @@ config.PKT_TIMEOUT = 5 -- facility authentication key (do NOT use one of your passwords) -- this enables verifying that messages are authentic -- all devices on the same network must use the same key --- message authentication codes require computing a hash on each message, so this can slow things down -- config.AUTH_KEY = "SCADAfacility123" -- expected number of reactors From b998634da1e986d82970a136c0ac52e2f1dc9cdd Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Thu, 29 Jun 2023 12:29:30 -0400 Subject: [PATCH 34/34] installer fixes --- ccmsi.lua | 6 +++--- install_manifest.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ccmsi.lua b/ccmsi.lua index c2018ac..6d5e7e8 100644 --- a/ccmsi.lua +++ b/ccmsi.lua @@ -20,7 +20,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. local function println(message) print(tostring(message)) end local function print(message) term.write(tostring(message)) end -local CCMSI_VERSION = "v1.5" +local CCMSI_VERSION = "v1.5a" local install_dir = "/.install-cache" local manifest_path = "https://mikaylafischler.github.io/cc-mek-scada/manifests/" @@ -62,7 +62,7 @@ local function pkg_message(message, package) white(); print(message .. " "); blu local function show_pkg_change(name, v_local, v_remote) if v_local ~= nil then if v_local ~= v_remote then - print("[" .. name .. "] updating "); blue(); print(v_local); white(); print(" \xbb "); blue(); println(v_local); white() + print("[" .. name .. "] updating "); blue(); print(v_local); white(); print(" \xbb "); blue(); println(v_remote); white() elseif mode == "install" then pkg_message("[" .. name .. "] reinstalling", v_local) end @@ -162,7 +162,7 @@ else -- determine target if mode == "check" then target = opts[2] else target = opts[3] end if (target ~= "main") and (target ~= "latest") and (target ~= "devel") then - if target ~= "" then yellow(); println("Unknown target, defaulting to 'main'"); white() end + if (target and target ~= "") then yellow(); println("Unknown target, defaulting to 'main'"); white() end target = "main" end diff --git a/install_manifest.json b/install_manifest.json index 0d4a88f..b93e2b4 100644 --- a/install_manifest.json +++ b/install_manifest.json @@ -1 +1 @@ -{"versions": {"installer": "v1.5", "bootloader": "0.2", "comms": "2.1.0", "graphics": "1.0.0", "lockbox": "1.0", "reactor-plc": "v1.5.0", "rtu": "v1.4.0", "supervisor": "v0.18.0", "coordinator": "v0.17.1", "pocket": "alpha-v0.5.1"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/tcd.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua", "scada-common/network.lua"], "graphics": ["graphics/element.lua", "graphics/events.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/listbox.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/tabbar.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/digest/md5.lua", "lockbox/mac/hmac.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/renderer.lua", "supervisor/databus.lua", "supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/panel/pgi.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/style.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/panel/components/pdg_entry.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/pocket.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/conn_waiting.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/boiler_page.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics", "lockbox"], "rtu": ["system", "common", "graphics", "lockbox"], "supervisor": ["system", "common", "graphics", "lockbox"], "coordinator": ["system", "common", "graphics", "lockbox"], "pocket": ["system", "common", "graphics", "lockbox"]}, "sizes": {"manifest": 5567, "system": 1991, "common": 97110, "graphics": 144556, "lockbox": 34900, "reactor-plc": 97698, "rtu": 102350, "supervisor": 315528, "coordinator": 198291, "pocket": 37736}} \ No newline at end of file +{"versions": {"installer": "v1.5a", "bootloader": "0.2", "comms": "2.1.0", "graphics": "1.0.0", "lockbox": "1.0", "reactor-plc": "v1.5.0", "rtu": "v1.4.0", "supervisor": "v0.18.0", "coordinator": "v0.17.1", "pocket": "alpha-v0.5.1"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/tcd.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua", "scada-common/network.lua"], "graphics": ["graphics/element.lua", "graphics/events.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/listbox.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/tabbar.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/digest/md5.lua", "lockbox/mac/hmac.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/renderer.lua", "supervisor/databus.lua", "supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/panel/pgi.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/style.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/panel/components/pdg_entry.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/pocket.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/conn_waiting.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/boiler_page.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics", "lockbox"], "rtu": ["system", "common", "graphics", "lockbox"], "supervisor": ["system", "common", "graphics", "lockbox"], "coordinator": ["system", "common", "graphics", "lockbox"], "pocket": ["system", "common", "graphics", "lockbox"]}, "sizes": {"manifest": 5568, "system": 1991, "common": 97109, "graphics": 144556, "lockbox": 34900, "reactor-plc": 97595, "rtu": 102247, "supervisor": 315425, "coordinator": 198188, "pocket": 37633}} \ No newline at end of file