From cc81bd57bb7ff94f2d8c6023ae7e4767d03087e6 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Mon, 1 Apr 2024 19:21:05 +0200 Subject: [PATCH 01/30] Simple model of encryption and communication user <-> keystore, 3 assertions all passing --- SPIN-verification/README.md | 15 +++ SPIN-verification/dist_coms.pml | 227 ++++++++++++++++++++++++++++++++ 2 files changed, 242 insertions(+) create mode 100644 SPIN-verification/README.md create mode 100644 SPIN-verification/dist_coms.pml diff --git a/SPIN-verification/README.md b/SPIN-verification/README.md new file mode 100644 index 0000000..7312cad --- /dev/null +++ b/SPIN-verification/README.md @@ -0,0 +1,15 @@ +# A Functional Verification of the KMS in SPIN +Currently models user and keystore interaction where user can encrypt DEKs and request assignment of KEKs from the Keystore. + +Number of DEKs: 2 +Number of KEKs: 2 + +## List of assertions + +**User Receive - assert(temp_key == DEKs[temp_key-1])** +A DEK received is one previously encrypted by the user +**User Receive - assert(temp_e_key.version > encrypted_DEKs[temp_e_key.id-1].version)** +If the same DEK is encrypted several times, the encryption is not identical +**Keystore Encrypt - assert(kek_id == 1 || kek_id == 2)** +Keystore only encrypts if a valid KEK has been included in the request + diff --git a/SPIN-verification/dist_coms.pml b/SPIN-verification/dist_coms.pml new file mode 100644 index 0000000..c6a09c1 --- /dev/null +++ b/SPIN-verification/dist_coms.pml @@ -0,0 +1,227 @@ + +#define NUM_DEKS 2 +#define NUM_KEKS 2 +#define U2K_MAX 3 +#define K2U_MAX 3 +#define K2AC_MAX 3 +#define AC2K_MAX 3 + +typedef Key { /* Unencrypted */ + int id + int version +} + +typedef E_Key { /* Encrypted */ + int id + int version + int ref_id + int ref_version +} + +mtype = {e_DEK, d_DEK, ass_KEK, verify_usr, deny} + +// u: User +// k: Keystore +// ac: Access Control +// { message type, KEY_ID, iteration, KEK_ID, E_KEY-ID, E_KEY-VERSION, E_KEY-REF-ID, E_KEY-REF-V } + +chan u2k = [U2K_MAX] of { mtype, int, int, int, int, int, int, int } // User -> Keystore +chan k2u = [K2U_MAX] of { mtype, int, int, int, int, int, int, int } // Keystore -> User +chan k2ac = [K2AC_MAX] of { mtype, int, int, int, int, int, int, int } // Keystore -> Access Control +chan ac2k = [AC2K_MAX] of { mtype, int, int, int, int, int, int, int } // Access Control -> Keystore + + +init { + + atomic { + run User() + run Keystore() + } + +} + +proctype User() +{ + mtype msg + int temp_key, kek_id, i, iteration = 0 + E_Key temp_e_key + E_Key encrypted_DEKs[NUM_DEKS] + int assigned_KEKs[NUM_KEKS], DEKs[NUM_DEKS] + + for (i in DEKs) { + DEKs[i] = i+1 + } + + for(i in assigned_KEKs) { + assigned_KEKs[i] = -1 + } + + + for (i in encrypted_DEKs) { + encrypted_DEKs[i].version = -1 + encrypted_DEKs[i].id = -1 + } + + Select_state: + + iteration++ + + do + :: goto Receive + :: goto Encrypt + :: goto Decrypt + :: goto Request_KEK + od + + Encrypt: + + if + :: len(u2k) != U2K_MAX -> + do + :: u2k!e_DEK, DEKs[0], iteration, assigned_KEKs[0], -1, -1, -1, -1 -> break + :: u2k!e_DEK, DEKs[0], iteration, assigned_KEKs[1], -1, -1, -1, -1 -> break + :: u2k!e_DEK, DEKs[1], iteration, assigned_KEKs[0], -1, -1, -1, -1 -> break + :: u2k!e_DEK, DEKs[1], iteration, assigned_KEKs[1], -1, -1, -1, -1 -> break + od + :: else -> skip + fi + + goto Select_state + + Receive: + if + :: len(k2u) != 0 -> + k2u?msg, temp_key, i, kek_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_id, temp_e_key.ref_version + if + :: msg == ass_KEK -> + assigned_KEKs[kek_id-1] = kek_id + :: msg == d_DEK -> + assert(temp_key == DEKs[temp_key-1]) + :: msg == deny -> skip + :: msg == e_DEK -> + assert(temp_e_key.version > encrypted_DEKs[temp_e_key.id-1].version) + encrypted_DEKs[temp_e_key.id-1].id = temp_e_key.id + encrypted_DEKs[temp_e_key.id-1].version = temp_e_key.version + encrypted_DEKs[temp_e_key.id-1].ref_id = temp_e_key.ref_id + encrypted_DEKs[temp_e_key.id-1].ref_version = temp_e_key.ref_version + fi + :: else -> skip + fi + + goto Select_state + + Decrypt: + + if + :: len(u2k) != U2K_MAX -> + if + :: encrypted_DEKs[0].id != -1 -> skip + :: encrypted_DEKs[1].id != -1 -> skip + :: else -> skip + fi + :: else -> skip + fi + + goto Select_state + + Request_KEK: + + if + :: len(u2k) != U2K_MAX -> + if + :: assigned_KEKs[0] == -1 -> + u2k!ass_KEK, -1, -1, 1, -1, -1, -1, -1 + :: assigned_KEKs[1] == -1 -> + u2k!ass_KEK, -1, -1, 2, -1, -1, -1, -1 + :: else -> skip + fi + :: else -> skip + fi + + goto Select_state +} + +proctype Keystore() +{ + mtype msg + int dek_id, kek_id, i, dek_1, dek_2, iteration = 0 + Key temp_key + E_Key temp_e_key + + Key KEKs[NUM_KEKS] + + + for(i in KEKs) { + KEKs[i].id = i+1 + KEKs[i].version = 1 + } + + Select_state: + + iteration++ + + do + :: goto Receive + :: goto Rotate + od + + Receive: + if + :: len(u2k) != 0 -> + u2k?msg, dek_id, i, kek_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_id, temp_e_key.ref_version + if + :: msg == e_DEK -> goto Encrypt + :: msg == d_DEK -> skip + :: msg == ass_KEK -> goto Assign_KEK + :: else -> skip + fi + :: else -> skip + fi + + goto Select_state + + Assign_KEK: + + k2u!msg, dek_id, i, kek_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_id, temp_e_key.ref_version + + goto Select_state + + Deny_request: + + k2u!deny, dek_id, i, kek_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_id, temp_e_key.ref_version + + goto Select_state + + Decrypt: + + goto Select_state + + Encrypt: + + if + :: kek_id == -1 -> goto Deny_request + :: else -> skip + fi + + assert(kek_id == 1 || kek_id == 2) + + temp_e_key.id = dek_id + temp_e_key.version = iteration + temp_e_key.ref_id = KEKs[kek_id-1].id + temp_e_key.ref_version = KEKs[kek_id-1].version + + k2u!msg, -1, i, kek_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_id, temp_e_key.ref_version + + goto Select_state + + Rotate: + + goto Select_state + +} + + +proctype AccessControl() +{ + mtype msg +} \ No newline at end of file From 019ad4d2c9df675978744851c38ecfec46ac7917 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Mon, 1 Apr 2024 19:25:49 +0200 Subject: [PATCH 02/30] Changed Markdown --- SPIN-verification/README.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/SPIN-verification/README.md b/SPIN-verification/README.md index 7312cad..b9f1864 100644 --- a/SPIN-verification/README.md +++ b/SPIN-verification/README.md @@ -1,15 +1,17 @@ # A Functional Verification of the KMS in SPIN Currently models user and keystore interaction where user can encrypt DEKs and request assignment of KEKs from the Keystore. -Number of DEKs: 2 +Number of DEKs: 2
Number of KEKs: 2 ## List of assertions -**User Receive - assert(temp_key == DEKs[temp_key-1])** -A DEK received is one previously encrypted by the user -**User Receive - assert(temp_e_key.version > encrypted_DEKs[temp_e_key.id-1].version)** -If the same DEK is encrypted several times, the encryption is not identical -**Keystore Encrypt - assert(kek_id == 1 || kek_id == 2)** -Keystore only encrypts if a valid KEK has been included in the request +**User Receive - assert(temp_key == DEKs[temp_key-1])**
+A DEK received is one previously encrypted by the user
+ +**User Receive - assert(temp_e_key.version > encrypted_DEKs[temp_e_key.id-1].version)**
+If the same DEK is encrypted several times, the encryption is not identical
+ +**Keystore Encrypt - assert(kek_id == 1 || kek_id == 2)**
+Keystore only encrypts if a valid KEK has been included in the request
From 8ad688639df1d0f149a660c97e2fa0c5b52e0e40 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Thu, 4 Apr 2024 15:04:04 +0200 Subject: [PATCH 03/30] Added Access Control Component --- SPIN-verification/README.md | 5 +- SPIN-verification/dist_coms.pml | 251 ++++++++++++++++++++++++++------ 2 files changed, 209 insertions(+), 47 deletions(-) diff --git a/SPIN-verification/README.md b/SPIN-verification/README.md index b9f1864..50557e0 100644 --- a/SPIN-verification/README.md +++ b/SPIN-verification/README.md @@ -12,6 +12,9 @@ A DEK received is one previously encrypted by the user
**User Receive - assert(temp_e_key.version > encrypted_DEKs[temp_e_key.id-1].version)**
If the same DEK is encrypted several times, the encryption is not identical
-**Keystore Encrypt - assert(kek_id == 1 || kek_id == 2)**
+**Keystore Encrypt - assert(kek_id > 0 && kek_id <= NUM_KEKS)**
Keystore only encrypts if a valid KEK has been included in the request
+**Keystore Decrypt - assert(KEKs[kek_id-1].version >= temp_e_key.ref_version)**
+The version of the KEK used in decryption is greater or equal to the one used for encryption
+ diff --git a/SPIN-verification/dist_coms.pml b/SPIN-verification/dist_coms.pml index c6a09c1..45f6bb5 100644 --- a/SPIN-verification/dist_coms.pml +++ b/SPIN-verification/dist_coms.pml @@ -1,11 +1,15 @@ #define NUM_DEKS 2 #define NUM_KEKS 2 +#define NUM_KEYSTORES 1 +#define NUM_USERS 1 #define U2K_MAX 3 #define K2U_MAX 3 #define K2AC_MAX 3 #define AC2K_MAX 3 + + typedef Key { /* Unencrypted */ int id int version @@ -18,17 +22,20 @@ typedef E_Key { /* Encrypted */ int ref_version } -mtype = {e_DEK, d_DEK, ass_KEK, verify_usr, deny} +mtype = { e_DEK, d_DEK, ass_KEK, deny, ack } // u: User // k: Keystore // ac: Access Control -// { message type, KEY_ID, iteration, KEK_ID, E_KEY-ID, E_KEY-VERSION, E_KEY-REF-ID, E_KEY-REF-V } +// { message type, KEY_ID, KEK_ID, E_KEY-ID, E_KEY-VERSION, E_KEY-REF-V, USER-ID } +// KEK_ID shares index to E_KEY-REF-ID in channels to reduce channel width -chan u2k = [U2K_MAX] of { mtype, int, int, int, int, int, int, int } // User -> Keystore -chan k2u = [K2U_MAX] of { mtype, int, int, int, int, int, int, int } // Keystore -> User -chan k2ac = [K2AC_MAX] of { mtype, int, int, int, int, int, int, int } // Keystore -> Access Control -chan ac2k = [AC2K_MAX] of { mtype, int, int, int, int, int, int, int } // Access Control -> Keystore +chan u2k = [U2K_MAX] of { mtype, int, int, int, int, int, int } // User -> Keystore +chan k2u = [K2U_MAX] of { mtype, int, int, int, int, int } // Keystore -> User + +// { message type, DEK_ID, KEK_ID, USER_ID} +chan k2ac = [K2AC_MAX] of { mtype, int, int, int } // Keystore -> Access Control +chan ac2k = [AC2K_MAX] of { mtype } // Access Control -> Keystore init { @@ -36,14 +43,16 @@ init { atomic { run User() run Keystore() + run AccessControl() } } + proctype User() { mtype msg - int temp_key, kek_id, i, iteration = 0 + int temp_key, i, iteration, id = 1 E_Key temp_e_key E_Key encrypted_DEKs[NUM_DEKS] int assigned_KEKs[NUM_KEKS], DEKs[NUM_DEKS] @@ -52,11 +61,6 @@ proctype User() DEKs[i] = i+1 } - for(i in assigned_KEKs) { - assigned_KEKs[i] = -1 - } - - for (i in encrypted_DEKs) { encrypted_DEKs[i].version = -1 encrypted_DEKs[i].id = -1 @@ -65,6 +69,7 @@ proctype User() Select_state: iteration++ + // printf("USER: %d\n", iteration) do :: goto Receive @@ -76,12 +81,12 @@ proctype User() Encrypt: if - :: len(u2k) != U2K_MAX -> + :: len(u2k) < U2K_MAX -> do - :: u2k!e_DEK, DEKs[0], iteration, assigned_KEKs[0], -1, -1, -1, -1 -> break - :: u2k!e_DEK, DEKs[0], iteration, assigned_KEKs[1], -1, -1, -1, -1 -> break - :: u2k!e_DEK, DEKs[1], iteration, assigned_KEKs[0], -1, -1, -1, -1 -> break - :: u2k!e_DEK, DEKs[1], iteration, assigned_KEKs[1], -1, -1, -1, -1 -> break + :: u2k!e_DEK, DEKs[0], assigned_KEKs[0], -1, -1, -1, id -> break + :: u2k!e_DEK, DEKs[0], assigned_KEKs[1], -1, -1, -1, id -> break + :: u2k!e_DEK, DEKs[1], assigned_KEKs[0], -1, -1, -1, id -> break + :: u2k!e_DEK, DEKs[1], assigned_KEKs[1], -1, -1, -1, id -> break od :: else -> skip fi @@ -90,11 +95,12 @@ proctype User() Receive: if - :: len(k2u) != 0 -> - k2u?msg, temp_key, i, kek_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_id, temp_e_key.ref_version + :: len(k2u) > 0 -> + k2u?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version if :: msg == ass_KEK -> - assigned_KEKs[kek_id-1] = kek_id + // KEK.id is stored in temp_e_key.ref_id to simplify channel operation + assigned_KEKs[temp_e_key.ref_id-1] = temp_e_key.ref_id :: msg == d_DEK -> assert(temp_key == DEKs[temp_key-1]) :: msg == deny -> skip @@ -111,12 +117,13 @@ proctype User() goto Select_state Decrypt: - if - :: len(u2k) != U2K_MAX -> + :: len(u2k) < U2K_MAX -> if - :: encrypted_DEKs[0].id != -1 -> skip - :: encrypted_DEKs[1].id != -1 -> skip + :: encrypted_DEKs[0].id != -1 -> + u2k!d_DEK, -1, encrypted_DEKs[0].ref_id, encrypted_DEKs[0].id, encrypted_DEKs[0].version, encrypted_DEKs[0].ref_version, id + :: encrypted_DEKs[1].id != -1 -> + u2k!d_DEK, -1, encrypted_DEKs[1].ref_id, encrypted_DEKs[1].id, encrypted_DEKs[1].version, encrypted_DEKs[1].ref_version, id :: else -> skip fi :: else -> skip @@ -125,14 +132,14 @@ proctype User() goto Select_state Request_KEK: - + if - :: len(u2k) != U2K_MAX -> + :: len(u2k) < U2K_MAX -> if - :: assigned_KEKs[0] == -1 -> - u2k!ass_KEK, -1, -1, 1, -1, -1, -1, -1 - :: assigned_KEKs[1] == -1 -> - u2k!ass_KEK, -1, -1, 2, -1, -1, -1, -1 + :: assigned_KEKs[0] == 0 -> + u2k!ass_KEK, -1, 1, -1, -1, -1, id + :: assigned_KEKs[1] == 0 -> + u2k!ass_KEK, -1, 2, -1, -1, -1, id :: else -> skip fi :: else -> skip @@ -144,7 +151,9 @@ proctype User() proctype Keystore() { mtype msg - int dek_id, kek_id, i, dek_1, dek_2, iteration = 0 + int dek_id, kek_id, i, iteration, user_id + bool decryptable, encryptable + Key temp_key E_Key temp_e_key @@ -159,6 +168,7 @@ proctype Keystore() Select_state: iteration++ + // printf("KEYSTORE: %d\n", iteration) do :: goto Receive @@ -166,12 +176,13 @@ proctype Keystore() od Receive: + if - :: len(u2k) != 0 -> - u2k?msg, dek_id, i, kek_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_id, temp_e_key.ref_version + :: len(u2k) > 0 -> + u2k?msg, dek_id, kek_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, user_id if :: msg == e_DEK -> goto Encrypt - :: msg == d_DEK -> skip + :: msg == d_DEK -> goto Decrypt :: msg == ass_KEK -> goto Assign_KEK :: else -> skip fi @@ -179,38 +190,87 @@ proctype Keystore() fi goto Select_state - + Assign_KEK: - k2u!msg, dek_id, i, kek_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_id, temp_e_key.ref_version - - goto Select_state + k2ac!msg, -1, kek_id, user_id + ac2k?msg + + if + :: msg == deny -> goto Deny_request + :: else -> skip + fi - Deny_request: - - k2u!deny, dek_id, i, kek_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_id, temp_e_key.ref_version + k2u!ass_KEK, -1, KEKs[kek_id-1].id, -1, -1, -1 goto Select_state - + Decrypt: + decryptable = false + + for (i in KEKs) { + if + :: KEKs[i].id == kek_id && KEKs[i].version >= temp_e_key.ref_version -> + decryptable = true + break + :: else -> skip + fi + } + + if + :: !decryptable -> goto Deny_request + :: else -> skip + fi + + assert(KEKs[kek_id-1].version >= temp_e_key.ref_version) + + k2ac!msg, dek_id, kek_id, user_id + ac2k?msg + + if + :: msg == deny -> goto Deny_request + :: else -> skip + fi + + k2u!d_DEK, temp_e_key.id, -1, -1, -1, -1 + goto Select_state Encrypt: - + + encryptable = false + + for (i in KEKs) { + if + :: KEKs[i].id == kek_id -> + encryptable = true + break + :: else -> skip + fi + } + if - :: kek_id == -1 -> goto Deny_request + :: !encryptable -> goto Deny_request :: else -> skip fi - assert(kek_id == 1 || kek_id == 2) + assert(kek_id > 0 && kek_id <= NUM_KEKS) + + k2ac!msg, dek_id, kek_id, user_id + ac2k?msg + + if + :: msg == deny -> goto Deny_request + :: else -> skip + fi temp_e_key.id = dek_id temp_e_key.version = iteration temp_e_key.ref_id = KEKs[kek_id-1].id temp_e_key.ref_version = KEKs[kek_id-1].version - k2u!msg, -1, i, kek_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_id, temp_e_key.ref_version + k2u!e_DEK, -1, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version goto Select_state @@ -218,10 +278,109 @@ proctype Keystore() goto Select_state + Deny_request: + + k2u!deny, -1, -1, -1, -1, -1 + + goto Select_state } +/* + ## Access Control Info ## + + user_x_kek_x_edeks - Relations between users KEKs and encrypted DEKs + + 0 - No relation + 1 - KEK relation exists + 2 - KEK and E_DEK relation exists + + Indexation is a 3d array inside a single array + +*/ + proctype AccessControl() { mtype msg + int dek_id, kek_id, user_id, idx, iteration + + int usr_x_kek_x_edeks[NUM_USERS*NUM_KEKS*NUM_DEKS] + + Select_state: + + iteration++ + + + k2ac?msg, dek_id, kek_id, user_id + // printf("ACCESS CONTROL: %d\n", iteration) + // printf("ACCESS CONTROL MSG: %d\n", msg) + + if + :: msg == ass_KEK -> goto Assign_KEK + :: msg == d_DEK -> goto Decrypt + :: msg == e_DEK -> goto Encrypt + :: else -> goto Deny_request + fi + + goto Select_state + + Assign_KEK: + + idx = (user_id - 1) * (NUM_KEKS*NUM_DEKS) + (kek_id - 1) * NUM_DEKS + + if + :: usr_x_kek_x_edeks[idx] < 1 -> + usr_x_kek_x_edeks[idx] = 1 + :: else -> goto Deny_request + fi + + goto Ack_request + + Decrypt: + + idx = (user_id - 1) * 3 + 2 * (kek_id - 1) + dek_id + + if + :: idx >= 0 && idx < NUM_USERS*NUM_KEKS*NUM_DEKS -> + if + :: usr_x_kek_x_edeks[idx] < 2 -> goto Deny_request + :: else -> skip + fi + :: else -> goto Deny_request + fi + + goto Ack_request + + Encrypt: + + idx = (user_id - 1) * (NUM_KEKS*NUM_DEKS) + (kek_id - 1) * NUM_DEKS + + if + :: idx >= 0 && idx < NUM_USERS*NUM_KEKS*NUM_DEKS -> + if + :: usr_x_kek_x_edeks[idx] < 1 -> goto Deny_request + :: else -> skip + fi + :: else -> goto Deny_request + fi + + idx = idx + dek_id - 1 + usr_x_kek_x_edeks[idx] = 2 + + goto Ack_request + + Ack_request: + + ac2k!ack + + goto Select_state + + Deny_request: + + ac2k!deny + + goto Select_state + + + } \ No newline at end of file From 951bc6d3449d618e8d98683e01db2c63e4cbf5d0 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Thu, 4 Apr 2024 15:06:38 +0200 Subject: [PATCH 04/30] Fixed indexation error in Access Control - Decrypt --- SPIN-verification/dist_coms.pml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SPIN-verification/dist_coms.pml b/SPIN-verification/dist_coms.pml index 45f6bb5..ed2bb69 100644 --- a/SPIN-verification/dist_coms.pml +++ b/SPIN-verification/dist_coms.pml @@ -338,7 +338,7 @@ proctype AccessControl() Decrypt: - idx = (user_id - 1) * 3 + 2 * (kek_id - 1) + dek_id + idx = (user_id - 1) * (NUM_KEKS*NUM_DEKS) + (kek_id - 1) * NUM_DEKS + dek_id if :: idx >= 0 && idx < NUM_USERS*NUM_KEKS*NUM_DEKS -> From 699ff680da505d6bf97f4bd267e70ae515425b37 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Thu, 18 Apr 2024 14:49:35 +0200 Subject: [PATCH 05/30] database component created, support for additional user in the works, one assertion violated atm --- SPIN-verification/README.md | 5 +- SPIN-verification/dist_coms.pml | 574 ++++++++++++++++++++++---------- 2 files changed, 394 insertions(+), 185 deletions(-) diff --git a/SPIN-verification/README.md b/SPIN-verification/README.md index 50557e0..d4082b2 100644 --- a/SPIN-verification/README.md +++ b/SPIN-verification/README.md @@ -1,8 +1,9 @@ # A Functional Verification of the KMS in SPIN Currently models user and keystore interaction where user can encrypt DEKs and request assignment of KEKs from the Keystore. -Number of DEKs: 2
-Number of KEKs: 2 +Number of Users: 1
+Number of DEKs per user: 2
+Number of KEKs: 3 ## List of assertions diff --git a/SPIN-verification/dist_coms.pml b/SPIN-verification/dist_coms.pml index ed2bb69..92761f4 100644 --- a/SPIN-verification/dist_coms.pml +++ b/SPIN-verification/dist_coms.pml @@ -1,14 +1,18 @@ - #define NUM_DEKS 2 -#define NUM_KEKS 2 +#define NUM_KEKS 3 #define NUM_KEYSTORES 1 #define NUM_USERS 1 #define U2K_MAX 3 #define K2U_MAX 3 #define K2AC_MAX 3 #define AC2K_MAX 3 - - +#define K2DB_MAX 3 +#define DB2K_MAX 3 +#define DB2U_MAX 5 +#define ROT_KEK_1 15000 +#define ROT_KEK_2 18000 +#define ROT_KEK_3 25000 +#define CACHE_CLEAR 4000 typedef Key { /* Unencrypted */ int id @@ -22,110 +26,199 @@ typedef E_Key { /* Encrypted */ int ref_version } -mtype = { e_DEK, d_DEK, ass_KEK, deny, ack } +mtype = { e_DEK, d_DEK, re_DEK, ass_KEK, rot_KEK, deny, ack } // u: User // k: Keystore // ac: Access Control + // { message type, KEY_ID, KEK_ID, E_KEY-ID, E_KEY-VERSION, E_KEY-REF-V, USER-ID } // KEK_ID shares index to E_KEY-REF-ID in channels to reduce channel width +chan u12k = [U2K_MAX] of { mtype, int, int, int, int, int, int } // User 1 -> Keystore +chan u22k = [U2K_MAX] of { mtype, int, int, int, int, int, int } // User 2 -> Keystore +chan k2u1 = [K2U_MAX] of { mtype, int, int, int, int, int } // Keystore -> User 1 +chan k2u2 = [K2U_MAX] of { mtype, int, int, int, int, int } // Keystore -> User 2 -chan u2k = [U2K_MAX] of { mtype, int, int, int, int, int, int } // User -> Keystore -chan k2u = [K2U_MAX] of { mtype, int, int, int, int, int } // Keystore -> User - -// { message type, DEK_ID, KEK_ID, USER_ID} -chan k2ac = [K2AC_MAX] of { mtype, int, int, int } // Keystore -> Access Control +// { message type, KEK_ID, USER_ID} +chan k2ac = [K2AC_MAX] of { mtype, int, int } // Keystore -> Access Control chan ac2k = [AC2K_MAX] of { mtype } // Access Control -> Keystore +// { message type, KEK_ID} +chan k2db = [K2DB_MAX] of { mtype, int } // Keystore -> Database +// { message type, id, version, rotation } +chan db2k = [DB2K_MAX] of { mtype, int, int } // Database -> Keystore + +// This channel emulates an external component notifying +// the user when a rotation has taken place +// { message type, kek1, kek2, kek3 } +chan db2u1 = [DB2U_MAX] of { mtype, bool, bool, bool } // Database -> User 1 +chan db2u2 = [DB2U_MAX] of { mtype, bool, bool, bool } // Database -> User 2 + +int iteration +bool clear_cache init { + iteration = 0 + clear_cache = false + atomic { - run User() + run User(1) run Keystore() + run Database() run AccessControl() } } - -proctype User() +proctype User(int id) { mtype msg - int temp_key, i, iteration, id = 1 + int temp_key, i, count + int assigned_KEKs[NUM_KEKS], DEKs[NUM_DEKS] E_Key temp_e_key E_Key encrypted_DEKs[NUM_DEKS] - int assigned_KEKs[NUM_KEKS], DEKs[NUM_DEKS] + bool recrypt_1, recrypt_2, recrypt_3, never_true for (i in DEKs) { DEKs[i] = i+1 } - for (i in encrypted_DEKs) { - encrypted_DEKs[i].version = -1 - encrypted_DEKs[i].id = -1 - } - Select_state: + + if + :: id == 1 -> + if + :: atomic{ db2u1?[msg, recrypt_1, recrypt_2, recrypt_3] -> db2u1?msg, recrypt_1, recrypt_2, recrypt_3 } -> + goto Recrypt + :: else -> skip + fi + :: id == 2 -> + if + :: atomic{ db2u2?[msg, recrypt_1, recrypt_2, recrypt_3] -> db2u1?msg, recrypt_1, recrypt_2, recrypt_3 } -> + goto Recrypt + :: else -> skip + fi + :: else -> never_true = true + fi - iteration++ - // printf("USER: %d\n", iteration) + assert(!never_true) + if + :: id == 1 -> assert(assigned_KEKs[2] == 0) + :: id == 2 -> assert(assigned_KEKs[0] == 0) + fi + do - :: goto Receive - :: goto Encrypt - :: goto Decrypt - :: goto Request_KEK + :: goto Encrypt + :: goto Decrypt + :: goto Request_KEK od Encrypt: - if - :: len(u2k) < U2K_MAX -> - do - :: u2k!e_DEK, DEKs[0], assigned_KEKs[0], -1, -1, -1, id -> break - :: u2k!e_DEK, DEKs[0], assigned_KEKs[1], -1, -1, -1, id -> break - :: u2k!e_DEK, DEKs[1], assigned_KEKs[0], -1, -1, -1, id -> break - :: u2k!e_DEK, DEKs[1], assigned_KEKs[1], -1, -1, -1, id -> break - od - :: else -> skip + do + :: u12k!e_DEK, DEKs[0], assigned_KEKs[0], -1, -1, -1, id -> break + :: u12k!e_DEK, DEKs[0], assigned_KEKs[1], -1, -1, -1, id -> break + :: u12k!e_DEK, DEKs[1], assigned_KEKs[0], -1, -1, -1, id -> break + :: u12k!e_DEK, DEKs[1], assigned_KEKs[1], -1, -1, -1, id -> break + od + + goto Receive + + Decrypt: + + if + :: encrypted_DEKs[0].id != 0 -> + u12k!d_DEK, -1, encrypted_DEKs[0].ref_id, encrypted_DEKs[0].id, encrypted_DEKs[0].version, encrypted_DEKs[0].ref_version, id + :: encrypted_DEKs[1].id != 0 -> + u12k!d_DEK, -1, encrypted_DEKs[1].ref_id, encrypted_DEKs[1].id, encrypted_DEKs[1].version, encrypted_DEKs[1].ref_version, id + :: else -> goto Select_state fi - goto Select_state + goto Receive - Receive: - if - :: len(k2u) > 0 -> - k2u?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version - if - :: msg == ass_KEK -> - // KEK.id is stored in temp_e_key.ref_id to simplify channel operation - assigned_KEKs[temp_e_key.ref_id-1] = temp_e_key.ref_id - :: msg == d_DEK -> - assert(temp_key == DEKs[temp_key-1]) - :: msg == deny -> skip - :: msg == e_DEK -> - assert(temp_e_key.version > encrypted_DEKs[temp_e_key.id-1].version) - encrypted_DEKs[temp_e_key.id-1].id = temp_e_key.id - encrypted_DEKs[temp_e_key.id-1].version = temp_e_key.version - encrypted_DEKs[temp_e_key.id-1].ref_id = temp_e_key.ref_id - encrypted_DEKs[temp_e_key.id-1].ref_version = temp_e_key.ref_version - fi - :: else -> skip + Recrypt: + + if + :: recrypt_1 && assigned_KEKs[0] != 0 && id == 1 -> + i = 0 + for (i in encrypted_DEKs) { + if + :: encrypted_DEKs[i].ref_id == assigned_KEKs[0] -> + u12k!re_DEK, -1, encrypted_DEKs[i].ref_id, encrypted_DEKs[i].id, encrypted_DEKs[i].version, encrypted_DEKs[i].ref_version, id + k2u1?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version + if + :: msg != deny -> + assert(temp_e_key.version > encrypted_DEKs[i].version) + assert(temp_e_key.ref_version > encrypted_DEKs[i].ref_version) + encrypted_DEKs[temp_e_key.id-1].id = temp_e_key.id + encrypted_DEKs[temp_e_key.id-1].version = temp_e_key.version + encrypted_DEKs[temp_e_key.id-1].ref_id = temp_e_key.ref_id + encrypted_DEKs[temp_e_key.id-1].ref_version = temp_e_key.ref_version + :: else -> skip + fi + :: else -> skip + fi + } + recrypt_1 = false + :: else -> skip fi - - goto Select_state - - Decrypt: + if - :: len(u2k) < U2K_MAX -> - if - :: encrypted_DEKs[0].id != -1 -> - u2k!d_DEK, -1, encrypted_DEKs[0].ref_id, encrypted_DEKs[0].id, encrypted_DEKs[0].version, encrypted_DEKs[0].ref_version, id - :: encrypted_DEKs[1].id != -1 -> - u2k!d_DEK, -1, encrypted_DEKs[1].ref_id, encrypted_DEKs[1].id, encrypted_DEKs[1].version, encrypted_DEKs[1].ref_version, id - :: else -> skip - fi + :: recrypt_2 && assigned_KEKs[1] != 0 -> + i = 0 + for (i in encrypted_DEKs) { + if + :: encrypted_DEKs[i].ref_id == assigned_KEKs[1] -> + if + :: id == 1 -> + u12k!re_DEK, -1, encrypted_DEKs[i].ref_id, encrypted_DEKs[i].id, encrypted_DEKs[i].version, encrypted_DEKs[i].ref_version, id + k2u1?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version + :: else -> + u22k!re_DEK, -1, encrypted_DEKs[i].ref_id, encrypted_DEKs[i].id, encrypted_DEKs[i].version, encrypted_DEKs[i].ref_version, id + k2u2?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version + fi + + if + :: msg != deny -> + assert(temp_e_key.version > encrypted_DEKs[i].version) + assert(temp_e_key.ref_version > encrypted_DEKs[i].ref_version) + encrypted_DEKs[temp_e_key.id-1].id = temp_e_key.id + encrypted_DEKs[temp_e_key.id-1].version = temp_e_key.version + encrypted_DEKs[temp_e_key.id-1].ref_id = temp_e_key.ref_id + encrypted_DEKs[temp_e_key.id-1].ref_version = temp_e_key.ref_version + :: else -> skip + fi + :: else -> skip + fi + } + recrypt_2 = false + :: else -> skip + fi + + if + :: recrypt_3 && assigned_KEKs[2] != 0 && id == 2 -> skip + i = 0 + for (i in encrypted_DEKs) { + if + :: encrypted_DEKs[i].ref_id == assigned_KEKs[2] -> + u22k!re_DEK, -1, encrypted_DEKs[i].ref_id, encrypted_DEKs[i].id, encrypted_DEKs[i].version, encrypted_DEKs[i].ref_version, id + k2u2?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version + if + :: msg != deny -> + assert(temp_e_key.version > encrypted_DEKs[i].version) + assert(temp_e_key.ref_version > encrypted_DEKs[i].ref_version) + encrypted_DEKs[temp_e_key.id-1].id = temp_e_key.id + encrypted_DEKs[temp_e_key.id-1].version = temp_e_key.version + encrypted_DEKs[temp_e_key.id-1].ref_id = temp_e_key.ref_id + encrypted_DEKs[temp_e_key.id-1].ref_version = temp_e_key.ref_version + :: else -> skip + fi + :: else -> skip + fi + } + recrypt_3 = false :: else -> skip fi @@ -134,66 +227,94 @@ proctype User() Request_KEK: if - :: len(u2k) < U2K_MAX -> + :: assigned_KEKs[0] == 0 && id == 1 -> + u12k!ass_KEK, -1, id, -1, -1, -1, id + :: assigned_KEKs[1] == 0 -> if - :: assigned_KEKs[0] == 0 -> - u2k!ass_KEK, -1, 1, -1, -1, -1, id - :: assigned_KEKs[1] == 0 -> - u2k!ass_KEK, -1, 2, -1, -1, -1, id - :: else -> skip + :: id == 1 -> u12k!ass_KEK, -1, 2, -1, -1, -1, id + :: id == 2 -> u22k!ass_KEK, -1, 2, -1, -1, -1, id fi - :: else -> skip + :: assigned_KEKs[2] == 0 && id == 2 -> + u22k!ass_KEK, -1, 3, -1, -1, -1, id + :: else -> goto Select_state fi + goto Receive + + Receive: + + if + :: id == 1 -> + k2u1?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version + :: else -> + k2u2?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version + fi + + if + :: msg == ass_KEK -> + // KEK.id is stored in temp_e_key.ref_id to simplify channel operation + assigned_KEKs[temp_e_key.ref_id-1] = temp_e_key.ref_id + :: msg == d_DEK -> + assert(temp_key == DEKs[temp_key-1]) + :: msg == deny -> skip + :: msg == e_DEK -> + assert(temp_e_key.version > encrypted_DEKs[temp_e_key.id-1].version) + encrypted_DEKs[temp_e_key.id-1].id = temp_e_key.id + encrypted_DEKs[temp_e_key.id-1].version = temp_e_key.version + encrypted_DEKs[temp_e_key.id-1].ref_id = temp_e_key.ref_id + encrypted_DEKs[temp_e_key.id-1].ref_version = temp_e_key.ref_version + fi + goto Select_state } proctype Keystore() { mtype msg - int dek_id, kek_id, i, iteration, user_id - bool decryptable, encryptable + int dek_id, kek_id, i, user_id, id, version, caser, count + bool valid Key temp_key E_Key temp_e_key - Key KEKs[NUM_KEKS] + Key v_KEKs[NUM_KEKS] - - for(i in KEKs) { - KEKs[i].id = i+1 - KEKs[i].version = 1 - } + Select_state: - - iteration++ - // printf("KEYSTORE: %d\n", iteration) - do - :: goto Receive - :: goto Rotate - od + if // Clear Cache + :: clear_cache -> + i = 0 + for (i in v_KEKs) { + v_KEKs[i].id = 0 -> v_KEKs[i].version = 0 + } + clear_cache = false + :: else -> skip + fi + + goto Receive Receive: if - :: len(u2k) > 0 -> - u2k?msg, dek_id, kek_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, user_id - if - :: msg == e_DEK -> goto Encrypt - :: msg == d_DEK -> goto Decrypt - :: msg == ass_KEK -> goto Assign_KEK - :: else -> skip - fi + :: atomic{ u12k?[msg, dek_id, kek_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, user_id] -> + u12k?msg, dek_id, kek_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, user_id } -> + // printf("KEK ID: %d\n", kek_id) + if + :: msg == e_DEK || msg == re_DEK -> goto Encrypt + :: msg == d_DEK -> goto Decrypt + :: msg == ass_KEK -> goto Assign_KEK + :: else -> skip + fi :: else -> skip fi - + goto Select_state - + Assign_KEK: - k2ac!msg, -1, kek_id, user_id + k2ac!msg, kek_id, user_id ac2k?msg if @@ -201,124 +322,231 @@ proctype Keystore() :: else -> skip fi - k2u!ass_KEK, -1, KEKs[kek_id-1].id, -1, -1, -1 + if + :: v_KEKs[kek_id-1].id == 0 -> + k2db!e_DEK, kek_id + db2k?msg, id, version + v_KEKs[kek_id-1].id = id + v_KEKs[kek_id-1].version = version + :: else -> skip + fi + + k2u1!ass_KEK, -1, v_KEKs[kek_id-1].id, -1, -1, -1 goto Select_state Decrypt: - decryptable = false + valid = true + + k2ac!msg, kek_id, user_id + ac2k?msg + + if + :: msg == deny -> goto Deny_request + :: else -> skip + fi - for (i in KEKs) { + d_step { if - :: KEKs[i].id == kek_id && KEKs[i].version >= temp_e_key.ref_version -> - decryptable = true - break - :: else -> skip + :: v_KEKs[kek_id-1].id == 0 -> caser = 1 + :: v_KEKs[kek_id-1].id == kek_id -> caser = 2 + :: else -> caser = 0 -> valid = false fi } - if - :: !decryptable -> goto Deny_request + if + :: caser == 1 -> + k2db!e_DEK, kek_id + db2k?msg, id, version + + if + :: msg != deny -> + v_KEKs[id-1].id = id + v_KEKs[id-1].version = version + if + :: v_KEKs[kek_id-1].version < temp_e_key.ref_version -> valid = false + :: else -> skip + fi + :: else -> valid = false + fi + :: caser == 2 + if + :: v_KEKs[kek_id-1].version >= temp_e_key.ref_version -> + skip + :: else -> + k2db!e_DEK, kek_id + db2k?msg, id, version + + v_KEKs[id-1].version = id + v_KEKs[id-1].version = version + + if + :: v_KEKs[id-1].version < temp_e_key.ref_version -> valid = false + :: else -> skip + fi + fi :: else -> skip fi - assert(KEKs[kek_id-1].version >= temp_e_key.ref_version) + if + :: valid -> skip + :: else -> goto Deny_request + fi - k2ac!msg, dek_id, kek_id, user_id - ac2k?msg + assert(v_KEKs[kek_id-1].version >= temp_e_key.ref_version) + + k2u1!d_DEK, temp_e_key.id, -1, -1, -1, -1 + + goto Select_state + + Encrypt: + + k2ac!msg, kek_id, user_id + ac2k?msg if :: msg == deny -> goto Deny_request :: else -> skip fi - k2u!d_DEK, temp_e_key.id, -1, -1, -1, -1 + k2db!e_DEK, kek_id + db2k?msg, id, version + + if + :: msg != deny -> + v_KEKs[id-1].id = id + v_KEKs[id-1].version = version + :: else -> goto Deny_request + fi + assert(kek_id > 0 && kek_id <= NUM_KEKS) + + if + :: msg == re_DEK -> + assert(temp_e_key.ref_version < v_KEKs[kek_id-1].version && temp_e_key.ref_version > v_KEKs[kek_id-1].version-2) + :: else -> temp_e_key.id = dek_id + fi + + temp_e_key.version = iteration + temp_e_key.ref_id = v_KEKs[kek_id-1].id + temp_e_key.ref_version = v_KEKs[kek_id-1].version + + k2u1!e_DEK, -1, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version goto Select_state - Encrypt: + Deny_request: + + k2u1!deny, -1, -1, -1, -1, -1 - encryptable = false + goto Select_state +} - for (i in KEKs) { - if - :: KEKs[i].id == kek_id -> - encryptable = true - break - :: else -> skip - fi - } +proctype Database() { - if - :: !encryptable -> goto Deny_request + mtype msg + int dek_id, kek_id, i, user_id + Key p_KEKs[NUM_KEKS] + + for (i in p_KEKs) { + p_KEKs[i].id = i+1 + p_KEKs[i].version = 1 + } + + Main: + + iteration++ + + if // Cache timer + :: iteration%CACHE_CLEAR == 0 -> + clear_cache = true :: else -> skip fi - assert(kek_id > 0 && kek_id <= NUM_KEKS) + if // Rotation + :: iteration%ROT_KEK_1 == 0 -> + p_KEKs[0].version++ + db2u1!rot_KEK, 1, 0, 0 + // db2u2!rot_KEK, 1, 0, 0 + :: else -> skip + fi - k2ac!msg, dek_id, kek_id, user_id - ac2k?msg - - if - :: msg == deny -> goto Deny_request + if // Rotation + :: iteration%ROT_KEK_2 == 0 -> + p_KEKs[1].version++ + db2u1!rot_KEK, 0, 1, 0 + // db2u2!rot_KEK, 0, 1, 0 :: else -> skip fi - temp_e_key.id = dek_id - temp_e_key.version = iteration - temp_e_key.ref_id = KEKs[kek_id-1].id - temp_e_key.ref_version = KEKs[kek_id-1].version + if // Rotation + :: iteration%ROT_KEK_3 == 0 -> + p_KEKs[2].version++ + db2u1!rot_KEK, 0, 0, 1 + // db2u2!rot_KEK, 0, 0, 1 + :: else -> skip + fi + + if + :: atomic{ k2db?[msg, kek_id] -> k2db?msg, kek_id } -> + if + :: (msg == e_DEK || msg == d_DEK || msg == ass_KEK || msg == re_DEK) -> goto Access_KEK + :: else -> goto Deny_request + fi + :: else -> skip + fi - k2u!e_DEK, -1, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version + goto Main - goto Select_state + Access_KEK: - Rotate: + i = 0 + for (i in p_KEKs) { + if + :: p_KEKs[i].id == kek_id -> + db2k!msg, p_KEKs[i].id, p_KEKs[i].version + goto Main + :: else -> skip + fi + } - goto Select_state + goto Deny_request Deny_request: - - k2u!deny, -1, -1, -1, -1, -1 + + db2k!deny, -1, -1 + + goto Main - goto Select_state } /* ## Access Control Info ## - user_x_kek_x_edeks - Relations between users KEKs and encrypted DEKs + user_x_kek - Relations between users and KEKs 0 - No relation 1 - KEK relation exists - 2 - KEK and E_DEK relation exists - Indexation is a 3d array inside a single array + Indexation is a 2d array inside a single array */ proctype AccessControl() { mtype msg - int dek_id, kek_id, user_id, idx, iteration + int kek_id, user_id, idx - int usr_x_kek_x_edeks[NUM_USERS*NUM_KEKS*NUM_DEKS] + int usr_x_kek[NUM_USERS*NUM_KEKS] Select_state: - - iteration++ - - - k2ac?msg, dek_id, kek_id, user_id - // printf("ACCESS CONTROL: %d\n", iteration) - // printf("ACCESS CONTROL MSG: %d\n", msg) + + k2ac?msg, kek_id, user_id if :: msg == ass_KEK -> goto Assign_KEK - :: msg == d_DEK -> goto Decrypt - :: msg == e_DEK -> goto Encrypt + :: msg == d_DEK || msg == e_DEK || msg == rot_KEK -> goto Authenticate_user :: else -> goto Deny_request fi @@ -326,24 +554,24 @@ proctype AccessControl() Assign_KEK: - idx = (user_id - 1) * (NUM_KEKS*NUM_DEKS) + (kek_id - 1) * NUM_DEKS + idx = (user_id - 1) * NUM_KEKS + (kek_id - 1) if - :: usr_x_kek_x_edeks[idx] < 1 -> - usr_x_kek_x_edeks[idx] = 1 + :: usr_x_kek[idx] < 1 -> + usr_x_kek[idx] = 1 :: else -> goto Deny_request fi goto Ack_request - Decrypt: + Authenticate_user: - idx = (user_id - 1) * (NUM_KEKS*NUM_DEKS) + (kek_id - 1) * NUM_DEKS + dek_id + idx = (user_id - 1) * NUM_KEKS + (kek_id - 1) if - :: idx >= 0 && idx < NUM_USERS*NUM_KEKS*NUM_DEKS -> + :: idx >= 0 && idx < NUM_USERS*NUM_KEKS -> if - :: usr_x_kek_x_edeks[idx] < 2 -> goto Deny_request + :: usr_x_kek[idx] < 1 -> goto Deny_request :: else -> skip fi :: else -> goto Deny_request @@ -351,24 +579,6 @@ proctype AccessControl() goto Ack_request - Encrypt: - - idx = (user_id - 1) * (NUM_KEKS*NUM_DEKS) + (kek_id - 1) * NUM_DEKS - - if - :: idx >= 0 && idx < NUM_USERS*NUM_KEKS*NUM_DEKS -> - if - :: usr_x_kek_x_edeks[idx] < 1 -> goto Deny_request - :: else -> skip - fi - :: else -> goto Deny_request - fi - - idx = idx + dek_id - 1 - usr_x_kek_x_edeks[idx] = 2 - - goto Ack_request - Ack_request: ac2k!ack @@ -381,6 +591,4 @@ proctype AccessControl() goto Select_state - - } \ No newline at end of file From 648295b4a2f95ff20b790c1460a2a8ff8bda39e9 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Thu, 18 Apr 2024 14:59:26 +0200 Subject: [PATCH 06/30] assertion violation fixed --- SPIN-verification/dist_coms.pml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/SPIN-verification/dist_coms.pml b/SPIN-verification/dist_coms.pml index 92761f4..c07a8f4 100644 --- a/SPIN-verification/dist_coms.pml +++ b/SPIN-verification/dist_coms.pml @@ -54,12 +54,12 @@ chan db2k = [DB2K_MAX] of { mtype, int, int } // Database -> Keystore chan db2u1 = [DB2U_MAX] of { mtype, bool, bool, bool } // Database -> User 1 chan db2u2 = [DB2U_MAX] of { mtype, bool, bool, bool } // Database -> User 2 -int iteration +int timer bool clear_cache init { - iteration = 0 + timer = 0 clear_cache = false atomic { @@ -300,7 +300,6 @@ proctype Keystore() if :: atomic{ u12k?[msg, dek_id, kek_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, user_id] -> u12k?msg, dek_id, kek_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, user_id } -> - // printf("KEK ID: %d\n", kek_id) if :: msg == e_DEK || msg == re_DEK -> goto Encrypt :: msg == d_DEK -> goto Decrypt @@ -427,7 +426,7 @@ proctype Keystore() :: else -> temp_e_key.id = dek_id fi - temp_e_key.version = iteration + temp_e_key.version = timer temp_e_key.ref_id = v_KEKs[kek_id-1].id temp_e_key.ref_version = v_KEKs[kek_id-1].version @@ -455,16 +454,16 @@ proctype Database() { Main: - iteration++ + timer++ if // Cache timer - :: iteration%CACHE_CLEAR == 0 -> + :: timer%CACHE_CLEAR == 0 -> clear_cache = true :: else -> skip fi if // Rotation - :: iteration%ROT_KEK_1 == 0 -> + :: timer%ROT_KEK_1 == 0 -> p_KEKs[0].version++ db2u1!rot_KEK, 1, 0, 0 // db2u2!rot_KEK, 1, 0, 0 @@ -472,7 +471,7 @@ proctype Database() { fi if // Rotation - :: iteration%ROT_KEK_2 == 0 -> + :: timer%ROT_KEK_2 == 0 -> p_KEKs[1].version++ db2u1!rot_KEK, 0, 1, 0 // db2u2!rot_KEK, 0, 1, 0 @@ -480,7 +479,7 @@ proctype Database() { fi if // Rotation - :: iteration%ROT_KEK_3 == 0 -> + :: timer%ROT_KEK_3 == 0 -> p_KEKs[2].version++ db2u1!rot_KEK, 0, 0, 1 // db2u2!rot_KEK, 0, 0, 1 @@ -504,6 +503,7 @@ proctype Database() { for (i in p_KEKs) { if :: p_KEKs[i].id == kek_id -> + timer++ db2k!msg, p_KEKs[i].id, p_KEKs[i].version goto Main :: else -> skip From 5abd84ab5cba43ab5e0c122ea05405d819d4cdf1 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Wed, 24 Apr 2024 01:33:59 +0200 Subject: [PATCH 07/30] KMS now delegates KEKs to tenants. Added alternative clock component. Added assigned_to field to keys. Need to delegate assignment next. --- SPIN-verification/dist_coms.pml | 368 ++++++++++++++++++++++---------- 1 file changed, 261 insertions(+), 107 deletions(-) diff --git a/SPIN-verification/dist_coms.pml b/SPIN-verification/dist_coms.pml index c07a8f4..74f43fc 100644 --- a/SPIN-verification/dist_coms.pml +++ b/SPIN-verification/dist_coms.pml @@ -1,22 +1,26 @@ #define NUM_DEKS 2 -#define NUM_KEKS 3 +#define NUM_KEKS 4 #define NUM_KEYSTORES 1 #define NUM_USERS 1 #define U2K_MAX 3 -#define K2U_MAX 3 -#define K2AC_MAX 3 -#define AC2K_MAX 3 +#define K2U_MAX 0 +#define K2AC_MAX 0 +#define AC2K_MAX 0 #define K2DB_MAX 3 -#define DB2K_MAX 3 +#define DB2K_MAX 0 #define DB2U_MAX 5 +#define ASS_MAX 2 #define ROT_KEK_1 15000 #define ROT_KEK_2 18000 #define ROT_KEK_3 25000 +#define ROT_KEK_4 24000 #define CACHE_CLEAR 4000 +#define USE_CLOCK false typedef Key { /* Unencrypted */ int id int version + int assigned_to } typedef E_Key { /* Encrypted */ @@ -32,7 +36,7 @@ mtype = { e_DEK, d_DEK, re_DEK, ass_KEK, rot_KEK, deny, ack } // k: Keystore // ac: Access Control -// { message type, KEY_ID, KEK_ID, E_KEY-ID, E_KEY-VERSION, E_KEY-REF-V, USER-ID } +// { message type, DEK_ID, KEK_ID, E_KEY-ID, E_KEY-VERSION, E_KEY-REF-V, USER-ID } // KEK_ID shares index to E_KEY-REF-ID in channels to reduce channel width chan u12k = [U2K_MAX] of { mtype, int, int, int, int, int, int } // User 1 -> Keystore chan u22k = [U2K_MAX] of { mtype, int, int, int, int, int, int } // User 2 -> Keystore @@ -43,18 +47,18 @@ chan k2u2 = [K2U_MAX] of { mtype, int, int, int, int, int } // Keystore -> User chan k2ac = [K2AC_MAX] of { mtype, int, int } // Keystore -> Access Control chan ac2k = [AC2K_MAX] of { mtype } // Access Control -> Keystore -// { message type, KEK_ID} -chan k2db = [K2DB_MAX] of { mtype, int } // Keystore -> Database -// { message type, id, version, rotation } -chan db2k = [DB2K_MAX] of { mtype, int, int } // Database -> Keystore +// { message type, KEK_ID, USER_ID} +chan k2db = [K2DB_MAX] of { mtype, int, int } // Keystore -> Database +// { message type, KEK_ID, KEK_VERSION, KEK_ASS-TO } +chan db2k = [DB2K_MAX] of { mtype, int, int, int } // Database -> Keystore // This channel emulates an external component notifying // the user when a rotation has taken place -// { message type, kek1, kek2, kek3 } -chan db2u1 = [DB2U_MAX] of { mtype, bool, bool, bool } // Database -> User 1 -chan db2u2 = [DB2U_MAX] of { mtype, bool, bool, bool } // Database -> User 2 +// { message type, KEK_ID } +chan db2u1 = [DB2U_MAX] of { mtype, int } // Database -> User 1 +chan db2u2 = [DB2U_MAX] of { mtype, int } // Database -> User 2 -int timer +int timer, rotate_1, rotate_2, rotate_3, rotate_4, commit_1, commit_2, commit_3, commit_4 bool clear_cache init { @@ -67,6 +71,10 @@ init { run Keystore() run Database() run AccessControl() + if + :: USE_CLOCK -> run Clock() + :: else -> skip + fi } } @@ -74,7 +82,7 @@ init { proctype User(int id) { mtype msg - int temp_key, i, count + int temp_key, i, ass_idx, recrypt_idx int assigned_KEKs[NUM_KEKS], DEKs[NUM_DEKS] E_Key temp_e_key E_Key encrypted_DEKs[NUM_DEKS] @@ -89,24 +97,16 @@ proctype User(int id) if :: id == 1 -> if - :: atomic{ db2u1?[msg, recrypt_1, recrypt_2, recrypt_3] -> db2u1?msg, recrypt_1, recrypt_2, recrypt_3 } -> + :: atomic{ db2u1?[msg, recrypt_idx] -> db2u1?msg, recrypt_idx } -> goto Recrypt :: else -> skip fi - :: id == 2 -> + :: else -> if - :: atomic{ db2u2?[msg, recrypt_1, recrypt_2, recrypt_3] -> db2u1?msg, recrypt_1, recrypt_2, recrypt_3 } -> + :: atomic{ db2u2?[msg, recrypt_idx] -> db2u2?msg, recrypt_idx } -> goto Recrypt :: else -> skip fi - :: else -> never_true = true - fi - - assert(!never_true) - - if - :: id == 1 -> assert(assigned_KEKs[2] == 0) - :: id == 2 -> assert(assigned_KEKs[0] == 0) fi do @@ -117,23 +117,44 @@ proctype User(int id) Encrypt: - do - :: u12k!e_DEK, DEKs[0], assigned_KEKs[0], -1, -1, -1, id -> break - :: u12k!e_DEK, DEKs[0], assigned_KEKs[1], -1, -1, -1, id -> break - :: u12k!e_DEK, DEKs[1], assigned_KEKs[0], -1, -1, -1, id -> break - :: u12k!e_DEK, DEKs[1], assigned_KEKs[1], -1, -1, -1, id -> break - od + if + :: id == 1 -> + do + :: u12k!e_DEK, DEKs[0], assigned_KEKs[0], -1, -1, -1, id -> break + :: u12k!e_DEK, DEKs[0], assigned_KEKs[1], -1, -1, -1, id -> break + :: u12k!e_DEK, DEKs[1], assigned_KEKs[0], -1, -1, -1, id -> break + :: u12k!e_DEK, DEKs[1], assigned_KEKs[1], -1, -1, -1, id -> break + od + :: else -> + do + :: u22k!e_DEK, DEKs[0], assigned_KEKs[0], -1, -1, -1, id -> break + :: u22k!e_DEK, DEKs[0], assigned_KEKs[1], -1, -1, -1, id -> break + :: u22k!e_DEK, DEKs[1], assigned_KEKs[0], -1, -1, -1, id -> break + :: u22k!e_DEK, DEKs[1], assigned_KEKs[1], -1, -1, -1, id -> break + od + fi goto Receive Decrypt: - + if - :: encrypted_DEKs[0].id != 0 -> - u12k!d_DEK, -1, encrypted_DEKs[0].ref_id, encrypted_DEKs[0].id, encrypted_DEKs[0].version, encrypted_DEKs[0].ref_version, id - :: encrypted_DEKs[1].id != 0 -> - u12k!d_DEK, -1, encrypted_DEKs[1].ref_id, encrypted_DEKs[1].id, encrypted_DEKs[1].version, encrypted_DEKs[1].ref_version, id - :: else -> goto Select_state + :: id == 1 -> + if + :: encrypted_DEKs[0].id != 0 -> + u12k!d_DEK, -1, encrypted_DEKs[0].ref_id, encrypted_DEKs[0].id, encrypted_DEKs[0].version, encrypted_DEKs[0].ref_version, id + :: encrypted_DEKs[1].id != 0 -> + u12k!d_DEK, -1, encrypted_DEKs[1].ref_id, encrypted_DEKs[1].id, encrypted_DEKs[1].version, encrypted_DEKs[1].ref_version, id + :: else -> goto Select_state + fi + :: else -> + if + :: encrypted_DEKs[0].id != 0 -> + u22k!d_DEK, -1, encrypted_DEKs[0].ref_id, encrypted_DEKs[0].id, encrypted_DEKs[0].version, encrypted_DEKs[0].ref_version, id + :: encrypted_DEKs[1].id != 0 -> + u22k!d_DEK, -1, encrypted_DEKs[1].ref_id, encrypted_DEKs[1].id, encrypted_DEKs[1].version, encrypted_DEKs[1].ref_version, id + :: else -> goto Select_state + fi fi goto Receive @@ -226,17 +247,9 @@ proctype User(int id) Request_KEK: - if - :: assigned_KEKs[0] == 0 && id == 1 -> - u12k!ass_KEK, -1, id, -1, -1, -1, id - :: assigned_KEKs[1] == 0 -> - if - :: id == 1 -> u12k!ass_KEK, -1, 2, -1, -1, -1, id - :: id == 2 -> u22k!ass_KEK, -1, 2, -1, -1, -1, id - fi - :: assigned_KEKs[2] == 0 && id == 2 -> - u22k!ass_KEK, -1, 3, -1, -1, -1, id - :: else -> goto Select_state + if + :: id == 1 -> u12k!ass_KEK, -1, -1, -1, -1, -1, id + :: else -> u22k!ass_KEK, -1, -1, -1, -1, -1, id fi goto Receive @@ -253,7 +266,8 @@ proctype User(int id) if :: msg == ass_KEK -> // KEK.id is stored in temp_e_key.ref_id to simplify channel operation - assigned_KEKs[temp_e_key.ref_id-1] = temp_e_key.ref_id + assigned_KEKs[ass_idx] = temp_e_key.ref_id + ass_idx++ :: msg == d_DEK -> assert(temp_key == DEKs[temp_key-1]) :: msg == deny -> skip @@ -271,23 +285,23 @@ proctype User(int id) proctype Keystore() { mtype msg - int dek_id, kek_id, i, user_id, id, version, caser, count - bool valid + int dek_id, kek_id, kek_ref, i, user_id, id, version, is_case, kek_idx, assigned_to + bool valid, received Key temp_key E_Key temp_e_key Key v_KEKs[NUM_KEKS] - - Select_state: if // Clear Cache :: clear_cache -> i = 0 for (i in v_KEKs) { - v_KEKs[i].id = 0 -> v_KEKs[i].version = 0 + v_KEKs[i].id = 0 + v_KEKs[i].version = 0 + v_KEKs[i].assigned_to = 0 } clear_cache = false :: else -> skip @@ -297,9 +311,22 @@ proctype Keystore() Receive: + received = false + if - :: atomic{ u12k?[msg, dek_id, kek_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, user_id] -> - u12k?msg, dek_id, kek_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, user_id } -> + :: atomic{ u12k?[msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, user_id] -> + u12k?msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, user_id } -> + received = true + kek_id = kek_ref-100 + :: atomic{ u22k?[msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, user_id] -> + u22k?msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, user_id } -> + received = true + kek_id = kek_ref-100 + :: else -> skip + fi + + if + :: received -> if :: msg == e_DEK || msg == re_DEK -> goto Encrypt :: msg == d_DEK -> goto Decrypt @@ -313,7 +340,17 @@ proctype Keystore() Assign_KEK: - k2ac!msg, kek_id, user_id + if + :: v_KEKs[kek_idx].id == 0 -> + k2db!ass_KEK, kek_idx+1, user_id + db2k?msg, id, version, assigned_to + v_KEKs[kek_idx].id = id + v_KEKs[kek_idx].version = version + v_KEKs[kek_idx].assigned_to = assigned_to + k2ac!msg, id, user_id + :: else -> k2ac!msg, v_KEKs[kek_idx], user_id + fi + ac2k?msg if @@ -321,16 +358,13 @@ proctype Keystore() :: else -> skip fi - if - :: v_KEKs[kek_id-1].id == 0 -> - k2db!e_DEK, kek_id - db2k?msg, id, version - v_KEKs[kek_id-1].id = id - v_KEKs[kek_id-1].version = version - :: else -> skip + + if + :: user_id == 1 -> k2u1!ass_KEK, -1, v_KEKs[kek_idx].id+100, -1, -1, -1 + :: else -> k2u2!ass_KEK, -1, v_KEKs[kek_idx].id+100, -1, -1, -1 fi - k2u1!ass_KEK, -1, v_KEKs[kek_id-1].id, -1, -1, -1 + kek_idx++ goto Select_state @@ -348,16 +382,16 @@ proctype Keystore() d_step { if - :: v_KEKs[kek_id-1].id == 0 -> caser = 1 - :: v_KEKs[kek_id-1].id == kek_id -> caser = 2 - :: else -> caser = 0 -> valid = false + :: v_KEKs[kek_id-1].id == 0 -> is_case = 1 + :: v_KEKs[kek_id-1].id == kek_id -> is_case = 2 + :: else -> is_case = 0 -> valid = false fi } if - :: caser == 1 -> - k2db!e_DEK, kek_id - db2k?msg, id, version + :: is_case == 1 -> + k2db!d_DEK, kek_id, user_id + db2k?msg, id, version, assigned_to if :: msg != deny -> @@ -369,13 +403,13 @@ proctype Keystore() fi :: else -> valid = false fi - :: caser == 2 + :: is_case == 2 if :: v_KEKs[kek_id-1].version >= temp_e_key.ref_version -> skip :: else -> - k2db!e_DEK, kek_id - db2k?msg, id, version + k2db!d_DEK, kek_id, user_id + db2k?msg, id, version, assigned_to v_KEKs[id-1].version = id v_KEKs[id-1].version = version @@ -389,12 +423,10 @@ proctype Keystore() fi if - :: valid -> skip + :: valid -> assert(v_KEKs[kek_id-1].version >= temp_e_key.ref_version) :: else -> goto Deny_request fi - assert(v_KEKs[kek_id-1].version >= temp_e_key.ref_version) - k2u1!d_DEK, temp_e_key.id, -1, -1, -1, -1 goto Select_state @@ -409,15 +441,17 @@ proctype Keystore() :: else -> skip fi - k2db!e_DEK, kek_id - db2k?msg, id, version + k2db!e_DEK, kek_id, user_id + db2k?msg, id, version, assigned_to if :: msg != deny -> v_KEKs[id-1].id = id v_KEKs[id-1].version = version + v_KEKs[id-1].assigned_to = assigned_to :: else -> goto Deny_request fi + assert(kek_id > 0 && kek_id <= NUM_KEKS) if @@ -427,7 +461,7 @@ proctype Keystore() fi temp_e_key.version = timer - temp_e_key.ref_id = v_KEKs[kek_id-1].id + temp_e_key.ref_id = v_KEKs[kek_id-1].id+100 temp_e_key.ref_version = v_KEKs[kek_id-1].version k2u1!e_DEK, -1, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version @@ -441,6 +475,15 @@ proctype Keystore() goto Select_state } +/** + In this model, the Database contains a timer that acts as a clock + that sends signals to users when rotation has been executed. + Rotation is not time-sensitive such that it is affected by + distributed clock-sync issues, so it could also be seen as a tenant + quering a clock to see if the scheduled rotation that could be part + of the metadata in the KEK information available to the tenant has + taken place. + */ proctype Database() { mtype msg @@ -454,35 +497,82 @@ proctype Database() { Main: - timer++ + if + :: !USE_CLOCK -> timer++ + :: else -> skip + fi if // Cache timer - :: timer%CACHE_CLEAR == 0 -> + :: !USE_CLOCK && timer%CACHE_CLEAR == 0 -> clear_cache = true :: else -> skip fi - if // Rotation - :: timer%ROT_KEK_1 == 0 -> + if // Rotation 1 + :: !USE_CLOCK && timer%ROT_KEK_1 == 0 -> + p_KEKs[0].version++ + + if + :: p_KEKs[0].assigned_to == 1 -> + db2u1!rot_KEK, p_KEKs[0].id+100 + :: else -> + db2u2!rot_KEK, p_KEKs[0].id+100 + fi + :: USE_CLOCK && rotate_1 > 0 -> p_KEKs[0].version++ - db2u1!rot_KEK, 1, 0, 0 - // db2u2!rot_KEK, 1, 0, 0 + rotate_1-- + commit_1++ :: else -> skip fi - if // Rotation - :: timer%ROT_KEK_2 == 0 -> + if // Rotation 2 + :: !USE_CLOCK && timer%ROT_KEK_2 == 0 -> + p_KEKs[1].version++ + + if + :: p_KEKs[1].assigned_to == 1 -> + db2u1!rot_KEK, p_KEKs[1].id+100 + :: else -> + db2u2!rot_KEK, p_KEKs[1].id+100 + fi + :: USE_CLOCK && rotate_2 > 0 -> p_KEKs[1].version++ - db2u1!rot_KEK, 0, 1, 0 - // db2u2!rot_KEK, 0, 1, 0 + rotate_2-- + commit_2++ :: else -> skip fi - if // Rotation - :: timer%ROT_KEK_3 == 0 -> + if // Rotation 3 + :: !USE_CLOCK && timer%ROT_KEK_3 == 0 -> p_KEKs[2].version++ - db2u1!rot_KEK, 0, 0, 1 - // db2u2!rot_KEK, 0, 0, 1 + + if + :: p_KEKs[2].assigned_to == 1 -> + db2u1!rot_KEK, p_KEKs[2].id+100 + :: else -> + db2u2!rot_KEK, p_KEKs[2].id+100 + fi + :: USE_CLOCK && rotate_3 > 0 -> + p_KEKs[2].version++ + rotate_3-- + commit_3++ + :: else -> skip + fi + + if // Rotation 4 + :: !USE_CLOCK && timer%ROT_KEK_4 == 0 -> + p_KEKs[3].version++ + + if + :: p_KEKs[3].assigned_to == 1 -> + db2u1!rot_KEK, p_KEKs[3].id+100 + :: else -> + db2u2!rot_KEK, p_KEKs[3].id+100 + fi + :: USE_CLOCK && rotate_4 > 0 -> + p_KEKs[3].version++ + rotate_4-- + commit_4++ :: else -> skip fi @@ -503,9 +593,14 @@ proctype Database() { for (i in p_KEKs) { if :: p_KEKs[i].id == kek_id -> - timer++ - db2k!msg, p_KEKs[i].id, p_KEKs[i].version + if + :: !USE_CLOCK -> timer++ + :: else -> skip + fi + db2k!msg, p_KEKs[i].id, p_KEKs[i].version, p_KEKs[i].assigned_to + goto Main + :: else -> skip fi } @@ -514,7 +609,7 @@ proctype Database() { Deny_request: - db2k!deny, -1, -1 + db2k!deny, -1, -1, -1 goto Main @@ -536,7 +631,7 @@ proctype Database() { proctype AccessControl() { mtype msg - int kek_id, user_id, idx + int kek_id, user_id, idx, i, num_assigned int usr_x_kek[NUM_USERS*NUM_KEKS] @@ -546,7 +641,7 @@ proctype AccessControl() if :: msg == ass_KEK -> goto Assign_KEK - :: msg == d_DEK || msg == e_DEK || msg == rot_KEK -> goto Authenticate_user + :: msg == d_DEK || msg == e_DEK || msg == rot_KEK -> goto Authorize :: else -> goto Deny_request fi @@ -554,20 +649,36 @@ proctype AccessControl() Assign_KEK: + num_assigned = 0 + i = 0 + + do + :: i < NUM_KEKS -> i++ + if + :: usr_x_kek[(user_id-1)*NUM_KEKS+i-1] > 0 -> num_assigned++ + :: else -> skip + fi + + if + :: num_assigned > ASS_MAX -> goto Deny_request + :: else -> skip + fi + :: else -> break + od + idx = (user_id - 1) * NUM_KEKS + (kek_id - 1) - if - :: usr_x_kek[idx] < 1 -> - usr_x_kek[idx] = 1 - :: else -> goto Deny_request + if + :: usr_x_kek[idx] > 1 -> goto Deny_request + :: else -> usr_x_kek[idx] = 1 fi goto Ack_request - Authenticate_user: + Authorize: idx = (user_id - 1) * NUM_KEKS + (kek_id - 1) - + if :: idx >= 0 && idx < NUM_USERS*NUM_KEKS -> if @@ -591,4 +702,47 @@ proctype AccessControl() goto Select_state -} \ No newline at end of file +} + +/** + Alternative component instead of the timer + in the Database component + */ +proctype Clock() { + + Main: + + timer++ + + if // Cache timer + :: timer%CACHE_CLEAR == 0 -> + clear_cache = true + :: else -> skip + fi + + if // Rotation + :: timer%ROT_KEK_1 == 0 -> + rotate_1++ + :: else -> skip + fi + + if // Rotation + :: timer%ROT_KEK_2 == 0 -> + rotate_2++ + :: else -> skip + fi + + if // Rotation + :: timer%ROT_KEK_3 == 0 -> + rotate_3++ + :: else -> skip + fi + + if // Rotation + :: timer%ROT_KEK_3 == 0 -> + rotate_4++ + :: else -> skip + fi + + goto Main +} From 019cd03366406b31f2cd5111b58d640c0fdb3f86 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Wed, 24 Apr 2024 15:37:20 +0200 Subject: [PATCH 08/30] User changed to Tenant --- SPIN-verification/dist_coms.pml | 84 +++++++++++++++++---------------- 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/SPIN-verification/dist_coms.pml b/SPIN-verification/dist_coms.pml index 74f43fc..40c7e21 100644 --- a/SPIN-verification/dist_coms.pml +++ b/SPIN-verification/dist_coms.pml @@ -1,7 +1,7 @@ #define NUM_DEKS 2 #define NUM_KEKS 4 #define NUM_KEYSTORES 1 -#define NUM_USERS 1 +#define NUM_TENANTS 1 #define U2K_MAX 3 #define K2U_MAX 0 #define K2AC_MAX 0 @@ -16,6 +16,8 @@ #define ROT_KEK_4 24000 #define CACHE_CLEAR 4000 #define USE_CLOCK false +#define SAME_TNT_ID false +#define SAME_KEK_ASSIGNED false typedef Key { /* Unencrypted */ int id @@ -32,31 +34,31 @@ typedef E_Key { /* Encrypted */ mtype = { e_DEK, d_DEK, re_DEK, ass_KEK, rot_KEK, deny, ack } -// u: User +// u: Tenant // k: Keystore // ac: Access Control -// { message type, DEK_ID, KEK_ID, E_KEY-ID, E_KEY-VERSION, E_KEY-REF-V, USER-ID } +// { message type, DEK_ID, KEK_ID, E_KEY-ID, E_KEY-VERSION, E_KEY-REF-V, TENANT-ID } // KEK_ID shares index to E_KEY-REF-ID in channels to reduce channel width -chan u12k = [U2K_MAX] of { mtype, int, int, int, int, int, int } // User 1 -> Keystore -chan u22k = [U2K_MAX] of { mtype, int, int, int, int, int, int } // User 2 -> Keystore -chan k2u1 = [K2U_MAX] of { mtype, int, int, int, int, int } // Keystore -> User 1 -chan k2u2 = [K2U_MAX] of { mtype, int, int, int, int, int } // Keystore -> User 2 +chan u12k = [U2K_MAX] of { mtype, int, int, int, int, int, int } // Tenant 1 -> Keystore +chan u22k = [U2K_MAX] of { mtype, int, int, int, int, int, int } // Tenant 2 -> Keystore +chan k2u1 = [K2U_MAX] of { mtype, int, int, int, int, int } // Keystore -> Tenant 1 +chan k2u2 = [K2U_MAX] of { mtype, int, int, int, int, int } // Keystore -> Tenant 2 -// { message type, KEK_ID, USER_ID} +// { message type, KEK_ID, tenant_id} chan k2ac = [K2AC_MAX] of { mtype, int, int } // Keystore -> Access Control chan ac2k = [AC2K_MAX] of { mtype } // Access Control -> Keystore -// { message type, KEK_ID, USER_ID} +// { message type, KEK_ID, tenant_id} chan k2db = [K2DB_MAX] of { mtype, int, int } // Keystore -> Database // { message type, KEK_ID, KEK_VERSION, KEK_ASS-TO } chan db2k = [DB2K_MAX] of { mtype, int, int, int } // Database -> Keystore // This channel emulates an external component notifying -// the user when a rotation has taken place +// the tenant when a rotation has taken place // { message type, KEK_ID } -chan db2u1 = [DB2U_MAX] of { mtype, int } // Database -> User 1 -chan db2u2 = [DB2U_MAX] of { mtype, int } // Database -> User 2 +chan db2u1 = [DB2U_MAX] of { mtype, int } // Database -> Tenant 1 +chan db2u2 = [DB2U_MAX] of { mtype, int } // Database -> Tenant 2 int timer, rotate_1, rotate_2, rotate_3, rotate_4, commit_1, commit_2, commit_3, commit_4 bool clear_cache @@ -67,7 +69,7 @@ init { clear_cache = false atomic { - run User(1) + run Tenant(1) run Keystore() run Database() run AccessControl() @@ -79,7 +81,7 @@ init { } -proctype User(int id) +proctype Tenant(int id) { mtype msg int temp_key, i, ass_idx, recrypt_idx @@ -285,7 +287,7 @@ proctype User(int id) proctype Keystore() { mtype msg - int dek_id, kek_id, kek_ref, i, user_id, id, version, is_case, kek_idx, assigned_to + int dek_id, kek_id, kek_ref, i, tenant_id, id, version, is_case, kek_idx, assigned_to bool valid, received Key temp_key @@ -314,12 +316,12 @@ proctype Keystore() received = false if - :: atomic{ u12k?[msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, user_id] -> - u12k?msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, user_id } -> + :: atomic{ u12k?[msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, tenant_id] -> + u12k?msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, tenant_id } -> received = true kek_id = kek_ref-100 - :: atomic{ u22k?[msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, user_id] -> - u22k?msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, user_id } -> + :: atomic{ u22k?[msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, tenant_id] -> + u22k?msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, tenant_id } -> received = true kek_id = kek_ref-100 :: else -> skip @@ -342,13 +344,13 @@ proctype Keystore() if :: v_KEKs[kek_idx].id == 0 -> - k2db!ass_KEK, kek_idx+1, user_id + k2db!ass_KEK, kek_idx+1, tenant_id db2k?msg, id, version, assigned_to v_KEKs[kek_idx].id = id v_KEKs[kek_idx].version = version v_KEKs[kek_idx].assigned_to = assigned_to - k2ac!msg, id, user_id - :: else -> k2ac!msg, v_KEKs[kek_idx], user_id + k2ac!msg, id, tenant_id + :: else -> k2ac!msg, v_KEKs[kek_idx], tenant_id fi ac2k?msg @@ -360,7 +362,7 @@ proctype Keystore() if - :: user_id == 1 -> k2u1!ass_KEK, -1, v_KEKs[kek_idx].id+100, -1, -1, -1 + :: tenant_id == 1 -> k2u1!ass_KEK, -1, v_KEKs[kek_idx].id+100, -1, -1, -1 :: else -> k2u2!ass_KEK, -1, v_KEKs[kek_idx].id+100, -1, -1, -1 fi @@ -372,7 +374,7 @@ proctype Keystore() valid = true - k2ac!msg, kek_id, user_id + k2ac!msg, kek_id, tenant_id ac2k?msg if @@ -390,7 +392,7 @@ proctype Keystore() if :: is_case == 1 -> - k2db!d_DEK, kek_id, user_id + k2db!d_DEK, kek_id, tenant_id db2k?msg, id, version, assigned_to if @@ -408,7 +410,7 @@ proctype Keystore() :: v_KEKs[kek_id-1].version >= temp_e_key.ref_version -> skip :: else -> - k2db!d_DEK, kek_id, user_id + k2db!d_DEK, kek_id, tenant_id db2k?msg, id, version, assigned_to v_KEKs[id-1].version = id @@ -433,7 +435,7 @@ proctype Keystore() Encrypt: - k2ac!msg, kek_id, user_id + k2ac!msg, kek_id, tenant_id ac2k?msg if @@ -441,7 +443,7 @@ proctype Keystore() :: else -> skip fi - k2db!e_DEK, kek_id, user_id + k2db!e_DEK, kek_id, tenant_id db2k?msg, id, version, assigned_to if @@ -477,7 +479,7 @@ proctype Keystore() /** In this model, the Database contains a timer that acts as a clock - that sends signals to users when rotation has been executed. + that sends signals to tenants when rotation has been executed. Rotation is not time-sensitive such that it is affected by distributed clock-sync issues, so it could also be seen as a tenant quering a clock to see if the scheduled rotation that could be part @@ -487,7 +489,7 @@ proctype Keystore() proctype Database() { mtype msg - int dek_id, kek_id, i, user_id + int dek_id, kek_id, i, tenant_id Key p_KEKs[NUM_KEKS] for (i in p_KEKs) { @@ -619,7 +621,7 @@ proctype Database() { /* ## Access Control Info ## - user_x_kek - Relations between users and KEKs + tenant_x_kek - Relations between tenants and KEKs 0 - No relation 1 - KEK relation exists @@ -631,13 +633,13 @@ proctype Database() { proctype AccessControl() { mtype msg - int kek_id, user_id, idx, i, num_assigned + int kek_id, tenant_id, idx, i, num_assigned - int usr_x_kek[NUM_USERS*NUM_KEKS] + int tnt_x_kek[NUM_TENANTS*NUM_KEKS] Select_state: - k2ac?msg, kek_id, user_id + k2ac?msg, kek_id, tenant_id if :: msg == ass_KEK -> goto Assign_KEK @@ -655,7 +657,7 @@ proctype AccessControl() do :: i < NUM_KEKS -> i++ if - :: usr_x_kek[(user_id-1)*NUM_KEKS+i-1] > 0 -> num_assigned++ + :: tnt_x_kek[(tenant_id-1)*NUM_KEKS+i-1] > 0 -> num_assigned++ :: else -> skip fi @@ -666,23 +668,23 @@ proctype AccessControl() :: else -> break od - idx = (user_id - 1) * NUM_KEKS + (kek_id - 1) + idx = (tenant_id - 1) * NUM_KEKS + (kek_id - 1) if - :: usr_x_kek[idx] > 1 -> goto Deny_request - :: else -> usr_x_kek[idx] = 1 + :: tnt_x_kek[idx] > 1 -> goto Deny_request + :: else -> tnt_x_kek[idx] = 1 fi goto Ack_request Authorize: - idx = (user_id - 1) * NUM_KEKS + (kek_id - 1) + idx = (tenant_id - 1) * NUM_KEKS + (kek_id - 1) if - :: idx >= 0 && idx < NUM_USERS*NUM_KEKS -> + :: idx >= 0 && idx < NUM_TENANTS*NUM_KEKS -> if - :: usr_x_kek[idx] < 1 -> goto Deny_request + :: tnt_x_kek[idx] < 1 -> goto Deny_request :: else -> skip fi :: else -> goto Deny_request From 43bd627a742a3823237197d10683e21dae4e4651 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Thu, 2 May 2024 11:31:33 +0200 Subject: [PATCH 09/30] Model is mostly done with an alternative model that only uses a single KEK in the system. --- SPIN-verification/README.md | 24 +- SPIN-verification/dist_coms.pml | 532 ++++++++++++++++---------------- 2 files changed, 273 insertions(+), 283 deletions(-) diff --git a/SPIN-verification/README.md b/SPIN-verification/README.md index d4082b2..f803eaa 100644 --- a/SPIN-verification/README.md +++ b/SPIN-verification/README.md @@ -1,21 +1,15 @@ # A Functional Verification of the KMS in SPIN -Currently models user and keystore interaction where user can encrypt DEKs and request assignment of KEKs from the Keystore. +Currently models tenant and keystore interaction where 2 tenants can encrypt DEKs and request assignment of KEKs from the Keystore.
-Number of Users: 1
-Number of DEKs per user: 2
-Number of KEKs: 3 +When Tenant 1 has encrypted a DEK, it is sent to Tenant 2 together with a *grant* token. Tenant 2 will store encrypted DEKs from Tenant 1 and send them for decryption with the token *grant*. The token is controlled with constants **GRANT** and **VALID_GRANT**. Only when the two are equal, will Tenant 2 be able to decrypt enncrypted DEKs received from Tenant 1.
-## List of assertions +By flagging **SAME_KEK_ASSIGNED** as true the max number of KEKs assigned will be set to 1 and both Tenants will be assigned the same KEK from the Keystore. This alternative model introduces a faulty behavior to observe verification failure.
-**User Receive - assert(temp_key == DEKs[temp_key-1])**
-A DEK received is one previously encrypted by the user
+On set intervals defined as constants, KEKs will be rotated in the database and signals will be sent to the tenants assigned those KEKs. Tenants will then Re-encrypt those encrypted DEKs in order to rotate the encryption.
-**User Receive - assert(temp_e_key.version > encrypted_DEKs[temp_e_key.id-1].version)**
-If the same DEK is encrypted several times, the encryption is not identical
- -**Keystore Encrypt - assert(kek_id > 0 && kek_id <= NUM_KEKS)**
-Keystore only encrypts if a valid KEK has been included in the request
- -**Keystore Decrypt - assert(KEKs[kek_id-1].version >= temp_e_key.ref_version)**
-The version of the KEK used in decryption is greater or equal to the one used for encryption
+## Some Default Values +Number of Tenants: 2
+Number of DEKs per Tenant: 2
+Number of KEKs in Keystore: 4
+Max number of KEKs per Tenant: 2 diff --git a/SPIN-verification/dist_coms.pml b/SPIN-verification/dist_coms.pml index 40c7e21..2780147 100644 --- a/SPIN-verification/dist_coms.pml +++ b/SPIN-verification/dist_coms.pml @@ -1,22 +1,24 @@ #define NUM_DEKS 2 #define NUM_KEKS 4 -#define NUM_KEYSTORES 1 -#define NUM_TENANTS 1 -#define U2K_MAX 3 -#define K2U_MAX 0 +#define NUM_TENANTS 2 +#define T2K_MAX 3 +#define K2T_MAX 0 #define K2AC_MAX 0 #define AC2K_MAX 0 #define K2DB_MAX 3 #define DB2K_MAX 0 -#define DB2U_MAX 5 +#define DB2T_MAX 5 +#define T_SEND_MAX 2 #define ASS_MAX 2 +#define SAME_KEK_MAX 1 +#define GRANT 123 +#define VALID_GRANT 123 +#define ENC_DUMMY 100 #define ROT_KEK_1 15000 #define ROT_KEK_2 18000 #define ROT_KEK_3 25000 #define ROT_KEK_4 24000 #define CACHE_CLEAR 4000 -#define USE_CLOCK false -#define SAME_TNT_ID false #define SAME_KEK_ASSIGNED false typedef Key { /* Unencrypted */ @@ -32,24 +34,27 @@ typedef E_Key { /* Encrypted */ int ref_version } -mtype = { e_DEK, d_DEK, re_DEK, ass_KEK, rot_KEK, deny, ack } +mtype = { e_DEK, d_DEK, re_DEK, ass_KEK, rot_KEK, send_e_DEK, deny, ack } // u: Tenant // k: Keystore // ac: Access Control -// { message type, DEK_ID, KEK_ID, E_KEY-ID, E_KEY-VERSION, E_KEY-REF-V, TENANT-ID } +// { message type, DEK_ID, KEK_ID, E_KEY-ID, E_KEY-VERSION, E_KEY-REF-V, TENANT_ID, (GRANT) } // KEK_ID shares index to E_KEY-REF-ID in channels to reduce channel width -chan u12k = [U2K_MAX] of { mtype, int, int, int, int, int, int } // Tenant 1 -> Keystore -chan u22k = [U2K_MAX] of { mtype, int, int, int, int, int, int } // Tenant 2 -> Keystore -chan k2u1 = [K2U_MAX] of { mtype, int, int, int, int, int } // Keystore -> Tenant 1 -chan k2u2 = [K2U_MAX] of { mtype, int, int, int, int, int } // Keystore -> Tenant 2 +chan t12k = [T2K_MAX] of { mtype, int, int, int, int, int, int } // Tenant 1 -> Keystore +chan t22k = [T2K_MAX] of { mtype, int, int, int, int, int, int, int } // Tenant 2 -> Keystore, added int field for grant token from Tenant 1 +chan k2t1 = [K2T_MAX] of { mtype, int, int, int, int, int } // Keystore -> Tenant 1 +chan k2t2 = [K2T_MAX] of { mtype, int, int, int, int, int } // Keystore -> Tenant 2 -// { message type, KEK_ID, tenant_id} -chan k2ac = [K2AC_MAX] of { mtype, int, int } // Keystore -> Access Control +// { message type, E_KEY-ID, E_KEY-VERSION, E_KEY-REF_ID, E_KEY-REF-V, GRANT } +chan t12t2 = [T_SEND_MAX] of { mtype, int, int, int, int, int } // Tenant 1 -> Tenant 2 + +// { message type, KEK_ID, TENANT_ID, GRANT} +chan k2ac = [K2AC_MAX] of { mtype, int, int, int } // Keystore -> Access Control chan ac2k = [AC2K_MAX] of { mtype } // Access Control -> Keystore -// { message type, KEK_ID, tenant_id} +// { message type, KEK_ID, TENANT_ID} chan k2db = [K2DB_MAX] of { mtype, int, int } // Keystore -> Database // { message type, KEK_ID, KEK_VERSION, KEK_ASS-TO } chan db2k = [DB2K_MAX] of { mtype, int, int, int } // Database -> Keystore @@ -57,8 +62,9 @@ chan db2k = [DB2K_MAX] of { mtype, int, int, int } // Database -> Keystore // This channel emulates an external component notifying // the tenant when a rotation has taken place // { message type, KEK_ID } -chan db2u1 = [DB2U_MAX] of { mtype, int } // Database -> Tenant 1 -chan db2u2 = [DB2U_MAX] of { mtype, int } // Database -> Tenant 2 +chan db2t1 = [DB2T_MAX] of { mtype, int } // Database -> Tenant 1 +chan db2t2 = [DB2T_MAX] of { mtype, int } // Database -> Tenant 2 + int timer, rotate_1, rotate_2, rotate_3, rotate_4, commit_1, commit_2, commit_3, commit_4 bool clear_cache @@ -69,49 +75,79 @@ init { clear_cache = false atomic { - run Tenant(1) - run Keystore() + + + int i + + for (i : 1 .. NUM_TENANTS) { + run Tenant(i) + } run Database() + run Keystore() run AccessControl() - if - :: USE_CLOCK -> run Clock() - :: else -> skip - fi + } - } proctype Tenant(int id) { mtype msg - int temp_key, i, ass_idx, recrypt_idx - int assigned_KEKs[NUM_KEKS], DEKs[NUM_DEKS] + int temp_key, i, ass_idx, recrypt_idx, grant + int assigned_KEKs[NUM_KEKS/2], DEKs[NUM_DEKS] E_Key temp_e_key - E_Key encrypted_DEKs[NUM_DEKS] - bool recrypt_1, recrypt_2, recrypt_3, never_true + E_Key encrypted_DEKs[NUM_DEKS], received_e_DEKs[NUM_DEKS] + bool sent_1, sent_2 - for (i in DEKs) { - DEKs[i] = i+1 + for (i : 0 .. NUM_DEKS-1) { + DEKs[i] = i + 1 + NUM_DEKS*(_pid-1) } Select_state: if - :: id == 1 -> + :: SAME_KEK_ASSIGNED -> assert(assigned_KEKs[1] == 0) + :: else -> skip + fi + // Receive rotation update ping + if + :: _pid == 1 -> if - :: atomic{ db2u1?[msg, recrypt_idx] -> db2u1?msg, recrypt_idx } -> + :: atomic{ db2t1?[msg, recrypt_idx] -> db2t1?msg, recrypt_idx } -> goto Recrypt :: else -> skip fi :: else -> if - :: atomic{ db2u2?[msg, recrypt_idx] -> db2u2?msg, recrypt_idx } -> + :: atomic{ db2t2?[msg, recrypt_idx] -> db2t2?msg, recrypt_idx } -> goto Recrypt :: else -> skip fi fi + + + // Receive from tenant 1 + if + :: _pid == 2 -> + if + :: atomic{ t12t2?[msg, temp_e_key.id, temp_e_key.version, temp_e_key.ref_id, temp_e_key.ref_version, grant] -> + t12t2?msg, temp_e_key.id, temp_e_key.version, temp_e_key.ref_id, temp_e_key.ref_version, grant } -> + assert(temp_e_key.id-ENC_DUMMY-1 < 2) + received_e_DEKs[temp_e_key.id-ENC_DUMMY-1].id = temp_e_key.id + received_e_DEKs[temp_e_key.id-ENC_DUMMY-1].version = temp_e_key.version + received_e_DEKs[temp_e_key.id-ENC_DUMMY-1].ref_id = temp_e_key.ref_id + received_e_DEKs[temp_e_key.id-ENC_DUMMY-1].ref_version = temp_e_key.ref_version + :: else -> skip + fi + :: else -> skip + fi + // Main selection loop do + :: if + :: _pid == 1 && !(sent_1 && sent_2) && (encrypted_DEKs[0].id != 0 || encrypted_DEKs[1].id != 0) -> + goto Send_to_tenant + :: else -> skip + fi :: goto Encrypt :: goto Decrypt :: goto Request_KEK @@ -120,19 +156,19 @@ proctype Tenant(int id) Encrypt: if - :: id == 1 -> + :: _pid == 1 -> do - :: u12k!e_DEK, DEKs[0], assigned_KEKs[0], -1, -1, -1, id -> break - :: u12k!e_DEK, DEKs[0], assigned_KEKs[1], -1, -1, -1, id -> break - :: u12k!e_DEK, DEKs[1], assigned_KEKs[0], -1, -1, -1, id -> break - :: u12k!e_DEK, DEKs[1], assigned_KEKs[1], -1, -1, -1, id -> break + :: t12k!e_DEK, DEKs[0], assigned_KEKs[0], -1, -1, -1, id -> break + :: t12k!e_DEK, DEKs[0], assigned_KEKs[1], -1, -1, -1, id -> break + :: t12k!e_DEK, DEKs[1], assigned_KEKs[0], -1, -1, -1, id -> break + :: t12k!e_DEK, DEKs[1], assigned_KEKs[1], -1, -1, -1, id -> break od :: else -> do - :: u22k!e_DEK, DEKs[0], assigned_KEKs[0], -1, -1, -1, id -> break - :: u22k!e_DEK, DEKs[0], assigned_KEKs[1], -1, -1, -1, id -> break - :: u22k!e_DEK, DEKs[1], assigned_KEKs[0], -1, -1, -1, id -> break - :: u22k!e_DEK, DEKs[1], assigned_KEKs[1], -1, -1, -1, id -> break + :: t22k!e_DEK, DEKs[0], assigned_KEKs[0], -1, -1, -1, id, grant -> break + :: t22k!e_DEK, DEKs[0], assigned_KEKs[1], -1, -1, -1, id, grant -> break + :: t22k!e_DEK, DEKs[1], assigned_KEKs[0], -1, -1, -1, id, grant -> break + :: t22k!e_DEK, DEKs[1], assigned_KEKs[1], -1, -1, -1, id, grant -> break od fi @@ -141,20 +177,24 @@ proctype Tenant(int id) Decrypt: if - :: id == 1 -> + :: _pid == 1 -> if :: encrypted_DEKs[0].id != 0 -> - u12k!d_DEK, -1, encrypted_DEKs[0].ref_id, encrypted_DEKs[0].id, encrypted_DEKs[0].version, encrypted_DEKs[0].ref_version, id + t12k!d_DEK, -1, encrypted_DEKs[0].ref_id, encrypted_DEKs[0].id, encrypted_DEKs[0].version, encrypted_DEKs[0].ref_version, id :: encrypted_DEKs[1].id != 0 -> - u12k!d_DEK, -1, encrypted_DEKs[1].ref_id, encrypted_DEKs[1].id, encrypted_DEKs[1].version, encrypted_DEKs[1].ref_version, id + t12k!d_DEK, -1, encrypted_DEKs[1].ref_id, encrypted_DEKs[1].id, encrypted_DEKs[1].version, encrypted_DEKs[1].ref_version, id :: else -> goto Select_state fi :: else -> if :: encrypted_DEKs[0].id != 0 -> - u22k!d_DEK, -1, encrypted_DEKs[0].ref_id, encrypted_DEKs[0].id, encrypted_DEKs[0].version, encrypted_DEKs[0].ref_version, id + t22k!d_DEK, -1, encrypted_DEKs[0].ref_id, encrypted_DEKs[0].id, encrypted_DEKs[0].version, encrypted_DEKs[0].ref_version, id, grant :: encrypted_DEKs[1].id != 0 -> - u22k!d_DEK, -1, encrypted_DEKs[1].ref_id, encrypted_DEKs[1].id, encrypted_DEKs[1].version, encrypted_DEKs[1].ref_version, id + t22k!d_DEK, -1, encrypted_DEKs[1].ref_id, encrypted_DEKs[1].id, encrypted_DEKs[1].version, encrypted_DEKs[1].ref_version, id, grant + :: received_e_DEKs[0].id != 0 -> + t22k!d_DEK, -1, received_e_DEKs[0].ref_id, received_e_DEKs[0].id, received_e_DEKs[0].version, received_e_DEKs[0].ref_version, id, grant + :: received_e_DEKs[1].id != 0 -> + t22k!d_DEK, -1, received_e_DEKs[1].ref_id, received_e_DEKs[1].id, received_e_DEKs[1].version, received_e_DEKs[1].ref_version, id, grant :: else -> goto Select_state fi fi @@ -163,106 +203,67 @@ proctype Tenant(int id) Recrypt: - if - :: recrypt_1 && assigned_KEKs[0] != 0 && id == 1 -> - i = 0 - for (i in encrypted_DEKs) { - if - :: encrypted_DEKs[i].ref_id == assigned_KEKs[0] -> - u12k!re_DEK, -1, encrypted_DEKs[i].ref_id, encrypted_DEKs[i].id, encrypted_DEKs[i].version, encrypted_DEKs[i].ref_version, id - k2u1?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version - if - :: msg != deny -> - assert(temp_e_key.version > encrypted_DEKs[i].version) - assert(temp_e_key.ref_version > encrypted_DEKs[i].ref_version) - encrypted_DEKs[temp_e_key.id-1].id = temp_e_key.id - encrypted_DEKs[temp_e_key.id-1].version = temp_e_key.version - encrypted_DEKs[temp_e_key.id-1].ref_id = temp_e_key.ref_id - encrypted_DEKs[temp_e_key.id-1].ref_version = temp_e_key.ref_version - :: else -> skip - fi - :: else -> skip - fi - } - recrypt_1 = false - :: else -> skip - fi - - if - :: recrypt_2 && assigned_KEKs[1] != 0 -> - i = 0 - for (i in encrypted_DEKs) { - if - :: encrypted_DEKs[i].ref_id == assigned_KEKs[1] -> - if - :: id == 1 -> - u12k!re_DEK, -1, encrypted_DEKs[i].ref_id, encrypted_DEKs[i].id, encrypted_DEKs[i].version, encrypted_DEKs[i].ref_version, id - k2u1?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version - :: else -> - u22k!re_DEK, -1, encrypted_DEKs[i].ref_id, encrypted_DEKs[i].id, encrypted_DEKs[i].version, encrypted_DEKs[i].ref_version, id - k2u2?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version - fi - - if - :: msg != deny -> - assert(temp_e_key.version > encrypted_DEKs[i].version) - assert(temp_e_key.ref_version > encrypted_DEKs[i].ref_version) - encrypted_DEKs[temp_e_key.id-1].id = temp_e_key.id - encrypted_DEKs[temp_e_key.id-1].version = temp_e_key.version - encrypted_DEKs[temp_e_key.id-1].ref_id = temp_e_key.ref_id - encrypted_DEKs[temp_e_key.id-1].ref_version = temp_e_key.ref_version - :: else -> skip - fi - :: else -> skip - fi - } - recrypt_2 = false - :: else -> skip - fi - - if - :: recrypt_3 && assigned_KEKs[2] != 0 && id == 2 -> skip - i = 0 - for (i in encrypted_DEKs) { - if - :: encrypted_DEKs[i].ref_id == assigned_KEKs[2] -> - u22k!re_DEK, -1, encrypted_DEKs[i].ref_id, encrypted_DEKs[i].id, encrypted_DEKs[i].version, encrypted_DEKs[i].ref_version, id - k2u2?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version - if - :: msg != deny -> - assert(temp_e_key.version > encrypted_DEKs[i].version) - assert(temp_e_key.ref_version > encrypted_DEKs[i].ref_version) - encrypted_DEKs[temp_e_key.id-1].id = temp_e_key.id - encrypted_DEKs[temp_e_key.id-1].version = temp_e_key.version - encrypted_DEKs[temp_e_key.id-1].ref_id = temp_e_key.ref_id - encrypted_DEKs[temp_e_key.id-1].ref_version = temp_e_key.ref_version - :: else -> skip - fi - :: else -> skip - fi - } - recrypt_3 = false - :: else -> skip - fi + i = 0; + for (i in encrypted_DEKs) { + if + :: encrypted_DEKs[i].ref_id == recrypt_idx -> + if // Send and Receive + :: _pid == 1 -> + t12k!re_DEK, -1, encrypted_DEKs[i].ref_id, encrypted_DEKs[i].id, encrypted_DEKs[i].version, encrypted_DEKs[i].ref_version, id + k2t1?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version + :: else -> + t22k!re_DEK, -1, encrypted_DEKs[i].ref_id, encrypted_DEKs[i].id, encrypted_DEKs[i].version, encrypted_DEKs[i].ref_version, id, grant + k2t2?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version + fi + + if + :: msg != deny -> + assert(temp_e_key.version > encrypted_DEKs[i].version) + assert(temp_e_key.ref_version >= encrypted_DEKs[i].ref_version) + assert(encrypted_DEKs[i].id == temp_e_key.id) + assert(recrypt_idx == temp_e_key.ref_id) + encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].id = temp_e_key.id + encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].version = temp_e_key.version + encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].ref_id = temp_e_key.ref_id + encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].ref_version = temp_e_key.ref_version + :: else -> skip + fi + :: else -> skip + fi + } goto Select_state Request_KEK: if - :: id == 1 -> u12k!ass_KEK, -1, -1, -1, -1, -1, id - :: else -> u22k!ass_KEK, -1, -1, -1, -1, -1, id + :: _pid == 1 -> t12k!ass_KEK, -1, -1, -1, -1, -1, id + :: else -> t22k!ass_KEK, -1, -1, -1, -1, -1, id fi goto Receive + Send_to_tenant: + + if + :: encrypted_DEKs[0].id != 0 -> + t12t2!send_e_DEK, encrypted_DEKs[0].id, encrypted_DEKs[0].version, encrypted_DEKs[0].ref_id, encrypted_DEKs[0].ref_version, GRANT + sent_1 = true + :: encrypted_DEKs[1].id != 0 -> + t12t2!send_e_DEK, encrypted_DEKs[1].id, encrypted_DEKs[1].version, encrypted_DEKs[1].ref_id, encrypted_DEKs[1].ref_version, GRANT + sent_2 = true + :: else -> skip + fi + + goto Select_state + Receive: if - :: id == 1 -> - k2u1?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version + :: _pid == 1 -> + k2t1?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version :: else -> - k2u2?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version + k2t2?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version fi if @@ -271,14 +272,16 @@ proctype Tenant(int id) assigned_KEKs[ass_idx] = temp_e_key.ref_id ass_idx++ :: msg == d_DEK -> - assert(temp_key == DEKs[temp_key-1]) + assert(temp_key == DEKs[(temp_key-1)%2] || (temp_key == received_e_DEKs[(temp_key-1)%2].id-ENC_DUMMY && grant == VALID_GRANT)) + assert(DEKs[0] != received_e_DEKs[(temp_key-1)%2].id-ENC_DUMMY) + assert(DEKs[1] != received_e_DEKs[(temp_key-1)%2].id-ENC_DUMMY) :: msg == deny -> skip :: msg == e_DEK -> - assert(temp_e_key.version > encrypted_DEKs[temp_e_key.id-1].version) - encrypted_DEKs[temp_e_key.id-1].id = temp_e_key.id - encrypted_DEKs[temp_e_key.id-1].version = temp_e_key.version - encrypted_DEKs[temp_e_key.id-1].ref_id = temp_e_key.ref_id - encrypted_DEKs[temp_e_key.id-1].ref_version = temp_e_key.ref_version + assert(temp_e_key.version > encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].version) + encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].id = temp_e_key.id + encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].version = temp_e_key.version + encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].ref_id = temp_e_key.ref_id + encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].ref_version = temp_e_key.ref_version fi goto Select_state @@ -286,8 +289,8 @@ proctype Tenant(int id) proctype Keystore() { - mtype msg - int dek_id, kek_id, kek_ref, i, tenant_id, id, version, is_case, kek_idx, assigned_to + mtype msg, enc_msg + int dek_id, kek_id, kek_ref, i, tenant_id, id, version, is_case, kek_idx, assigned_to, grant bool valid, received Key temp_key @@ -297,6 +300,8 @@ proctype Keystore() Select_state: + grant = 0 + if // Clear Cache :: clear_cache -> i = 0 @@ -316,14 +321,14 @@ proctype Keystore() received = false if - :: atomic{ u12k?[msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, tenant_id] -> - u12k?msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, tenant_id } -> + :: atomic{ t12k?[msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, tenant_id] -> + t12k?msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, tenant_id } -> received = true - kek_id = kek_ref-100 - :: atomic{ u22k?[msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, tenant_id] -> - u22k?msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, tenant_id } -> + kek_id = kek_ref-ENC_DUMMY + :: atomic{ t22k?[msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, tenant_id, grant] -> + t22k?msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, tenant_id, grant } -> received = true - kek_id = kek_ref-100 + kek_id = kek_ref-ENC_DUMMY :: else -> skip fi @@ -342,31 +347,36 @@ proctype Keystore() Assign_KEK: - if - :: v_KEKs[kek_idx].id == 0 -> - k2db!ass_KEK, kek_idx+1, tenant_id - db2k?msg, id, version, assigned_to - v_KEKs[kek_idx].id = id - v_KEKs[kek_idx].version = version - v_KEKs[kek_idx].assigned_to = assigned_to - k2ac!msg, id, tenant_id - :: else -> k2ac!msg, v_KEKs[kek_idx], tenant_id + k2db!ass_KEK, kek_idx+1, tenant_id + db2k?msg, id, version, assigned_to + + if + :: msg == deny -> goto Deny_request + :: else -> skip fi + + v_KEKs[kek_idx].id = id + v_KEKs[kek_idx].version = version + v_KEKs[kek_idx].assigned_to = assigned_to + + k2ac!msg, id, tenant_id, grant ac2k?msg - + if :: msg == deny -> goto Deny_request :: else -> skip fi - if - :: tenant_id == 1 -> k2u1!ass_KEK, -1, v_KEKs[kek_idx].id+100, -1, -1, -1 - :: else -> k2u2!ass_KEK, -1, v_KEKs[kek_idx].id+100, -1, -1, -1 + :: tenant_id == 1 -> k2t1!ass_KEK, -1, v_KEKs[kek_idx].id+ENC_DUMMY, -1, -1, -1 + :: else -> k2t2!ass_KEK, -1, v_KEKs[kek_idx].id+ENC_DUMMY, -1, -1, -1 fi - kek_idx++ + if + :: !SAME_KEK_ASSIGNED -> kek_idx++ + :: else -> skip + fi goto Select_state @@ -374,7 +384,7 @@ proctype Keystore() valid = true - k2ac!msg, kek_id, tenant_id + k2ac!msg, kek_id, tenant_id, grant ac2k?msg if @@ -429,15 +439,23 @@ proctype Keystore() :: else -> goto Deny_request fi - k2u1!d_DEK, temp_e_key.id, -1, -1, -1, -1 + if + :: tenant_id == 1 -> k2t1!d_DEK, temp_e_key.id-ENC_DUMMY, -1, -1, -1, -1 + :: else -> k2t2!d_DEK, temp_e_key.id-ENC_DUMMY, -1, -1, -1, -1 + fi goto Select_state Encrypt: - k2ac!msg, kek_id, tenant_id + if + :: msg == re_DEK -> enc_msg = re_DEK + :: else -> enc_msg = e_DEK + fi + + k2ac!msg, kek_id, tenant_id, grant ac2k?msg - + if :: msg == deny -> goto Deny_request :: else -> skip @@ -457,31 +475,37 @@ proctype Keystore() assert(kek_id > 0 && kek_id <= NUM_KEKS) if - :: msg == re_DEK -> - assert(temp_e_key.ref_version < v_KEKs[kek_id-1].version && temp_e_key.ref_version > v_KEKs[kek_id-1].version-2) - :: else -> temp_e_key.id = dek_id + :: enc_msg == re_DEK -> + assert(temp_e_key.ref_version <= v_KEKs[kek_id-1].version && temp_e_key.ref_version > v_KEKs[kek_id-1].version-2) + :: else -> temp_e_key.id = dek_id+ENC_DUMMY fi temp_e_key.version = timer - temp_e_key.ref_id = v_KEKs[kek_id-1].id+100 + temp_e_key.ref_id = v_KEKs[kek_id-1].id+ENC_DUMMY temp_e_key.ref_version = v_KEKs[kek_id-1].version - k2u1!e_DEK, -1, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version + if + :: tenant_id == 1 -> k2t1!enc_msg, -1, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version + :: else -> k2t2!enc_msg, -1, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version + fi goto Select_state Deny_request: - - k2u1!deny, -1, -1, -1, -1, -1 + + if + :: tenant_id == 1 -> k2t1!deny, -1, -1, -1, -1, -1 + :: else -> k2t2!deny, -1, -1, -1, -1, -1 + fi goto Select_state } /** - In this model, the Database contains a timer that acts as a clock - that sends signals to tenants when rotation has been executed. - Rotation is not time-sensitive such that it is affected by - distributed clock-sync issues, so it could also be seen as a tenant + When the Clock component is disabled, the Database contains a timer + that acts as a clock sending signals to tenants when rotation has + been executed. Rotation is not time-sensitive such that it is affected + by distributed clock-sync issues, so it could also be seen as a tenant quering a clock to see if the scheduled rotation that could be part of the metadata in the KEK information available to the tenant has taken place. @@ -489,7 +513,7 @@ proctype Keystore() proctype Database() { mtype msg - int dek_id, kek_id, i, tenant_id + int dek_id, kek_id, i, tenant_id Key p_KEKs[NUM_KEKS] for (i in p_KEKs) { @@ -498,88 +522,85 @@ proctype Database() { } Main: - - if - :: !USE_CLOCK -> timer++ - :: else -> skip - fi + + timer++ if // Cache timer - :: !USE_CLOCK && timer%CACHE_CLEAR == 0 -> + :: timer%CACHE_CLEAR == 0 -> clear_cache = true :: else -> skip fi if // Rotation 1 - :: !USE_CLOCK && timer%ROT_KEK_1 == 0 -> + :: timer%ROT_KEK_1 == 0 -> p_KEKs[0].version++ if :: p_KEKs[0].assigned_to == 1 -> - db2u1!rot_KEK, p_KEKs[0].id+100 - :: else -> - db2u2!rot_KEK, p_KEKs[0].id+100 + db2t1!rot_KEK, p_KEKs[0].id+ENC_DUMMY + :: p_KEKs[0].assigned_to == 2 -> + db2t2!rot_KEK, p_KEKs[0].id+ENC_DUMMY + :: p_KEKs[0].assigned_to == 3 -> + db2t2!rot_KEK, p_KEKs[0].id+ENC_DUMMY + db2t1!rot_KEK, p_KEKs[0].id+ENC_DUMMY + :: else -> skip fi - :: USE_CLOCK && rotate_1 > 0 -> - p_KEKs[0].version++ - rotate_1-- - commit_1++ :: else -> skip fi if // Rotation 2 - :: !USE_CLOCK && timer%ROT_KEK_2 == 0 -> + :: timer%ROT_KEK_2 == 0 -> p_KEKs[1].version++ if :: p_KEKs[1].assigned_to == 1 -> - db2u1!rot_KEK, p_KEKs[1].id+100 - :: else -> - db2u2!rot_KEK, p_KEKs[1].id+100 + db2t1!rot_KEK, p_KEKs[1].id+ENC_DUMMY + :: p_KEKs[1].assigned_to == 2 -> + db2t2!rot_KEK, p_KEKs[1].id+ENC_DUMMY + :: p_KEKs[1].assigned_to == 3 -> + db2t2!rot_KEK, p_KEKs[1].id+ENC_DUMMY + db2t1!rot_KEK, p_KEKs[1].id+ENC_DUMMY + :: else -> skip fi - :: USE_CLOCK && rotate_2 > 0 -> - p_KEKs[1].version++ - rotate_2-- - commit_2++ :: else -> skip fi if // Rotation 3 - :: !USE_CLOCK && timer%ROT_KEK_3 == 0 -> + :: timer%ROT_KEK_3 == 0 -> p_KEKs[2].version++ if :: p_KEKs[2].assigned_to == 1 -> - db2u1!rot_KEK, p_KEKs[2].id+100 - :: else -> - db2u2!rot_KEK, p_KEKs[2].id+100 + db2t1!rot_KEK, p_KEKs[2].id+ENC_DUMMY + :: p_KEKs[2].assigned_to == 2 -> + db2t2!rot_KEK, p_KEKs[2].id+ENC_DUMMY + :: p_KEKs[2].assigned_to == 3 -> + db2t2!rot_KEK, p_KEKs[2].id+ENC_DUMMY + db2t1!rot_KEK, p_KEKs[2].id+ENC_DUMMY + :: else -> skip fi - :: USE_CLOCK && rotate_3 > 0 -> - p_KEKs[2].version++ - rotate_3-- - commit_3++ :: else -> skip fi if // Rotation 4 - :: !USE_CLOCK && timer%ROT_KEK_4 == 0 -> + :: timer%ROT_KEK_4 == 0 -> p_KEKs[3].version++ if :: p_KEKs[3].assigned_to == 1 -> - db2u1!rot_KEK, p_KEKs[3].id+100 - :: else -> - db2u2!rot_KEK, p_KEKs[3].id+100 + db2t1!rot_KEK, p_KEKs[3].id+ENC_DUMMY + :: p_KEKs[3].assigned_to == 2 -> + db2t2!rot_KEK, p_KEKs[3].id+ENC_DUMMY + :: p_KEKs[3].assigned_to == 3 -> + db2t2!rot_KEK, p_KEKs[3].id+ENC_DUMMY + db2t1!rot_KEK, p_KEKs[3].id+ENC_DUMMY + :: else -> skip fi - :: USE_CLOCK && rotate_4 > 0 -> - p_KEKs[3].version++ - rotate_4-- - commit_4++ :: else -> skip fi if - :: atomic{ k2db?[msg, kek_id] -> k2db?msg, kek_id } -> + :: atomic{ k2db?[msg, kek_id, tenant_id] -> k2db?msg, kek_id, tenant_id } -> if :: (msg == e_DEK || msg == d_DEK || msg == ass_KEK || msg == re_DEK) -> goto Access_KEK :: else -> goto Deny_request @@ -595,10 +616,18 @@ proctype Database() { for (i in p_KEKs) { if :: p_KEKs[i].id == kek_id -> + + timer++ + if - :: !USE_CLOCK -> timer++ + :: msg == ass_KEK -> + if + :: p_KEKs[i].assigned_to > 0 -> p_KEKs[i].assigned_to = 3 + :: else -> p_KEKs[i].assigned_to = tenant_id + fi :: else -> skip fi + db2k!msg, p_KEKs[i].id, p_KEKs[i].version, p_KEKs[i].assigned_to goto Main @@ -633,17 +662,16 @@ proctype Database() { proctype AccessControl() { mtype msg - int kek_id, tenant_id, idx, i, num_assigned - + int kek_id, tenant_id, idx, i, num_assigned, grant int tnt_x_kek[NUM_TENANTS*NUM_KEKS] Select_state: - - k2ac?msg, kek_id, tenant_id + + k2ac?msg, kek_id, tenant_id, grant if :: msg == ass_KEK -> goto Assign_KEK - :: msg == d_DEK || msg == e_DEK || msg == rot_KEK -> goto Authorize + :: msg == d_DEK || msg == e_DEK || msg == re_DEK -> goto Authorize :: else -> goto Deny_request fi @@ -662,7 +690,8 @@ proctype AccessControl() fi if - :: num_assigned > ASS_MAX -> goto Deny_request + :: num_assigned >= ASS_MAX -> goto Deny_request + :: SAME_KEK_ASSIGNED && num_assigned >= SAME_KEK_MAX -> goto Deny_request :: else -> skip fi :: else -> break @@ -684,12 +713,22 @@ proctype AccessControl() if :: idx >= 0 && idx < NUM_TENANTS*NUM_KEKS -> if - :: tnt_x_kek[idx] < 1 -> goto Deny_request + :: tnt_x_kek[idx] < 1 -> + if + :: grant == VALID_GRANT -> + idx = kek_id - 1 + if + :: tnt_x_kek[idx] < 1 -> goto Deny_request + :: else -> skip + fi + :: else -> goto Deny_request + fi :: else -> skip fi :: else -> goto Deny_request fi + goto Ack_request Ack_request: @@ -705,46 +744,3 @@ proctype AccessControl() goto Select_state } - -/** - Alternative component instead of the timer - in the Database component - */ -proctype Clock() { - - Main: - - timer++ - - if // Cache timer - :: timer%CACHE_CLEAR == 0 -> - clear_cache = true - :: else -> skip - fi - - if // Rotation - :: timer%ROT_KEK_1 == 0 -> - rotate_1++ - :: else -> skip - fi - - if // Rotation - :: timer%ROT_KEK_2 == 0 -> - rotate_2++ - :: else -> skip - fi - - if // Rotation - :: timer%ROT_KEK_3 == 0 -> - rotate_3++ - :: else -> skip - fi - - if // Rotation - :: timer%ROT_KEK_3 == 0 -> - rotate_4++ - :: else -> skip - fi - - goto Main -} From 323a3f56a67fa1ebac0ce7936304dc9448742203 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Thu, 2 May 2024 11:36:13 +0200 Subject: [PATCH 10/30] removed some global vars --- SPIN-verification/dist_coms.pml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SPIN-verification/dist_coms.pml b/SPIN-verification/dist_coms.pml index 2780147..a22f962 100644 --- a/SPIN-verification/dist_coms.pml +++ b/SPIN-verification/dist_coms.pml @@ -66,7 +66,7 @@ chan db2t1 = [DB2T_MAX] of { mtype, int } // Database -> Tenant 1 chan db2t2 = [DB2T_MAX] of { mtype, int } // Database -> Tenant 2 -int timer, rotate_1, rotate_2, rotate_3, rotate_4, commit_1, commit_2, commit_3, commit_4 +int timer bool clear_cache init { From ede879b41187d483191e194ff4daac2f96a39312 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Thu, 2 May 2024 11:37:25 +0200 Subject: [PATCH 11/30] changed process id check to simply passed id parameter in proctype Tenant() --- SPIN-verification/dist_coms.pml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/SPIN-verification/dist_coms.pml b/SPIN-verification/dist_coms.pml index a22f962..a9f5461 100644 --- a/SPIN-verification/dist_coms.pml +++ b/SPIN-verification/dist_coms.pml @@ -99,7 +99,7 @@ proctype Tenant(int id) bool sent_1, sent_2 for (i : 0 .. NUM_DEKS-1) { - DEKs[i] = i + 1 + NUM_DEKS*(_pid-1) + DEKs[i] = i + 1 + NUM_DEKS*(id-1) } Select_state: @@ -110,7 +110,7 @@ proctype Tenant(int id) fi // Receive rotation update ping if - :: _pid == 1 -> + :: id == 1 -> if :: atomic{ db2t1?[msg, recrypt_idx] -> db2t1?msg, recrypt_idx } -> goto Recrypt @@ -127,7 +127,7 @@ proctype Tenant(int id) // Receive from tenant 1 if - :: _pid == 2 -> + :: id == 2 -> if :: atomic{ t12t2?[msg, temp_e_key.id, temp_e_key.version, temp_e_key.ref_id, temp_e_key.ref_version, grant] -> t12t2?msg, temp_e_key.id, temp_e_key.version, temp_e_key.ref_id, temp_e_key.ref_version, grant } -> @@ -144,7 +144,7 @@ proctype Tenant(int id) // Main selection loop do :: if - :: _pid == 1 && !(sent_1 && sent_2) && (encrypted_DEKs[0].id != 0 || encrypted_DEKs[1].id != 0) -> + :: id == 1 && !(sent_1 && sent_2) && (encrypted_DEKs[0].id != 0 || encrypted_DEKs[1].id != 0) -> goto Send_to_tenant :: else -> skip fi @@ -156,7 +156,7 @@ proctype Tenant(int id) Encrypt: if - :: _pid == 1 -> + :: id == 1 -> do :: t12k!e_DEK, DEKs[0], assigned_KEKs[0], -1, -1, -1, id -> break :: t12k!e_DEK, DEKs[0], assigned_KEKs[1], -1, -1, -1, id -> break @@ -177,7 +177,7 @@ proctype Tenant(int id) Decrypt: if - :: _pid == 1 -> + :: id == 1 -> if :: encrypted_DEKs[0].id != 0 -> t12k!d_DEK, -1, encrypted_DEKs[0].ref_id, encrypted_DEKs[0].id, encrypted_DEKs[0].version, encrypted_DEKs[0].ref_version, id @@ -208,7 +208,7 @@ proctype Tenant(int id) if :: encrypted_DEKs[i].ref_id == recrypt_idx -> if // Send and Receive - :: _pid == 1 -> + :: id == 1 -> t12k!re_DEK, -1, encrypted_DEKs[i].ref_id, encrypted_DEKs[i].id, encrypted_DEKs[i].version, encrypted_DEKs[i].ref_version, id k2t1?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version :: else -> @@ -237,7 +237,7 @@ proctype Tenant(int id) Request_KEK: if - :: _pid == 1 -> t12k!ass_KEK, -1, -1, -1, -1, -1, id + :: id == 1 -> t12k!ass_KEK, -1, -1, -1, -1, -1, id :: else -> t22k!ass_KEK, -1, -1, -1, -1, -1, id fi @@ -260,7 +260,7 @@ proctype Tenant(int id) Receive: if - :: _pid == 1 -> + :: id == 1 -> k2t1?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version :: else -> k2t2?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version From fd161d3c4c0280dd46d2d6b119d0bb510b80ac48 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Thu, 2 May 2024 11:39:38 +0200 Subject: [PATCH 12/30] Formatting and edited comments --- SPIN-verification/dist_coms.pml | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/SPIN-verification/dist_coms.pml b/SPIN-verification/dist_coms.pml index a9f5461..ac8e0d4 100644 --- a/SPIN-verification/dist_coms.pml +++ b/SPIN-verification/dist_coms.pml @@ -75,7 +75,6 @@ init { clear_cache = false atomic { - int i @@ -124,7 +123,6 @@ proctype Tenant(int id) fi fi - // Receive from tenant 1 if :: id == 2 -> @@ -502,13 +500,12 @@ proctype Keystore() } /** - When the Clock component is disabled, the Database contains a timer - that acts as a clock sending signals to tenants when rotation has - been executed. Rotation is not time-sensitive such that it is affected - by distributed clock-sync issues, so it could also be seen as a tenant - quering a clock to see if the scheduled rotation that could be part - of the metadata in the KEK information available to the tenant has - taken place. + The Database contains a timer that acts as a clock sending signals to + tenants when rotation has been executed. Rotation is not time-sensitive + such that it is affected by distributed clock-sync issues, so it could + also be seen as a tenant quering a clock to see if the scheduled rotation + that could be part of the metadata in the KEK information available to + the tenant has taken place. */ proctype Database() { @@ -646,7 +643,6 @@ proctype Database() { } - /* ## Access Control Info ## From 9dddc3880bb2698a22a7e6c0f671ff86a737e079 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Thu, 2 May 2024 17:24:30 +0200 Subject: [PATCH 13/30] Added some information in README.md --- SPIN-verification/README.md | 12 ++++++++++++ SPIN-verification/dist_coms.pml | 27 +++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/SPIN-verification/README.md b/SPIN-verification/README.md index f803eaa..8ec8515 100644 --- a/SPIN-verification/README.md +++ b/SPIN-verification/README.md @@ -7,6 +7,18 @@ By flagging **SAME_KEK_ASSIGNED** as true the max number of KEKs assigned will b On set intervals defined as constants, KEKs will be rotated in the database and signals will be sent to the tenants assigned those KEKs. Tenants will then Re-encrypt those encrypted DEKs in order to rotate the encryption.
+## To Run +Most of this can be done with an external tool such as iSpin, additional information found [here](https://spinroot.com/spin/Man/README.html).
+spin -T dist_coms.pml - Regular run that will halt on error and print any statements in the code.
+spin -T -a dist_coms.pml - generates pan.c for verification.
+ +**Compile pan.c** +gcc -w -o pan pan.c - (semi-)optional flags used currently (-DMEMLIM=12000 -O2 -DVECTORSZ=1280 -DXUSAFE )
+ +**Verify** +./pan -m100000000 -a -c1
+ + ## Some Default Values Number of Tenants: 2
Number of DEKs per Tenant: 2
diff --git a/SPIN-verification/dist_coms.pml b/SPIN-verification/dist_coms.pml index ac8e0d4..eabb7df 100644 --- a/SPIN-verification/dist_coms.pml +++ b/SPIN-verification/dist_coms.pml @@ -68,6 +68,13 @@ chan db2t2 = [DB2T_MAX] of { mtype, int } // Database -> Tenant 2 int timer bool clear_cache +// LTL variables +int enc_1 = 1000, u_enc_1 = 1, enc_2 = 1000, u_enc_2 = 1 + + +// LTL claims +// ltl { [] conf } +//ltl Confidentiality { [] (enc_1 != u_enc_1 && enc_2 != u_enc_2 && enc_1 > 100 && enc_2 > 100 && u_enc_1 < 5 && u_enc_2 < 5) } init { @@ -266,16 +273,32 @@ proctype Tenant(int id) if :: msg == ass_KEK -> - // KEK.id is stored in temp_e_key.ref_id to simplify channel operation assigned_KEKs[ass_idx] = temp_e_key.ref_id ass_idx++ :: msg == d_DEK -> assert(temp_key == DEKs[(temp_key-1)%2] || (temp_key == received_e_DEKs[(temp_key-1)%2].id-ENC_DUMMY && grant == VALID_GRANT)) assert(DEKs[0] != received_e_DEKs[(temp_key-1)%2].id-ENC_DUMMY) assert(DEKs[1] != received_e_DEKs[(temp_key-1)%2].id-ENC_DUMMY) + if + :: id == 1 -> + enc_1 = encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].id + u_enc_1 = temp_key + :: else -> + enc_2 = encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].id + u_enc_2 = temp_key + enc_2 = received_e_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].id + fi :: msg == deny -> skip :: msg == e_DEK -> assert(temp_e_key.version > encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].version) + if + :: id == 1 -> + enc_1 = temp_e_key.id + u_enc_1 = DEKs[(temp_e_key.id-ENC_DUMMY-1)%2] + :: else -> + enc_2 = temp_e_key.id + u_enc_2 = DEKs[(temp_e_key.id-ENC_DUMMY-1)%2] + fi encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].id = temp_e_key.id encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].version = temp_e_key.version encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].ref_id = temp_e_key.ref_id @@ -510,7 +533,7 @@ proctype Keystore() proctype Database() { mtype msg - int dek_id, kek_id, i, tenant_id + int kek_id, i, tenant_id Key p_KEKs[NUM_KEKS] for (i in p_KEKs) { From f21e16d96443343e0d58927471e03fd06f858332 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Thu, 2 May 2024 17:26:56 +0200 Subject: [PATCH 14/30] Formatting in README.md --- SPIN-verification/README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/SPIN-verification/README.md b/SPIN-verification/README.md index 8ec8515..5867bc4 100644 --- a/SPIN-verification/README.md +++ b/SPIN-verification/README.md @@ -7,15 +7,17 @@ By flagging **SAME_KEK_ASSIGNED** as true the max number of KEKs assigned will b On set intervals defined as constants, KEKs will be rotated in the database and signals will be sent to the tenants assigned those KEKs. Tenants will then Re-encrypt those encrypted DEKs in order to rotate the encryption.
-## To Run +## To Run and Verify Most of this can be done with an external tool such as iSpin, additional information found [here](https://spinroot.com/spin/Man/README.html).
+ +**Run Code**
spin -T dist_coms.pml - Regular run that will halt on error and print any statements in the code.
spin -T -a dist_coms.pml - generates pan.c for verification.
-**Compile pan.c** +**Compile pan.c**
gcc -w -o pan pan.c - (semi-)optional flags used currently (-DMEMLIM=12000 -O2 -DVECTORSZ=1280 -DXUSAFE )
-**Verify** +**Verify**
./pan -m100000000 -a -c1
From f765133f27f4471b0783d083b59ab50a1b9e28f8 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Fri, 3 May 2024 19:57:02 +0200 Subject: [PATCH 15/30] Reduced memory usage significantly --- SPIN-verification/README.md | 2 +- SPIN-verification/dist_coms.pml | 835 ++++++++++++++++++-------------- 2 files changed, 470 insertions(+), 367 deletions(-) diff --git a/SPIN-verification/README.md b/SPIN-verification/README.md index 5867bc4..a135205 100644 --- a/SPIN-verification/README.md +++ b/SPIN-verification/README.md @@ -5,7 +5,7 @@ When Tenant 1 has encrypted a DEK, it is sent to Tenant 2 together with a *grant By flagging **SAME_KEK_ASSIGNED** as true the max number of KEKs assigned will be set to 1 and both Tenants will be assigned the same KEK from the Keystore. This alternative model introduces a faulty behavior to observe verification failure.
-On set intervals defined as constants, KEKs will be rotated in the database and signals will be sent to the tenants assigned those KEKs. Tenants will then Re-encrypt those encrypted DEKs in order to rotate the encryption.
+On set intervals defined as constants, KEKs will be rotated in the database and signals will be sent to the tenants assigned those KEKs. Tenants will then re-encrypt those encrypted DEKs in order to rotate the encryption.
## To Run and Verify Most of this can be done with an external tool such as iSpin, additional information found [here](https://spinroot.com/spin/Man/README.html).
diff --git a/SPIN-verification/dist_coms.pml b/SPIN-verification/dist_coms.pml index eabb7df..a5b8db0 100644 --- a/SPIN-verification/dist_coms.pml +++ b/SPIN-verification/dist_coms.pml @@ -1,19 +1,20 @@ #define NUM_DEKS 2 #define NUM_KEKS 4 #define NUM_TENANTS 2 -#define T2K_MAX 3 +#define T2K_MAX 1 #define K2T_MAX 0 #define K2AC_MAX 0 #define AC2K_MAX 0 -#define K2DB_MAX 3 +#define K2DB_MAX 1 #define DB2K_MAX 0 -#define DB2T_MAX 5 +#define DB2T_MAX 2 #define T_SEND_MAX 2 #define ASS_MAX 2 #define SAME_KEK_MAX 1 -#define GRANT 123 -#define VALID_GRANT 123 -#define ENC_DUMMY 100 +#define GRANT 1 +#define VALID_GRANT 1 +#define ENC_DUMMY 5 +#define EMPTY_PASS 0 #define ROT_KEK_1 15000 #define ROT_KEK_2 18000 #define ROT_KEK_3 25000 @@ -21,55 +22,56 @@ #define CACHE_CLEAR 4000 #define SAME_KEK_ASSIGNED false -typedef Key { /* Unencrypted */ - int id +typedef KEK { /* Unencrypted */ + unsigned id : 3 int version - int assigned_to + unsigned assigned_to : 2 } typedef E_Key { /* Encrypted */ - int id + unsigned id : 4 int version - int ref_id + unsigned ref_id : 4 int ref_version } mtype = { e_DEK, d_DEK, re_DEK, ass_KEK, rot_KEK, send_e_DEK, deny, ack } -// u: Tenant +// t: Tenant // k: Keystore // ac: Access Control +// db: Database -// { message type, DEK_ID, KEK_ID, E_KEY-ID, E_KEY-VERSION, E_KEY-REF-V, TENANT_ID, (GRANT) } +// { message type, DEK_ID, KEK_ID, E_KEY-ID, E_KEY-VERSION, E_KEY-REF_V, TENANT_ID, (GRANT) } // KEK_ID shares index to E_KEY-REF-ID in channels to reduce channel width -chan t12k = [T2K_MAX] of { mtype, int, int, int, int, int, int } // Tenant 1 -> Keystore -chan t22k = [T2K_MAX] of { mtype, int, int, int, int, int, int, int } // Tenant 2 -> Keystore, added int field for grant token from Tenant 1 -chan k2t1 = [K2T_MAX] of { mtype, int, int, int, int, int } // Keystore -> Tenant 1 -chan k2t2 = [K2T_MAX] of { mtype, int, int, int, int, int } // Keystore -> Tenant 2 +chan t12k = [T2K_MAX] of { mtype, byte, byte, byte, int, int, byte } // Tenant 1 -> Keystore +chan t22k = [T2K_MAX] of { mtype, byte, byte, byte, int, int, byte, byte } // Tenant 2 -> Keystore, added byte field for grant token from Tenant 1 +chan k2t1 = [K2T_MAX] of { mtype, byte, byte, byte, int, int } // Keystore -> Tenant 1 +chan k2t2 = [K2T_MAX] of { mtype, byte, byte, byte, int, int } // Keystore -> Tenant 2 -// { message type, E_KEY-ID, E_KEY-VERSION, E_KEY-REF_ID, E_KEY-REF-V, GRANT } -chan t12t2 = [T_SEND_MAX] of { mtype, int, int, int, int, int } // Tenant 1 -> Tenant 2 +// { message type, E_KEY-ID, E_KEY-VERSION, E_KEY-REF_ID, E_KEY-REF_V, GRANT } +chan t12t2 = [T_SEND_MAX] of { mtype, byte, byte, byte, int, byte } // Tenant 1 -> Tenant 2 // { message type, KEK_ID, TENANT_ID, GRANT} -chan k2ac = [K2AC_MAX] of { mtype, int, int, int } // Keystore -> Access Control +chan k2ac = [K2AC_MAX] of { mtype, byte, byte, byte } // Keystore -> Access Control chan ac2k = [AC2K_MAX] of { mtype } // Access Control -> Keystore // { message type, KEK_ID, TENANT_ID} -chan k2db = [K2DB_MAX] of { mtype, int, int } // Keystore -> Database -// { message type, KEK_ID, KEK_VERSION, KEK_ASS-TO } -chan db2k = [DB2K_MAX] of { mtype, int, int, int } // Database -> Keystore +chan k2db = [K2DB_MAX] of { mtype, byte, byte } // Keystore -> Database +// { message type, KEK_ID, KEK-VERSION, KEK-ASS_TO } +chan db2k = [DB2K_MAX] of { mtype, byte, int, byte } // Database -> Keystore // This channel emulates an external component notifying // the tenant when a rotation has taken place // { message type, KEK_ID } -chan db2t1 = [DB2T_MAX] of { mtype, int } // Database -> Tenant 1 -chan db2t2 = [DB2T_MAX] of { mtype, int } // Database -> Tenant 2 +chan db2t1 = [DB2T_MAX] of { mtype, byte } // Database -> Tenant 1 +chan db2t2 = [DB2T_MAX] of { mtype, byte } // Database -> Tenant 2 int timer bool clear_cache // LTL variables -int enc_1 = 1000, u_enc_1 = 1, enc_2 = 1000, u_enc_2 = 1 +unsigned enc_1 : 4, u_enc_1 : 3, enc_2 : 4, u_enc_2 : 3 // LTL claims @@ -78,12 +80,15 @@ int enc_1 = 1000, u_enc_1 = 1, enc_2 = 1000, u_enc_2 = 1 init { - timer = 0 - clear_cache = false - atomic { + enc_1 = 15 + u_enc_1 = 0 + enc_2 = 15 + u_enc_2 = 0 + timer = 0 + clear_cache = false - int i + unsigned i : 2 for (i : 1 .. NUM_TENANTS) { run Tenant(i) @@ -95,56 +100,60 @@ init { } } -proctype Tenant(int id) +proctype Tenant(unsigned id : 2) { mtype msg - int temp_key, i, ass_idx, recrypt_idx, grant - int assigned_KEKs[NUM_KEKS/2], DEKs[NUM_DEKS] + unsigned temp_key : 3, i : 3, ass_idx : 2, recrypt_idx : 4 + bit grant + byte assigned_KEKs[NUM_KEKS/2], DEKs[NUM_DEKS] E_Key temp_e_key E_Key encrypted_DEKs[NUM_DEKS], received_e_DEKs[NUM_DEKS] bool sent_1, sent_2 - - for (i : 0 .. NUM_DEKS-1) { - DEKs[i] = i + 1 + NUM_DEKS*(id-1) + + atomic { + for (i : 0 .. NUM_DEKS-1) { + DEKs[i] = i + 1 + NUM_DEKS*(id-1) + } } Select_state: - if - :: SAME_KEK_ASSIGNED -> assert(assigned_KEKs[1] == 0) - :: else -> skip - fi - // Receive rotation update ping - if - :: id == 1 -> + atomic{ if - :: atomic{ db2t1?[msg, recrypt_idx] -> db2t1?msg, recrypt_idx } -> - goto Recrypt + :: SAME_KEK_ASSIGNED -> assert(assigned_KEKs[1] == 0) :: else -> skip fi - :: else -> + // Receive rotation update ping if - :: atomic{ db2t2?[msg, recrypt_idx] -> db2t2?msg, recrypt_idx } -> - goto Recrypt - :: else -> skip + :: id == 1 -> + if + :: db2t1?[msg, recrypt_idx] -> db2t1?msg, recrypt_idx -> + goto Recrypt + :: else -> skip + fi + :: else -> + if + :: db2t2?[msg, recrypt_idx] -> db2t2?msg, recrypt_idx -> + goto Recrypt + :: else -> skip + fi fi - fi - // Receive from tenant 1 - if - :: id == 2 -> if - :: atomic{ t12t2?[msg, temp_e_key.id, temp_e_key.version, temp_e_key.ref_id, temp_e_key.ref_version, grant] -> - t12t2?msg, temp_e_key.id, temp_e_key.version, temp_e_key.ref_id, temp_e_key.ref_version, grant } -> - assert(temp_e_key.id-ENC_DUMMY-1 < 2) - received_e_DEKs[temp_e_key.id-ENC_DUMMY-1].id = temp_e_key.id - received_e_DEKs[temp_e_key.id-ENC_DUMMY-1].version = temp_e_key.version - received_e_DEKs[temp_e_key.id-ENC_DUMMY-1].ref_id = temp_e_key.ref_id - received_e_DEKs[temp_e_key.id-ENC_DUMMY-1].ref_version = temp_e_key.ref_version + :: id == 2 -> + if + :: t12t2?[msg, temp_e_key.id, temp_e_key.version, temp_e_key.ref_id, temp_e_key.ref_version, grant] -> + t12t2?msg, temp_e_key.id, temp_e_key.version, temp_e_key.ref_id, temp_e_key.ref_version, grant -> + assert(temp_e_key.id-ENC_DUMMY-1 < 2) + received_e_DEKs[temp_e_key.id-ENC_DUMMY-1].id = temp_e_key.id + received_e_DEKs[temp_e_key.id-ENC_DUMMY-1].version = temp_e_key.version + received_e_DEKs[temp_e_key.id-ENC_DUMMY-1].ref_id = temp_e_key.ref_id + received_e_DEKs[temp_e_key.id-ENC_DUMMY-1].ref_version = temp_e_key.ref_version + :: else -> skip + fi :: else -> skip fi - :: else -> skip - fi + } // Main selection loop do @@ -160,79 +169,85 @@ proctype Tenant(int id) Encrypt: - if - :: id == 1 -> - do - :: t12k!e_DEK, DEKs[0], assigned_KEKs[0], -1, -1, -1, id -> break - :: t12k!e_DEK, DEKs[0], assigned_KEKs[1], -1, -1, -1, id -> break - :: t12k!e_DEK, DEKs[1], assigned_KEKs[0], -1, -1, -1, id -> break - :: t12k!e_DEK, DEKs[1], assigned_KEKs[1], -1, -1, -1, id -> break - od - :: else -> - do - :: t22k!e_DEK, DEKs[0], assigned_KEKs[0], -1, -1, -1, id, grant -> break - :: t22k!e_DEK, DEKs[0], assigned_KEKs[1], -1, -1, -1, id, grant -> break - :: t22k!e_DEK, DEKs[1], assigned_KEKs[0], -1, -1, -1, id, grant -> break - :: t22k!e_DEK, DEKs[1], assigned_KEKs[1], -1, -1, -1, id, grant -> break - od - fi + atomic { + if + :: id == 1 -> + do + :: t12k!e_DEK, DEKs[0], assigned_KEKs[0], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id -> break + :: t12k!e_DEK, DEKs[0], assigned_KEKs[1], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id -> break + :: t12k!e_DEK, DEKs[1], assigned_KEKs[0], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id -> break + :: t12k!e_DEK, DEKs[1], assigned_KEKs[1], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id -> break + od + :: else -> + do + :: t22k!e_DEK, DEKs[0], assigned_KEKs[0], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant -> break + :: t22k!e_DEK, DEKs[0], assigned_KEKs[1], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant -> break + :: t22k!e_DEK, DEKs[1], assigned_KEKs[0], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant -> break + :: t22k!e_DEK, DEKs[1], assigned_KEKs[1], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant -> break + od + fi + } goto Receive Decrypt: - if - :: id == 1 -> + atomic { if - :: encrypted_DEKs[0].id != 0 -> - t12k!d_DEK, -1, encrypted_DEKs[0].ref_id, encrypted_DEKs[0].id, encrypted_DEKs[0].version, encrypted_DEKs[0].ref_version, id - :: encrypted_DEKs[1].id != 0 -> - t12k!d_DEK, -1, encrypted_DEKs[1].ref_id, encrypted_DEKs[1].id, encrypted_DEKs[1].version, encrypted_DEKs[1].ref_version, id - :: else -> goto Select_state - fi - :: else -> - if - :: encrypted_DEKs[0].id != 0 -> - t22k!d_DEK, -1, encrypted_DEKs[0].ref_id, encrypted_DEKs[0].id, encrypted_DEKs[0].version, encrypted_DEKs[0].ref_version, id, grant - :: encrypted_DEKs[1].id != 0 -> - t22k!d_DEK, -1, encrypted_DEKs[1].ref_id, encrypted_DEKs[1].id, encrypted_DEKs[1].version, encrypted_DEKs[1].ref_version, id, grant - :: received_e_DEKs[0].id != 0 -> - t22k!d_DEK, -1, received_e_DEKs[0].ref_id, received_e_DEKs[0].id, received_e_DEKs[0].version, received_e_DEKs[0].ref_version, id, grant - :: received_e_DEKs[1].id != 0 -> - t22k!d_DEK, -1, received_e_DEKs[1].ref_id, received_e_DEKs[1].id, received_e_DEKs[1].version, received_e_DEKs[1].ref_version, id, grant - :: else -> goto Select_state + :: id == 1 -> + if + :: encrypted_DEKs[0].id != 0 -> + t12k!d_DEK, EMPTY_PASS, encrypted_DEKs[0].ref_id, encrypted_DEKs[0].id, encrypted_DEKs[0].version, encrypted_DEKs[0].ref_version, id + :: encrypted_DEKs[1].id != 0 -> + t12k!d_DEK, EMPTY_PASS, encrypted_DEKs[1].ref_id, encrypted_DEKs[1].id, encrypted_DEKs[1].version, encrypted_DEKs[1].ref_version, id + :: else -> goto Select_state + fi + :: else -> + if + :: encrypted_DEKs[0].id != 0 -> + t22k!d_DEK, EMPTY_PASS, encrypted_DEKs[0].ref_id, encrypted_DEKs[0].id, encrypted_DEKs[0].version, encrypted_DEKs[0].ref_version, id, grant + :: encrypted_DEKs[1].id != 0 -> + t22k!d_DEK, EMPTY_PASS, encrypted_DEKs[1].ref_id, encrypted_DEKs[1].id, encrypted_DEKs[1].version, encrypted_DEKs[1].ref_version, id, grant + :: received_e_DEKs[0].id != 0 -> + t22k!d_DEK, EMPTY_PASS, received_e_DEKs[0].ref_id, received_e_DEKs[0].id, received_e_DEKs[0].version, received_e_DEKs[0].ref_version, id, grant + :: received_e_DEKs[1].id != 0 -> + t22k!d_DEK, EMPTY_PASS, received_e_DEKs[1].ref_id, received_e_DEKs[1].id, received_e_DEKs[1].version, received_e_DEKs[1].ref_version, id, grant + :: else -> goto Select_state + fi fi - fi + } goto Receive Recrypt: - i = 0; + i = 0 for (i in encrypted_DEKs) { if :: encrypted_DEKs[i].ref_id == recrypt_idx -> if // Send and Receive :: id == 1 -> - t12k!re_DEK, -1, encrypted_DEKs[i].ref_id, encrypted_DEKs[i].id, encrypted_DEKs[i].version, encrypted_DEKs[i].ref_version, id + t12k!re_DEK, EMPTY_PASS, encrypted_DEKs[i].ref_id, encrypted_DEKs[i].id, encrypted_DEKs[i].version, encrypted_DEKs[i].ref_version, id k2t1?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version :: else -> - t22k!re_DEK, -1, encrypted_DEKs[i].ref_id, encrypted_DEKs[i].id, encrypted_DEKs[i].version, encrypted_DEKs[i].ref_version, id, grant + t22k!re_DEK, EMPTY_PASS, encrypted_DEKs[i].ref_id, encrypted_DEKs[i].id, encrypted_DEKs[i].version, encrypted_DEKs[i].ref_version, id, grant k2t2?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version fi - if - :: msg != deny -> - assert(temp_e_key.version > encrypted_DEKs[i].version) - assert(temp_e_key.ref_version >= encrypted_DEKs[i].ref_version) - assert(encrypted_DEKs[i].id == temp_e_key.id) - assert(recrypt_idx == temp_e_key.ref_id) - encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].id = temp_e_key.id - encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].version = temp_e_key.version - encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].ref_id = temp_e_key.ref_id - encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].ref_version = temp_e_key.ref_version - :: else -> skip - fi + d_step { + if + :: msg != deny -> + assert(temp_e_key.version > encrypted_DEKs[i].version) + assert(temp_e_key.ref_version >= encrypted_DEKs[i].ref_version) + assert(encrypted_DEKs[i].id == temp_e_key.id) + assert(recrypt_idx == temp_e_key.ref_id) + encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].id = temp_e_key.id + encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].version = temp_e_key.version + encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].ref_id = temp_e_key.ref_id + encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].ref_version = temp_e_key.ref_version + :: else -> skip + fi + } :: else -> skip fi } @@ -241,24 +256,28 @@ proctype Tenant(int id) Request_KEK: - if - :: id == 1 -> t12k!ass_KEK, -1, -1, -1, -1, -1, id - :: else -> t22k!ass_KEK, -1, -1, -1, -1, -1, id - fi + atomic { + if + :: id == 1 -> t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id + :: else -> t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id + fi + } goto Receive Send_to_tenant: - if - :: encrypted_DEKs[0].id != 0 -> - t12t2!send_e_DEK, encrypted_DEKs[0].id, encrypted_DEKs[0].version, encrypted_DEKs[0].ref_id, encrypted_DEKs[0].ref_version, GRANT - sent_1 = true - :: encrypted_DEKs[1].id != 0 -> - t12t2!send_e_DEK, encrypted_DEKs[1].id, encrypted_DEKs[1].version, encrypted_DEKs[1].ref_id, encrypted_DEKs[1].ref_version, GRANT - sent_2 = true - :: else -> skip - fi + atomic { + if + :: encrypted_DEKs[0].id != 0 -> + t12t2!send_e_DEK, encrypted_DEKs[0].id, encrypted_DEKs[0].version, encrypted_DEKs[0].ref_id, encrypted_DEKs[0].ref_version, GRANT + sent_1 = true + :: encrypted_DEKs[1].id != 0 -> + t12t2!send_e_DEK, encrypted_DEKs[1].id, encrypted_DEKs[1].version, encrypted_DEKs[1].ref_id, encrypted_DEKs[1].ref_version, GRANT + sent_2 = true + :: else -> skip + fi + } goto Select_state @@ -270,40 +289,46 @@ proctype Tenant(int id) :: else -> k2t2?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version fi - - if - :: msg == ass_KEK -> - assigned_KEKs[ass_idx] = temp_e_key.ref_id - ass_idx++ - :: msg == d_DEK -> - assert(temp_key == DEKs[(temp_key-1)%2] || (temp_key == received_e_DEKs[(temp_key-1)%2].id-ENC_DUMMY && grant == VALID_GRANT)) - assert(DEKs[0] != received_e_DEKs[(temp_key-1)%2].id-ENC_DUMMY) - assert(DEKs[1] != received_e_DEKs[(temp_key-1)%2].id-ENC_DUMMY) - if - :: id == 1 -> - enc_1 = encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].id - u_enc_1 = temp_key - :: else -> - enc_2 = encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].id - u_enc_2 = temp_key - enc_2 = received_e_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].id - fi - :: msg == deny -> skip - :: msg == e_DEK -> - assert(temp_e_key.version > encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].version) - if - :: id == 1 -> - enc_1 = temp_e_key.id - u_enc_1 = DEKs[(temp_e_key.id-ENC_DUMMY-1)%2] - :: else -> - enc_2 = temp_e_key.id - u_enc_2 = DEKs[(temp_e_key.id-ENC_DUMMY-1)%2] - fi - encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].id = temp_e_key.id - encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].version = temp_e_key.version - encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].ref_id = temp_e_key.ref_id - encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].ref_version = temp_e_key.ref_version - fi + + d_step { + if + :: msg == ass_KEK -> + assigned_KEKs[ass_idx] = temp_e_key.ref_id + ass_idx++ + :: msg == d_DEK -> + assert(temp_key == DEKs[(temp_key-1)%2] || (temp_key == received_e_DEKs[(temp_key-1)%2].id-ENC_DUMMY && grant == VALID_GRANT)) + assert(DEKs[0] != received_e_DEKs[(temp_key-1)%2].id-ENC_DUMMY) + assert(DEKs[1] != received_e_DEKs[(temp_key-1)%2].id-ENC_DUMMY) + if + :: id == 1 -> + enc_1 = encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].id + u_enc_1 = temp_key + :: else -> + enc_2 = encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].id + u_enc_2 = temp_key + enc_2 = received_e_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].id + fi + :: msg == deny -> skip + :: msg == e_DEK -> + assert(temp_e_key.version > encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].version) + if + :: id == 1 -> + enc_1 = temp_e_key.id + u_enc_1 = DEKs[(temp_e_key.id-ENC_DUMMY-1)%2] + :: else -> + enc_2 = temp_e_key.id + u_enc_2 = DEKs[(temp_e_key.id-ENC_DUMMY-1)%2] + fi + encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].id = temp_e_key.id + encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].version = temp_e_key.version + encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].ref_id = temp_e_key.ref_id + encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].ref_version = temp_e_key.ref_version + fi + enc_1 = 15 + u_enc_1 = 0 + enc_2 = 15 + u_enc_2 = 0 + } goto Select_state } @@ -311,47 +336,58 @@ proctype Tenant(int id) proctype Keystore() { mtype msg, enc_msg - int dek_id, kek_id, kek_ref, i, tenant_id, id, version, is_case, kek_idx, assigned_to, grant + int version + unsigned dek_id : 3, kek_id : 3, kek_ref : 4, i : 3, tenant_id : 2, id : 3, is_case : 2, kek_idx : 3, assigned_to : 2 + bit grant bool valid, received - Key temp_key + KEK temp_key E_Key temp_e_key - Key v_KEKs[NUM_KEKS] + KEK v_KEKs[NUM_KEKS] Select_state: - grant = 0 - - if // Clear Cache - :: clear_cache -> - i = 0 - for (i in v_KEKs) { - v_KEKs[i].id = 0 - v_KEKs[i].version = 0 - v_KEKs[i].assigned_to = 0 - } - clear_cache = false - :: else -> skip - fi + atomic { + if // Clear Cache + :: clear_cache -> + i = 0 + for (i in v_KEKs) { + v_KEKs[i].id = 0 + v_KEKs[i].version = 0 + v_KEKs[i].assigned_to = 0 + } + clear_cache = false + :: else -> skip + fi + } goto Receive Receive: + + atomic { - received = false + received = false - if - :: atomic{ t12k?[msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, tenant_id] -> - t12k?msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, tenant_id } -> - received = true - kek_id = kek_ref-ENC_DUMMY - :: atomic{ t22k?[msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, tenant_id, grant] -> - t22k?msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, tenant_id, grant } -> - received = true - kek_id = kek_ref-ENC_DUMMY - :: else -> skip - fi + if + :: t12k?[msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, tenant_id] -> + t12k?msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, tenant_id -> + received = true + if + :: kek_ref > 0 -> kek_id = kek_ref-ENC_DUMMY + :: else -> skip + fi + :: t22k?[msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, tenant_id, grant] -> + t22k?msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, tenant_id, grant -> + received = true + if + :: kek_ref > 0 -> kek_id = kek_ref-ENC_DUMMY + :: else -> skip + fi + :: else -> skip + fi + } if :: received -> @@ -375,12 +411,14 @@ proctype Keystore() :: msg == deny -> goto Deny_request :: else -> skip fi + + atomic { + v_KEKs[kek_idx].id = id + v_KEKs[kek_idx].version = version + v_KEKs[kek_idx].assigned_to = assigned_to - v_KEKs[kek_idx].id = id - v_KEKs[kek_idx].version = version - v_KEKs[kek_idx].assigned_to = assigned_to - - k2ac!msg, id, tenant_id, grant + k2ac!msg, id, tenant_id, grant + } ac2k?msg @@ -389,21 +427,25 @@ proctype Keystore() :: else -> skip fi - if - :: tenant_id == 1 -> k2t1!ass_KEK, -1, v_KEKs[kek_idx].id+ENC_DUMMY, -1, -1, -1 - :: else -> k2t2!ass_KEK, -1, v_KEKs[kek_idx].id+ENC_DUMMY, -1, -1, -1 - fi + atomic { + if + :: tenant_id == 1 -> k2t1!ass_KEK, EMPTY_PASS, v_KEKs[kek_idx].id+ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS + :: else -> k2t2!ass_KEK, EMPTY_PASS, v_KEKs[kek_idx].id+ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS + fi - if - :: !SAME_KEK_ASSIGNED -> kek_idx++ - :: else -> skip - fi + if + :: !SAME_KEK_ASSIGNED -> kek_idx++ + :: else -> skip + fi + } goto Select_state Decrypt: - valid = true + atomic { + valid = true + } k2ac!msg, kek_id, tenant_id, grant ac2k?msg @@ -426,16 +468,19 @@ proctype Keystore() k2db!d_DEK, kek_id, tenant_id db2k?msg, id, version, assigned_to - if - :: msg != deny -> - v_KEKs[id-1].id = id - v_KEKs[id-1].version = version + d_step { + if + :: msg != deny -> + v_KEKs[id-1].id = id + v_KEKs[id-1].version = version + if - :: v_KEKs[kek_id-1].version < temp_e_key.ref_version -> valid = false + :: v_KEKs[kek_id-1].version < temp_e_key.ref_version -> valid = false :: else -> skip fi - :: else -> valid = false - fi + :: else -> valid = false + fi + } :: is_case == 2 if :: v_KEKs[kek_id-1].version >= temp_e_key.ref_version -> @@ -443,14 +488,16 @@ proctype Keystore() :: else -> k2db!d_DEK, kek_id, tenant_id db2k?msg, id, version, assigned_to - - v_KEKs[id-1].version = id - v_KEKs[id-1].version = version - if - :: v_KEKs[id-1].version < temp_e_key.ref_version -> valid = false - :: else -> skip - fi + d_step { + v_KEKs[id-1].version = id + v_KEKs[id-1].version = version + + if + :: v_KEKs[id-1].version < temp_e_key.ref_version -> valid = false + :: else -> skip + fi + } fi :: else -> skip fi @@ -460,19 +507,23 @@ proctype Keystore() :: else -> goto Deny_request fi - if - :: tenant_id == 1 -> k2t1!d_DEK, temp_e_key.id-ENC_DUMMY, -1, -1, -1, -1 - :: else -> k2t2!d_DEK, temp_e_key.id-ENC_DUMMY, -1, -1, -1, -1 - fi + atomic { + if + :: tenant_id == 1 -> k2t1!d_DEK, temp_e_key.id-ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS + :: else -> k2t2!d_DEK, temp_e_key.id-ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS + fi + } goto Select_state Encrypt: - if - :: msg == re_DEK -> enc_msg = re_DEK - :: else -> enc_msg = e_DEK - fi + atomic { + if + :: msg == re_DEK -> enc_msg = re_DEK + :: else -> enc_msg = e_DEK + fi + } k2ac!msg, kek_id, tenant_id, grant ac2k?msg @@ -487,37 +538,44 @@ proctype Keystore() if :: msg != deny -> + d_step { v_KEKs[id-1].id = id v_KEKs[id-1].version = version v_KEKs[id-1].assigned_to = assigned_to + } :: else -> goto Deny_request fi assert(kek_id > 0 && kek_id <= NUM_KEKS) - if - :: enc_msg == re_DEK -> - assert(temp_e_key.ref_version <= v_KEKs[kek_id-1].version && temp_e_key.ref_version > v_KEKs[kek_id-1].version-2) - :: else -> temp_e_key.id = dek_id+ENC_DUMMY - fi - - temp_e_key.version = timer - temp_e_key.ref_id = v_KEKs[kek_id-1].id+ENC_DUMMY - temp_e_key.ref_version = v_KEKs[kek_id-1].version + d_step { + if + :: enc_msg == re_DEK -> + assert(temp_e_key.ref_version <= v_KEKs[kek_id-1].version && temp_e_key.ref_version > v_KEKs[kek_id-1].version-2) + :: else -> temp_e_key.id = dek_id+ENC_DUMMY + fi + temp_e_key.version = timer + temp_e_key.ref_id = v_KEKs[kek_id-1].id+ENC_DUMMY + temp_e_key.ref_version = v_KEKs[kek_id-1].version + } - if - :: tenant_id == 1 -> k2t1!enc_msg, -1, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version - :: else -> k2t2!enc_msg, -1, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version - fi + atomic { + if + :: tenant_id == 1 -> k2t1!enc_msg, EMPTY_PASS, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version + :: else -> k2t2!enc_msg, EMPTY_PASS, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version + fi + } goto Select_state Deny_request: - if - :: tenant_id == 1 -> k2t1!deny, -1, -1, -1, -1, -1 - :: else -> k2t2!deny, -1, -1, -1, -1, -1 - fi + atomic { + if + :: tenant_id == 1 -> k2t1!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS + :: else -> k2t2!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS + fi + } goto Select_state } @@ -533,91 +591,96 @@ proctype Keystore() proctype Database() { mtype msg - int kek_id, i, tenant_id - Key p_KEKs[NUM_KEKS] + unsigned kek_id : 3, i : 3, tenant_id : 2 + KEK p_KEKs[NUM_KEKS] + bool accessed - for (i in p_KEKs) { - p_KEKs[i].id = i+1 - p_KEKs[i].version = 1 + atomic { + for (i in p_KEKs) { + p_KEKs[i].id = i+1 + p_KEKs[i].version = 1 + } } Main: - timer++ + atomic { + timer++ - if // Cache timer - :: timer%CACHE_CLEAR == 0 -> - clear_cache = true - :: else -> skip - fi + if // Cache timer + :: timer%CACHE_CLEAR == 0 -> + clear_cache = true + :: else -> skip + fi - if // Rotation 1 - :: timer%ROT_KEK_1 == 0 -> - p_KEKs[0].version++ + if // Rotation 1 + :: timer%ROT_KEK_1 == 0 -> + p_KEKs[0].version++ - if - :: p_KEKs[0].assigned_to == 1 -> - db2t1!rot_KEK, p_KEKs[0].id+ENC_DUMMY - :: p_KEKs[0].assigned_to == 2 -> - db2t2!rot_KEK, p_KEKs[0].id+ENC_DUMMY - :: p_KEKs[0].assigned_to == 3 -> - db2t2!rot_KEK, p_KEKs[0].id+ENC_DUMMY - db2t1!rot_KEK, p_KEKs[0].id+ENC_DUMMY - :: else -> skip - fi - :: else -> skip - fi + if + :: p_KEKs[0].assigned_to == 1 -> + db2t1!rot_KEK, p_KEKs[0].id+ENC_DUMMY + :: p_KEKs[0].assigned_to == 2 -> + db2t2!rot_KEK, p_KEKs[0].id+ENC_DUMMY + :: p_KEKs[0].assigned_to == 3 -> + db2t2!rot_KEK, p_KEKs[0].id+ENC_DUMMY + db2t1!rot_KEK, p_KEKs[0].id+ENC_DUMMY + :: else -> skip + fi + :: else -> skip + fi - if // Rotation 2 - :: timer%ROT_KEK_2 == 0 -> - p_KEKs[1].version++ + if // Rotation 2 + :: timer%ROT_KEK_2 == 0 -> + p_KEKs[1].version++ - if - :: p_KEKs[1].assigned_to == 1 -> - db2t1!rot_KEK, p_KEKs[1].id+ENC_DUMMY - :: p_KEKs[1].assigned_to == 2 -> - db2t2!rot_KEK, p_KEKs[1].id+ENC_DUMMY - :: p_KEKs[1].assigned_to == 3 -> - db2t2!rot_KEK, p_KEKs[1].id+ENC_DUMMY - db2t1!rot_KEK, p_KEKs[1].id+ENC_DUMMY - :: else -> skip - fi - :: else -> skip - fi + if + :: p_KEKs[1].assigned_to == 1 -> + db2t1!rot_KEK, p_KEKs[1].id+ENC_DUMMY + :: p_KEKs[1].assigned_to == 2 -> + db2t2!rot_KEK, p_KEKs[1].id+ENC_DUMMY + :: p_KEKs[1].assigned_to == 3 -> + db2t2!rot_KEK, p_KEKs[1].id+ENC_DUMMY + db2t1!rot_KEK, p_KEKs[1].id+ENC_DUMMY + :: else -> skip + fi + :: else -> skip + fi - if // Rotation 3 - :: timer%ROT_KEK_3 == 0 -> - p_KEKs[2].version++ + if // Rotation 3 + :: timer%ROT_KEK_3 == 0 -> + p_KEKs[2].version++ - if - :: p_KEKs[2].assigned_to == 1 -> - db2t1!rot_KEK, p_KEKs[2].id+ENC_DUMMY - :: p_KEKs[2].assigned_to == 2 -> - db2t2!rot_KEK, p_KEKs[2].id+ENC_DUMMY - :: p_KEKs[2].assigned_to == 3 -> - db2t2!rot_KEK, p_KEKs[2].id+ENC_DUMMY - db2t1!rot_KEK, p_KEKs[2].id+ENC_DUMMY - :: else -> skip - fi - :: else -> skip - fi + if + :: p_KEKs[2].assigned_to == 1 -> + db2t1!rot_KEK, p_KEKs[2].id+ENC_DUMMY + :: p_KEKs[2].assigned_to == 2 -> + db2t2!rot_KEK, p_KEKs[2].id+ENC_DUMMY + :: p_KEKs[2].assigned_to == 3 -> + db2t2!rot_KEK, p_KEKs[2].id+ENC_DUMMY + db2t1!rot_KEK, p_KEKs[2].id+ENC_DUMMY + :: else -> skip + fi + :: else -> skip + fi - if // Rotation 4 - :: timer%ROT_KEK_4 == 0 -> - p_KEKs[3].version++ + if // Rotation 4 + :: timer%ROT_KEK_4 == 0 -> + p_KEKs[3].version++ - if - :: p_KEKs[3].assigned_to == 1 -> - db2t1!rot_KEK, p_KEKs[3].id+ENC_DUMMY - :: p_KEKs[3].assigned_to == 2 -> - db2t2!rot_KEK, p_KEKs[3].id+ENC_DUMMY - :: p_KEKs[3].assigned_to == 3 -> - db2t2!rot_KEK, p_KEKs[3].id+ENC_DUMMY - db2t1!rot_KEK, p_KEKs[3].id+ENC_DUMMY - :: else -> skip - fi - :: else -> skip - fi + if + :: p_KEKs[3].assigned_to == 1 -> + db2t1!rot_KEK, p_KEKs[3].id+ENC_DUMMY + :: p_KEKs[3].assigned_to == 2 -> + db2t2!rot_KEK, p_KEKs[3].id+ENC_DUMMY + :: p_KEKs[3].assigned_to == 3 -> + db2t2!rot_KEK, p_KEKs[3].id+ENC_DUMMY + db2t1!rot_KEK, p_KEKs[3].id+ENC_DUMMY + :: else -> skip + fi + :: else -> skip + fi + } if :: atomic{ k2db?[msg, kek_id, tenant_id] -> k2db?msg, kek_id, tenant_id } -> @@ -632,35 +695,39 @@ proctype Database() { Access_KEK: - i = 0 - for (i in p_KEKs) { - if - :: p_KEKs[i].id == kek_id -> - - timer++ + atomic { + accessed = false + i = 0 + for (i in p_KEKs) { + if + :: p_KEKs[i].id == kek_id -> + + timer++ - if - :: msg == ass_KEK -> if - :: p_KEKs[i].assigned_to > 0 -> p_KEKs[i].assigned_to = 3 - :: else -> p_KEKs[i].assigned_to = tenant_id + :: msg == ass_KEK -> + if + :: p_KEKs[i].assigned_to > 0 -> p_KEKs[i].assigned_to = 3 + :: else -> p_KEKs[i].assigned_to = tenant_id + fi + :: else -> skip fi - :: else -> skip - fi - - db2k!msg, p_KEKs[i].id, p_KEKs[i].version, p_KEKs[i].assigned_to - - goto Main - - :: else -> skip - fi + + db2k!msg, p_KEKs[i].id, p_KEKs[i].version, p_KEKs[i].assigned_to + accessed = true + :: else -> skip + fi + } } - - goto Deny_request + + if + :: accessed -> goto Main + :: else -> goto Deny_request + fi Deny_request: - db2k!deny, -1, -1, -1 + atomic { db2k!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS } goto Main @@ -681,8 +748,10 @@ proctype Database() { proctype AccessControl() { mtype msg - int kek_id, tenant_id, idx, i, num_assigned, grant - int tnt_x_kek[NUM_TENANTS*NUM_KEKS] + unsigned kek_id : 3, tenant_id : 2, idx : 4, i : 3, num_assigned : 3 + bit grant + bool authorized + byte tnt_x_kek[NUM_TENANTS*NUM_KEKS] Select_state: @@ -698,67 +767,101 @@ proctype AccessControl() Assign_KEK: - num_assigned = 0 - i = 0 + atomic { + num_assigned = 0 + i = 0 + authorized = true + do + :: i < NUM_KEKS -> i++ + if + :: tnt_x_kek[(tenant_id-1)*NUM_KEKS+i-1] > 0 -> num_assigned++ + :: else -> skip + fi - do - :: i < NUM_KEKS -> i++ - if - :: tnt_x_kek[(tenant_id-1)*NUM_KEKS+i-1] > 0 -> num_assigned++ - :: else -> skip - fi + if + :: num_assigned >= ASS_MAX -> authorized = false -> break + :: SAME_KEK_ASSIGNED && num_assigned >= SAME_KEK_MAX -> authorized = false -> break + :: else -> skip + fi + :: else -> break + od + num_assigned = 0 + i = 0 + } + + if + :: !authorized -> goto Deny_request + :: else -> skip + fi + + d_step { + idx = (tenant_id - 1) * NUM_KEKS + (kek_id - 1) if - :: num_assigned >= ASS_MAX -> goto Deny_request - :: SAME_KEK_ASSIGNED && num_assigned >= SAME_KEK_MAX -> goto Deny_request - :: else -> skip + :: tnt_x_kek[idx] > 1 -> authorized = false + :: else -> tnt_x_kek[idx] = 1 fi - :: else -> break - od - - idx = (tenant_id - 1) * NUM_KEKS + (kek_id - 1) + idx = 0 + } if - :: tnt_x_kek[idx] > 1 -> goto Deny_request - :: else -> tnt_x_kek[idx] = 1 + :: !authorized -> goto Deny_request + :: else -> skip fi goto Ack_request Authorize: - idx = (tenant_id - 1) * NUM_KEKS + (kek_id - 1) - - if - :: idx >= 0 && idx < NUM_TENANTS*NUM_KEKS -> + atomic { if - :: tnt_x_kek[idx] < 1 -> + :: kek_id == 0 -> authorized = false + :: else -> skip + fi + + if + :: authorized -> + idx = (tenant_id - 1) * NUM_KEKS + (kek_id - 1) + if - :: grant == VALID_GRANT -> - idx = kek_id - 1 + :: idx >= 0 && idx < NUM_TENANTS*NUM_KEKS -> if - :: tnt_x_kek[idx] < 1 -> goto Deny_request + :: tnt_x_kek[idx] < 1 -> + if + :: grant == VALID_GRANT -> + idx = kek_id - 1 + if + :: tnt_x_kek[idx] < 1 -> authorized = false + :: else -> skip + fi + :: else -> authorized = false + fi :: else -> skip fi - :: else -> goto Deny_request + :: else -> authorized = false fi :: else -> skip fi - :: else -> goto Deny_request - fi + idx = 0 + } + + if + :: !authorized -> goto Deny_request + :: else -> skip + fi goto Ack_request Ack_request: - ac2k!ack + atomic { ac2k!ack } goto Select_state Deny_request: - ac2k!deny + atomic { ac2k!deny } goto Select_state From 5e0a755b7067c74a0154f85baa0bc5966466f2e4 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Mon, 13 May 2024 12:32:56 +0200 Subject: [PATCH 16/30] New model_c which is asynch and can handle 2 requests and be run in about 30 minutes --- SPIN-verification/dist_coms.pml | 240 ++++++---- SPIN-verification/model_c.pml | 778 ++++++++++++++++++++++++++++++++ 2 files changed, 931 insertions(+), 87 deletions(-) create mode 100644 SPIN-verification/model_c.pml diff --git a/SPIN-verification/dist_coms.pml b/SPIN-verification/dist_coms.pml index a5b8db0..224a5d1 100644 --- a/SPIN-verification/dist_coms.pml +++ b/SPIN-verification/dist_coms.pml @@ -15,10 +15,10 @@ #define VALID_GRANT 1 #define ENC_DUMMY 5 #define EMPTY_PASS 0 -#define ROT_KEK_1 15000 -#define ROT_KEK_2 18000 -#define ROT_KEK_3 25000 -#define ROT_KEK_4 24000 +#define ROT_KEK_1 400000 +#define ROT_KEK_2 240000 +#define ROT_KEK_3 210000 +#define ROT_KEK_4 440000 #define CACHE_CLEAR 4000 #define SAME_KEK_ASSIGNED false @@ -50,7 +50,7 @@ chan k2t1 = [K2T_MAX] of { mtype, byte, byte, byte, int, int } // Keystore -> Te chan k2t2 = [K2T_MAX] of { mtype, byte, byte, byte, int, int } // Keystore -> Tenant 2 // { message type, E_KEY-ID, E_KEY-VERSION, E_KEY-REF_ID, E_KEY-REF_V, GRANT } -chan t12t2 = [T_SEND_MAX] of { mtype, byte, byte, byte, int, byte } // Tenant 1 -> Tenant 2 +chan t12t2 = [T_SEND_MAX] of { mtype, byte, int, byte, int, byte } // Tenant 1 -> Tenant 2 // { message type, KEK_ID, TENANT_ID, GRANT} chan k2ac = [K2AC_MAX] of { mtype, byte, byte, byte } // Keystore -> Access Control @@ -67,24 +67,20 @@ chan db2k = [DB2K_MAX] of { mtype, byte, int, byte } // Database -> Keystore chan db2t1 = [DB2T_MAX] of { mtype, byte } // Database -> Tenant 1 chan db2t2 = [DB2T_MAX] of { mtype, byte } // Database -> Tenant 2 - +chan a = [0] of {int} int timer -bool clear_cache +bool clear_cache, done // LTL variables -unsigned enc_1 : 4, u_enc_1 : 3, enc_2 : 4, u_enc_2 : 3 +unsigned enc_1 : 4 = 15, u_enc_1 : 4 = 14, enc_2 : 4 = 15, u_enc_2 : 4 = 14, sent : 2 // LTL claims // ltl { [] conf } -//ltl Confidentiality { [] (enc_1 != u_enc_1 && enc_2 != u_enc_2 && enc_1 > 100 && enc_2 > 100 && u_enc_1 < 5 && u_enc_2 < 5) } - +// ltl Confidentiality { [] (enc_1 != u_enc_1 && enc_2 != u_enc_2 && enc_1 > 4 && enc_2 > 4 && (u_enc_1 == 14||u_enc_1 < 5) && (u_enc_2 == 14 || u_enc_2 < 5)) } +// bool ps_confidentiality, ps_integrity, ps_authentication, ps_authorization, ps_consistency, pl_confidentiality, pl_integrity, pl_authentication, pl_authorization, pl_consistency +// TRY TO VIOLATE LTL init { - atomic { - enc_1 = 15 - u_enc_1 = 0 - enc_2 = 15 - u_enc_2 = 0 timer = 0 clear_cache = false @@ -96,10 +92,10 @@ init { run Database() run Keystore() run AccessControl() - } } + proctype Tenant(unsigned id : 2) { mtype msg @@ -107,8 +103,8 @@ proctype Tenant(unsigned id : 2) bit grant byte assigned_KEKs[NUM_KEKS/2], DEKs[NUM_DEKS] E_Key temp_e_key - E_Key encrypted_DEKs[NUM_DEKS], received_e_DEKs[NUM_DEKS] - bool sent_1, sent_2 + E_Key encrypted_DEKs[NUM_DEKS], received_e_DEK + bool sent2tenant atomic { for (i : 0 .. NUM_DEKS-1) { @@ -117,8 +113,9 @@ proctype Tenant(unsigned id : 2) } Select_state: - + enc_1 = u_enc_1 atomic{ + if :: SAME_KEK_ASSIGNED -> assert(assigned_KEKs[1] == 0) :: else -> skip @@ -126,6 +123,8 @@ proctype Tenant(unsigned id : 2) // Receive rotation update ping if :: id == 1 -> + // printf("encrypted_DEKs[%d]: %d\n", 0, encrypted_DEKs[0].id) + // printf("encrypted_DEKs[%d]: %d\n", 1, encrypted_DEKs[1].id) if :: db2t1?[msg, recrypt_idx] -> db2t1?msg, recrypt_idx -> goto Recrypt @@ -141,27 +140,31 @@ proctype Tenant(unsigned id : 2) // Receive from tenant 1 if :: id == 2 -> + if :: t12t2?[msg, temp_e_key.id, temp_e_key.version, temp_e_key.ref_id, temp_e_key.ref_version, grant] -> t12t2?msg, temp_e_key.id, temp_e_key.version, temp_e_key.ref_id, temp_e_key.ref_version, grant -> assert(temp_e_key.id-ENC_DUMMY-1 < 2) - received_e_DEKs[temp_e_key.id-ENC_DUMMY-1].id = temp_e_key.id - received_e_DEKs[temp_e_key.id-ENC_DUMMY-1].version = temp_e_key.version - received_e_DEKs[temp_e_key.id-ENC_DUMMY-1].ref_id = temp_e_key.ref_id - received_e_DEKs[temp_e_key.id-ENC_DUMMY-1].ref_version = temp_e_key.ref_version + received_e_DEK.id = temp_e_key.id + received_e_DEK.version = temp_e_key.version + received_e_DEK.ref_id = temp_e_key.ref_id + received_e_DEK.ref_version = temp_e_key.ref_version :: else -> skip fi :: else -> skip fi } + + + + // if + // :: id == 1 -> printf("HERE\n") + // :: else -> skip + // fi + // Main selection loop do - :: if - :: id == 1 && !(sent_1 && sent_2) && (encrypted_DEKs[0].id != 0 || encrypted_DEKs[1].id != 0) -> - goto Send_to_tenant - :: else -> skip - fi :: goto Encrypt :: goto Decrypt :: goto Request_KEK @@ -169,24 +172,26 @@ proctype Tenant(unsigned id : 2) Encrypt: - atomic { if :: id == 1 -> - do - :: t12k!e_DEK, DEKs[0], assigned_KEKs[0], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id -> break - :: t12k!e_DEK, DEKs[0], assigned_KEKs[1], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id -> break - :: t12k!e_DEK, DEKs[1], assigned_KEKs[0], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id -> break - :: t12k!e_DEK, DEKs[1], assigned_KEKs[1], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id -> break - od + atomic { + do + :: t12k!e_DEK, DEKs[0], assigned_KEKs[0], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id -> break + :: t12k!e_DEK, DEKs[0], assigned_KEKs[1], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id -> break + :: t12k!e_DEK, DEKs[1], assigned_KEKs[0], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id -> break + :: t12k!e_DEK, DEKs[1], assigned_KEKs[1], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id -> break + od + } :: else -> - do - :: t22k!e_DEK, DEKs[0], assigned_KEKs[0], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant -> break - :: t22k!e_DEK, DEKs[0], assigned_KEKs[1], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant -> break - :: t22k!e_DEK, DEKs[1], assigned_KEKs[0], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant -> break - :: t22k!e_DEK, DEKs[1], assigned_KEKs[1], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant -> break - od + atomic { + do + :: t22k!e_DEK, DEKs[0], assigned_KEKs[0], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant -> break + :: t22k!e_DEK, DEKs[0], assigned_KEKs[1], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant -> break + :: t22k!e_DEK, DEKs[1], assigned_KEKs[0], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant -> break + :: t22k!e_DEK, DEKs[1], assigned_KEKs[1], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant -> break + od + } fi - } goto Receive @@ -208,10 +213,8 @@ proctype Tenant(unsigned id : 2) t22k!d_DEK, EMPTY_PASS, encrypted_DEKs[0].ref_id, encrypted_DEKs[0].id, encrypted_DEKs[0].version, encrypted_DEKs[0].ref_version, id, grant :: encrypted_DEKs[1].id != 0 -> t22k!d_DEK, EMPTY_PASS, encrypted_DEKs[1].ref_id, encrypted_DEKs[1].id, encrypted_DEKs[1].version, encrypted_DEKs[1].ref_version, id, grant - :: received_e_DEKs[0].id != 0 -> - t22k!d_DEK, EMPTY_PASS, received_e_DEKs[0].ref_id, received_e_DEKs[0].id, received_e_DEKs[0].version, received_e_DEKs[0].ref_version, id, grant - :: received_e_DEKs[1].id != 0 -> - t22k!d_DEK, EMPTY_PASS, received_e_DEKs[1].ref_id, received_e_DEKs[1].id, received_e_DEKs[1].version, received_e_DEKs[1].ref_version, id, grant + :: received_e_DEK.id != 0 -> + t22k!d_DEK, EMPTY_PASS, received_e_DEK.ref_id, received_e_DEK.id, received_e_DEK.version, received_e_DEK.ref_version, id, grant :: else -> goto Select_state fi fi @@ -221,8 +224,9 @@ proctype Tenant(unsigned id : 2) Recrypt: - i = 0 - for (i in encrypted_DEKs) { + i = 0 + for (i : 0 .. NUM_DEKS-1) { + if :: encrypted_DEKs[i].ref_id == recrypt_idx -> if // Send and Receive @@ -259,54 +263,72 @@ proctype Tenant(unsigned id : 2) atomic { if :: id == 1 -> t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id - :: else -> t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id + :: else -> t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant fi } goto Receive - Send_to_tenant: - - atomic { - if - :: encrypted_DEKs[0].id != 0 -> - t12t2!send_e_DEK, encrypted_DEKs[0].id, encrypted_DEKs[0].version, encrypted_DEKs[0].ref_id, encrypted_DEKs[0].ref_version, GRANT - sent_1 = true - :: encrypted_DEKs[1].id != 0 -> - t12t2!send_e_DEK, encrypted_DEKs[1].id, encrypted_DEKs[1].version, encrypted_DEKs[1].ref_id, encrypted_DEKs[1].ref_version, GRANT - sent_2 = true - :: else -> skip - fi - } - - goto Select_state Receive: if - :: id == 1 -> - k2t1?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version - :: else -> - k2t2?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version + :: !done -> + if + :: id == 1 -> + k2t1?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version + :: else -> + k2t2?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version + fi + :: else -> + msg = deny + if + :: id == 1 -> + if + :: atomic { k2t1?[msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version] -> + k2t1?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version} + :: else -> skip + fi + :: else -> + if + :: atomic { k2t2?[msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version] -> + k2t2?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version} + :: else -> skip + fi + fi fi - d_step { + atomic { if :: msg == ass_KEK -> assigned_KEKs[ass_idx] = temp_e_key.ref_id + // printf("ass[%d]: %d\n", ass_idx, assigned_KEKs[ass_idx] ) ass_idx++ :: msg == d_DEK -> - assert(temp_key == DEKs[(temp_key-1)%2] || (temp_key == received_e_DEKs[(temp_key-1)%2].id-ENC_DUMMY && grant == VALID_GRANT)) - assert(DEKs[0] != received_e_DEKs[(temp_key-1)%2].id-ENC_DUMMY) - assert(DEKs[1] != received_e_DEKs[(temp_key-1)%2].id-ENC_DUMMY) + assert(temp_key == DEKs[(temp_key-1)%2] || (temp_key == received_e_DEK.id-ENC_DUMMY && grant == VALID_GRANT)) + assert(DEKs[0] != received_e_DEK.id-ENC_DUMMY) + assert(DEKs[1] != received_e_DEK.id-ENC_DUMMY) if :: id == 1 -> - enc_1 = encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].id + enc_1 = encrypted_DEKs[(temp_key-1)%2].id u_enc_1 = temp_key + // printf("enc_1: %d, u_enc_1: %d\n", enc_1, u_enc_1) :: else -> - enc_2 = encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].id + enc_2 = encrypted_DEKs[(temp_key-1)%2].id u_enc_2 = temp_key - enc_2 = received_e_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].id + if + :: temp_key == encrypted_DEKs[(temp_key-1)%2].id-ENC_DUMMY -> + assert(temp_key == enc_2-ENC_DUMMY) + :: else -> skip + fi + // printf("enc_2: %d, u_enc_2: %d\n", enc_2, u_enc_2) + enc_2 = received_e_DEK.id + // printf("enc_2: %d, u_enc_2: %d\n", enc_2, u_enc_2) + if + :: temp_key == received_e_DEK.id-ENC_DUMMY -> + assert(temp_key == enc_2-ENC_DUMMY) + :: else -> skip + fi fi :: msg == deny -> skip :: msg == e_DEK -> @@ -323,20 +345,42 @@ proctype Tenant(unsigned id : 2) encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].version = temp_e_key.version encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].ref_id = temp_e_key.ref_id encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].ref_version = temp_e_key.ref_version + if + :: id == 1 && !sent2tenant -> goto Send_to_tenant + :: else -> skip + fi fi - enc_1 = 15 - u_enc_1 = 0 - enc_2 = 15 - u_enc_2 = 0 + // enc_1 = 15 + // u_enc_1 = 14 + // enc_2 = 15 + // u_enc_2 = 14 } + // enc_1 = 15 + // u_enc_1 = 15 + // enc_2 = 15 + // u_enc_2 = 15 + goto Select_state + + Send_to_tenant: + + atomic { + t12t2!send_e_DEK, temp_e_key.id, temp_e_key.version, temp_e_key.ref_id, temp_e_key.ref_version, GRANT + sent2tenant = true + sent++ + // enc_1 = 15 + // u_enc_1 = 14 + // enc_2 = 15 + // u_enc_2 = 14 + } + goto Select_state } proctype Keystore() { mtype msg, enc_msg - int version + int version // , receive unsigned dek_id : 3, kek_id : 3, kek_ref : 4, i : 3, tenant_id : 2, id : 3, is_case : 2, kek_idx : 3, assigned_to : 2 bit grant bool valid, received @@ -352,7 +396,7 @@ proctype Keystore() if // Clear Cache :: clear_cache -> i = 0 - for (i in v_KEKs) { + for (i : 0 .. NUM_KEKS-1) { v_KEKs[i].id = 0 v_KEKs[i].version = 0 v_KEKs[i].assigned_to = 0 @@ -367,7 +411,13 @@ proctype Keystore() Receive: atomic { - + // receive++ + // if + // :: !done && receive > 20 ->// && sent > 1 -> + // //printf("BTB: %d\n", timer) + // done == true + // :: else -> skip + // fi received = false if @@ -552,7 +602,12 @@ proctype Keystore() if :: enc_msg == re_DEK -> assert(temp_e_key.ref_version <= v_KEKs[kek_id-1].version && temp_e_key.ref_version > v_KEKs[kek_id-1].version-2) - :: else -> temp_e_key.id = dek_id+ENC_DUMMY + :: else -> + // if + // :: tenant_id == 1 -> printf("P1 DEK: %d\n", dek_id) + // :: else -> printf("P2 DEK: %d\n", dek_id) + // fi + temp_e_key.id = dek_id+ENC_DUMMY fi temp_e_key.version = timer temp_e_key.ref_id = v_KEKs[kek_id-1].id+ENC_DUMMY @@ -596,7 +651,8 @@ proctype Database() { bool accessed atomic { - for (i in p_KEKs) { + i = 0 + for (i : 0 .. NUM_KEKS-1) { p_KEKs[i].id = i+1 p_KEKs[i].version = 1 } @@ -605,7 +661,10 @@ proctype Database() { Main: atomic { - timer++ + if + :: !done -> timer++ + :: else -> skip + fi if // Cache timer :: timer%CACHE_CLEAR == 0 -> @@ -698,7 +757,7 @@ proctype Database() { atomic { accessed = false i = 0 - for (i in p_KEKs) { + for (i : 0 .. NUM_KEKS-1) { if :: p_KEKs[i].id == kek_id -> @@ -756,11 +815,16 @@ proctype AccessControl() Select_state: k2ac?msg, kek_id, tenant_id, grant + // do + // :: k2ac?msg, kek_id, tenant_id, grant -> break + // :: timeout -> goto Select_state + // od if :: msg == ass_KEK -> goto Assign_KEK :: msg == d_DEK || msg == e_DEK || msg == re_DEK -> goto Authorize - :: else -> goto Deny_request + // :: else -> goto Deny_request + :: else -> skip fi goto Select_state @@ -865,4 +929,6 @@ proctype AccessControl() goto Select_state + Terminate: + } diff --git a/SPIN-verification/model_c.pml b/SPIN-verification/model_c.pml new file mode 100644 index 0000000..fb30976 --- /dev/null +++ b/SPIN-verification/model_c.pml @@ -0,0 +1,778 @@ +#define NUM_DEKS 1 +#define NUM_KEKS 2 +#define NUM_TENANTS 2 +#define T2K_MAX 1 +#define K2T_MAX 1 +#define K2AC_MAX 1 +#define AC2K_MAX 1 +#define K2DB_MAX 1 +#define DB2K_MAX 1 +#define REQ_MAX 2 +#define DB2T_MAX 1 +#define T_SEND_MAX 1 +#define ASS_MAX 1 +#define GRANT 1 +#define VALID_GRANT 1 +#define ENC_DUMMY 5 +#define EMPTY_PASS 0 +#define ROT_KEK_1 5 +#define ROT_KEK_2 17 +#define CACHE_CLEAR 8 +#define SAME_KEK_ASSIGNED false + +typedef KEK { /* Unencrypted */ + unsigned id : 2 + bit version +} + + +typedef E_Key { /* Encrypted */ + unsigned id : 3 + unsigned ref_id : 3 + bit enc_version + bit ref_version +} + +mtype = { e_DEK, d_DEK, re_DEK, ass_KEK, ass_KEK2 rot_KEK, send_e_DEK, deny, ack } + +// t: Tenant +// k: Keystore +// ac: Access Control +// db: Database + +// { message type, DEK_ID, KEK_ID, E_KEY-ID, E_KEY-ENC_V, E_KEY-REF_V, TENANT_ID, (GRANT) } +chan t12k = [T2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte } // Tenant 1 -> Keystore, |t12k| = 7 +chan t22k = [T2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte } // Tenant 2 -> Keystore, |t22k| = 8 +chan k2t1 = [K2T_MAX] of { mtype, byte, byte, byte, byte, byte } // Keystore -> Tenant 1, |k2t1| = 8 +chan k2t2 = [K2T_MAX] of { mtype, byte, byte, byte, byte, byte } // Keystore -> Tenant 2, |k2t2| = 8 +// { message type, E_KEY-ID, E_KEY-REF_ID, E_KEY-ENC_V, E_KEY-REF_V, GRANT } size = 6 +chan t12t2 = [T_SEND_MAX] of { mtype, byte } // Tenant 1 -> Tenant 2 + +// { message type, KEK_ID, TENANT_ID, GRANT} +chan k2ac = [K2AC_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte } // Keystore -> Access Control, |k2ac| = 8 +chan ac2k = [AC2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte } // Access Control -> Keystore, |ac2k| = 8 + +// { message type, KEK_ID, TENANT_ID} +chan k2db = [K2DB_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte } // Keystore -> Database, |k2db| = 8 +// { message type, KEK_ID, KEK-VERSION, KEK-ASS_TO } +chan db2k = [DB2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte, byte } // Database -> Keystore, |db2k| = 10 + +// This channel emulates an external component notifying +// the tenant when a curr_rotation has taken place +// { message type, KEK_ID } +chan db2t1 = [DB2T_MAX] of { mtype, byte } // Database -> Tenant 1, |db2t1| = 1 +chan db2t2 = [DB2T_MAX] of { mtype, byte } // Database -> Tenant 2, |db2t2| = 1 + +int timer +bool clear_cache, curr_rotation, start +// LTL variables +unsigned enc_1 : 4 = 15, u_enc_1 : 4 = 14, enc_2 : 4 = 15, u_enc_2 : 4 = 14 +unsigned db2t1_buff: 1, db2t2_buff: 1 +unsigned t12k_buff: 3, t22k_buff: 3 +unsigned k2t1_buff: 3, k2t2_buff: 3 +unsigned k2db_buff: 3, db2k_buff: 3 +unsigned k2ac_buff: 3, ac2k_buff: 3 +unsigned req_buff: 3 + + + +// LTL claims +// ltl { [] conf } +// ltl Confidentiality { [] (enc_1 != u_enc_1 && enc_2 != u_enc_2 && enc_1 > 4 && enc_2 > 4 && (u_enc_1 == 14||u_enc_1 < 5) && (u_enc_2 == 14 || u_enc_2 < 5)) } +// bool ps_confidentiality, ps_integrity, ps_authentication, ps_authorization, ps_consistency, pl_confidentiality, pl_integrity, pl_authentication, pl_authorization, pl_consistency +// TRY TO VIOLATE LTL +init { + atomic { + + timer = 0 + + run Tenant(1) + run Tenant(2) + run Database() + run Keystore() + run AccessControl() + } +} + + +proctype Tenant(unsigned id : 2) +{ + mtype msg = deny + unsigned temp_key : 3, recrypt_idx : 4, assigned_KEK : 3, dek_id : 2 = id + bit grant + E_Key temp_e_key, encrypted_DEK, received_e_DEK + bool sent2tenant + + Select_id: + + if + :: id == 1 -> goto ID_1 + :: id == 2 -> goto ID_2 + fi + + ID_1: + // printf("ID1\n") + start = true + atomic { + if + :: k2t1_buff > 0 -> k2t1?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version -> k2t1_buff-- -> + if + :: msg == ass_KEK -> goto Assign_KEK_receive + :: msg == d_DEK -> goto Decrypt_receive + :: msg == e_DEK -> goto Encrypt_receive + :: else -> skip + fi + :: else -> skip + fi + + if + :: t12k_buff < T2K_MAX -> + do + :: t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id -> break + :: t12k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.enc_version, encrypted_DEK.ref_version, id -> break + :: t12k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id -> break + od + + t12k_buff++ + + :: else -> skip + fi + + goto ID_1 + } + + + ID_2: + + // printf("ID2\n") + start = true + atomic { + + if + :: k2t2_buff > 0 -> k2t2?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version -> k2t2_buff-- -> + if + :: msg == ass_KEK -> goto Assign_KEK_receive + :: msg == d_DEK -> goto Decrypt_receive + :: msg == e_DEK -> goto Encrypt_receive + :: else -> skip + fi + :: else -> skip + fi + + if + :: t22k_buff < T2K_MAX -> + do + :: t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant -> break + :: t22k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.enc_version, encrypted_DEK.ref_version, id, grant -> break + :: t22k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant -> break + od + + t22k_buff++ + + :: else -> skip + fi + + goto ID_2 + } + + + Assign_KEK_receive: + + atomic { + + assigned_KEK = temp_e_key.ref_id + + goto Cleanup + } + + Decrypt_receive: + + atomic { + assert(dek_id == temp_key) + + goto Cleanup + } + + Encrypt_receive: + + atomic { + + // if + // :: encrypted_DEK.id == 0 -> skip + // :: encrypted_DEK.id != 0 && temp_e_key.ref_version < encrypted_DEK.ref_version -> //TODO + // if + // :: temp_e_key.ref_id-ENC_DUMMY == 1 -> assert(curr_rotation_1) -> curr_rotation_1 = false + // :: else -> assert(curr_rotation_2) -> curr_rotation_2 = false + // fi + // :: else -> assert(temp_e_key.ref_version >= encrypted_DEK.ref_version) + // fi + // printf("NUMBER %d SAYS HELLO\n", id) + if + :: encrypted_DEK.id != 0 -> + // assert( temp_e_key.enc_version != encrypted_DEK.enc_version ) //TODO + assert(temp_e_key.id-ENC_DUMMY == dek_id) + assert(temp_e_key.ref_id == assigned_KEK) + :: else -> skip + fi + + encrypted_DEK.id = temp_e_key.id + encrypted_DEK.enc_version = temp_e_key.enc_version + encrypted_DEK.ref_id = temp_e_key.ref_id + encrypted_DEK.ref_version = temp_e_key.ref_version + + goto Cleanup + } + + Cleanup: + + atomic { + + msg = deny + temp_key = 0 + temp_e_key.ref_id = 0 + temp_e_key.id = 0 + temp_e_key.enc_version = 0 + temp_e_key.ref_version = 0 + + if + :: id == 1 -> goto ID_1 + :: else -> goto ID_2 + fi + } +} + +proctype Keystore() +{ + mtype msg = deny, enc_msg + unsigned dek_id : 3, kek_id : 3, kek_ref : 3, i : 3, tenant_id : 3, id : 2, version: 1, is_case : 2, select_case : 3 + + bit grant + bool valid, cache_cleared + + KEK temp_key + E_Key temp_e_key + + KEK v_KEKs[NUM_KEKS] + + Select_state: + + // printf("KEYSTORE\n") + //FROM AC + + + // cache_cleared = !cache_cleared + start = true + atomic { + + grant = 0 + + if + :: ac2k_buff > 0 -> ac2k?msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant -> ac2k_buff-- -> + + select_case = 2 + + if + :: kek_ref > 5 -> kek_id = kek_ref-ENC_DUMMY + :: else -> kek_id = 0 + fi + + if + :: msg == ass_KEK -> goto Assign_KEK + :: msg == ass_KEK2 -> select_case = 4 -> goto Assign_KEK + // :: msg == d_DEK -> k2db_buff < K2DB_MAX -> k2db!d_DEK, dek_id, kek_id, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant -> k2db_buff++ + :: msg == d_DEK -> goto Decrypt + :: msg == e_DEK -> goto Encrypt + :: msg == deny -> goto Deny_request + :: else -> skip + fi + + //FROM DB + :: db2k_buff > 0 -> db2k?msg, dek_id, kek_id, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant, version -> db2k_buff-- -> + + select_case = 3 + + if + :: tenant_id == 1 -> + if + :: msg == ass_KEK -> goto Assign_KEK + // :: msg == d_DEK -> k2t1_buff < K2T_MAX -> k2t1!d_DEK, dek_id, kek_id+ENC_DUMMY, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version -> req_buff-- -> k2t1_buff++ + :: msg == d_DEK -> goto Decrypt + :: msg == e_DEK -> goto Encrypt + :: msg == deny -> goto Deny_request + :: else -> skip + fi + :: else -> + if + :: msg == ass_KEK -> goto Assign_KEK + // :: msg == d_DEK -> k2t2_buff < K2T_MAX -> k2t2!d_DEK, dek_id, kek_id+ENC_DUMMY, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version -> req_buff-- -> k2t2_buff++ + :: msg == d_DEK -> goto Decrypt + :: msg == e_DEK -> goto Encrypt + :: msg == deny -> goto Deny_request + :: else -> skip + fi + fi + :: else -> skip + fi + + //FROM TENANT + if + :: req_buff < REQ_MAX && t12k_buff > 0 -> t12k?msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id -> req_buff++ -> t12k_buff-- -> + + select_case = 1 + + if + :: msg == ass_KEK -> goto Assign_KEK + // :: msg == d_DEK -> k2ac_buff < K2AC_MAX -> k2ac!d_DEK, dek_id, kek_ref, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant -> k2ac_buff++ + :: msg == d_DEK -> goto Decrypt + :: msg == e_DEK -> goto Encrypt + :: else -> assert(false) + fi + :: req_buff < REQ_MAX && t22k_buff > 0 -> t22k?msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant -> req_buff++ -> t22k_buff-- -> + + select_case = 1 + + if + :: kek_ref > 5 -> kek_id = kek_ref-ENC_DUMMY + :: else -> kek_id = 0 + fi + + if + :: msg == ass_KEK -> goto Assign_KEK + // :: msg == d_DEK -> k2ac_buff < K2AC_MAX -> k2ac!d_DEK, dek_id, kek_ref, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant -> k2ac_buff++ + :: msg == d_DEK -> goto Decrypt + :: msg == e_DEK -> goto Encrypt + :: else -> assert(false) + fi + :: else -> skip + fi + + goto Select_state + } + + Assign_KEK: + + atomic { + + assert(msg == ass_KEK && select_case == 3 || msg == ass_KEK && select_case == 2 || msg == ass_KEK && select_case == 1 || msg == ass_KEK2 && select_case == 4) + + if // From Tenant to Access Control + :: select_case == 1 -> + k2ac_buff < K2AC_MAX + k2ac!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, tenant_id, grant + k2ac_buff++ + + // From Access Control to Database + :: select_case == 2 -> + // if + // :: !SAME_KEK_ASSIGNED -> kek_id = tenant_id + // :: else -> kek_id = 1 + // fi + + assert(kek_id > 0) + + if // Already in memory so skip Database + :: (v_KEKs[kek_id-1].id == kek_id && !cache_cleared) || (v_KEKs[kek_id-1].id == kek_id && v_KEKs[kek_id-1].version != temp_e_key.ref_version) -> + select_case = 5 + :: else -> + k2db_buff < K2DB_MAX + k2db!ass_KEK, EMPTY_PASS, kek_id, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, tenant_id, grant + k2db_buff++ + fi + + // From Database to Access Control + :: select_case == 3 -> + select_case = 5 + v_KEKs[kek_id-1].id = kek_id + v_KEKs[kek_id-1].version = version + assert(kek_id > 0) + + // From Access Control to Tenant + :: select_case == 4 -> + if + :: tenant_id == 1 -> k2t1_buff < K2T_MAX + k2t1!ass_KEK, EMPTY_PASS, kek_ref, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS + req_buff-- -> k2t1_buff++ + :: else -> k2t2_buff < K2T_MAX + k2t2!ass_KEK, EMPTY_PASS, kek_ref, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS + req_buff-- -> k2t2_buff++ + fi + :: else -> assert(false) + fi + + if // DB -> KS -> AC or Database skip from case 2 AC -> KS -> AC + :: select_case == 5 -> + k2ac_buff < K2AC_MAX + k2ac!ass_KEK2, EMPTY_PASS, kek_id+ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, tenant_id, grant + k2ac_buff++ + :: else -> skip + fi + + goto Cleanup + } + + Decrypt: + + atomic { + + if // From Tenant to Access Control + :: select_case == 1 -> k2ac_buff < K2AC_MAX -> + + k2ac!d_DEK, dek_id, kek_ref, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant + k2ac_buff++ + + // From Access Control to Database + :: select_case == 2 -> + if // Already in memory so skip Database + :: (v_KEKs[kek_id-1].id == kek_id && !cache_cleared) || (v_KEKs[kek_id-1].id == kek_id && v_KEKs[kek_id-1].version != temp_e_key.ref_version) -> + select_case = 4 + :: else -> + k2db_buff < K2DB_MAX -> + k2db!d_DEK, dek_id, kek_id, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant + k2db_buff++ + fi + + // From Database to Tenant + :: select_case == 3 -> + select_case = 4 + v_KEKs[id-1].id = id + v_KEKs[id-1].version = version + :: else -> assert(false) + fi + + if // DB -> KS -> T or Database skip from case 2 AC -> KS -> T + :: select_case == 4 -> + if + :: tenant_id == 1 -> k2t1_buff < K2T_MAX + k2t1!d_DEK, temp_e_key.id-ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS + req_buff-- -> k2t1_buff++ + :: else -> k2t2_buff < K2T_MAX + k2t2!d_DEK, temp_e_key.id-ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS + req_buff-- -> k2t2_buff++ + fi + :: else -> skip + fi + + goto Cleanup + } + + Encrypt: + + atomic { + + if // From Tenant to Access Control + :: select_case == 1 -> k2ac_buff < K2AC_MAX -> + + k2ac!e_DEK, dek_id, kek_ref, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant + k2ac_buff++ + + // From Access Control to Database + :: select_case == 2 -> k2db_buff < K2DB_MAX -> + + k2db!e_DEK, dek_id, kek_id, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant + k2db_buff++ + + // From Database to Tenant + :: select_case == 3 -> + v_KEKs[kek_id-1].id = kek_id + v_KEKs[kek_id-1].version = version + + temp_e_key.id = dek_id+ENC_DUMMY + temp_e_key.enc_version = !temp_e_key.enc_version // PUT IN A GLOBAL HERE THAT ENCRYPYTS DIFFERENT BEFORE EACH SEND + temp_e_key.ref_id = v_KEKs[kek_id-1].id+ENC_DUMMY + temp_e_key.ref_version = v_KEKs[kek_id-1].version + + if + :: tenant_id == 1 -> k2t1_buff < K2T_MAX -> + + k2t1!e_DEK, dek_id, kek_id+ENC_DUMMY, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version + req_buff-- + k2t1_buff++ + + :: else -> k2t2_buff < K2T_MAX -> + + k2t2!e_DEK, dek_id, kek_id+ENC_DUMMY, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version + req_buff-- + k2t2_buff++ + + fi + :: else -> assert(false) + fi + + + goto Cleanup + } + + Deny_request: + + atomic { + + if + :: tenant_id == 1 -> + k2t1_buff < K2T_MAX + k2t1!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS + k2t1_buff++ + req_buff-- + :: else -> + k2t2_buff < K2T_MAX + k2t2!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS + k2t2_buff++ + req_buff-- + fi + select_case = 0 + + msg = deny + goto Cleanup + } + + Cleanup: + + atomic { + + select_case = 0 + msg = deny + dek_id = 0 + kek_id = 0 + kek_ref = 0 + i = 0 + tenant_id = 0 + id = 0 + version= 0 + is_case = 0 + select_case = 0 + temp_e_key.id = 0 + temp_e_key.enc_version = 0 + temp_e_key.ref_id = 0 + temp_e_key.ref_version = 0 + temp_key.version = 0 + temp_key.id = 0 + + goto Select_state + } +} + + +proctype Database() { + + mtype msg = deny + unsigned kek_id : 3, i : 3, tenant_id : 3, dek_id : 2, version : 1 + bit grant + KEK p_KEKs[NUM_KEKS] + E_Key temp_e_key + bool accessed + + atomic { + i = 0 + for (i : 0 .. NUM_KEKS-1) { + p_KEKs[i].id = i+1 + } + i = 0 + } + + Select_state: + + // curr_rotation = !curr_rotation + start = true + atomic { + + p_KEKs[1].version = curr_rotation + p_KEKs[0].version = curr_rotation + + k2db_buff > 0 + k2db?msg, dek_id, kek_id, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant + k2db_buff-- + + assert(kek_id>0) + + do + :: (msg == e_DEK || msg == d_DEK || msg == ass_KEK || msg == re_DEK) -> goto Access_KEK + :: msg == rot_KEK -> goto Rotate_KEK + od + + } + + Access_KEK: + + atomic { + + i = 0 + for (i : 0 .. NUM_KEKS-1) { + if + :: p_KEKs[i].id == kek_id -> + + db2k_buff < DB2K_MAX + db2k!msg, dek_id, p_KEKs[i].id, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant, p_KEKs[i].version + db2k_buff++ + + goto Cleanup + + :: else -> skip + fi + } + + goto Deny_request + + } + + Rotate_KEK: + + atomic { + + goto Cleanup + } + + Deny_request: + + atomic { + + db2k_buff < DB2K_MAX + db2k!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, tenant_id, EMPTY_PASS, EMPTY_PASS + db2k_buff++ + + goto Cleanup + } + + Cleanup: + + atomic { + + accessed = false + i = 0 + msg = deny + dek_id = 0 + kek_id = 0 + temp_e_key.id = 0 + temp_e_key.enc_version = 0 + temp_e_key.ref_version = 0 + tenant_id = 0 + grant = 0 + + goto Select_state + } +} + +proctype AccessControl() +{ + mtype msg = deny + unsigned kek_ref : 3, tenant_id : 3, i : 3, num_assigned : 3, dek_id : 2, assigned_1 : 3, assigned_2 : 3 + bit grant + E_Key temp_e_key + + + Select_state: + + start = true + // printf("ACCESS CONTROL\n") + atomic { + + k2ac_buff > 0 + k2ac?msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant + k2ac_buff-- + + if + :: msg == ass_KEK -> goto Assign_KEK_authorize + :: msg == ass_KEK2 -> goto Assign_KEK2_authorize + :: msg == d_DEK || msg == e_DEK || msg == re_DEK -> goto Authorize + :: else -> goto Deny_request + fi + + } + + + Assign_KEK_authorize: + + // Request access to generate a KEK + atomic { + + if + :: kek_ref == 0 -> + if + :: tenant_id == 1 && assigned_1 > 0 -> goto Deny_request + :: tenant_id == 2 && assigned_2 > 0 -> goto Deny_request + :: else -> skip + fi + :: else -> goto Deny_request + fi + + ac2k_buff < AC2K_MAX + ac2k!ass_KEK, dek_id, kek_ref, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant + ac2k_buff++ + + goto Cleanup + } + + Assign_KEK2_authorize: + + // Newly generated key assigned + atomic { + + assert(kek_ref > 5) + + if + :: tenant_id == 1 -> assigned_1 = kek_ref + :: tenant_id == 2 -> assigned_2 = kek_ref + fi + + ac2k_buff < AC2K_MAX + ac2k!ass_KEK2, dek_id, kek_ref, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant + ac2k_buff++ + + goto Cleanup + } + + + Authorize: + + atomic { + + if + :: kek_ref != 6 && kek_ref != 7 -> goto Deny_request + :: else -> skip + fi + + if + :: tenant_id == 1 && (kek_ref != assigned_1) -> goto Deny_request + :: tenant_id == 2 && (kek_ref != assigned_2) -> + if + :: grant == VALID_GRANT && assigned_1 == kek_ref -> skip + :: else -> goto Deny_request + fi + :: else -> skip + fi + + ac2k_buff < AC2K_MAX + ac2k!msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant + ac2k_buff++ + + goto Cleanup + } + + Deny_request: + + atomic { + + ac2k_buff < AC2K_MAX + ac2k!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, tenant_id, EMPTY_PASS + ac2k_buff++ + + + goto Cleanup + } + + Cleanup: + + atomic { + + num_assigned = 0 + i = 0 + msg = deny + dek_id = 0 + kek_ref = 0 + temp_e_key.id = 0 + temp_e_key.enc_version = 0 + temp_e_key.ref_version = 0 + tenant_id = 0 + grant = 0 + + goto Select_state + } +} From 95f62a14e350a8dfcf90e06629ef1ea32ef606b2 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Sat, 18 May 2024 02:11:54 +0200 Subject: [PATCH 17/30] Safety v1 for model 1 verified --- SPIN-verification/model_c.pml | 951 +++++++++++++++++++++++----------- 1 file changed, 659 insertions(+), 292 deletions(-) diff --git a/SPIN-verification/model_c.pml b/SPIN-verification/model_c.pml index fb30976..b4128e3 100644 --- a/SPIN-verification/model_c.pml +++ b/SPIN-verification/model_c.pml @@ -1,6 +1,12 @@ #define NUM_DEKS 1 #define NUM_KEKS 2 #define NUM_TENANTS 2 +#define VALID_GRANT 1 +#define ENC_DUMMY 5 +#define EMPTY_PASS 0 +#define SAME_KEK_ASSIGNED false + +// CHANNEL CAPS #define T2K_MAX 1 #define K2T_MAX 1 #define K2AC_MAX 1 @@ -8,17 +14,15 @@ #define K2DB_MAX 1 #define DB2K_MAX 1 #define REQ_MAX 2 -#define DB2T_MAX 1 -#define T_SEND_MAX 1 -#define ASS_MAX 1 -#define GRANT 1 -#define VALID_GRANT 1 -#define ENC_DUMMY 5 -#define EMPTY_PASS 0 -#define ROT_KEK_1 5 -#define ROT_KEK_2 17 -#define CACHE_CLEAR 8 -#define SAME_KEK_ASSIGNED false + +/** + MODELS + 1: Assignemnt and Encryption. + 2: Decryption + 2: Tenant 1 full operations, Tenant 2 only Decrypts encrypted DEKs received from Tenant 1 with different grants + 3: Re-Encryption of encrypted DEKs +*/ +#define MODEL 3 typedef KEK { /* Unencrypted */ unsigned id : 2 @@ -26,54 +30,46 @@ typedef KEK { /* Unencrypted */ } -typedef E_Key { /* Encrypted */ +typedef E_DEK { /* Encrypted */ unsigned id : 3 unsigned ref_id : 3 bit enc_version bit ref_version } -mtype = { e_DEK, d_DEK, re_DEK, ass_KEK, ass_KEK2 rot_KEK, send_e_DEK, deny, ack } +mtype = { e_DEK, d_DEK, re_DEK, ass_KEK, ass_KEK2, deny } -// t: Tenant +// t1: Tenant 1 +// t2: Tenant 2 // k: Keystore // ac: Access Control // db: Database -// { message type, DEK_ID, KEK_ID, E_KEY-ID, E_KEY-ENC_V, E_KEY-REF_V, TENANT_ID, (GRANT) } -chan t12k = [T2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte } // Tenant 1 -> Keystore, |t12k| = 7 -chan t22k = [T2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte } // Tenant 2 -> Keystore, |t22k| = 8 -chan k2t1 = [K2T_MAX] of { mtype, byte, byte, byte, byte, byte } // Keystore -> Tenant 1, |k2t1| = 8 -chan k2t2 = [K2T_MAX] of { mtype, byte, byte, byte, byte, byte } // Keystore -> Tenant 2, |k2t2| = 8 -// { message type, E_KEY-ID, E_KEY-REF_ID, E_KEY-ENC_V, E_KEY-REF_V, GRANT } size = 6 -chan t12t2 = [T_SEND_MAX] of { mtype, byte } // Tenant 1 -> Tenant 2 - -// { message type, KEK_ID, TENANT_ID, GRANT} -chan k2ac = [K2AC_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte } // Keystore -> Access Control, |k2ac| = 8 -chan ac2k = [AC2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte } // Access Control -> Keystore, |ac2k| = 8 - -// { message type, KEK_ID, TENANT_ID} -chan k2db = [K2DB_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte } // Keystore -> Database, |k2db| = 8 -// { message type, KEK_ID, KEK-VERSION, KEK-ASS_TO } -chan db2k = [DB2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte, byte } // Database -> Keystore, |db2k| = 10 - -// This channel emulates an external component notifying -// the tenant when a curr_rotation has taken place -// { message type, KEK_ID } -chan db2t1 = [DB2T_MAX] of { mtype, byte } // Database -> Tenant 1, |db2t1| = 1 -chan db2t2 = [DB2T_MAX] of { mtype, byte } // Database -> Tenant 2, |db2t2| = 1 - -int timer -bool clear_cache, curr_rotation, start -// LTL variables -unsigned enc_1 : 4 = 15, u_enc_1 : 4 = 14, enc_2 : 4 = 15, u_enc_2 : 4 = 14 -unsigned db2t1_buff: 1, db2t2_buff: 1 +// { message type, DEK_ID, KEK_ID, E_KEY-ID, (E_KEY-ENC_V), E_KEY-REF_V, TENANT_ID, (GRANT), (KEK-VERSION), AUTH } +chan t12k = [T2K_MAX] of { mtype, byte, byte, byte, byte, byte } // Tenant 1 -> Keystore, |t12k| = 6 +chan k2t1 = [K2T_MAX] of { mtype, byte, byte, byte, byte, byte, byte } // Keystore -> Tenant 1, |k2t1| = 7 + +chan t22k = [T2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte } // Tenant 2 -> Keystore, |t22k| = 7 +chan k2t2 = [K2T_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte } // Keystore -> Tenant 2, |k2t2| = 8 + +chan k2ac = [K2AC_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte } // Keystore -> Access Control, |k2ac| = 8 +chan ac2k = [AC2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte } // Access Control -> Keystore, |ac2k| = 8 + +chan k2db = [K2DB_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte } // Keystore -> Database, |k2db| = 8 +chan db2k = [DB2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte, byte } // Database -> Keystore, |db2k| = 9 + +bool exit_atomic +local bool cache_cleared, p_rotated_1, p_rotated_2 + +// Channel buffers unsigned t12k_buff: 3, t22k_buff: 3 unsigned k2t1_buff: 3, k2t2_buff: 3 unsigned k2db_buff: 3, db2k_buff: 3 unsigned k2ac_buff: 3, ac2k_buff: 3 unsigned req_buff: 3 +// LTL variables +bool p_assigned_1, p_assigned_2, p_enc_1, p_enc_2, p_1 = true, p_2 = true, p_conf = true, p_authentic = true, p_int = true // LTL claims @@ -81,98 +77,311 @@ unsigned req_buff: 3 // ltl Confidentiality { [] (enc_1 != u_enc_1 && enc_2 != u_enc_2 && enc_1 > 4 && enc_2 > 4 && (u_enc_1 == 14||u_enc_1 < 5) && (u_enc_2 == 14 || u_enc_2 < 5)) } // bool ps_confidentiality, ps_integrity, ps_authentication, ps_authorization, ps_consistency, pl_confidentiality, pl_integrity, pl_authentication, pl_authorization, pl_consistency // TRY TO VIOLATE LTL +ltl safety_model_1 { [](p_conf && p_authentic && p_int) && [](p_1 && p_2)&& ( p_enc_1 -> p_assigned_1 ) && ( p_enc_2 -> p_assigned_2 ) } +ltl liveness_model_1 {[]<>(p_enc_1 && p_enc_2) && (!p_enc_1 U p_assigned_1) && (!p_enc_2 U p_assigned_2)} +// ltl safety_model_2 +// ltl liveness_model_2 +// ltl safety_model_3 +// ltl liveness_model_3 +// ltl safety_model_4 +// ltl liveness_model_4 init { + atomic { - timer = 0 - - run Tenant(1) - run Tenant(2) + run Tenant_1() + run Tenant_2() run Database() run Keystore() run AccessControl() + } } - - -proctype Tenant(unsigned id : 2) +/** + Order of operations + (DB step is optional for Decrypt when the KEK is not in v-memory) + Assign KEK: T -> KS -> AC -> KS -> DB -> KS -> AC -> KS -> T + Decrypt: T -> KS -> AC -> KS -> (DB) -> KS -> T + Encrypt: T -> KS -> AC -> KS -> DB -> KS -> T + Recrypt: T -> KS -> AC -> KS -> DB -> KS -> T + */ + +proctype Tenant_1() { mtype msg = deny - unsigned temp_key : 3, recrypt_idx : 4, assigned_KEK : 3, dek_id : 2 = id - bit grant - E_Key temp_e_key, encrypted_DEK, received_e_DEK - bool sent2tenant + unsigned temp_dek: 3, assigned_KEK : 3, ref_version_1 : 1, ref_version_2 : 1 + unsigned id : 2 = 1 + unsigned dek_id : 2 = 1 + bit auth - Select_id: - - if - :: id == 1 -> goto ID_1 - :: id == 2 -> goto ID_2 - fi + E_DEK temp_e_dek, encrypted_DEK + + atomic { + do + :: MODEL == 1 -> break + :: MODEL == 2 -> + encrypted_DEK.id = 6 + encrypted_DEK.ref_id = 6 + ref_version_1 = 0 + ref_version_2 = 1 + break + :: MODEL == 3 -> + encrypted_DEK.id = 6 + encrypted_DEK.ref_id = 6 + break + od + } + + Select_state: + + exit_atomic = true - ID_1: - // printf("ID1\n") - start = true atomic { - if - :: k2t1_buff > 0 -> k2t1?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version -> k2t1_buff-- -> + + + do + :: k2t1_buff > 0 -> k2t1?msg, temp_dek, temp_e_dek.ref_id, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, auth -> k2t1_buff-- -> + + // CONFIDENTIALITY VIOLATION + if + :: temp_e_dek.id == 1 || temp_e_dek.id == 2 -> p_conf = false + :: temp_e_dek.ref_id == 1 || temp_e_dek.ref_id == 2 -> p_conf = false + :: else -> skip + fi + + // AUTHENTICATION VIOLATION + if + :: auth != 1 -> p_authentic = false + :: else -> skip + fi + if :: msg == ass_KEK -> goto Assign_KEK_receive :: msg == d_DEK -> goto Decrypt_receive :: msg == e_DEK -> goto Encrypt_receive - :: else -> skip + :: msg == re_DEK -> goto Recrypt_Receive + :: else -> + if + :: MODEL == 1 -> + if + :: assigned_KEK != 0 -> p_1 = false + :: else -> skip + fi + :: else -> skip + fi fi - :: else -> skip - fi - if + break + :: t12k_buff < T2K_MAX -> do - :: t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id -> break - :: t12k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.enc_version, encrypted_DEK.ref_version, id -> break - :: t12k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id -> break + :: MODEL == 1 -> + do + :: t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id -> break + :: t12k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id -> break + od + break + :: MODEL == 2 -> + do + :: t12k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, ref_version_1, id -> break + :: t12k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, ref_version_2, id -> break + :: t12k!d_DEK, EMPTY_PASS, EMPTY_PASS, encrypted_DEK.id, ref_version_2, id -> break + od + break + :: MODEL == 3 -> t12k!re_DEK, assigned_KEK, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.ref_version, id -> break od t12k_buff++ - - :: else -> skip - fi + break - goto ID_1 + :: else -> break + od + + goto Select_state } - + + Assign_KEK_receive: - ID_2: + atomic { + + // P VIOLATION + d_step { + if + :: assigned_KEK == temp_e_dek.ref_id -> p_int = false + :: p_assigned_2 -> p_1 = false + :: else -> skip + fi + } + + p_assigned_1 = true + assigned_KEK = temp_e_dek.ref_id + + goto Cleanup + } + + Decrypt_receive: - // printf("ID2\n") - start = true atomic { - if - :: k2t2_buff > 0 -> k2t2?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version -> k2t2_buff-- -> + assert(dek_id == temp_dek) + + goto Cleanup + } + + Encrypt_receive: + + atomic { + + p_enc_1 = true + + // P VIOLATION + d_step { + if + :: temp_e_dek.enc_version == encrypted_DEK.enc_version -> p_1 = false + :: temp_e_dek.id-ENC_DUMMY != dek_id -> p_int = false + :: temp_e_dek.ref_id != assigned_KEK -> p_int = false + :: else -> skip + fi + } + + encrypted_DEK.id = temp_e_dek.id + encrypted_DEK.enc_version = temp_e_dek.enc_version + encrypted_DEK.ref_id = temp_e_dek.ref_id + encrypted_DEK.ref_version = temp_e_dek.ref_version + + goto Cleanup + } + + Recrypt_Receive: + + atomic { + assert(temp_e_dek.enc_version != encrypted_DEK.enc_version) + assert(temp_e_dek.id-ENC_DUMMY == dek_id) + encrypted_DEK.id = temp_e_dek.id + encrypted_DEK.enc_version = temp_e_dek.enc_version + encrypted_DEK.ref_id = temp_e_dek.ref_id + encrypted_DEK.ref_version = temp_e_dek.ref_version + + goto Cleanup + } + + Cleanup: + + atomic { + + auth = 0 + msg = deny + temp_dek = 0 + temp_e_dek.ref_id = 0 + temp_e_dek.id = 0 + temp_e_dek.enc_version = 0 + temp_e_dek.ref_version = 0 + + goto Select_state + } +} + +proctype Tenant_2() +{ + mtype msg = deny + unsigned temp_dek: 3, assigned_KEK : 3, grant : 2, ref_version_1 : 1, ref_version_2 : 1 + unsigned id : 2 = 2 + unsigned dek_id : 2 = 2 + bit auth + E_DEK temp_e_dek, encrypted_DEK, received_e_DEK + + atomic { + + do + :: MODEL == 1 -> break + :: MODEL == 2 -> + received_e_DEK.id = 6 + received_e_DEK.ref_id = 6 + encrypted_DEK.id = 7 + encrypted_DEK.ref_id = 7 + ref_version_1 = 0 + ref_version_2 = 1 + break + // :: MODEL == 2 -> + // break + :: MODEL == 3 -> + encrypted_DEK.id = 7 + encrypted_DEK.ref_id = 7 + received_e_DEK.id = 6 + received_e_DEK.ref_id = 6 + break + od + } + + Select_state: + + exit_atomic = true + + atomic { + + do + :: k2t2_buff > 0 -> k2t2?msg, temp_dek, temp_e_dek.ref_id, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, grant, auth -> k2t2_buff-- -> + // CONFIDENTIALITY VIOLATION + if + :: temp_e_dek.id == 1 || temp_e_dek.id == 2 -> p_conf = false + :: temp_e_dek.ref_id == 1 || temp_e_dek.ref_id == 2 -> p_conf = false + :: else -> skip + fi + + // AUTHENTICATION VIOLATION + if + :: auth != 1 -> p_authentic = false + :: else -> skip + fi + if :: msg == ass_KEK -> goto Assign_KEK_receive :: msg == d_DEK -> goto Decrypt_receive :: msg == e_DEK -> goto Encrypt_receive - :: else -> skip + :: msg == re_DEK -> goto Recrypt_Receive + :: else -> + if + :: MODEL == 1 -> + if + :: assigned_KEK != 0 -> p_2 = false + :: else -> skip + fi + :: else -> skip + fi fi - :: else -> skip - fi - if + break + :: t22k_buff < T2K_MAX -> + do - :: t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant -> break - :: t22k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.enc_version, encrypted_DEK.ref_version, id, grant -> break - :: t22k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant -> break + :: MODEL == 1 -> + do + :: t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant -> break + :: t22k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, grant -> break + od + break + :: MODEL == 2 -> + do + :: t22k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, ref_version_1, id, grant -> break + :: t22k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, ref_version_2, id, grant -> break + :: t22k!d_DEK, EMPTY_PASS, EMPTY_PASS, encrypted_DEK.id, ref_version_1, id, grant -> break + // :: t22k!d_DEK, EMPTY_PASS, received_e_DEK.ref_id, received_e_DEK.id, ref_version_1, id, VALID_GRANT -> break + // :: t22k!d_DEK, EMPTY_PASS, received_e_DEK.ref_id, received_e_DEK.id, ref_version_2, id, VALID_GRANT -> break + // :: t22k!d_DEK, EMPTY_PASS, received_e_DEK.ref_id, received_e_DEK.id, ref_version_1, id, grant -> break + // :: t22k!d_DEK, EMPTY_PASS, received_e_DEK.ref_id, received_e_DEK.id, ref_version_2, id, grant -> break + od + break + :: MODEL == 3 -> t22k!re_DEK, assigned_KEK, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.ref_version, id, grant -> break od t22k_buff++ + break - :: else -> skip - fi + :: else -> break + od - goto ID_2 + goto Select_state } @@ -180,7 +389,17 @@ proctype Tenant(unsigned id : 2) atomic { - assigned_KEK = temp_e_key.ref_id + // P VIOLATION + d_step { + if + :: assigned_KEK == temp_e_dek.ref_id -> p_int = false + :: p_assigned_2 -> p_2 = false // liveness + :: else -> skip + fi + } + + p_assigned_2 = true + assigned_KEK = temp_e_dek.ref_id goto Cleanup } @@ -188,7 +407,9 @@ proctype Tenant(unsigned id : 2) Decrypt_receive: atomic { - assert(dek_id == temp_key) + + assert(dek_id == temp_dek || (grant != 0 && temp_dek == 1)) + // assert(false) goto Cleanup } @@ -197,154 +418,183 @@ proctype Tenant(unsigned id : 2) atomic { + // printf("Received 2\n") // if // :: encrypted_DEK.id == 0 -> skip - // :: encrypted_DEK.id != 0 && temp_e_key.ref_version < encrypted_DEK.ref_version -> //TODO + // :: encrypted_DEK.id != 0 && temp_e_dek.ref_version < encrypted_DEK.ref_version -> //TODO // if - // :: temp_e_key.ref_id-ENC_DUMMY == 1 -> assert(curr_rotation_1) -> curr_rotation_1 = false + // :: temp_e_dek.ref_id-ENC_DUMMY == 1 -> assert(curr_rotation_1) -> curr_rotation_1 = false // :: else -> assert(curr_rotation_2) -> curr_rotation_2 = false // fi - // :: else -> assert(temp_e_key.ref_version >= encrypted_DEK.ref_version) + // :: else -> assert(temp_e_dek.ref_version >= encrypted_DEK.ref_version) // fi - // printf("NUMBER %d SAYS HELLO\n", id) + p_enc_2 = true + // SAFETY VIOLATION if - :: encrypted_DEK.id != 0 -> - // assert( temp_e_key.enc_version != encrypted_DEK.enc_version ) //TODO - assert(temp_e_key.id-ENC_DUMMY == dek_id) - assert(temp_e_key.ref_id == assigned_KEK) + :: temp_e_dek.enc_version == encrypted_DEK.enc_version -> p_2 = false + :: temp_e_dek.id-ENC_DUMMY != dek_id -> p_2 = false + :: temp_e_dek.ref_id != assigned_KEK -> p_2 = false :: else -> skip fi - - encrypted_DEK.id = temp_e_key.id - encrypted_DEK.enc_version = temp_e_key.enc_version - encrypted_DEK.ref_id = temp_e_key.ref_id - encrypted_DEK.ref_version = temp_e_key.ref_version + + encrypted_DEK.id = temp_e_dek.id + encrypted_DEK.enc_version = temp_e_dek.enc_version + encrypted_DEK.ref_id = temp_e_dek.ref_id + encrypted_DEK.ref_version = temp_e_dek.ref_version goto Cleanup } + Recrypt_Receive: + + atomic { + + assert(temp_e_dek.enc_version != encrypted_DEK.enc_version) + assert(temp_e_dek.id-ENC_DUMMY == dek_id) + + encrypted_DEK.id = temp_e_dek.id + encrypted_DEK.enc_version = temp_e_dek.enc_version + encrypted_DEK.ref_id = temp_e_dek.ref_id + encrypted_DEK.ref_version = temp_e_dek.ref_version + + goto Cleanup + } + Cleanup: atomic { + auth = 0 + grant = 0 msg = deny - temp_key = 0 - temp_e_key.ref_id = 0 - temp_e_key.id = 0 - temp_e_key.enc_version = 0 - temp_e_key.ref_version = 0 + temp_dek = 0 + temp_e_dek.ref_id = 0 + temp_e_dek.id = 0 + temp_e_dek.enc_version = 0 + temp_e_dek.ref_version = 0 - if - :: id == 1 -> goto ID_1 - :: else -> goto ID_2 - fi + goto Select_state } } proctype Keystore() { mtype msg = deny, enc_msg - unsigned dek_id : 3, kek_id : 3, kek_ref : 3, i : 3, tenant_id : 3, id : 2, version: 1, is_case : 2, select_case : 3 - - bit grant - bool valid, cache_cleared - + unsigned dek_id : 3, kek_id : 3, kek_ref : 3, tenant_id : 3, select_case : 3, grant : 2, kek_version : 1, auth : 1 + bit id = 1 + bit last_enc_1, last_enc_2 + E_DEK temp_e_dek KEK temp_key - E_Key temp_e_key - KEK v_KEKs[NUM_KEKS] + atomic{ + + if + :: MODEL != 1 -> + v_KEKs[0].id = 1 + v_KEKs[0].id = 2 + :: else -> skip + fi + } + Select_state: - // printf("KEYSTORE\n") - //FROM AC - + exit_atomic = true - // cache_cleared = !cache_cleared - start = true atomic { - grant = 0 - if - :: ac2k_buff > 0 -> ac2k?msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant -> ac2k_buff-- -> + :: MODEL == 1 -> skip + :: else -> cache_cleared = !cache_cleared + fi + + p_rotated_1 = false + p_rotated_2 = false + // do // Cache clear + // :: v_KEKs[0].id = 0 + // v_KEKs[0].id = 0 + // break + // :: v_KEKs[0].id = 1 + // v_KEKs[0].id = 2 + // break + // od + + + do //FROM AC + :: ac2k_buff > 0 -> ac2k?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, auth -> ac2k_buff-- -> select_case = 2 if + :: auth != 1 -> p_authentic = false -> goto Deny_request + :: else -> skip + fi + + if // Dereference KEK encryption with MK :: kek_ref > 5 -> kek_id = kek_ref-ENC_DUMMY :: else -> kek_id = 0 fi - if + do :: msg == ass_KEK -> goto Assign_KEK :: msg == ass_KEK2 -> select_case = 4 -> goto Assign_KEK - // :: msg == d_DEK -> k2db_buff < K2DB_MAX -> k2db!d_DEK, dek_id, kek_id, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant -> k2db_buff++ :: msg == d_DEK -> goto Decrypt :: msg == e_DEK -> goto Encrypt + :: msg == re_DEK -> goto Recrypt :: msg == deny -> goto Deny_request - :: else -> skip - fi + od - //FROM DB - :: db2k_buff > 0 -> db2k?msg, dek_id, kek_id, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant, version -> db2k_buff-- -> + //FROM DB + :: db2k_buff > 0 -> db2k?msg, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, kek_version, auth -> db2k_buff-- -> select_case = 3 if - :: tenant_id == 1 -> - if - :: msg == ass_KEK -> goto Assign_KEK - // :: msg == d_DEK -> k2t1_buff < K2T_MAX -> k2t1!d_DEK, dek_id, kek_id+ENC_DUMMY, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version -> req_buff-- -> k2t1_buff++ - :: msg == d_DEK -> goto Decrypt - :: msg == e_DEK -> goto Encrypt - :: msg == deny -> goto Deny_request - :: else -> skip - fi - :: else -> - if - :: msg == ass_KEK -> goto Assign_KEK - // :: msg == d_DEK -> k2t2_buff < K2T_MAX -> k2t2!d_DEK, dek_id, kek_id+ENC_DUMMY, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version -> req_buff-- -> k2t2_buff++ - :: msg == d_DEK -> goto Decrypt - :: msg == e_DEK -> goto Encrypt - :: msg == deny -> goto Deny_request - :: else -> skip - fi + :: auth != 1 -> p_authentic = false -> goto Deny_request + :: else -> skip fi - :: else -> skip - fi - - //FROM TENANT - if - :: req_buff < REQ_MAX && t12k_buff > 0 -> t12k?msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id -> req_buff++ -> t12k_buff-- -> + + do + :: msg == ass_KEK -> goto Assign_KEK + :: msg == d_DEK -> goto Decrypt + :: msg == e_DEK -> goto Encrypt + :: msg == re_DEK -> goto Recrypt + :: msg == deny -> goto Deny_request + od + + // FROM TENANT + :: req_buff < REQ_MAX && t12k_buff > 0 -> t12k?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id -> req_buff++ -> t12k_buff-- -> select_case = 1 if + :: tenant_id != 1 -> p_authentic = false -> goto Deny_request + :: else -> skip + fi + + do :: msg == ass_KEK -> goto Assign_KEK - // :: msg == d_DEK -> k2ac_buff < K2AC_MAX -> k2ac!d_DEK, dek_id, kek_ref, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant -> k2ac_buff++ :: msg == d_DEK -> goto Decrypt :: msg == e_DEK -> goto Encrypt - :: else -> assert(false) - fi - :: req_buff < REQ_MAX && t22k_buff > 0 -> t22k?msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant -> req_buff++ -> t22k_buff-- -> + :: msg == re_DEK -> goto Recrypt + od + :: req_buff < REQ_MAX && t22k_buff > 0 -> t22k?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant -> req_buff++ -> t22k_buff-- -> select_case = 1 - + if - :: kek_ref > 5 -> kek_id = kek_ref-ENC_DUMMY - :: else -> kek_id = 0 + :: tenant_id != 2 -> p_authentic = false -> goto Deny_request + :: else -> skip fi - if + do :: msg == ass_KEK -> goto Assign_KEK - // :: msg == d_DEK -> k2ac_buff < K2AC_MAX -> k2ac!d_DEK, dek_id, kek_ref, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant -> k2ac_buff++ :: msg == d_DEK -> goto Decrypt :: msg == e_DEK -> goto Encrypt - :: else -> assert(false) - fi - :: else -> skip - fi + :: msg == re_DEK -> goto Recrypt + od + :: else -> break + od goto Select_state } @@ -353,12 +603,10 @@ proctype Keystore() atomic { - assert(msg == ass_KEK && select_case == 3 || msg == ass_KEK && select_case == 2 || msg == ass_KEK && select_case == 1 || msg == ass_KEK2 && select_case == 4) - if // From Tenant to Access Control :: select_case == 1 -> k2ac_buff < K2AC_MAX - k2ac!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, tenant_id, grant + k2ac!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, tenant_id, grant, id k2ac_buff++ // From Access Control to Database @@ -367,46 +615,41 @@ proctype Keystore() // :: !SAME_KEK_ASSIGNED -> kek_id = tenant_id // :: else -> kek_id = 1 // fi + kek_id = tenant_id - assert(kek_id > 0) - - if // Already in memory so skip Database - :: (v_KEKs[kek_id-1].id == kek_id && !cache_cleared) || (v_KEKs[kek_id-1].id == kek_id && v_KEKs[kek_id-1].version != temp_e_key.ref_version) -> - select_case = 5 - :: else -> - k2db_buff < K2DB_MAX - k2db!ass_KEK, EMPTY_PASS, kek_id, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, tenant_id, grant - k2db_buff++ - fi + k2db_buff < K2DB_MAX + k2db!ass_KEK, EMPTY_PASS, kek_id, EMPTY_PASS, EMPTY_PASS, tenant_id, grant, id + k2db_buff++ // From Database to Access Control :: select_case == 3 -> - select_case = 5 + v_KEKs[kek_id-1].id = kek_id - v_KEKs[kek_id-1].version = version - assert(kek_id > 0) + v_KEKs[kek_id-1].version = kek_version + k2ac_buff < K2AC_MAX + k2ac!ass_KEK2, EMPTY_PASS, kek_id+ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, tenant_id, grant, id + k2ac_buff++ // From Access Control to Tenant :: select_case == 4 -> + + if // ack from Tenant was received during concurrent processing + :: tenant_id == 1 && p_assigned_1 -> goto Deny_request + :: tenant_id == 2 && p_assigned_2 -> goto Deny_request + :: else -> skip + fi + if :: tenant_id == 1 -> k2t1_buff < K2T_MAX - k2t1!ass_KEK, EMPTY_PASS, kek_ref, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS + k2t1!ass_KEK, EMPTY_PASS, kek_ref, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id req_buff-- -> k2t1_buff++ :: else -> k2t2_buff < K2T_MAX - k2t2!ass_KEK, EMPTY_PASS, kek_ref, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS + k2t2!ass_KEK, EMPTY_PASS, kek_ref, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, grant, id req_buff-- -> k2t2_buff++ fi :: else -> assert(false) fi - if // DB -> KS -> AC or Database skip from case 2 AC -> KS -> AC - :: select_case == 5 -> - k2ac_buff < K2AC_MAX - k2ac!ass_KEK2, EMPTY_PASS, kek_id+ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, tenant_id, grant - k2ac_buff++ - :: else -> skip - fi - goto Cleanup } @@ -415,38 +658,39 @@ proctype Keystore() atomic { if // From Tenant to Access Control - :: select_case == 1 -> k2ac_buff < K2AC_MAX -> + :: select_case == 1 -> - k2ac!d_DEK, dek_id, kek_ref, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant + k2ac_buff < K2AC_MAX + k2ac!d_DEK, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id k2ac_buff++ // From Access Control to Database :: select_case == 2 -> if // Already in memory so skip Database - :: (v_KEKs[kek_id-1].id == kek_id && !cache_cleared) || (v_KEKs[kek_id-1].id == kek_id && v_KEKs[kek_id-1].version != temp_e_key.ref_version) -> + // :: v_KEKs[kek_id-1].id == kek_id && v_KEKs[kek_id-1].version == temp_e_dek.ref_version -> + :: cache_cleared || v_KEKs[kek_id-1].version == temp_e_dek.ref_version -> select_case = 4 :: else -> k2db_buff < K2DB_MAX -> - k2db!d_DEK, dek_id, kek_id, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant + k2db!d_DEK, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id k2db_buff++ fi // From Database to Tenant :: select_case == 3 -> select_case = 4 - v_KEKs[id-1].id = id - v_KEKs[id-1].version = version - :: else -> assert(false) + v_KEKs[kek_id-1].id = kek_id + v_KEKs[kek_id-1].version = kek_version fi if // DB -> KS -> T or Database skip from case 2 AC -> KS -> T :: select_case == 4 -> if :: tenant_id == 1 -> k2t1_buff < K2T_MAX - k2t1!d_DEK, temp_e_key.id-ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS + k2t1!d_DEK, temp_e_dek.id-ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id req_buff-- -> k2t1_buff++ :: else -> k2t2_buff < K2T_MAX - k2t2!d_DEK, temp_e_key.id-ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS + k2t2!d_DEK, temp_e_dek.id-ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, grant, id req_buff-- -> k2t2_buff++ fi :: else -> skip @@ -460,44 +704,141 @@ proctype Keystore() atomic { if // From Tenant to Access Control - :: select_case == 1 -> k2ac_buff < K2AC_MAX -> + :: select_case == 1 -> - k2ac!e_DEK, dek_id, kek_ref, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant + k2ac_buff < K2AC_MAX + k2ac!e_DEK, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id k2ac_buff++ // From Access Control to Database - :: select_case == 2 -> k2db_buff < K2DB_MAX -> + :: select_case == 2 -> - k2db!e_DEK, dek_id, kek_id, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant + k2db_buff < K2DB_MAX + k2db!e_DEK, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id k2db_buff++ // From Database to Tenant :: select_case == 3 -> + v_KEKs[kek_id-1].id = kek_id - v_KEKs[kek_id-1].version = version + if + :: tenant_id == 1 && v_KEKs[kek_id-1].version != kek_version -> + p_rotated_1 = true + :: tenant_id == 2 && v_KEKs[kek_id-1].version != kek_version -> + p_rotated_2 = true + :: else skip + fi + v_KEKs[kek_id-1].version = kek_version + + temp_e_dek.id = dek_id+ENC_DUMMY + temp_e_dek.ref_id = v_KEKs[kek_id-1].id+ENC_DUMMY + temp_e_dek.ref_version = v_KEKs[kek_id-1].version + do + :: tenant_id == 1 -> + + last_enc_1 = !last_enc_1 + temp_e_dek.enc_version = last_enc_1 + + k2t1_buff < K2T_MAX + k2t1!e_DEK, dek_id, kek_id+ENC_DUMMY, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, id + req_buff-- + k2t1_buff++ + break + + :: tenant_id == 2 -> + + last_enc_2 = !last_enc_2 + temp_e_dek.enc_version = last_enc_2 + + k2t2_buff < K2T_MAX + k2t2!e_DEK, dek_id, kek_id+ENC_DUMMY, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, grant, id + req_buff-- + k2t2_buff++ + break + od + fi + + goto Cleanup + } - temp_e_key.id = dek_id+ENC_DUMMY - temp_e_key.enc_version = !temp_e_key.enc_version // PUT IN A GLOBAL HERE THAT ENCRYPYTS DIFFERENT BEFORE EACH SEND - temp_e_key.ref_id = v_KEKs[kek_id-1].id+ENC_DUMMY - temp_e_key.ref_version = v_KEKs[kek_id-1].version + Recrypt: + + atomic { - if - :: tenant_id == 1 -> k2t1_buff < K2T_MAX -> + if // From Tenant to Access Control + :: select_case == 1 -> + + k2ac_buff < K2AC_MAX + k2ac!re_DEK, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id + k2ac_buff++ + + // From Access Control to Database + :: select_case == 2 -> - k2t1!e_DEK, dek_id, kek_id+ENC_DUMMY, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version - req_buff-- - k2t1_buff++ + // "if" decrypts before accessing DB to receive a fresh encryption KEK + // "else" needs a fresh KEK to decrypt, but will use that KEK to encrypt - :: else -> k2t2_buff < K2T_MAX -> + if + :: cache_cleared || v_KEKs[kek_id-1].version == temp_e_dek.ref_version -> + // :: v_KEKs[kek_id-1].id == kek_id && v_KEKs[kek_id-1].version == temp_e_dek.ref_version -> + dek_id = temp_e_dek.id-ENC_DUMMY // decrypted here + :: else -> skip + fi - k2t2!e_DEK, dek_id, kek_id+ENC_DUMMY, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version - req_buff-- - k2t2_buff++ + k2db_buff < K2DB_MAX + k2db!re_DEK, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id + k2db_buff++ + + // From Database to Tenant + :: select_case == 3 -> + v_KEKs[kek_id-1].id = kek_id + v_KEKs[kek_id-1].version = kek_version + + // "if" 1 and 2 where decrypted in case 2 above + // "if" 6 and 7 needed a fresh KEK to be decrypted + + if // Mainly to ensure that every path is hit + :: dek_id == 1 -> + temp_e_dek.id = dek_id+ENC_DUMMY // encrypted here + :: dek_id == 2 -> + temp_e_dek.id = dek_id+ENC_DUMMY // encrypted here + :: else -> + if + :: temp_e_dek.id == 6 -> + assert(6 < 86) // decrypted and encrypted here + :: temp_e_dek.id == 7 -> + assert(6 < 88) // decrypted and encrypted here fi - :: else -> assert(false) + fi + + temp_e_dek.ref_id = v_KEKs[kek_id-1].id+ENC_DUMMY + temp_e_dek.ref_version = v_KEKs[kek_id-1].version + + do + :: tenant_id == 1 -> + + last_enc_1 = !last_enc_1 + temp_e_dek.enc_version = last_enc_1 + + k2t1_buff < K2T_MAX + k2t1!re_DEK, dek_id, kek_id+ENC_DUMMY, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, id + req_buff-- + k2t1_buff++ + break + + :: tenant_id == 2 -> + + last_enc_2 = !last_enc_2 + temp_e_dek.enc_version = last_enc_2 + + k2t2_buff < K2T_MAX + k2t2!re_DEK, dek_id, kek_id+ENC_DUMMY, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, grant, id + req_buff-- + k2t2_buff++ + break + od fi - goto Cleanup } @@ -509,40 +850,37 @@ proctype Keystore() if :: tenant_id == 1 -> k2t1_buff < K2T_MAX - k2t1!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS + k2t1!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id k2t1_buff++ req_buff-- :: else -> k2t2_buff < K2T_MAX - k2t2!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS + k2t2!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, grant, id k2t2_buff++ req_buff-- fi - select_case = 0 - msg = deny goto Cleanup } Cleanup: atomic { - + + auth = 0 + grant = 0 select_case = 0 msg = deny dek_id = 0 kek_id = 0 kek_ref = 0 - i = 0 + kek_version = 0 tenant_id = 0 - id = 0 - version= 0 - is_case = 0 select_case = 0 - temp_e_key.id = 0 - temp_e_key.enc_version = 0 - temp_e_key.ref_id = 0 - temp_e_key.ref_version = 0 + temp_e_dek.id = 0 + temp_e_dek.enc_version = 0 + temp_e_dek.ref_id = 0 + temp_e_dek.ref_version = 0 temp_key.version = 0 temp_key.id = 0 @@ -554,38 +892,45 @@ proctype Keystore() proctype Database() { mtype msg = deny - unsigned kek_id : 3, i : 3, tenant_id : 3, dek_id : 2, version : 1 - bit grant + unsigned kek_id : 3, i : 3, tenant_id : 3, dek_id : 2, grant : 2, version : 1, auth : 1 + bit id = 1 + bit curr_rotation + KEK p_KEKs[NUM_KEKS] - E_Key temp_e_key - bool accessed + p_KEKs[0].id = 1 + p_KEKs[1].id = 2 + E_DEK temp_e_dek - atomic { - i = 0 - for (i : 0 .. NUM_KEKS-1) { - p_KEKs[i].id = i+1 - } - i = 0 - } - Select_state: - // curr_rotation = !curr_rotation - start = true + // exit_atomic = true + curr_rotation = !curr_rotation + atomic { - p_KEKs[1].version = curr_rotation + // do // Rotation + // :: curr_rotation = 0 -> break + // :: curr_rotation = 1 -> break + // od + p_KEKs[0].version = curr_rotation + p_KEKs[1].version = curr_rotation k2db_buff > 0 - k2db?msg, dek_id, kek_id, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant + k2db?msg, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, auth k2db_buff-- - - assert(kek_id>0) + // AUTHENTICATION VIOLATION + if + :: auth != 1 -> p_authentic = false -> goto Deny_request + :: else -> skip + fi + + assert(kek_id>0 && kek_id<3) + do :: (msg == e_DEK || msg == d_DEK || msg == ass_KEK || msg == re_DEK) -> goto Access_KEK - :: msg == rot_KEK -> goto Rotate_KEK + :: else -> goto Deny_request od } @@ -594,15 +939,14 @@ proctype Database() { atomic { - i = 0 for (i : 0 .. NUM_KEKS-1) { if :: p_KEKs[i].id == kek_id -> - + db2k_buff < DB2K_MAX - db2k!msg, dek_id, p_KEKs[i].id, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant, p_KEKs[i].version + db2k!msg, dek_id, p_KEKs[i].id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, p_KEKs[i].version, id db2k_buff++ - + goto Cleanup :: else -> skip @@ -625,7 +969,7 @@ proctype Database() { atomic { db2k_buff < DB2K_MAX - db2k!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, tenant_id, EMPTY_PASS, EMPTY_PASS + db2k!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, tenant_id, EMPTY_PASS, EMPTY_PASS, id db2k_buff++ goto Cleanup @@ -635,14 +979,14 @@ proctype Database() { atomic { - accessed = false + auth = 0 i = 0 msg = deny dek_id = 0 kek_id = 0 - temp_e_key.id = 0 - temp_e_key.enc_version = 0 - temp_e_key.ref_version = 0 + temp_e_dek.id = 0 + temp_e_dek.enc_version = 0 + temp_e_dek.ref_version = 0 tenant_id = 0 grant = 0 @@ -653,25 +997,48 @@ proctype Database() { proctype AccessControl() { mtype msg = deny - unsigned kek_ref : 3, tenant_id : 3, i : 3, num_assigned : 3, dek_id : 2, assigned_1 : 3, assigned_2 : 3 - bit grant - E_Key temp_e_key + unsigned kek_ref : 3, tenant_id : 3, auth : 1, i : 3, num_assigned : 3, dek_id : 2, grant : 2, assigned_1 : 3, assigned_2 : 3 + bit id = 1 + E_DEK temp_e_dek + atomic { + + if + :: MODEL != 1 -> + assigned_1 = 6 + assigned_2 = 7 + :: else -> skip + fi + } + Select_state: - start = true - // printf("ACCESS CONTROL\n") + exit_atomic = true + atomic { k2ac_buff > 0 - k2ac?msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant + k2ac?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, auth k2ac_buff-- + // CONFIDENTIALITY VIOLATION + if + :: temp_e_dek.id == 1 || temp_e_dek.id == 2 -> p_conf = false + :: temp_e_dek.ref_id == 1 || temp_e_dek.ref_id == 2 -> p_conf = false + :: kek_ref == 1 || kek_ref == 2 -> p_conf = false + :: else -> skip + fi + // AUTHENTICATION VIOLATION + if + :: auth != 1 -> p_authentic = false -> goto Deny_request + :: else -> skip + fi + if :: msg == ass_KEK -> goto Assign_KEK_authorize :: msg == ass_KEK2 -> goto Assign_KEK2_authorize - :: msg == d_DEK || msg == e_DEK || msg == re_DEK -> goto Authorize + :: (msg == d_DEK || msg == e_DEK || msg == re_DEK) -> goto Authorize :: else -> goto Deny_request fi @@ -694,7 +1061,7 @@ proctype AccessControl() fi ac2k_buff < AC2K_MAX - ac2k!ass_KEK, dek_id, kek_ref, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant + ac2k!ass_KEK, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id ac2k_buff++ goto Cleanup @@ -708,14 +1075,15 @@ proctype AccessControl() assert(kek_ref > 5) if - :: tenant_id == 1 -> assigned_1 = kek_ref - :: tenant_id == 2 -> assigned_2 = kek_ref + :: tenant_id == 1 && assigned_1 == 0 -> assigned_1 = kek_ref + :: tenant_id == 2 && assigned_2 == 0 -> assigned_2 = kek_ref + :: else -> goto Deny_request fi ac2k_buff < AC2K_MAX - ac2k!ass_KEK2, dek_id, kek_ref, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant + ac2k!ass_KEK2, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id ac2k_buff++ - + goto Cleanup } @@ -732,15 +1100,15 @@ proctype AccessControl() if :: tenant_id == 1 && (kek_ref != assigned_1) -> goto Deny_request :: tenant_id == 2 && (kek_ref != assigned_2) -> - if - :: grant == VALID_GRANT && assigned_1 == kek_ref -> skip - :: else -> goto Deny_request - fi + if + :: grant == VALID_GRANT && assigned_1 == kek_ref && msg == d_DEK -> skip + :: else -> goto Deny_request + fi :: else -> skip fi ac2k_buff < AC2K_MAX - ac2k!msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.enc_version, temp_e_key.ref_version, tenant_id, grant + ac2k!msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id ac2k_buff++ goto Cleanup @@ -751,7 +1119,7 @@ proctype AccessControl() atomic { ac2k_buff < AC2K_MAX - ac2k!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, tenant_id, EMPTY_PASS + ac2k!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, tenant_id, EMPTY_PASS, id ac2k_buff++ @@ -762,14 +1130,13 @@ proctype AccessControl() atomic { - num_assigned = 0 - i = 0 + auth = 0 msg = deny dek_id = 0 kek_ref = 0 - temp_e_key.id = 0 - temp_e_key.enc_version = 0 - temp_e_key.ref_version = 0 + temp_e_dek.id = 0 + temp_e_dek.enc_version = 0 + temp_e_dek.ref_version = 0 tenant_id = 0 grant = 0 From abd6dab6102ef3174b002a4d7683b647ddee8cd0 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Thu, 23 May 2024 22:04:34 +0200 Subject: [PATCH 18/30] model_c contains assign, encrypt and decrypt and ready to be verified. Recrypt to be finalized as well as decryption with grant. MIT-license added --- SPIN-verification/LICENSE.txt | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 SPIN-verification/LICENSE.txt diff --git a/SPIN-verification/LICENSE.txt b/SPIN-verification/LICENSE.txt new file mode 100644 index 0000000..220f951 --- /dev/null +++ b/SPIN-verification/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Sebastian Owuya + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the Software), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. From 1c7ddaaab729887801c8bf19670b50ea46c1e216 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Thu, 23 May 2024 22:07:45 +0200 Subject: [PATCH 19/30] changes weren't added to model_c, so recommit --- SPIN-verification/model_c.pml | 614 +++++++++++++++++++--------------- 1 file changed, 347 insertions(+), 267 deletions(-) diff --git a/SPIN-verification/model_c.pml b/SPIN-verification/model_c.pml index b4128e3..cc2bb4b 100644 --- a/SPIN-verification/model_c.pml +++ b/SPIN-verification/model_c.pml @@ -1,10 +1,33 @@ +/* +MIT License + +Copyright (c) 2024 Sebastian Owuya + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + #define NUM_DEKS 1 #define NUM_KEKS 2 #define NUM_TENANTS 2 #define VALID_GRANT 1 #define ENC_DUMMY 5 #define EMPTY_PASS 0 -#define SAME_KEK_ASSIGNED false // CHANNEL CAPS #define T2K_MAX 1 @@ -13,16 +36,18 @@ #define AC2K_MAX 1 #define K2DB_MAX 1 #define DB2K_MAX 1 + +// REQUEST LIMIT OF CONCURRENT PROCESSING IN KEYSTORE #define REQ_MAX 2 /** MODELS 1: Assignemnt and Encryption. - 2: Decryption + 2: Decryption with 2: Tenant 1 full operations, Tenant 2 only Decrypts encrypted DEKs received from Tenant 1 with different grants 3: Re-Encryption of encrypted DEKs */ -#define MODEL 3 +#define MODEL 1 typedef KEK { /* Unencrypted */ unsigned id : 2 @@ -46,20 +71,20 @@ mtype = { e_DEK, d_DEK, re_DEK, ass_KEK, ass_KEK2, deny } // db: Database // { message type, DEK_ID, KEK_ID, E_KEY-ID, (E_KEY-ENC_V), E_KEY-REF_V, TENANT_ID, (GRANT), (KEK-VERSION), AUTH } -chan t12k = [T2K_MAX] of { mtype, byte, byte, byte, byte, byte } // Tenant 1 -> Keystore, |t12k| = 6 -chan k2t1 = [K2T_MAX] of { mtype, byte, byte, byte, byte, byte, byte } // Keystore -> Tenant 1, |k2t1| = 7 +chan t12k = [T2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte } // Tenant 1 -> Keystore, |t12k| = 6 +chan k2t1 = [K2T_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte } // Keystore -> Tenant 1, |k2t1| = 7 -chan t22k = [T2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte } // Tenant 2 -> Keystore, |t22k| = 7 -chan k2t2 = [K2T_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte } // Keystore -> Tenant 2, |k2t2| = 8 +chan t22k = [T2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte } // Tenant 2 -> Keystore, |t22k| = 7 +chan k2t2 = [K2T_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte, byte } // Keystore -> Tenant 2, |k2t2| = 8 -chan k2ac = [K2AC_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte } // Keystore -> Access Control, |k2ac| = 8 -chan ac2k = [AC2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte } // Access Control -> Keystore, |ac2k| = 8 +chan k2ac = [K2AC_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte, byte } // Keystore -> Access Control, |k2ac| = 8 +chan ac2k = [AC2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte, byte } // Access Control -> Keystore, |ac2k| = 8 -chan k2db = [K2DB_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte } // Keystore -> Database, |k2db| = 8 -chan db2k = [DB2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte, byte } // Database -> Keystore, |db2k| = 9 +chan k2db = [K2DB_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte, byte } // Keystore -> Database, |k2db| = 8 +chan db2k = [DB2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte, byte, byte } // Database -> Keystore, |db2k| = 9 bool exit_atomic -local bool cache_cleared, p_rotated_1, p_rotated_2 +local bool cache_cleared // Channel buffers unsigned t12k_buff: 3, t22k_buff: 3 @@ -69,22 +94,27 @@ unsigned k2ac_buff: 3, ac2k_buff: 3 unsigned req_buff: 3 // LTL variables -bool p_assigned_1, p_assigned_2, p_enc_1, p_enc_2, p_1 = true, p_2 = true, p_conf = true, p_authentic = true, p_int = true - +bool p_assigned_1, p_assigned_2, curr_rotation//, db_active +bool p_conf = true, p_authentic = true, p_int = true, p_sync = true, p_protocol = true +local bool p_rotated_1 , p_rotated_2, p_enc_1, p_enc_2, db_skip_1, db_skip_2//, p_dec_1, p_dec_2 +//unsigned p_enc_1 : 3, p_enc_2 : 3, p_dec_1 : 3, p_dec_2 : 3 //, p_will_rotate_1, p_will_rotate_2 +// unsigned count_1 : 2, count_2 : 2 // LTL claims -// ltl { [] conf } -// ltl Confidentiality { [] (enc_1 != u_enc_1 && enc_2 != u_enc_2 && enc_1 > 4 && enc_2 > 4 && (u_enc_1 == 14||u_enc_1 < 5) && (u_enc_2 == 14 || u_enc_2 < 5)) } -// bool ps_confidentiality, ps_integrity, ps_authentication, ps_authorization, ps_consistency, pl_confidentiality, pl_integrity, pl_authentication, pl_authorization, pl_consistency -// TRY TO VIOLATE LTL -ltl safety_model_1 { [](p_conf && p_authentic && p_int) && [](p_1 && p_2)&& ( p_enc_1 -> p_assigned_1 ) && ( p_enc_2 -> p_assigned_2 ) } -ltl liveness_model_1 {[]<>(p_enc_1 && p_enc_2) && (!p_enc_1 U p_assigned_1) && (!p_enc_2 U p_assigned_2)} -// ltl safety_model_2 -// ltl liveness_model_2 -// ltl safety_model_3 -// ltl liveness_model_3 -// ltl safety_model_4 -// ltl liveness_model_4 +ltl safety_model_1 { [](p_conf && p_authentic && p_int && p_protocol && p_sync && (Tenant_1[1]@Decrypt_receive -> p_enc_1) && (Tenant_2[2]@Decrypt_receive -> p_enc_2) && (p_enc_1 -> p_assigned_1) && (p_enc_2 -> p_assigned_2 )) } +// ltl liveness_existence_1 {!([]<>(Tenant_1[1]@Encrypt_receive))} +// ltl liveness_existence_2 {!([]<>(Tenant_1[1]@Decrypt_receive))} +// ltl liveness_existence_3 {!([]<>(Tenant_1[1]@Decrypt_receive) && ![]<>(Tenant_1[1]@Encrypt_receive))} +// ltl liveness_existence_4 {!([]<>(Tenant_2[2]@Encrypt_receive))} +// ltl liveness_existence_5 {!([]<>(Tenant_2[2]@Decrypt_receive))} +// ltl liveness_existence_6 {!([]<>(Tenant_2[2]@Decrypt_receive) && ![]<>(Tenant_2[2]@Encrypt_receive))} +// ltl liveness_existence_7 {!([]<>(Tenant_1[1]@Encrypt_receive) && []<>(Tenant_1[1]@Decrypt_receive && Tenant_2[2]@Encrypt_receive) && []<>(Tenant_2[2]@Decrypt_receive))} +ltl liveness_model_1 { ([]<>(Tenant_1[1]@Encrypt_receive) -> ([]<>(p_rotated_1) && []<>(!p_rotated_1))) && ([]<>(Tenant_2[2]@Encrypt_receive) -> ([]<>(p_rotated_2) && []<>(!p_rotated_2))) && + ([]<>(Tenant_1[1]@Decrypt_receive) -> ([]<>(p_rotated_1) && []<>(!p_rotated_1))) && ([]<>(Tenant_2[2]@Decrypt_receive) -> ([]<>(p_rotated_2) && []<>(!p_rotated_2))) && + (([]<>(Tenant_1[1]@Decrypt_receive) && ![]<>(Tenant_1[1]@Encrypt_receive))-> ([]<>(db_skip_1) && []<>(!db_skip_1))) && + (([]<>(Tenant_2[2]@Decrypt_receive) && ![]<>(Tenant_2[2]@Encrypt_receive))-> ([]<>(db_skip_2) && []<>(!db_skip_2))) } + + init { atomic { @@ -109,10 +139,10 @@ init { proctype Tenant_1() { mtype msg = deny - unsigned temp_dek: 3, assigned_KEK : 3, ref_version_1 : 1, ref_version_2 : 1 + unsigned temp_dek: 3, assigned_KEK : 3, ref_version_1 : 1, ref_version_2 : 1, step : 4 unsigned id : 2 = 1 unsigned dek_id : 2 = 1 - bit auth + bit auth, denied E_DEK temp_e_dek, encrypted_DEK @@ -133,52 +163,53 @@ proctype Tenant_1() } Select_state: - + exit_atomic = true atomic { - do - :: k2t1_buff > 0 -> k2t1?msg, temp_dek, temp_e_dek.ref_id, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, auth -> k2t1_buff-- -> - - // CONFIDENTIALITY VIOLATION + :: k2t1_buff > 0 -> k2t1?msg, temp_dek, temp_e_dek.ref_id, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, auth, step -> req_buff-- -> k2t1_buff-- -> + // AUTHENTICATION OR CONFIDENTIALITY VIOLATION if :: temp_e_dek.id == 1 || temp_e_dek.id == 2 -> p_conf = false :: temp_e_dek.ref_id == 1 || temp_e_dek.ref_id == 2 -> p_conf = false - :: else -> skip - fi - - // AUTHENTICATION VIOLATION - if :: auth != 1 -> p_authentic = false :: else -> skip fi if - :: msg == ass_KEK -> goto Assign_KEK_receive - :: msg == d_DEK -> goto Decrypt_receive - :: msg == e_DEK -> goto Encrypt_receive - :: msg == re_DEK -> goto Recrypt_Receive - :: else -> + :: msg == deny -> + denied = true + // if + // :: step != 2 -> p_protocol = false + // :: else -> skip + // fi + :: else -> + denied = false if - :: MODEL == 1 -> - if - :: assigned_KEK != 0 -> p_1 = false - :: else -> skip - fi - :: else -> skip - fi + :: msg == ass_KEK -> goto Assign_KEK_receive + :: msg == d_DEK -> goto Decrypt_receive + :: msg == e_DEK -> goto Encrypt_receive + :: msg == re_DEK -> goto Recrypt_Receive + fi fi - - break - + // break + :: t12k_buff < T2K_MAX -> + do :: MODEL == 1 -> do - :: t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id -> break - :: t12k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id -> break + :: !(denied && p_assigned_1) -> + Assign_send: + t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, 1 -> break + :: !(denied && !p_assigned_1) -> + Encrypt_send: + t12k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, 1 -> break + :: !(denied && encrypted_DEK.id == 0) -> + Decrypt_send: + t12k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.ref_version, id, 1 -> break od break :: MODEL == 2 -> @@ -190,28 +221,24 @@ proctype Tenant_1() break :: MODEL == 3 -> t12k!re_DEK, assigned_KEK, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.ref_version, id -> break od - t12k_buff++ - break - - :: else -> break + // break od - goto Select_state } + Assign_KEK_receive: atomic { - - // P VIOLATION - d_step { - if - :: assigned_KEK == temp_e_dek.ref_id -> p_int = false - :: p_assigned_2 -> p_1 = false - :: else -> skip - fi - } + + // PROTOCOL, SYNCHRONIZATION OR INTEGRITY VIOLATION + if + :: step != 8 -> p_protocol = false + :: assigned_KEK == temp_e_dek.ref_id -> p_int = false + :: p_assigned_1 -> p_sync = false + :: else -> skip + fi p_assigned_1 = true assigned_KEK = temp_e_dek.ref_id @@ -222,33 +249,37 @@ proctype Tenant_1() Decrypt_receive: atomic { - + // PROTOCOL OR INTEGRITY VIOLATION + if + :: step != 4 && step != 6 -> p_protocol = false + :: dek_id != temp_dek -> p_int = false + :: else -> skip + fi + // printf("1\n") assert(dek_id == temp_dek) - goto Cleanup } Encrypt_receive: atomic { - - p_enc_1 = true - // P VIOLATION - d_step { - if - :: temp_e_dek.enc_version == encrypted_DEK.enc_version -> p_1 = false - :: temp_e_dek.id-ENC_DUMMY != dek_id -> p_int = false - :: temp_e_dek.ref_id != assigned_KEK -> p_int = false - :: else -> skip - fi - } + // PROTOCOL, SYNCHRONIZATION OR INTEGRITY VIOLATION + if + :: step != 6 -> p_protocol = false + :: temp_e_dek.enc_version == encrypted_DEK.enc_version -> p_sync = false + :: temp_e_dek.id-ENC_DUMMY != dek_id -> p_int = false + :: temp_e_dek.ref_id != assigned_KEK -> p_int = false + :: else -> skip + fi encrypted_DEK.id = temp_e_dek.id encrypted_DEK.enc_version = temp_e_dek.enc_version encrypted_DEK.ref_id = temp_e_dek.ref_id encrypted_DEK.ref_version = temp_e_dek.ref_version + p_enc_1 = true + goto Cleanup } @@ -268,7 +299,7 @@ proctype Tenant_1() Cleanup: atomic { - + step = 0 auth = 0 msg = deny temp_dek = 0 @@ -284,10 +315,10 @@ proctype Tenant_1() proctype Tenant_2() { mtype msg = deny - unsigned temp_dek: 3, assigned_KEK : 3, grant : 2, ref_version_1 : 1, ref_version_2 : 1 + unsigned temp_dek: 3, assigned_KEK : 3, grant : 2, ref_version_1 : 1, ref_version_2 : 1, step : 4 unsigned id : 2 = 2 unsigned dek_id : 2 = 2 - bit auth + bit auth, denied E_DEK temp_e_dek, encrypted_DEK, received_e_DEK atomic { @@ -320,45 +351,48 @@ proctype Tenant_2() atomic { do - :: k2t2_buff > 0 -> k2t2?msg, temp_dek, temp_e_dek.ref_id, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, grant, auth -> k2t2_buff-- -> - // CONFIDENTIALITY VIOLATION + :: k2t2_buff > 0 -> k2t2?msg, temp_dek, temp_e_dek.ref_id, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, grant, auth, step -> req_buff-- -> k2t2_buff-- -> + // AUTHENTICATION OR CONFIDENTIALITY VIOLATION if + :: auth != 1 -> p_authentic = false :: temp_e_dek.id == 1 || temp_e_dek.id == 2 -> p_conf = false :: temp_e_dek.ref_id == 1 || temp_e_dek.ref_id == 2 -> p_conf = false :: else -> skip fi - // AUTHENTICATION VIOLATION if - :: auth != 1 -> p_authentic = false - :: else -> skip - fi - - if - :: msg == ass_KEK -> goto Assign_KEK_receive - :: msg == d_DEK -> goto Decrypt_receive - :: msg == e_DEK -> goto Encrypt_receive - :: msg == re_DEK -> goto Recrypt_Receive - :: else -> + :: msg == deny -> + denied = true + // PROTOCOL VIOLATION + // if + // :: step != 4 -> p_protocol = false + // :: else -> skip + // fi + :: else -> + denied = false if - :: MODEL == 1 -> - if - :: assigned_KEK != 0 -> p_2 = false - :: else -> skip - fi - :: else -> skip - fi + :: msg == ass_KEK -> goto Assign_KEK_receive + :: msg == d_DEK -> goto Decrypt_receive + :: msg == e_DEK -> goto Encrypt_receive + :: msg == re_DEK -> goto Recrypt_Receive + fi fi - break - + // break :: t22k_buff < T2K_MAX -> do :: MODEL == 1 -> do - :: t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant -> break - :: t22k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, grant -> break + :: !(denied && p_assigned_2) -> + Assign_send: + t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant, 1 -> break + :: !(denied && !p_assigned_2) -> + Encrypt_send: + t22k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, grant, 1 -> break + :: !(denied && encrypted_DEK.id == 0) -> + Decrypt_send: + t22k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.ref_version, id, grant, 1 -> break od break :: MODEL == 2 -> @@ -374,30 +408,24 @@ proctype Tenant_2() break :: MODEL == 3 -> t22k!re_DEK, assigned_KEK, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.ref_version, id, grant -> break od - t22k_buff++ - break - - :: else -> break + // break od - - goto Select_state + } + Assign_KEK_receive: atomic { - - // P VIOLATION - d_step { - if - :: assigned_KEK == temp_e_dek.ref_id -> p_int = false - :: p_assigned_2 -> p_2 = false // liveness - :: else -> skip - fi - } - + // PROTOCOL, SYNCHRONIZATION OR INTEGRITY VIOLATION + if + :: step != 8 -> p_protocol = false + :: assigned_KEK == temp_e_dek.ref_id -> p_int = false + :: p_assigned_2 -> p_sync = false // liveness + :: else -> skip + fi p_assigned_2 = true assigned_KEK = temp_e_dek.ref_id @@ -407,8 +435,14 @@ proctype Tenant_2() Decrypt_receive: atomic { - - assert(dek_id == temp_dek || (grant != 0 && temp_dek == 1)) + // printf("2\n") + // PROTOCOL OR INTEGRITY VIOLATION + if + :: step != 4 && step != 6 -> p_protocol = false + :: dek_id != temp_dek -> p_int = false + :: grant == 1 && temp_dek != 1 -> p_int = false + :: else -> skip + fi // assert(false) goto Cleanup @@ -418,29 +452,21 @@ proctype Tenant_2() atomic { - // printf("Received 2\n") - // if - // :: encrypted_DEK.id == 0 -> skip - // :: encrypted_DEK.id != 0 && temp_e_dek.ref_version < encrypted_DEK.ref_version -> //TODO - // if - // :: temp_e_dek.ref_id-ENC_DUMMY == 1 -> assert(curr_rotation_1) -> curr_rotation_1 = false - // :: else -> assert(curr_rotation_2) -> curr_rotation_2 = false - // fi - // :: else -> assert(temp_e_dek.ref_version >= encrypted_DEK.ref_version) - // fi - p_enc_2 = true - // SAFETY VIOLATION + // PROTOCOL, SYNCHRONIZATION OR INTEGRITY VIOLATION if - :: temp_e_dek.enc_version == encrypted_DEK.enc_version -> p_2 = false - :: temp_e_dek.id-ENC_DUMMY != dek_id -> p_2 = false - :: temp_e_dek.ref_id != assigned_KEK -> p_2 = false + :: step != 6 -> p_protocol = false + :: temp_e_dek.enc_version == encrypted_DEK.enc_version -> p_sync = false + :: temp_e_dek.id-ENC_DUMMY != dek_id -> p_int = false + :: temp_e_dek.ref_id != assigned_KEK -> p_int = false :: else -> skip fi - + encrypted_DEK.id = temp_e_dek.id encrypted_DEK.enc_version = temp_e_dek.enc_version encrypted_DEK.ref_id = temp_e_dek.ref_id encrypted_DEK.ref_version = temp_e_dek.ref_version + + p_enc_2 = true goto Cleanup } @@ -472,6 +498,7 @@ proctype Tenant_2() temp_e_dek.id = 0 temp_e_dek.enc_version = 0 temp_e_dek.ref_version = 0 + step = 0 goto Select_state } @@ -479,10 +506,10 @@ proctype Tenant_2() proctype Keystore() { - mtype msg = deny, enc_msg - unsigned dek_id : 3, kek_id : 3, kek_ref : 3, tenant_id : 3, select_case : 3, grant : 2, kek_version : 1, auth : 1 + mtype msg = deny + unsigned dek_id : 3, kek_id : 3, kek_ref : 3, tenant_id : 3, select_case : 3, grant : 2, kek_version : 1, auth : 1, step : 3 bit id = 1 - bit last_enc_1, last_enc_2 + bit last_enc_1, last_enc_2, turn E_DEK temp_e_dek KEK temp_key KEK v_KEKs[NUM_KEKS] @@ -499,34 +526,22 @@ proctype Keystore() Select_state: - exit_atomic = true + cache_cleared = !cache_cleared atomic { - if - :: MODEL == 1 -> skip - :: else -> cache_cleared = !cache_cleared - fi - - p_rotated_1 = false - p_rotated_2 = false - // do // Cache clear - // :: v_KEKs[0].id = 0 - // v_KEKs[0].id = 0 - // break - // :: v_KEKs[0].id = 1 - // v_KEKs[0].id = 2 - // break - // od - do //FROM AC - :: ac2k_buff > 0 -> ac2k?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, auth -> ac2k_buff-- -> + :: ac2k_buff > 0 -> ac2k?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, auth, step -> ac2k_buff-- -> select_case = 2 + // PROTOCOL OR AUTHENTICATION VIOLATION if :: auth != 1 -> p_authentic = false -> goto Deny_request + :: msg == ass_KEK2 && step != 7 -> p_protocol = false + :: msg != ass_KEK2 && msg != deny && step != 3 -> p_protocol = false + :: msg == deny && step != 7 && step != 3 -> p_protocol = false :: else -> skip fi @@ -545,12 +560,14 @@ proctype Keystore() od //FROM DB - :: db2k_buff > 0 -> db2k?msg, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, kek_version, auth -> db2k_buff-- -> - + :: db2k_buff > 0 -> db2k?msg, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, kek_version, auth, step -> db2k_buff-- -> + select_case = 3 + // PROTOCOL OR AUTHENTICATION VIOLATION if :: auth != 1 -> p_authentic = false -> goto Deny_request + :: step != 5 -> p_protocol = false :: else -> skip fi @@ -562,13 +579,16 @@ proctype Keystore() :: msg == deny -> goto Deny_request od + // FROM TENANT - :: req_buff < REQ_MAX && t12k_buff > 0 -> t12k?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id -> req_buff++ -> t12k_buff-- -> - - select_case = 1 + :: (turn == 1 || (turn == 0 && t22k_buff == 0)) && req_buff < REQ_MAX && t12k_buff > 0 -> t12k?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, step -> req_buff++ -> t12k_buff-- -> + select_case = 1 + turn = 0 + // PROTOCOL OR AUTHENTICATION VIOLATION if :: tenant_id != 1 -> p_authentic = false -> goto Deny_request + :: step != 1 -> p_protocol = false :: else -> skip fi @@ -578,12 +598,14 @@ proctype Keystore() :: msg == e_DEK -> goto Encrypt :: msg == re_DEK -> goto Recrypt od - :: req_buff < REQ_MAX && t22k_buff > 0 -> t22k?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant -> req_buff++ -> t22k_buff-- -> + :: (turn == 0 || (turn == 1 && t12k_buff == 0)) && req_buff < REQ_MAX && t22k_buff > 0 -> t22k?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, step -> req_buff++ -> t22k_buff-- -> select_case = 1 - + turn = 1 + // PROTOCOL OR AUTHENTICATION VIOLATION if :: tenant_id != 2 -> p_authentic = false -> goto Deny_request + :: step != 1 -> p_protocol = false :: else -> skip fi @@ -593,11 +615,9 @@ proctype Keystore() :: msg == e_DEK -> goto Encrypt :: msg == re_DEK -> goto Recrypt od - :: else -> break od - - goto Select_state } + Assign_KEK: @@ -605,8 +625,9 @@ proctype Keystore() if // From Tenant to Access Control :: select_case == 1 -> + k2ac_buff < K2AC_MAX - k2ac!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, tenant_id, grant, id + k2ac!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, tenant_id, grant, id, step+1 k2ac_buff++ // From Access Control to Database @@ -618,7 +639,7 @@ proctype Keystore() kek_id = tenant_id k2db_buff < K2DB_MAX - k2db!ass_KEK, EMPTY_PASS, kek_id, EMPTY_PASS, EMPTY_PASS, tenant_id, grant, id + k2db!ass_KEK, EMPTY_PASS, kek_id, EMPTY_PASS, EMPTY_PASS, tenant_id, grant, id, step+1 k2db_buff++ // From Database to Access Control @@ -628,8 +649,9 @@ proctype Keystore() v_KEKs[kek_id-1].version = kek_version k2ac_buff < K2AC_MAX - k2ac!ass_KEK2, EMPTY_PASS, kek_id+ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, tenant_id, grant, id + k2ac!ass_KEK2, EMPTY_PASS, kek_id+ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, tenant_id, grant, id, step+1 k2ac_buff++ + // From Access Control to Tenant :: select_case == 4 -> @@ -641,13 +663,14 @@ proctype Keystore() if :: tenant_id == 1 -> k2t1_buff < K2T_MAX - k2t1!ass_KEK, EMPTY_PASS, kek_ref, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id - req_buff-- -> k2t1_buff++ + k2t1!ass_KEK, EMPTY_PASS, kek_ref, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, step+1 + // req_buff-- -> + k2t1_buff++ :: else -> k2t2_buff < K2T_MAX - k2t2!ass_KEK, EMPTY_PASS, kek_ref, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, grant, id - req_buff-- -> k2t2_buff++ + k2t2!ass_KEK, EMPTY_PASS, kek_ref, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, grant, id, step+1 + // req_buff-- -> + k2t2_buff++ fi - :: else -> assert(false) fi goto Cleanup @@ -661,37 +684,66 @@ proctype Keystore() :: select_case == 1 -> k2ac_buff < K2AC_MAX - k2ac!d_DEK, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id + k2ac!d_DEK, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 k2ac_buff++ // From Access Control to Database :: select_case == 2 -> if // Already in memory so skip Database - // :: v_KEKs[kek_id-1].id == kek_id && v_KEKs[kek_id-1].version == temp_e_dek.ref_version -> - :: cache_cleared || v_KEKs[kek_id-1].version == temp_e_dek.ref_version -> - select_case = 4 + :: !cache_cleared || !(v_KEKs[kek_id-1].version == 1 && temp_e_dek.ref_version == 0) -> + + select_case = 4 + + if + :: tenant_id == 1 -> db_skip_1 = true -> skip + :: tenant_id == 2 -> db_skip_2 = true -> skip + fi :: else -> - k2db_buff < K2DB_MAX -> - k2db!d_DEK, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id - k2db_buff++ + if + :: tenant_id == 1 -> db_skip_1 = false -> skip + :: tenant_id == 2 -> db_skip_2 = false -> skip + fi + k2db_buff < K2DB_MAX -> + k2db!d_DEK, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 + k2db_buff++ fi // From Database to Tenant :: select_case == 3 -> + select_case = 4 + v_KEKs[kek_id-1].id = kek_id v_KEKs[kek_id-1].version = kek_version + + // ROTATION CHECK + if + :: tenant_id == 1 -> + if + :: v_KEKs[kek_id-1].version == 0 -> + p_rotated_1 = true + :: else -> p_rotated_1 = false + fi + :: tenant_id == 2 -> + if + :: v_KEKs[kek_id-1].version == 0 -> + p_rotated_2 = true + :: else -> p_rotated_2 = false + fi + fi fi if // DB -> KS -> T or Database skip from case 2 AC -> KS -> T :: select_case == 4 -> if :: tenant_id == 1 -> k2t1_buff < K2T_MAX - k2t1!d_DEK, temp_e_dek.id-ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id - req_buff-- -> k2t1_buff++ + k2t1!d_DEK, temp_e_dek.id-ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, step+1 + // req_buff-- -> + k2t1_buff++ :: else -> k2t2_buff < K2T_MAX - k2t2!d_DEK, temp_e_dek.id-ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, grant, id - req_buff-- -> k2t2_buff++ + k2t2!d_DEK, temp_e_dek.id-ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, grant, id, step+1 + // req_buff-- -> + k2t2_buff++ fi :: else -> skip fi @@ -705,43 +757,52 @@ proctype Keystore() if // From Tenant to Access Control :: select_case == 1 -> - + k2ac_buff < K2AC_MAX - k2ac!e_DEK, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id + k2ac!e_DEK, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 k2ac_buff++ // From Access Control to Database :: select_case == 2 -> k2db_buff < K2DB_MAX - k2db!e_DEK, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id + k2db!e_DEK, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 k2db_buff++ // From Database to Tenant :: select_case == 3 -> - + + v_KEKs[kek_id-1].version = kek_version v_KEKs[kek_id-1].id = kek_id + // ROTATION CHECK if - :: tenant_id == 1 && v_KEKs[kek_id-1].version != kek_version -> - p_rotated_1 = true - :: tenant_id == 2 && v_KEKs[kek_id-1].version != kek_version -> - p_rotated_2 = true - :: else skip + :: tenant_id == 1 -> + if + :: v_KEKs[kek_id-1].version == 0 -> + p_rotated_1 = true + :: else -> p_rotated_1 = false + fi + :: tenant_id == 2 -> + if + :: v_KEKs[kek_id-1].version == 0 -> + p_rotated_2 = true + :: else -> p_rotated_2 = false + fi fi - v_KEKs[kek_id-1].version = kek_version + + temp_e_dek.id = dek_id+ENC_DUMMY temp_e_dek.ref_id = v_KEKs[kek_id-1].id+ENC_DUMMY temp_e_dek.ref_version = v_KEKs[kek_id-1].version + do :: tenant_id == 1 -> - last_enc_1 = !last_enc_1 temp_e_dek.enc_version = last_enc_1 k2t1_buff < K2T_MAX - k2t1!e_DEK, dek_id, kek_id+ENC_DUMMY, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, id - req_buff-- + k2t1!e_DEK, dek_id, kek_id+ENC_DUMMY, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, id, step+1 k2t1_buff++ break @@ -751,8 +812,7 @@ proctype Keystore() temp_e_dek.enc_version = last_enc_2 k2t2_buff < K2T_MAX - k2t2!e_DEK, dek_id, kek_id+ENC_DUMMY, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, grant, id - req_buff-- + k2t2!e_DEK, dek_id, kek_id+ENC_DUMMY, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, grant, id, step+1 k2t2_buff++ break od @@ -769,7 +829,7 @@ proctype Keystore() :: select_case == 1 -> k2ac_buff < K2AC_MAX - k2ac!re_DEK, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id + k2ac!re_DEK, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 k2ac_buff++ // From Access Control to Database @@ -786,7 +846,7 @@ proctype Keystore() fi k2db_buff < K2DB_MAX - k2db!re_DEK, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id + k2db!re_DEK, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 k2db_buff++ // From Database to Tenant @@ -822,8 +882,8 @@ proctype Keystore() temp_e_dek.enc_version = last_enc_1 k2t1_buff < K2T_MAX - k2t1!re_DEK, dek_id, kek_id+ENC_DUMMY, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, id - req_buff-- + k2t1!re_DEK, dek_id, kek_id+ENC_DUMMY, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, id, step+1 + // req_buff-- k2t1_buff++ break @@ -833,8 +893,8 @@ proctype Keystore() temp_e_dek.enc_version = last_enc_2 k2t2_buff < K2T_MAX - k2t2!re_DEK, dek_id, kek_id+ENC_DUMMY, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, grant, id - req_buff-- + k2t2!re_DEK, dek_id, kek_id+ENC_DUMMY, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, grant, id, step+1 + // req_buff-- k2t2_buff++ break od @@ -846,18 +906,36 @@ proctype Keystore() Deny_request: atomic { - + if :: tenant_id == 1 -> - k2t1_buff < K2T_MAX - k2t1!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id - k2t1_buff++ - req_buff-- + if + :: p_assigned_1 && MODEL == 1 -> + // SYNCHRONIZATION VIOLATION + if + :: (msg != ass_KEK || msg != ass_KEK2) && kek_ref == 6 -> p_sync = false + :: else -> skip + fi + :: else -> skip + fi + k2t1_buff < K2T_MAX + k2t1!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, step+1 + k2t1_buff++ + // req_buff-- :: else -> - k2t2_buff < K2T_MAX - k2t2!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, grant, id - k2t2_buff++ - req_buff-- + if + :: p_assigned_2 && MODEL == 1 -> + // SYNCHRONIZATION VIOLATION + if + :: (msg != ass_KEK || msg != ass_KEK2) && kek_ref == 7 -> p_sync = false + :: else -> skip + fi + :: else -> skip + fi + k2t2_buff < K2T_MAX + k2t2!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, grant, id, step+1 + k2t2_buff++ + // req_buff-- fi goto Cleanup @@ -869,7 +947,6 @@ proctype Keystore() auth = 0 grant = 0 - select_case = 0 msg = deny dek_id = 0 kek_id = 0 @@ -883,18 +960,17 @@ proctype Keystore() temp_e_dek.ref_version = 0 temp_key.version = 0 temp_key.id = 0 - - goto Select_state + step = 0 } + goto Select_state } proctype Database() { mtype msg = deny - unsigned kek_id : 3, i : 3, tenant_id : 3, dek_id : 2, grant : 2, version : 1, auth : 1 + unsigned kek_id : 3, i : 3, tenant_id : 3, dek_id : 2, grant : 2, auth : 1, step : 3 bit id = 1 - bit curr_rotation KEK p_KEKs[NUM_KEKS] p_KEKs[0].id = 1 @@ -903,30 +979,20 @@ proctype Database() { Select_state: - // exit_atomic = true - curr_rotation = !curr_rotation + exit_atomic = true atomic { - - // do // Rotation - // :: curr_rotation = 0 -> break - // :: curr_rotation = 1 -> break - // od - - p_KEKs[0].version = curr_rotation - p_KEKs[1].version = curr_rotation - k2db_buff > 0 - k2db?msg, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, auth + k2db?msg, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, auth, step k2db_buff-- - // AUTHENTICATION VIOLATION + // PROTOCOL, AUTHENTICATION OR INTEGRITY VIOLATION if + :: step != 4 -> p_protocol = false :: auth != 1 -> p_authentic = false -> goto Deny_request + :: kek_id != 1 && kek_id != 2 -> p_int = false :: else -> skip fi - - assert(kek_id>0 && kek_id<3) do :: (msg == e_DEK || msg == d_DEK || msg == ass_KEK || msg == re_DEK) -> goto Access_KEK @@ -944,7 +1010,11 @@ proctype Database() { :: p_KEKs[i].id == kek_id -> db2k_buff < DB2K_MAX - db2k!msg, dek_id, p_KEKs[i].id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, p_KEKs[i].version, id + // curr_rotation = !curr_rotation + // p_KEKs[0].version = curr_rotation + // p_KEKs[1].version = curr_rotation + p_KEKs[i].version = !p_KEKs[i].version + db2k!msg, dek_id, p_KEKs[i].id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, p_KEKs[i].version, id, step+1 db2k_buff++ goto Cleanup @@ -957,21 +1027,17 @@ proctype Database() { } - Rotate_KEK: - - atomic { - - goto Cleanup - } - Deny_request: atomic { db2k_buff < DB2K_MAX - db2k!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, tenant_id, EMPTY_PASS, EMPTY_PASS, id + db2k!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, tenant_id, EMPTY_PASS, EMPTY_PASS, id, step+1 db2k_buff++ + // SYNCHRONIZATION VIOLATION IN ACCESS CONTROL + p_sync = false + goto Cleanup } @@ -989,6 +1055,7 @@ proctype Database() { temp_e_dek.ref_version = 0 tenant_id = 0 grant = 0 + step = 0 goto Select_state } @@ -997,7 +1064,7 @@ proctype Database() { proctype AccessControl() { mtype msg = deny - unsigned kek_ref : 3, tenant_id : 3, auth : 1, i : 3, num_assigned : 3, dek_id : 2, grant : 2, assigned_1 : 3, assigned_2 : 3 + unsigned kek_ref : 3, tenant_id : 3, auth : 1, dek_id : 2, grant : 2, assigned_1 : 3, assigned_2 : 3, step : 3 bit id = 1 E_DEK temp_e_dek @@ -1017,24 +1084,22 @@ proctype AccessControl() exit_atomic = true atomic { - k2ac_buff > 0 - k2ac?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, auth + k2ac?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, auth, step k2ac_buff-- - // CONFIDENTIALITY VIOLATION + // PROTOCOL, AUTHENTICATION OR CONFIDENTIALITY VIOLATION if :: temp_e_dek.id == 1 || temp_e_dek.id == 2 -> p_conf = false :: temp_e_dek.ref_id == 1 || temp_e_dek.ref_id == 2 -> p_conf = false :: kek_ref == 1 || kek_ref == 2 -> p_conf = false - :: else -> skip - fi - // AUTHENTICATION VIOLATION - if :: auth != 1 -> p_authentic = false -> goto Deny_request + :: msg != ass_KEK2 && step != 2 -> p_protocol = false + :: msg == ass_KEK2 && step != 6 -> p_protocol = false :: else -> skip fi + if :: msg == ass_KEK -> goto Assign_KEK_authorize :: msg == ass_KEK2 -> goto Assign_KEK2_authorize @@ -1050,6 +1115,7 @@ proctype AccessControl() // Request access to generate a KEK atomic { + if :: kek_ref == 0 -> if @@ -1061,7 +1127,7 @@ proctype AccessControl() fi ac2k_buff < AC2K_MAX - ac2k!ass_KEK, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id + ac2k!ass_KEK, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 ac2k_buff++ goto Cleanup @@ -1073,7 +1139,7 @@ proctype AccessControl() atomic { assert(kek_ref > 5) - + if :: tenant_id == 1 && assigned_1 == 0 -> assigned_1 = kek_ref :: tenant_id == 2 && assigned_2 == 0 -> assigned_2 = kek_ref @@ -1081,7 +1147,7 @@ proctype AccessControl() fi ac2k_buff < AC2K_MAX - ac2k!ass_KEK2, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id + ac2k!ass_KEK2, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 ac2k_buff++ goto Cleanup @@ -1091,7 +1157,7 @@ proctype AccessControl() Authorize: atomic { - + if :: kek_ref != 6 && kek_ref != 7 -> goto Deny_request :: else -> skip @@ -1108,7 +1174,7 @@ proctype AccessControl() fi ac2k_buff < AC2K_MAX - ac2k!msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id + ac2k!msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 ac2k_buff++ goto Cleanup @@ -1118,8 +1184,21 @@ proctype AccessControl() atomic { + if + :: msg == e_DEK || msg == re_DEK || msg == d_DEK -> + // SYNCHRONIZATION VIOLATION + if + :: tenant_id == 1 && kek_ref == 6 -> + p_sync = false + :: tenant_id == 2 && kek_ref == 7 && grant != VALID_GRANT -> + p_sync = false + :: else -> skip + fi + :: else -> skip + fi + ac2k_buff < AC2K_MAX - ac2k!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, tenant_id, EMPTY_PASS, id + ac2k!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, tenant_id, EMPTY_PASS, id, step+1 ac2k_buff++ @@ -1129,7 +1208,7 @@ proctype AccessControl() Cleanup: atomic { - + // db_active = false auth = 0 msg = deny dek_id = 0 @@ -1139,6 +1218,7 @@ proctype AccessControl() temp_e_dek.ref_version = 0 tenant_id = 0 grant = 0 + step = 0 goto Select_state } From 72dac4f857bf57bffc86c1744e729f205de213f3 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Mon, 27 May 2024 18:39:53 +0200 Subject: [PATCH 20/30] Refactored model_c and renamed it model.pml --- SPIN-verification/{model_c.pml => model.pml} | 734 +++++++++---------- 1 file changed, 327 insertions(+), 407 deletions(-) rename SPIN-verification/{model_c.pml => model.pml} (59%) diff --git a/SPIN-verification/model_c.pml b/SPIN-verification/model.pml similarity index 59% rename from SPIN-verification/model_c.pml rename to SPIN-verification/model.pml index cc2bb4b..0f21348 100644 --- a/SPIN-verification/model_c.pml +++ b/SPIN-verification/model.pml @@ -49,7 +49,7 @@ THE SOFTWARE. */ #define MODEL 1 -typedef KEK { /* Unencrypted */ +typedef KEK { unsigned id : 2 bit version } @@ -83,9 +83,6 @@ chan ac2k = [AC2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte, byt chan k2db = [K2DB_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte, byte } // Keystore -> Database, |k2db| = 8 chan db2k = [DB2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte, byte, byte } // Database -> Keystore, |db2k| = 9 -bool exit_atomic -local bool cache_cleared - // Channel buffers unsigned t12k_buff: 3, t22k_buff: 3 unsigned k2t1_buff: 3, k2t2_buff: 3 @@ -93,15 +90,24 @@ unsigned k2db_buff: 3, db2k_buff: 3 unsigned k2ac_buff: 3, ac2k_buff: 3 unsigned req_buff: 3 +bool exit_atomic +local bool cache_cleared + + // LTL variables -bool p_assigned_1, p_assigned_2, curr_rotation//, db_active -bool p_conf = true, p_authentic = true, p_int = true, p_sync = true, p_protocol = true -local bool p_rotated_1 , p_rotated_2, p_enc_1, p_enc_2, db_skip_1, db_skip_2//, p_dec_1, p_dec_2 +bool p_assigned_1, p_assigned_2, curr_rotation +bool p_conf = true, p_authentic = true, p_int = true, p_sync = true, p_protocol = true, p_cache = true +local bool p_rotated_1 , p_rotated_2, p_enc_1, p_enc_2, db_skip_1, db_skip_2 //unsigned p_enc_1 : 3, p_enc_2 : 3, p_dec_1 : 3, p_dec_2 : 3 //, p_will_rotate_1, p_will_rotate_2 // unsigned count_1 : 2, count_2 : 2 // LTL claims -ltl safety_model_1 { [](p_conf && p_authentic && p_int && p_protocol && p_sync && (Tenant_1[1]@Decrypt_receive -> p_enc_1) && (Tenant_2[2]@Decrypt_receive -> p_enc_2) && (p_enc_1 -> p_assigned_1) && (p_enc_2 -> p_assigned_2 )) } +ltl safety_model_1 { [](p_conf && p_authentic && p_int && p_protocol && p_sync && /*p_cache &&*/ (Tenant_1[1]@Decrypt_receive -> p_enc_1) && + (Tenant_2[2]@Decrypt_receive -> p_enc_2) && (p_enc_1 -> p_assigned_1) && (p_enc_2 -> p_assigned_2 )) + // && + // (Tenant_1[1]@Recrypt_Receive -> p_enc_1) && (Tenant_2[2]@Recrypt_Receive -> p_enc_2) + } +// && (Database[3]@Access_KEK && []!(enabled(3))) // ltl liveness_existence_1 {!([]<>(Tenant_1[1]@Encrypt_receive))} // ltl liveness_existence_2 {!([]<>(Tenant_1[1]@Decrypt_receive))} // ltl liveness_existence_3 {!([]<>(Tenant_1[1]@Decrypt_receive) && ![]<>(Tenant_1[1]@Encrypt_receive))} @@ -109,10 +115,11 @@ ltl safety_model_1 { [](p_conf && p_authentic && p_int && p_protocol && p_sync & // ltl liveness_existence_5 {!([]<>(Tenant_2[2]@Decrypt_receive))} // ltl liveness_existence_6 {!([]<>(Tenant_2[2]@Decrypt_receive) && ![]<>(Tenant_2[2]@Encrypt_receive))} // ltl liveness_existence_7 {!([]<>(Tenant_1[1]@Encrypt_receive) && []<>(Tenant_1[1]@Decrypt_receive && Tenant_2[2]@Encrypt_receive) && []<>(Tenant_2[2]@Decrypt_receive))} -ltl liveness_model_1 { ([]<>(Tenant_1[1]@Encrypt_receive) -> ([]<>(p_rotated_1) && []<>(!p_rotated_1))) && ([]<>(Tenant_2[2]@Encrypt_receive) -> ([]<>(p_rotated_2) && []<>(!p_rotated_2))) && - ([]<>(Tenant_1[1]@Decrypt_receive) -> ([]<>(p_rotated_1) && []<>(!p_rotated_1))) && ([]<>(Tenant_2[2]@Decrypt_receive) -> ([]<>(p_rotated_2) && []<>(!p_rotated_2))) && - (([]<>(Tenant_1[1]@Decrypt_receive) && ![]<>(Tenant_1[1]@Encrypt_receive))-> ([]<>(db_skip_1) && []<>(!db_skip_1))) && - (([]<>(Tenant_2[2]@Decrypt_receive) && ![]<>(Tenant_2[2]@Encrypt_receive))-> ([]<>(db_skip_2) && []<>(!db_skip_2))) } +// ltl liveness_model_2 { ([]<>(p_rotated_1) && []<>(!p_rotated_1)) && ([]<>(p_rotated_2) && []<>(!p_rotated_2)) } +// ltl liveness_model_1 { ([]<>(Tenant_1[1]@Encrypt_receive) -> ([]<>(p_rotated_1) && []<>(!p_rotated_1))) && ([]<>(Tenant_2[2]@Encrypt_receive) -> ([]<>(p_rotated_2) && []<>(!p_rotated_2))) && +// ([]<>(Tenant_1[1]@Decrypt_receive) -> ([]<>(p_rotated_1) && []<>(!p_rotated_1))) && ([]<>(Tenant_2[2]@Decrypt_receive) -> ([]<>(p_rotated_2) && []<>(!p_rotated_2))) && +// (([]<>(Tenant_1[1]@Decrypt_receive) && ![]<>(Tenant_1[1]@Encrypt_receive))-> ([]<>(db_skip_1) && []<>(!db_skip_1))) && +// (([]<>(Tenant_2[2]@Decrypt_receive) && ![]<>(Tenant_2[2]@Encrypt_receive))-> ([]<>(db_skip_2) && []<>(!db_skip_2))) } init { @@ -149,13 +156,14 @@ proctype Tenant_1() atomic { do :: MODEL == 1 -> break - :: MODEL == 2 -> + :: MODEL == 2 -> break + :: MODEL == 3 -> encrypted_DEK.id = 6 encrypted_DEK.ref_id = 6 ref_version_1 = 0 ref_version_2 = 1 break - :: MODEL == 3 -> + :: MODEL == 4 -> encrypted_DEK.id = 6 encrypted_DEK.ref_id = 6 break @@ -170,64 +178,78 @@ proctype Tenant_1() do :: k2t1_buff > 0 -> k2t1?msg, temp_dek, temp_e_dek.ref_id, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, auth, step -> req_buff-- -> k2t1_buff-- -> - // AUTHENTICATION OR CONFIDENTIALITY VIOLATION - if - :: temp_e_dek.id == 1 || temp_e_dek.id == 2 -> p_conf = false - :: temp_e_dek.ref_id == 1 || temp_e_dek.ref_id == 2 -> p_conf = false - :: auth != 1 -> p_authentic = false - :: else -> skip - fi - - if - :: msg == deny -> - denied = true - // if - // :: step != 2 -> p_protocol = false - // :: else -> skip - // fi - :: else -> - denied = false - if - :: msg == ass_KEK -> goto Assign_KEK_receive - :: msg == d_DEK -> goto Decrypt_receive - :: msg == e_DEK -> goto Encrypt_receive - :: msg == re_DEK -> goto Recrypt_Receive - fi - fi - // break + + goto Receive - :: t12k_buff < T2K_MAX -> + :: t12k_buff < T2K_MAX && k2t1_buff == 0-> do :: MODEL == 1 -> do :: !(denied && p_assigned_1) -> - Assign_send: t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, 1 -> break :: !(denied && !p_assigned_1) -> - Encrypt_send: t12k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, 1 -> break - :: !(denied && encrypted_DEK.id == 0) -> - Decrypt_send: + :: !(denied && !p_enc_1) -> t12k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.ref_version, id, 1 -> break + // :: !(denied && !p_enc_1) -> + // t12k!re_DEK, EMPTY_PASS, encrypted_DEK.ref_id,encrypted_DEK.id, EMPTY_PASS, id, 1 -> break od break :: MODEL == 2 -> + do + :: !(denied && p_assigned_1) -> + t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, 1 -> break + :: !(denied && !p_assigned_1) -> + t12k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, 1 -> break + od + break + :: MODEL == 3 -> do :: t12k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, ref_version_1, id -> break :: t12k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, ref_version_2, id -> break - :: t12k!d_DEK, EMPTY_PASS, EMPTY_PASS, encrypted_DEK.id, ref_version_2, id -> break + :: !denied -> t12k!d_DEK, EMPTY_PASS, EMPTY_PASS, encrypted_DEK.id, ref_version_2, id -> break od break - :: MODEL == 3 -> t12k!re_DEK, assigned_KEK, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.ref_version, id -> break + :: MODEL == 4 -> + t12k!re_DEK, assigned_KEK, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.ref_version, id -> break od t12k_buff++ - // break od } - + Receive: + atomic { + + // AUTHENTICATION OR CONFIDENTIALITY VIOLATION + if + :: temp_e_dek.id == 1 || temp_e_dek.id == 2 -> p_conf = false + :: temp_e_dek.ref_id == 1 || temp_e_dek.ref_id == 2 -> p_conf = false + :: auth != 1 -> p_authentic = false + :: else -> skip + fi + + if + :: msg == deny -> + denied = true + if + :: (step % 2) != 0 -> p_protocol = false + :: else -> skip + fi + :: else -> + denied = false + if + :: msg == ass_KEK -> goto Assign_KEK_receive + :: msg == d_DEK -> goto Decrypt_receive + :: msg == e_DEK -> goto Encrypt_receive + :: msg == re_DEK -> goto Recrypt_Receive + fi + fi + + goto Cleanup + } + Assign_KEK_receive: atomic { @@ -243,20 +265,21 @@ proctype Tenant_1() p_assigned_1 = true assigned_KEK = temp_e_dek.ref_id + goto Cleanup } Decrypt_receive: atomic { + // PROTOCOL OR INTEGRITY VIOLATION if :: step != 4 && step != 6 -> p_protocol = false :: dek_id != temp_dek -> p_int = false :: else -> skip fi - // printf("1\n") - assert(dek_id == temp_dek) + goto Cleanup } @@ -273,12 +296,14 @@ proctype Tenant_1() :: else -> skip fi + // printf("HERE 1: %d, and %d\n", temp_e_dek.id, temp_e_dek.ref_id) encrypted_DEK.id = temp_e_dek.id encrypted_DEK.enc_version = temp_e_dek.enc_version encrypted_DEK.ref_id = temp_e_dek.ref_id encrypted_DEK.ref_version = temp_e_dek.ref_version p_enc_1 = true + // printf("%d\n", encrypted_DEK.id) goto Cleanup } @@ -286,8 +311,15 @@ proctype Tenant_1() Recrypt_Receive: atomic { - assert(temp_e_dek.enc_version != encrypted_DEK.enc_version) - assert(temp_e_dek.id-ENC_DUMMY == dek_id) + + if + :: step != 6 -> p_protocol = false + :: temp_e_dek.enc_version == encrypted_DEK.enc_version -> p_sync = false + :: temp_e_dek.id-ENC_DUMMY != dek_id -> p_int = false + :: temp_e_dek.ref_id != assigned_KEK -> p_int = false + :: else -> skip + fi + encrypted_DEK.id = temp_e_dek.id encrypted_DEK.enc_version = temp_e_dek.enc_version encrypted_DEK.ref_id = temp_e_dek.ref_id @@ -325,7 +357,8 @@ proctype Tenant_2() do :: MODEL == 1 -> break - :: MODEL == 2 -> + :: MODEL == 2 -> break + :: MODEL == 3 -> received_e_DEK.id = 6 received_e_DEK.ref_id = 6 encrypted_DEK.id = 7 @@ -333,9 +366,7 @@ proctype Tenant_2() ref_version_1 = 0 ref_version_2 = 1 break - // :: MODEL == 2 -> - // break - :: MODEL == 3 -> + :: MODEL == 4 -> encrypted_DEK.id = 7 encrypted_DEK.ref_id = 7 received_e_DEK.id = 6 @@ -352,83 +383,97 @@ proctype Tenant_2() do :: k2t2_buff > 0 -> k2t2?msg, temp_dek, temp_e_dek.ref_id, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, grant, auth, step -> req_buff-- -> k2t2_buff-- -> - // AUTHENTICATION OR CONFIDENTIALITY VIOLATION - if - :: auth != 1 -> p_authentic = false - :: temp_e_dek.id == 1 || temp_e_dek.id == 2 -> p_conf = false - :: temp_e_dek.ref_id == 1 || temp_e_dek.ref_id == 2 -> p_conf = false - :: else -> skip - fi - - if - :: msg == deny -> - denied = true - // PROTOCOL VIOLATION - // if - // :: step != 4 -> p_protocol = false - // :: else -> skip - // fi - :: else -> - denied = false - if - :: msg == ass_KEK -> goto Assign_KEK_receive - :: msg == d_DEK -> goto Decrypt_receive - :: msg == e_DEK -> goto Encrypt_receive - :: msg == re_DEK -> goto Recrypt_Receive - fi - fi + + goto Receive - // break - :: t22k_buff < T2K_MAX -> + :: t22k_buff < T2K_MAX && k2t2_buff == 0 -> do :: MODEL == 1 -> do :: !(denied && p_assigned_2) -> - Assign_send: t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant, 1 -> break :: !(denied && !p_assigned_2) -> - Encrypt_send: t22k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, grant, 1 -> break - :: !(denied && encrypted_DEK.id == 0) -> - Decrypt_send: + :: !(denied && !p_enc_2) -> t22k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.ref_version, id, grant, 1 -> break + // :: !(denied && !p_enc_2) -> + // t22k!re_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, EMPTY_PASS, id, grant, 1 -> break od break :: MODEL == 2 -> + do + :: !(denied && p_assigned_2) -> + t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant, 1 -> break + :: !(denied && !p_assigned_2) -> + t22k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, grant, 1 -> break + od + break + :: MODEL == 3 -> do :: t22k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, ref_version_1, id, grant -> break :: t22k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, ref_version_2, id, grant -> break - :: t22k!d_DEK, EMPTY_PASS, EMPTY_PASS, encrypted_DEK.id, ref_version_1, id, grant -> break - // :: t22k!d_DEK, EMPTY_PASS, received_e_DEK.ref_id, received_e_DEK.id, ref_version_1, id, VALID_GRANT -> break - // :: t22k!d_DEK, EMPTY_PASS, received_e_DEK.ref_id, received_e_DEK.id, ref_version_2, id, VALID_GRANT -> break - // :: t22k!d_DEK, EMPTY_PASS, received_e_DEK.ref_id, received_e_DEK.id, ref_version_1, id, grant -> break - // :: t22k!d_DEK, EMPTY_PASS, received_e_DEK.ref_id, received_e_DEK.id, ref_version_2, id, grant -> break + :: !denied -> t22k!d_DEK, EMPTY_PASS, EMPTY_PASS, encrypted_DEK.id, ref_version_1, id, grant -> break + :: t22k!d_DEK, EMPTY_PASS, received_e_DEK.ref_id, received_e_DEK.id, ref_version_1, id, VALID_GRANT -> break + :: t22k!d_DEK, EMPTY_PASS, received_e_DEK.ref_id, received_e_DEK.id, ref_version_2, id, VALID_GRANT -> break + :: !denied -> t22k!d_DEK, EMPTY_PASS, received_e_DEK.ref_id, received_e_DEK.id, ref_version_1, id, grant -> break + :: !denied -> t22k!d_DEK, EMPTY_PASS, received_e_DEK.ref_id, received_e_DEK.id, ref_version_2, id, grant -> break od break - :: MODEL == 3 -> t22k!re_DEK, assigned_KEK, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.ref_version, id, grant -> break + :: MODEL == 4 -> t22k!re_DEK, assigned_KEK, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.ref_version, id, grant -> break od t22k_buff++ - // break od } + Receive: + + atomic { + + // AUTHENTICATION OR CONFIDENTIALITY VIOLATION + if + :: auth != 1 -> p_authentic = false + :: temp_e_dek.id == 1 || temp_e_dek.id == 2 -> p_conf = false + :: temp_e_dek.ref_id == 1 || temp_e_dek.ref_id == 2 -> p_conf = false + :: else -> skip + fi + + if + :: msg == deny -> + denied = true + // PROTOCOL VIOLATION + if + :: (step % 2) != 0 -> p_protocol = false + :: else -> skip + fi + :: else -> + denied = false + if + :: msg == ass_KEK -> goto Assign_KEK_receive + :: msg == d_DEK -> goto Decrypt_receive + :: msg == e_DEK -> goto Encrypt_receive + :: msg == re_DEK -> goto Recrypt_Receive + fi + fi + goto Cleanup + } Assign_KEK_receive: atomic { + // PROTOCOL, SYNCHRONIZATION OR INTEGRITY VIOLATION if :: step != 8 -> p_protocol = false - :: assigned_KEK == temp_e_dek.ref_id -> p_int = false + :: temp_e_dek.ref_id != 7 -> p_int = false :: p_assigned_2 -> p_sync = false // liveness :: else -> skip fi p_assigned_2 = true assigned_KEK = temp_e_dek.ref_id - + goto Cleanup } @@ -443,7 +488,6 @@ proctype Tenant_2() :: grant == 1 && temp_dek != 1 -> p_int = false :: else -> skip fi - // assert(false) goto Cleanup } @@ -451,6 +495,7 @@ proctype Tenant_2() Encrypt_receive: atomic { + // printf("HERE 2: %d, and %d\n", temp_e_dek.id, temp_e_dek.ref_id) // PROTOCOL, SYNCHRONIZATION OR INTEGRITY VIOLATION if @@ -460,11 +505,12 @@ proctype Tenant_2() :: temp_e_dek.ref_id != assigned_KEK -> p_int = false :: else -> skip fi - encrypted_DEK.id = temp_e_dek.id encrypted_DEK.enc_version = temp_e_dek.enc_version encrypted_DEK.ref_id = temp_e_dek.ref_id encrypted_DEK.ref_version = temp_e_dek.ref_version + // printf("ID: %d ", encrypted_DEK.id) + // printf("KEK: %d ", encrypted_DEK.ref_id) p_enc_2 = true @@ -475,8 +521,14 @@ proctype Tenant_2() atomic { - assert(temp_e_dek.enc_version != encrypted_DEK.enc_version) - assert(temp_e_dek.id-ENC_DUMMY == dek_id) + // PROTOCOL, SYNCHRONIZATION OR INTEGRITY VIOLATION + if + :: step != 6 -> p_protocol = false + :: temp_e_dek.enc_version == encrypted_DEK.enc_version -> p_sync = false + :: temp_e_dek.id-ENC_DUMMY != dek_id -> p_int = false + :: temp_e_dek.ref_id != assigned_KEK -> p_int = false + :: else -> skip + fi encrypted_DEK.id = temp_e_dek.id encrypted_DEK.enc_version = temp_e_dek.enc_version @@ -514,28 +566,27 @@ proctype Keystore() KEK temp_key KEK v_KEKs[NUM_KEKS] - atomic{ + // atomic{ - if - :: MODEL != 1 -> - v_KEKs[0].id = 1 - v_KEKs[0].id = 2 - :: else -> skip - fi - } + // if + // :: MODEL != 1 -> + // v_KEKs[0].id = 1 + // v_KEKs[0].id = 2 + // :: else -> skip + // fi + // } Select_state: - cache_cleared = !cache_cleared - atomic { + // cache_cleared = !cache_cleared + exit_atomic = true + atomic { do //FROM AC - :: ac2k_buff > 0 -> ac2k?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, auth, step -> ac2k_buff-- -> + :: ac2k_buff > 0 && db2k_buff == 0-> ac2k?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, auth, step -> ac2k_buff-- -> - select_case = 2 - // PROTOCOL OR AUTHENTICATION VIOLATION if :: auth != 1 -> p_authentic = false -> goto Deny_request @@ -551,19 +602,18 @@ proctype Keystore() fi do - :: msg == ass_KEK -> goto Assign_KEK - :: msg == ass_KEK2 -> select_case = 4 -> goto Assign_KEK - :: msg == d_DEK -> goto Decrypt - :: msg == e_DEK -> goto Encrypt - :: msg == re_DEK -> goto Recrypt + :: msg == ass_KEK2 -> goto Assign_KEK_return + :: msg == d_DEK -> goto Decrypt_Database_Check :: msg == deny -> goto Deny_request + :: msg == ass_KEK -> kek_id = tenant_id -> break + :: else -> break od - + + goto Send_to_Database + //FROM DB :: db2k_buff > 0 -> db2k?msg, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, kek_version, auth, step -> db2k_buff-- -> - select_case = 3 - // PROTOCOL OR AUTHENTICATION VIOLATION if :: auth != 1 -> p_authentic = false -> goto Deny_request @@ -571,335 +621,207 @@ proctype Keystore() :: else -> skip fi - do - :: msg == ass_KEK -> goto Assign_KEK - :: msg == d_DEK -> goto Decrypt - :: msg == e_DEK -> goto Encrypt - :: msg == re_DEK -> goto Recrypt + // Update KEKs + if :: msg == deny -> goto Deny_request + :: else -> + v_KEKs[kek_id-1].id = kek_id + v_KEKs[kek_id-1].version = kek_version + fi + + // ROTATION CHECK + if + :: tenant_id == 1 -> + if + :: v_KEKs[kek_id-1].version == 0 -> + p_rotated_1 = true + :: else -> p_rotated_1 = false + fi + :: tenant_id == 2 -> + if + :: v_KEKs[kek_id-1].version == 0 -> + p_rotated_2 = true + :: else -> p_rotated_2 = false + fi + fi + + do + :: msg == ass_KEK -> + msg = ass_KEK2 + kek_ref = kek_id+ENC_DUMMY + goto Send_to_Access_Control + :: msg == d_DEK -> goto Decrypt_return + :: msg == e_DEK || msg == re_DEK -> assert(msg != ass_KEK) -> goto Encrypt_return od // FROM TENANT - :: (turn == 1 || (turn == 0 && t22k_buff == 0)) && req_buff < REQ_MAX && t12k_buff > 0 -> t12k?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, step -> req_buff++ -> t12k_buff-- -> + :: (turn == 1 || (turn == 0 && t22k_buff == 0)) && req_buff < REQ_MAX && t12k_buff > 0 && ac2k_buff == 0 && db2k_buff == 0 -> + t12k?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, step -> req_buff++ -> t12k_buff-- -> - select_case = 1 turn = 0 + // PROTOCOL OR AUTHENTICATION VIOLATION if :: tenant_id != 1 -> p_authentic = false -> goto Deny_request :: step != 1 -> p_protocol = false :: else -> skip fi + + goto Send_to_Access_Control - do - :: msg == ass_KEK -> goto Assign_KEK - :: msg == d_DEK -> goto Decrypt - :: msg == e_DEK -> goto Encrypt - :: msg == re_DEK -> goto Recrypt - od - :: (turn == 0 || (turn == 1 && t12k_buff == 0)) && req_buff < REQ_MAX && t22k_buff > 0 -> t22k?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, step -> req_buff++ -> t22k_buff-- -> + :: (turn == 0 || (turn == 1 && t12k_buff == 0)) && req_buff < REQ_MAX && t22k_buff > 0 && ac2k_buff == 0 && db2k_buff == 0 -> + t22k?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, step -> req_buff++ -> t22k_buff-- -> - select_case = 1 turn = 1 + // PROTOCOL OR AUTHENTICATION VIOLATION if :: tenant_id != 2 -> p_authentic = false -> goto Deny_request :: step != 1 -> p_protocol = false :: else -> skip fi - - do - :: msg == ass_KEK -> goto Assign_KEK - :: msg == d_DEK -> goto Decrypt - :: msg == e_DEK -> goto Encrypt - :: msg == re_DEK -> goto Recrypt - od + + goto Send_to_Access_Control + od } - - - Assign_KEK: - - atomic { - - if // From Tenant to Access Control - :: select_case == 1 -> - - k2ac_buff < K2AC_MAX - k2ac!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, tenant_id, grant, id, step+1 - k2ac_buff++ - - // From Access Control to Database - :: select_case == 2 -> - // if - // :: !SAME_KEK_ASSIGNED -> kek_id = tenant_id - // :: else -> kek_id = 1 - // fi - kek_id = tenant_id - - k2db_buff < K2DB_MAX - k2db!ass_KEK, EMPTY_PASS, kek_id, EMPTY_PASS, EMPTY_PASS, tenant_id, grant, id, step+1 - k2db_buff++ - - // From Database to Access Control - :: select_case == 3 -> - v_KEKs[kek_id-1].id = kek_id - v_KEKs[kek_id-1].version = kek_version + Send_to_Access_Control: - k2ac_buff < K2AC_MAX - k2ac!ass_KEK2, EMPTY_PASS, kek_id+ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, tenant_id, grant, id, step+1 - k2ac_buff++ + atomic { - // From Access Control to Tenant - :: select_case == 4 -> + k2ac_buff < K2AC_MAX + k2ac!msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 + k2ac_buff++ - if // ack from Tenant was received during concurrent processing - :: tenant_id == 1 && p_assigned_1 -> goto Deny_request - :: tenant_id == 2 && p_assigned_2 -> goto Deny_request - :: else -> skip - fi - - if - :: tenant_id == 1 -> k2t1_buff < K2T_MAX - k2t1!ass_KEK, EMPTY_PASS, kek_ref, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, step+1 - // req_buff-- -> - k2t1_buff++ - :: else -> k2t2_buff < K2T_MAX - k2t2!ass_KEK, EMPTY_PASS, kek_ref, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, grant, id, step+1 - // req_buff-- -> - k2t2_buff++ - fi - fi + goto Cleanup + } + Send_to_Database: + + atomic { + + k2db_buff < K2DB_MAX + k2db!msg, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 + k2db_buff++ + goto Cleanup } + - Decrypt: + Decrypt_Database_Check: atomic { - - if // From Tenant to Access Control - :: select_case == 1 -> - - k2ac_buff < K2AC_MAX - k2ac!d_DEK, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 - k2ac_buff++ + + if // Already in memory so skip Database + :: !(cache_cleared || (v_KEKs[kek_id-1].version == 1 && temp_e_dek.ref_version == 0)) -> - // From Access Control to Database - :: select_case == 2 -> - if // Already in memory so skip Database - :: !cache_cleared || !(v_KEKs[kek_id-1].version == 1 && temp_e_dek.ref_version == 0) -> - - select_case = 4 - - if - :: tenant_id == 1 -> db_skip_1 = true -> skip - :: tenant_id == 2 -> db_skip_2 = true -> skip - fi - :: else -> - if - :: tenant_id == 1 -> db_skip_1 = false -> skip - :: tenant_id == 2 -> db_skip_2 = false -> skip - fi - k2db_buff < K2DB_MAX -> - k2db!d_DEK, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 - k2db_buff++ + if + :: tenant_id == 1 -> db_skip_1 = true -> skip + :: tenant_id == 2 -> db_skip_2 = true -> skip fi - - // From Database to Tenant - :: select_case == 3 -> - - select_case = 4 - - v_KEKs[kek_id-1].id = kek_id - v_KEKs[kek_id-1].version = kek_version - - // ROTATION CHECK - if - :: tenant_id == 1 -> - if - :: v_KEKs[kek_id-1].version == 0 -> - p_rotated_1 = true - :: else -> p_rotated_1 = false - fi - :: tenant_id == 2 -> - if - :: v_KEKs[kek_id-1].version == 0 -> - p_rotated_2 = true - :: else -> p_rotated_2 = false - fi - fi - fi - - if // DB -> KS -> T or Database skip from case 2 AC -> KS -> T - :: select_case == 4 -> + :: else -> if - :: tenant_id == 1 -> k2t1_buff < K2T_MAX - k2t1!d_DEK, temp_e_dek.id-ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, step+1 - // req_buff-- -> - k2t1_buff++ - :: else -> k2t2_buff < K2T_MAX - k2t2!d_DEK, temp_e_dek.id-ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, grant, id, step+1 - // req_buff-- -> - k2t2_buff++ + :: tenant_id == 1 -> db_skip_1 = false -> skip + :: tenant_id == 2 -> db_skip_2 = false -> skip fi + fi + + // // CACHE VIOLATION + // if + // :: !(v_KEKs[kek_id-1].version == 1 && temp_e_dek.ref_version == 0) -> + // if + // :: tenant_id == 1 -> p_cache = (db_skip_1 || cache_cleared) + // :: tenant_id == 2 -> p_cache = (db_skip_2 || cache_cleared) + // fi + // :: else -> skip + // fi + + + if + :: tenant_id == 1 && !db_skip_1 -> goto Send_to_Database + :: tenant_id == 2 && !db_skip_2 -> goto Send_to_Database :: else -> skip fi - goto Cleanup + goto Decrypt_return } - - Encrypt: + + Decrypt_return: atomic { - if // From Tenant to Access Control - :: select_case == 1 -> - - k2ac_buff < K2AC_MAX - k2ac!e_DEK, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 - k2ac_buff++ - - // From Access Control to Database - :: select_case == 2 -> - - k2db_buff < K2DB_MAX - k2db!e_DEK, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 - k2db_buff++ - - // From Database to Tenant - :: select_case == 3 -> - - v_KEKs[kek_id-1].version = kek_version - v_KEKs[kek_id-1].id = kek_id - // ROTATION CHECK - if - :: tenant_id == 1 -> - if - :: v_KEKs[kek_id-1].version == 0 -> - p_rotated_1 = true - :: else -> p_rotated_1 = false - fi - :: tenant_id == 2 -> - if - :: v_KEKs[kek_id-1].version == 0 -> - p_rotated_2 = true - :: else -> p_rotated_2 = false - fi - fi - + if + :: tenant_id == 1 -> + k2t1_buff < K2T_MAX + k2t1!d_DEK, temp_e_dek.id-ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, step+1 + k2t1_buff++ + :: else -> + k2t2_buff < K2T_MAX + k2t2!d_DEK, temp_e_dek.id-ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, grant, id, step+1 + k2t2_buff++ + fi + goto Cleanup + } + + Assign_KEK_return: - temp_e_dek.id = dek_id+ENC_DUMMY - temp_e_dek.ref_id = v_KEKs[kek_id-1].id+ENC_DUMMY - temp_e_dek.ref_version = v_KEKs[kek_id-1].version + atomic { - do - :: tenant_id == 1 -> - last_enc_1 = !last_enc_1 - temp_e_dek.enc_version = last_enc_1 - - k2t1_buff < K2T_MAX - k2t1!e_DEK, dek_id, kek_id+ENC_DUMMY, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, id, step+1 - k2t1_buff++ - break - - :: tenant_id == 2 -> - - last_enc_2 = !last_enc_2 - temp_e_dek.enc_version = last_enc_2 - - k2t2_buff < K2T_MAX - k2t2!e_DEK, dek_id, kek_id+ENC_DUMMY, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, grant, id, step+1 - k2t2_buff++ - break - od + if // ack from Tenant was received during concurrent processing + :: tenant_id == 1 && p_assigned_1 -> goto Deny_request + :: tenant_id == 2 && p_assigned_2 -> goto Deny_request + :: else -> skip fi + if + :: tenant_id == 1 -> k2t1_buff < K2T_MAX + k2t1!ass_KEK, EMPTY_PASS, kek_ref, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, step+1 + k2t1_buff++ + :: else -> k2t2_buff < K2T_MAX + k2t2!ass_KEK, EMPTY_PASS, kek_ref, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, grant, id, step+1 + k2t2_buff++ + fi + goto Cleanup } - Recrypt: - - atomic { + Encrypt_return: - if // From Tenant to Access Control - :: select_case == 1 -> - - k2ac_buff < K2AC_MAX - k2ac!re_DEK, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 - k2ac_buff++ + // From Database to Tenant + atomic { - // From Access Control to Database - :: select_case == 2 -> - - // "if" decrypts before accessing DB to receive a fresh encryption KEK - // "else" needs a fresh KEK to decrypt, but will use that KEK to encrypt - - if - :: cache_cleared || v_KEKs[kek_id-1].version == temp_e_dek.ref_version -> - // :: v_KEKs[kek_id-1].id == kek_id && v_KEKs[kek_id-1].version == temp_e_dek.ref_version -> - dek_id = temp_e_dek.id-ENC_DUMMY // decrypted here - :: else -> skip - fi - - k2db_buff < K2DB_MAX - k2db!re_DEK, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 - k2db_buff++ - - // From Database to Tenant - :: select_case == 3 -> - - v_KEKs[kek_id-1].id = kek_id - v_KEKs[kek_id-1].version = kek_version - - // "if" 1 and 2 where decrypted in case 2 above - // "if" 6 and 7 needed a fresh KEK to be decrypted - - if // Mainly to ensure that every path is hit - :: dek_id == 1 -> - temp_e_dek.id = dek_id+ENC_DUMMY // encrypted here - :: dek_id == 2 -> - temp_e_dek.id = dek_id+ENC_DUMMY // encrypted here - :: else -> - if - :: temp_e_dek.id == 6 -> - assert(6 < 86) // decrypted and encrypted here - :: temp_e_dek.id == 7 -> - assert(6 < 88) // decrypted and encrypted here - fi - fi - - temp_e_dek.ref_id = v_KEKs[kek_id-1].id+ENC_DUMMY - temp_e_dek.ref_version = v_KEKs[kek_id-1].version - - do - :: tenant_id == 1 -> + if + :: msg == e_DEK -> temp_e_dek.id = dek_id+ENC_DUMMY + :: else -> skip + fi - last_enc_1 = !last_enc_1 - temp_e_dek.enc_version = last_enc_1 - - k2t1_buff < K2T_MAX - k2t1!re_DEK, dek_id, kek_id+ENC_DUMMY, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, id, step+1 - // req_buff-- - k2t1_buff++ - break + temp_e_dek.ref_id = v_KEKs[kek_id-1].id+ENC_DUMMY + temp_e_dek.ref_version = v_KEKs[kek_id-1].version + + do + :: tenant_id == 1 -> + last_enc_1 = !last_enc_1 + temp_e_dek.enc_version = last_enc_1 - :: tenant_id == 2 -> - - last_enc_2 = !last_enc_2 - temp_e_dek.enc_version = last_enc_2 - - k2t2_buff < K2T_MAX - k2t2!re_DEK, dek_id, kek_id+ENC_DUMMY, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, grant, id, step+1 - // req_buff-- - k2t2_buff++ - break - od - fi + k2t1_buff < K2T_MAX + k2t1!msg, dek_id, kek_id+ENC_DUMMY, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, id, step+1 + k2t1_buff++ + break + :: tenant_id == 2 -> + + last_enc_2 = !last_enc_2 + temp_e_dek.enc_version = last_enc_2 + + k2t2_buff < K2T_MAX + k2t2!msg, dek_id, kek_id+ENC_DUMMY, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, grant, id, step+1 + k2t2_buff++ + break + od + goto Cleanup } @@ -921,7 +843,6 @@ proctype Keystore() k2t1_buff < K2T_MAX k2t1!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, step+1 k2t1_buff++ - // req_buff-- :: else -> if :: p_assigned_2 && MODEL == 1 -> @@ -935,7 +856,6 @@ proctype Keystore() k2t2_buff < K2T_MAX k2t2!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, grant, id, step+1 k2t2_buff++ - // req_buff-- fi goto Cleanup @@ -969,7 +889,7 @@ proctype Keystore() proctype Database() { mtype msg = deny - unsigned kek_id : 3, i : 3, tenant_id : 3, dek_id : 2, grant : 2, auth : 1, step : 3 + unsigned kek_id : 3, i : 3, tenant_id : 3, dek_id : 3, grant : 2, auth : 1, step : 3 bit id = 1 KEK p_KEKs[NUM_KEKS] @@ -1004,7 +924,7 @@ proctype Database() { Access_KEK: atomic { - + for (i : 0 .. NUM_KEKS-1) { if :: p_KEKs[i].id == kek_id -> @@ -1064,20 +984,20 @@ proctype Database() { proctype AccessControl() { mtype msg = deny - unsigned kek_ref : 3, tenant_id : 3, auth : 1, dek_id : 2, grant : 2, assigned_1 : 3, assigned_2 : 3, step : 3 + unsigned kek_ref : 3, tenant_id : 3, auth : 1, dek_id : 3, grant : 2, assigned_1 : 3, assigned_2 : 3, step : 3 bit id = 1 E_DEK temp_e_dek - atomic { + // atomic { - if - :: MODEL != 1 -> - assigned_1 = 6 - assigned_2 = 7 - :: else -> skip - fi + // if + // :: MODEL != 1 -> + // assigned_1 = 6 + // assigned_2 = 7 + // :: else -> skip + // fi - } + // } Select_state: @@ -1162,7 +1082,7 @@ proctype AccessControl() :: kek_ref != 6 && kek_ref != 7 -> goto Deny_request :: else -> skip fi - + assert((kek_ref == 6 && tenant_id == 1) || (kek_ref == 7 && tenant_id == 2)) if :: tenant_id == 1 && (kek_ref != assigned_1) -> goto Deny_request :: tenant_id == 2 && (kek_ref != assigned_2) -> @@ -1172,7 +1092,7 @@ proctype AccessControl() fi :: else -> skip fi - + // printf("AC: %d\n", temp_e_dek.id) ac2k_buff < AC2K_MAX ac2k!msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 ac2k_buff++ From f31e139f80755d920b8d632ed51757dfecd57ca8 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Tue, 4 Jun 2024 12:53:35 +0200 Subject: [PATCH 21/30] Models A-D verified --- SPIN-verification/model.pml | 633 +++++++++++++++++++++--------------- 1 file changed, 377 insertions(+), 256 deletions(-) diff --git a/SPIN-verification/model.pml b/SPIN-verification/model.pml index 0f21348..9b14bbc 100644 --- a/SPIN-verification/model.pml +++ b/SPIN-verification/model.pml @@ -22,6 +22,23 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/** + MODELS + + 1=Initial Model with some modifications 2=A 3=B 4=C 5=D In the paper. + + 1: Full operations. + 2: Assignemnt and Encryption. + 3: Decryption + 4: Re-Encryption of encrypted DEKs + 5: Tenant 1 assignment and encryption, Tenant 2 only Decrypts encrypted DEKs received from Tenant 1 with different grants. + + If MODEL == 2 then IS_MODEL_2 == 1 + If MODEL != 2 then IS_MODEL_2 == 0 +*/ +#define MODEL 4 +#define IS_MODEL_2 0 + #define NUM_DEKS 1 #define NUM_KEKS 2 #define NUM_TENANTS 2 @@ -32,32 +49,34 @@ THE SOFTWARE. // CHANNEL CAPS #define T2K_MAX 1 #define K2T_MAX 1 -#define K2AC_MAX 1 -#define AC2K_MAX 1 -#define K2DB_MAX 1 -#define DB2K_MAX 1 + +// MODEL 2 +#if IS_MODEL_2 + #define K2AC_MAX 2 + #define AC2K_MAX 2 + #define K2DB_MAX 2 + #define DB2K_MAX 2 +#else + #define K2AC_MAX 1 + #define AC2K_MAX 1 + #define K2DB_MAX 1 + #define DB2K_MAX 1 +#endif // REQUEST LIMIT OF CONCURRENT PROCESSING IN KEYSTORE #define REQ_MAX 2 -/** - MODELS - 1: Assignemnt and Encryption. - 2: Decryption with - 2: Tenant 1 full operations, Tenant 2 only Decrypts encrypted DEKs received from Tenant 1 with different grants - 3: Re-Encryption of encrypted DEKs -*/ -#define MODEL 1 + typedef KEK { - unsigned id : 2 + unsigned id : 3 bit version } typedef E_DEK { /* Encrypted */ unsigned id : 3 - unsigned ref_id : 3 + unsigned ref_id : 4 bit enc_version bit ref_version } @@ -71,16 +90,16 @@ mtype = { e_DEK, d_DEK, re_DEK, ass_KEK, ass_KEK2, deny } // db: Database // { message type, DEK_ID, KEK_ID, E_KEY-ID, (E_KEY-ENC_V), E_KEY-REF_V, TENANT_ID, (GRANT), (KEK-VERSION), AUTH } -chan t12k = [T2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte } // Tenant 1 -> Keystore, |t12k| = 6 +chan t12k = [T2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte } // Tenant 1 -> Keystore, |t12k| = 6 chan k2t1 = [K2T_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte } // Keystore -> Tenant 1, |k2t1| = 7 chan t22k = [T2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte } // Tenant 2 -> Keystore, |t22k| = 7 -chan k2t2 = [K2T_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte, byte } // Keystore -> Tenant 2, |k2t2| = 8 +chan k2t2 = [K2T_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte, byte } // Keystore -> Tenant 2, |k2t2| = 8 -chan k2ac = [K2AC_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte, byte } // Keystore -> Access Control, |k2ac| = 8 -chan ac2k = [AC2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte, byte } // Access Control -> Keystore, |ac2k| = 8 +chan k2ac = [K2AC_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte, byte } // Keystore -> Access Control, |k2ac| = 8 +chan ac2k = [AC2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte, byte } // Access Control -> Keystore, |ac2k| = 8 -chan k2db = [K2DB_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte, byte } // Keystore -> Database, |k2db| = 8 +chan k2db = [K2DB_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte, byte } // Keystore -> Database, |k2db| = 8 chan db2k = [DB2K_MAX] of { mtype, byte, byte, byte, byte, byte, byte, byte, byte, byte } // Database -> Keystore, |db2k| = 9 // Channel buffers @@ -95,31 +114,26 @@ local bool cache_cleared // LTL variables -bool p_assigned_1, p_assigned_2, curr_rotation -bool p_conf = true, p_authentic = true, p_int = true, p_sync = true, p_protocol = true, p_cache = true -local bool p_rotated_1 , p_rotated_2, p_enc_1, p_enc_2, db_skip_1, db_skip_2 -//unsigned p_enc_1 : 3, p_enc_2 : 3, p_dec_1 : 3, p_dec_2 : 3 //, p_will_rotate_1, p_will_rotate_2 -// unsigned count_1 : 2, count_2 : 2 +#define p_authentic (((Keystore[4]@Send_to_Access_Control || Keystore[4]@Send_to_Database || Keystore[4]@Encrypt_return || Keystore[4]@Decrypt_return || Keystore[4]@Assign_KEK_return) && !auth_ks) || \ + (Database[3]@Access_KEK && !auth_db) || (AccessControl[5]@Select_state && !auth_ac) || (Tenant_1[1]@Receive && !auth_t1) || (Tenant_2[2]@Receive && !auth_t2)) + +bool p_assigned_1, p_assigned_2, p_enc_1 +bool p_conf = true, p_int = true, p_sync = true, p_protocol = true, p_cache = true +local bool p_rotated_1 , p_rotated_2, p_enc_2, auth_ks, auth_db, auth_ac, auth_t1, auth_t2, grant_t2 +local unsigned m4_KEK_t1 : 4, m4_KEK_t2 : 4 // LTL claims -ltl safety_model_1 { [](p_conf && p_authentic && p_int && p_protocol && p_sync && /*p_cache &&*/ (Tenant_1[1]@Decrypt_receive -> p_enc_1) && - (Tenant_2[2]@Decrypt_receive -> p_enc_2) && (p_enc_1 -> p_assigned_1) && (p_enc_2 -> p_assigned_2 )) - // && - // (Tenant_1[1]@Recrypt_Receive -> p_enc_1) && (Tenant_2[2]@Recrypt_Receive -> p_enc_2) - } -// && (Database[3]@Access_KEK && []!(enabled(3))) -// ltl liveness_existence_1 {!([]<>(Tenant_1[1]@Encrypt_receive))} -// ltl liveness_existence_2 {!([]<>(Tenant_1[1]@Decrypt_receive))} -// ltl liveness_existence_3 {!([]<>(Tenant_1[1]@Decrypt_receive) && ![]<>(Tenant_1[1]@Encrypt_receive))} -// ltl liveness_existence_4 {!([]<>(Tenant_2[2]@Encrypt_receive))} -// ltl liveness_existence_5 {!([]<>(Tenant_2[2]@Decrypt_receive))} -// ltl liveness_existence_6 {!([]<>(Tenant_2[2]@Decrypt_receive) && ![]<>(Tenant_2[2]@Encrypt_receive))} -// ltl liveness_existence_7 {!([]<>(Tenant_1[1]@Encrypt_receive) && []<>(Tenant_1[1]@Decrypt_receive && Tenant_2[2]@Encrypt_receive) && []<>(Tenant_2[2]@Decrypt_receive))} -// ltl liveness_model_2 { ([]<>(p_rotated_1) && []<>(!p_rotated_1)) && ([]<>(p_rotated_2) && []<>(!p_rotated_2)) } -// ltl liveness_model_1 { ([]<>(Tenant_1[1]@Encrypt_receive) -> ([]<>(p_rotated_1) && []<>(!p_rotated_1))) && ([]<>(Tenant_2[2]@Encrypt_receive) -> ([]<>(p_rotated_2) && []<>(!p_rotated_2))) && -// ([]<>(Tenant_1[1]@Decrypt_receive) -> ([]<>(p_rotated_1) && []<>(!p_rotated_1))) && ([]<>(Tenant_2[2]@Decrypt_receive) -> ([]<>(p_rotated_2) && []<>(!p_rotated_2))) && -// (([]<>(Tenant_1[1]@Decrypt_receive) && ![]<>(Tenant_1[1]@Encrypt_receive))-> ([]<>(db_skip_1) && []<>(!db_skip_1))) && -// (([]<>(Tenant_2[2]@Decrypt_receive) && ![]<>(Tenant_2[2]@Encrypt_receive))-> ([]<>(db_skip_2) && []<>(!db_skip_2))) } +// ltl safety { [](p_conf && p_int && p_protocol && p_sync && p_cache && !p_authentic && (Tenant_1[1]@Decrypt_receive -> p_enc_1) && +// (Tenant_2[2]@Decrypt_receive -> (p_enc_2 || (grant_t2 && p_enc_1))) && (p_enc_1 -> p_assigned_1) && (p_enc_2 -> p_assigned_2 )) && +// (Tenant_1[1]@Recrypt_Receive -> p_enc_1) && (Tenant_2[2]@Recrypt_Receive -> p_enc_2) +// } + + +// ltl liveness_model_2 { ([]<>(p_rotated_1) && []<>(!p_rotated_1)) && ([]<>(p_rotated_2) && []<>(!p_rotated_2)) } +ltl liveness_model_4 { ([]<>(m4_KEK_t1 == 6) && []<>(m4_KEK_t1 == 8)) && ([]<>(m4_KEK_t2 == 7) && []<>(m4_KEK_t2 == 9)) } +// ltl liveness_model_3 { ([]<>(Tenant_2[2]@Decrypt_receive) && []<>(Tenant_1[1]@Decrypt_receive)) && ((Database[3]@Access_KEK) -> <>(Database[3]@Cleanup)) } +// ltl liveness_model_5 {<>[]!(Tenant_1[1]@Encrypt_receive || Tenant_1[1]@Assign_KEK_receive) && []<>(Tenant_2[2]@Decrypt_receive) && ((Database[3]@Access_KEK) -> <>(Database[3]@Cleanup))} + init { @@ -146,30 +160,13 @@ init { proctype Tenant_1() { mtype msg = deny - unsigned temp_dek: 3, assigned_KEK : 3, ref_version_1 : 1, ref_version_2 : 1, step : 4 + unsigned temp_dek: 3, assigned_KEK : 3, step : 4 unsigned id : 2 = 1 unsigned dek_id : 2 = 1 - bit auth, denied + bit denied E_DEK temp_e_dek, encrypted_DEK - atomic { - do - :: MODEL == 1 -> break - :: MODEL == 2 -> break - :: MODEL == 3 -> - encrypted_DEK.id = 6 - encrypted_DEK.ref_id = 6 - ref_version_1 = 0 - ref_version_2 = 1 - break - :: MODEL == 4 -> - encrypted_DEK.id = 6 - encrypted_DEK.ref_id = 6 - break - od - } - Select_state: exit_atomic = true @@ -177,11 +174,18 @@ proctype Tenant_1() atomic { do - :: k2t1_buff > 0 -> k2t1?msg, temp_dek, temp_e_dek.ref_id, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, auth, step -> req_buff-- -> k2t1_buff-- -> + :: k2t1_buff > 0 -> k2t1?msg, temp_dek, temp_e_dek.ref_id, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, auth_t1, step -> k2t1_buff-- -> + // AUTHENTICATION OR CONFIDENTIALITY VIOLATION + if + :: !auth_t1 -> denied = true -> goto Cleanup + :: ((temp_e_dek.id > 0 && temp_e_dek.id < ENC_DUMMY) || (temp_e_dek.ref_id > 0 && temp_e_dek.ref_id < ENC_DUMMY)) -> p_conf = false -> goto Cleanup + :: else -> skip + fi + goto Receive - :: t12k_buff < T2K_MAX && k2t1_buff == 0-> + :: t12k_buff < T2K_MAX && k2t1_buff == 0 -> do :: MODEL == 1 -> @@ -192,8 +196,8 @@ proctype Tenant_1() t12k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, 1 -> break :: !(denied && !p_enc_1) -> t12k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.ref_version, id, 1 -> break - // :: !(denied && !p_enc_1) -> - // t12k!re_DEK, EMPTY_PASS, encrypted_DEK.ref_id,encrypted_DEK.id, EMPTY_PASS, id, 1 -> break + :: !(denied && !p_enc_1) -> + t12k!re_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, EMPTY_PASS, id, 1 -> break od break :: MODEL == 2 -> @@ -202,43 +206,74 @@ proctype Tenant_1() t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, 1 -> break :: !(denied && !p_assigned_1) -> t12k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, 1 -> break + :: !denied -> + t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, 0, 1 -> break od break :: MODEL == 3 -> + + if + :: p_enc_1 -> encrypted_DEK.ref_version = !encrypted_DEK.ref_version + :: else -> skip + fi + do - :: t12k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, ref_version_1, id -> break - :: t12k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, ref_version_2, id -> break - :: !denied -> t12k!d_DEK, EMPTY_PASS, EMPTY_PASS, encrypted_DEK.id, ref_version_2, id -> break + :: !p_assigned_1 -> + t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, 1 -> break + :: p_assigned_1 && !p_enc_1 -> + t12k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, 1 -> break + :: !(denied && !p_enc_1) -> + t12k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.ref_version, id, 1 -> break od break :: MODEL == 4 -> - t12k!re_DEK, assigned_KEK, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.ref_version, id -> break + do + :: !p_assigned_1 -> + t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, 1 -> break + :: p_assigned_1 && !p_enc_1 -> + t12k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, 1 -> break + :: !(denied && !p_enc_1) -> + t12k!re_DEK, EMPTY_PASS, m4_KEK_t1, encrypted_DEK.id, encrypted_DEK.ref_version, id, 1 -> break + od + break + :: MODEL == 5 -> + do + :: !p_assigned_1 -> + t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, 1 -> break + :: p_assigned_1 && !p_enc_1 -> + t12k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, 1 -> break + :: p_enc_1 -> + t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, 0, 1 -> break + od + break od + t12k_buff++ + od } Receive: - atomic { - // AUTHENTICATION OR CONFIDENTIALITY VIOLATION - if - :: temp_e_dek.id == 1 || temp_e_dek.id == 2 -> p_conf = false - :: temp_e_dek.ref_id == 1 || temp_e_dek.ref_id == 2 -> p_conf = false - :: auth != 1 -> p_authentic = false - :: else -> skip - fi + atomic { + req_buff-- + if :: msg == deny -> + denied = true + if :: (step % 2) != 0 -> p_protocol = false :: else -> skip fi + :: else -> + denied = false + if :: msg == ass_KEK -> goto Assign_KEK_receive :: msg == d_DEK -> goto Decrypt_receive @@ -272,7 +307,6 @@ proctype Tenant_1() Decrypt_receive: atomic { - // PROTOCOL OR INTEGRITY VIOLATION if :: step != 4 && step != 6 -> p_protocol = false @@ -286,7 +320,6 @@ proctype Tenant_1() Encrypt_receive: atomic { - // PROTOCOL, SYNCHRONIZATION OR INTEGRITY VIOLATION if :: step != 6 -> p_protocol = false @@ -296,14 +329,17 @@ proctype Tenant_1() :: else -> skip fi - // printf("HERE 1: %d, and %d\n", temp_e_dek.id, temp_e_dek.ref_id) encrypted_DEK.id = temp_e_dek.id encrypted_DEK.enc_version = temp_e_dek.enc_version encrypted_DEK.ref_id = temp_e_dek.ref_id encrypted_DEK.ref_version = temp_e_dek.ref_version + if + :: MODEL == 4 -> m4_KEK_t1 = encrypted_DEK.ref_id + :: else -> skip + fi + p_enc_1 = true - // printf("%d\n", encrypted_DEK.id) goto Cleanup } @@ -316,23 +352,33 @@ proctype Tenant_1() :: step != 6 -> p_protocol = false :: temp_e_dek.enc_version == encrypted_DEK.enc_version -> p_sync = false :: temp_e_dek.id-ENC_DUMMY != dek_id -> p_int = false - :: temp_e_dek.ref_id != assigned_KEK -> p_int = false + :: temp_e_dek.ref_id != assigned_KEK && temp_e_dek.ref_id != 8 -> p_int = false :: else -> skip fi - + encrypted_DEK.id = temp_e_dek.id encrypted_DEK.enc_version = temp_e_dek.enc_version encrypted_DEK.ref_id = temp_e_dek.ref_id encrypted_DEK.ref_version = temp_e_dek.ref_version + if + :: MODEL == 4 -> + if + :: encrypted_DEK.ref_id == 6 -> m4_KEK_t1 = 8 + :: else -> m4_KEK_t1 = 6 + fi + :: else -> skip + fi + goto Cleanup } Cleanup: atomic { + + auth_t1 = 0 step = 0 - auth = 0 msg = deny temp_dek = 0 temp_e_dek.ref_id = 0 @@ -347,33 +393,12 @@ proctype Tenant_1() proctype Tenant_2() { mtype msg = deny - unsigned temp_dek: 3, assigned_KEK : 3, grant : 2, ref_version_1 : 1, ref_version_2 : 1, step : 4 + unsigned temp_dek: 3, assigned_KEK : 3, step : 4 unsigned id : 2 = 2 unsigned dek_id : 2 = 2 - bit auth, denied - E_DEK temp_e_dek, encrypted_DEK, received_e_DEK - - atomic { + bit denied - do - :: MODEL == 1 -> break - :: MODEL == 2 -> break - :: MODEL == 3 -> - received_e_DEK.id = 6 - received_e_DEK.ref_id = 6 - encrypted_DEK.id = 7 - encrypted_DEK.ref_id = 7 - ref_version_1 = 0 - ref_version_2 = 1 - break - :: MODEL == 4 -> - encrypted_DEK.id = 7 - encrypted_DEK.ref_id = 7 - received_e_DEK.id = 6 - received_e_DEK.ref_id = 6 - break - od - } + E_DEK temp_e_dek, encrypted_DEK, received_e_DEK Select_state: @@ -382,8 +407,16 @@ proctype Tenant_2() atomic { do - :: k2t2_buff > 0 -> k2t2?msg, temp_dek, temp_e_dek.ref_id, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, grant, auth, step -> req_buff-- -> k2t2_buff-- -> - + :: k2t2_buff > 0 -> k2t2?msg, temp_dek, temp_e_dek.ref_id, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, grant_t2, auth_t2, step -> k2t2_buff-- -> + + // AUTHENTICATION OR CONFIDENTIALITY VIOLATION + if + :: !auth_t2 -> denied = true -> goto Cleanup + :: temp_e_dek.id > 0 && temp_e_dek.id < ENC_DUMMY -> p_conf = false -> goto Cleanup + :: temp_e_dek.ref_id > 0 && temp_e_dek.ref_id < ENC_DUMMY -> p_conf = false -> goto Cleanup + :: else -> skip + fi + goto Receive :: t22k_buff < T2K_MAX && k2t2_buff == 0 -> @@ -392,37 +425,73 @@ proctype Tenant_2() :: MODEL == 1 -> do :: !(denied && p_assigned_2) -> - t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant, 1 -> break + t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant_t2, 1 -> break :: !(denied && !p_assigned_2) -> - t22k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, grant, 1 -> break + t22k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, grant_t2, 1 -> break :: !(denied && !p_enc_2) -> - t22k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.ref_version, id, grant, 1 -> break - // :: !(denied && !p_enc_2) -> - // t22k!re_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, EMPTY_PASS, id, grant, 1 -> break + t22k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.ref_version, id, grant_t2, 1 -> break + :: !(denied && !p_enc_2) -> + t22k!re_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, EMPTY_PASS, id, grant_t2, 1 -> break od break :: MODEL == 2 -> do :: !(denied && p_assigned_2) -> - t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant, 1 -> break + t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant_t2, 1 -> break :: !(denied && !p_assigned_2) -> - t22k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, grant, 1 -> break + t22k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, grant_t2, 1 -> break + :: !denied -> + t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, 0, grant_t2, 1 -> break od break :: MODEL == 3 -> + + if + :: p_enc_2 -> encrypted_DEK.ref_version = !encrypted_DEK.ref_version + :: else -> skip + fi + + do + :: !p_assigned_2 -> + t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant_t2, 1 -> break + :: p_assigned_2 && !p_enc_2 -> + t22k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, grant_t2, 1 -> break + :: !(denied & !p_enc_2) -> + t22k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.ref_version, id, grant_t2, 1 -> break + od + break + + :: MODEL == 4 -> + do + :: !p_assigned_2 -> + t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant_t2, 1 -> break + :: p_assigned_2 && !p_enc_2 -> + t22k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, grant_t2, 1 -> break + :: !(denied && !p_enc_2) + t22k!re_DEK, EMPTY_PASS, m4_KEK_t2, encrypted_DEK.id, encrypted_DEK.ref_version, id, grant_t2, 1 -> break + od + break + :: MODEL == 5 -> + + received_e_DEK.ref_version = !received_e_DEK.ref_version + + if + :: p_enc_1 && received_e_DEK.id == 0 -> + received_e_DEK.id = 6 + received_e_DEK.ref_id = 6 + :: else -> skip + fi + do - :: t22k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, ref_version_1, id, grant -> break - :: t22k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, ref_version_2, id, grant -> break - :: !denied -> t22k!d_DEK, EMPTY_PASS, EMPTY_PASS, encrypted_DEK.id, ref_version_1, id, grant -> break - :: t22k!d_DEK, EMPTY_PASS, received_e_DEK.ref_id, received_e_DEK.id, ref_version_1, id, VALID_GRANT -> break - :: t22k!d_DEK, EMPTY_PASS, received_e_DEK.ref_id, received_e_DEK.id, ref_version_2, id, VALID_GRANT -> break - :: !denied -> t22k!d_DEK, EMPTY_PASS, received_e_DEK.ref_id, received_e_DEK.id, ref_version_1, id, grant -> break - :: !denied -> t22k!d_DEK, EMPTY_PASS, received_e_DEK.ref_id, received_e_DEK.id, ref_version_2, id, grant -> break + :: !denied -> + t22k!d_DEK, EMPTY_PASS, received_e_DEK.ref_id, received_e_DEK.id, received_e_DEK.ref_version, id, grant_t2, 1 -> break + :: t22k!d_DEK, EMPTY_PASS, received_e_DEK.ref_id, received_e_DEK.id, received_e_DEK.ref_version, id, VALID_GRANT, 1 -> break od break - :: MODEL == 4 -> t22k!re_DEK, assigned_KEK, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.ref_version, id, grant -> break od + t22k_buff++ + od } @@ -431,24 +500,23 @@ proctype Tenant_2() atomic { - // AUTHENTICATION OR CONFIDENTIALITY VIOLATION - if - :: auth != 1 -> p_authentic = false - :: temp_e_dek.id == 1 || temp_e_dek.id == 2 -> p_conf = false - :: temp_e_dek.ref_id == 1 || temp_e_dek.ref_id == 2 -> p_conf = false - :: else -> skip - fi - + req_buff-- + if :: msg == deny -> + denied = true + // PROTOCOL VIOLATION if :: (step % 2) != 0 -> p_protocol = false :: else -> skip fi + :: else -> + denied = false + if :: msg == ass_KEK -> goto Assign_KEK_receive :: msg == d_DEK -> goto Decrypt_receive @@ -467,10 +535,11 @@ proctype Tenant_2() // PROTOCOL, SYNCHRONIZATION OR INTEGRITY VIOLATION if :: step != 8 -> p_protocol = false - :: temp_e_dek.ref_id != 7 -> p_int = false + :: temp_e_dek.ref_id != 7 -> p_int = false :: p_assigned_2 -> p_sync = false // liveness :: else -> skip fi + p_assigned_2 = true assigned_KEK = temp_e_dek.ref_id @@ -480,22 +549,20 @@ proctype Tenant_2() Decrypt_receive: atomic { - // printf("2\n") + // PROTOCOL OR INTEGRITY VIOLATION if :: step != 4 && step != 6 -> p_protocol = false - :: dek_id != temp_dek -> p_int = false - :: grant == 1 && temp_dek != 1 -> p_int = false + :: !(dek_id == temp_dek || (grant_t2 && temp_dek == 1))-> p_int = false :: else -> skip fi - + goto Cleanup } Encrypt_receive: atomic { - // printf("HERE 2: %d, and %d\n", temp_e_dek.id, temp_e_dek.ref_id) // PROTOCOL, SYNCHRONIZATION OR INTEGRITY VIOLATION if @@ -505,13 +572,17 @@ proctype Tenant_2() :: temp_e_dek.ref_id != assigned_KEK -> p_int = false :: else -> skip fi + encrypted_DEK.id = temp_e_dek.id encrypted_DEK.enc_version = temp_e_dek.enc_version encrypted_DEK.ref_id = temp_e_dek.ref_id encrypted_DEK.ref_version = temp_e_dek.ref_version - // printf("ID: %d ", encrypted_DEK.id) - // printf("KEK: %d ", encrypted_DEK.ref_id) + if + :: MODEL == 4 -> m4_KEK_t2 = encrypted_DEK.ref_id + :: else -> skip + fi + p_enc_2 = true goto Cleanup @@ -526,7 +597,7 @@ proctype Tenant_2() :: step != 6 -> p_protocol = false :: temp_e_dek.enc_version == encrypted_DEK.enc_version -> p_sync = false :: temp_e_dek.id-ENC_DUMMY != dek_id -> p_int = false - :: temp_e_dek.ref_id != assigned_KEK -> p_int = false + :: temp_e_dek.ref_id != assigned_KEK && temp_e_dek.ref_id != 9 -> p_int = false :: else -> skip fi @@ -535,15 +606,23 @@ proctype Tenant_2() encrypted_DEK.ref_id = temp_e_dek.ref_id encrypted_DEK.ref_version = temp_e_dek.ref_version + if + :: MODEL == 4 -> + if + :: encrypted_DEK.ref_id == 7 -> m4_KEK_t2 = 9 + :: else -> m4_KEK_t2 = 7 + fi + :: else -> skip + fi + goto Cleanup } Cleanup: atomic { - - auth = 0 - grant = 0 + auth_t2 = 0 + grant_t2 = 0 msg = deny temp_dek = 0 temp_e_dek.ref_id = 0 @@ -559,43 +638,47 @@ proctype Tenant_2() proctype Keystore() { mtype msg = deny - unsigned dek_id : 3, kek_id : 3, kek_ref : 3, tenant_id : 3, select_case : 3, grant : 2, kek_version : 1, auth : 1, step : 3 + unsigned dek_id : 3, kek_id : 3, kek_ref : 4, tenant_id : 3, grant : 2, kek_version : 1, step : 3, array_size : 3 = 4 bit id = 1 bit last_enc_1, last_enc_2, turn + bool db_skip_1, db_skip_2 + + if + :: MODEL != 4 -> + array_size = NUM_KEKS + :: else -> skip + fi + E_DEK temp_e_dek KEK temp_key - KEK v_KEKs[NUM_KEKS] - - // atomic{ - - // if - // :: MODEL != 1 -> - // v_KEKs[0].id = 1 - // v_KEKs[0].id = 2 - // :: else -> skip - // fi - // } + KEK v_KEKs[array_size] Select_state: - // cache_cleared = !cache_cleared - exit_atomic = true + do + :: MODEL == 3 || MODEL == 5 -> cache_cleared = !cache_cleared -> break + :: else -> cache_cleared = cache_cleared -> break + od + // exit_atomic = true atomic { do //FROM AC - :: ac2k_buff > 0 && db2k_buff == 0-> ac2k?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, auth, step -> ac2k_buff-- -> - + :: ac2k_buff > 0 && db2k_buff == 0-> ac2k?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, auth_ks, step -> ac2k_buff-- -> + // PROTOCOL OR AUTHENTICATION VIOLATION if - :: auth != 1 -> p_authentic = false -> goto Deny_request + :: !auth_ks -> goto Cleanup + :: else -> skip + fi + if :: msg == ass_KEK2 && step != 7 -> p_protocol = false :: msg != ass_KEK2 && msg != deny && step != 3 -> p_protocol = false :: msg == deny && step != 7 && step != 3 -> p_protocol = false :: else -> skip fi - + if // Dereference KEK encryption with MK :: kek_ref > 5 -> kek_id = kek_ref-ENC_DUMMY :: else -> kek_id = 0 @@ -612,11 +695,11 @@ proctype Keystore() goto Send_to_Database //FROM DB - :: db2k_buff > 0 -> db2k?msg, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, kek_version, auth, step -> db2k_buff-- -> + :: db2k_buff > 0 -> db2k?msg, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, kek_version, auth_ks, step -> db2k_buff-- -> // PROTOCOL OR AUTHENTICATION VIOLATION if - :: auth != 1 -> p_authentic = false -> goto Deny_request + :: !auth_ks -> goto Cleanup :: step != 5 -> p_protocol = false :: else -> skip fi @@ -651,7 +734,7 @@ proctype Keystore() kek_ref = kek_id+ENC_DUMMY goto Send_to_Access_Control :: msg == d_DEK -> goto Decrypt_return - :: msg == e_DEK || msg == re_DEK -> assert(msg != ass_KEK) -> goto Encrypt_return + :: msg == e_DEK || msg == re_DEK -> goto Encrypt_return od @@ -660,10 +743,11 @@ proctype Keystore() t12k?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, step -> req_buff++ -> t12k_buff-- -> turn = 0 + auth_ks = tenant_id // PROTOCOL OR AUTHENTICATION VIOLATION if - :: tenant_id != 1 -> p_authentic = false -> goto Deny_request + :: !auth_ks -> tenant_id = 1 -> goto Deny_request :: step != 1 -> p_protocol = false :: else -> skip fi @@ -674,10 +758,10 @@ proctype Keystore() t22k?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, step -> req_buff++ -> t22k_buff-- -> turn = 1 - + auth_ks = tenant_id/2 // PROTOCOL OR AUTHENTICATION VIOLATION if - :: tenant_id != 2 -> p_authentic = false -> goto Deny_request + :: !auth_ks -> tenant_id = 2 -> goto Deny_request :: step != 1 -> p_protocol = false :: else -> skip fi @@ -687,10 +771,18 @@ proctype Keystore() od } + Send_to_Access_Control: atomic { - + + if + :: MODEL == 2 -> + k2ac_buff < K2AC_MAX + k2ac!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, 0, step+1 + k2ac_buff++ + :: else -> skip + fi k2ac_buff < K2AC_MAX k2ac!msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 k2ac_buff++ @@ -701,11 +793,18 @@ proctype Keystore() Send_to_Database: atomic { - + + if + :: MODEL == 2 -> + k2db_buff < K2DB_MAX + k2db!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, 0, step+1 + k2db_buff++ + :: else -> skip + fi k2db_buff < K2DB_MAX k2db!msg, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 k2db_buff++ - + goto Cleanup } @@ -728,15 +827,15 @@ proctype Keystore() fi fi - // // CACHE VIOLATION - // if - // :: !(v_KEKs[kek_id-1].version == 1 && temp_e_dek.ref_version == 0) -> - // if - // :: tenant_id == 1 -> p_cache = (db_skip_1 || cache_cleared) - // :: tenant_id == 2 -> p_cache = (db_skip_2 || cache_cleared) - // fi - // :: else -> skip - // fi + // CACHE VIOLATION + if + :: !(v_KEKs[kek_id-1].version == 1 && temp_e_dek.ref_version == 0) -> + if + :: tenant_id == 1 -> p_cache = (db_skip_1 || cache_cleared) + :: tenant_id == 2 -> p_cache = (db_skip_2 || cache_cleared) + fi + :: else -> skip + fi if @@ -754,13 +853,13 @@ proctype Keystore() if :: tenant_id == 1 -> - k2t1_buff < K2T_MAX - k2t1!d_DEK, temp_e_dek.id-ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, step+1 - k2t1_buff++ + k2t1_buff < K2T_MAX + k2t1!d_DEK, temp_e_dek.id-ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, step+1 + k2t1_buff++ :: else -> - k2t2_buff < K2T_MAX - k2t2!d_DEK, temp_e_dek.id-ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, grant, id, step+1 - k2t2_buff++ + k2t2_buff < K2T_MAX + k2t2!d_DEK, temp_e_dek.id-ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, grant, id, step+1 + k2t2_buff++ fi goto Cleanup @@ -777,12 +876,14 @@ proctype Keystore() fi if - :: tenant_id == 1 -> k2t1_buff < K2T_MAX - k2t1!ass_KEK, EMPTY_PASS, kek_ref, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, step+1 - k2t1_buff++ - :: else -> k2t2_buff < K2T_MAX - k2t2!ass_KEK, EMPTY_PASS, kek_ref, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, grant, id, step+1 - k2t2_buff++ + :: tenant_id == 1 -> + k2t1_buff < K2T_MAX + k2t1!ass_KEK, EMPTY_PASS, kek_ref, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, step+1 + k2t1_buff++ + :: else -> + k2t2_buff < K2T_MAX + k2t2!ass_KEK, EMPTY_PASS, kek_ref, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, grant, id, step+1 + k2t2_buff++ fi goto Cleanup @@ -803,9 +904,10 @@ proctype Keystore() do :: tenant_id == 1 -> + last_enc_1 = !last_enc_1 temp_e_dek.enc_version = last_enc_1 - + k2t1_buff < K2T_MAX k2t1!msg, dek_id, kek_id+ENC_DUMMY, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, id, step+1 k2t1_buff++ @@ -818,7 +920,7 @@ proctype Keystore() k2t2_buff < K2T_MAX k2t2!msg, dek_id, kek_id+ENC_DUMMY, temp_e_dek.id, temp_e_dek.enc_version, temp_e_dek.ref_version, grant, id, step+1 - k2t2_buff++ + k2t2_buff++ break od @@ -864,8 +966,7 @@ proctype Keystore() Cleanup: atomic { - - auth = 0 + auth_ks = 0 grant = 0 msg = deny dek_id = 0 @@ -873,7 +974,6 @@ proctype Keystore() kek_ref = 0 kek_version = 0 tenant_id = 0 - select_case = 0 temp_e_dek.id = 0 temp_e_dek.enc_version = 0 temp_e_dek.ref_id = 0 @@ -889,28 +989,40 @@ proctype Keystore() proctype Database() { mtype msg = deny - unsigned kek_id : 3, i : 3, tenant_id : 3, dek_id : 3, grant : 2, auth : 1, step : 3 + unsigned kek_id : 3, i : 3, tenant_id : 3, dek_id : 3, grant : 2, step : 3, array_size : 3 = 4 bit id = 1 - KEK p_KEKs[NUM_KEKS] - p_KEKs[0].id = 1 - p_KEKs[1].id = 2 + if + :: MODEL != 4 -> + array_size = NUM_KEKS + :: else -> skip + fi + + KEK p_KEKs[array_size] E_DEK temp_e_dek + for (i : 0 .. array_size-1) { + p_KEKs[i].id = i+1 + } + Select_state: - exit_atomic = true + k2db_buff > 0 atomic { - k2db_buff > 0 - k2db?msg, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, auth, step + + k2db?msg, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, auth_db, step k2db_buff-- // PROTOCOL, AUTHENTICATION OR INTEGRITY VIOLATION + if + :: !auth_db -> goto Cleanup + :: else -> skip + fi + if :: step != 4 -> p_protocol = false - :: auth != 1 -> p_authentic = false -> goto Deny_request - :: kek_id != 1 && kek_id != 2 -> p_int = false + :: kek_id < 1 && kek_id > 4 -> p_int = false :: else -> skip fi @@ -924,21 +1036,10 @@ proctype Database() { Access_KEK: atomic { - - for (i : 0 .. NUM_KEKS-1) { + i = 0 + for (i : 0 .. array_size-1) { if - :: p_KEKs[i].id == kek_id -> - - db2k_buff < DB2K_MAX - // curr_rotation = !curr_rotation - // p_KEKs[0].version = curr_rotation - // p_KEKs[1].version = curr_rotation - p_KEKs[i].version = !p_KEKs[i].version - db2k!msg, dek_id, p_KEKs[i].id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, p_KEKs[i].version, id, step+1 - db2k_buff++ - - goto Cleanup - + :: p_KEKs[i].id == kek_id -> goto Send :: else -> skip fi } @@ -947,6 +1048,25 @@ proctype Database() { } + Send: + atomic { + + p_KEKs[i].version = !p_KEKs[i].version + + if + :: MODEL == 2 -> + db2k_buff < DB2K_MAX + db2k!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, 0, step+1 + db2k_buff++ + :: else -> skip + fi + db2k_buff < DB2K_MAX + db2k!msg, dek_id, p_KEKs[i].id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, p_KEKs[i].version, id, step+1 + db2k_buff++ + + goto Cleanup + } + Deny_request: atomic { @@ -965,7 +1085,7 @@ proctype Database() { atomic { - auth = 0 + auth_db = 0 i = 0 msg = deny dek_id = 0 @@ -984,58 +1104,54 @@ proctype Database() { proctype AccessControl() { mtype msg = deny - unsigned kek_ref : 3, tenant_id : 3, auth : 1, dek_id : 3, grant : 2, assigned_1 : 3, assigned_2 : 3, step : 3 + unsigned kek_ref : 4, tenant_id : 3, dek_id : 3, grant : 1, assigned_1 : 3, assigned_2 : 3, step : 3 bit id = 1 E_DEK temp_e_dek - // atomic { - - // if - // :: MODEL != 1 -> - // assigned_1 = 6 - // assigned_2 = 7 - // :: else -> skip - // fi - - // } - - Select_state: + Receive: - exit_atomic = true + k2ac_buff > 0 atomic { - k2ac_buff > 0 - k2ac?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, auth, step + + k2ac?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, auth_ac, step k2ac_buff-- - + + if + :: !auth_ac -> goto Cleanup + :: else -> skip + fi + // PROTOCOL, AUTHENTICATION OR CONFIDENTIALITY VIOLATION if - :: temp_e_dek.id == 1 || temp_e_dek.id == 2 -> p_conf = false - :: temp_e_dek.ref_id == 1 || temp_e_dek.ref_id == 2 -> p_conf = false - :: kek_ref == 1 || kek_ref == 2 -> p_conf = false - :: auth != 1 -> p_authentic = false -> goto Deny_request + :: temp_e_dek.ref_id > 0 && temp_e_dek.ref_id < ENC_DUMMY -> p_conf = false + :: temp_e_dek.id > 0 && temp_e_dek.id < ENC_DUMMY -> p_conf = false + :: kek_ref > 0 && kek_ref < ENC_DUMMY -> p_conf = false + :: !auth_ac -> goto Cleanup :: msg != ass_KEK2 && step != 2 -> p_protocol = false :: msg == ass_KEK2 && step != 6 -> p_protocol = false :: else -> skip fi + goto Select_state + } + + Select_state: + atomic { if :: msg == ass_KEK -> goto Assign_KEK_authorize :: msg == ass_KEK2 -> goto Assign_KEK2_authorize :: (msg == d_DEK || msg == e_DEK || msg == re_DEK) -> goto Authorize :: else -> goto Deny_request fi - } - Assign_KEK_authorize: // Request access to generate a KEK atomic { - if :: kek_ref == 0 -> if @@ -1058,8 +1174,6 @@ proctype AccessControl() // Newly generated key assigned atomic { - assert(kek_ref > 5) - if :: tenant_id == 1 && assigned_1 == 0 -> assigned_1 = kek_ref :: tenant_id == 2 && assigned_2 == 0 -> assigned_2 = kek_ref @@ -1079,20 +1193,27 @@ proctype AccessControl() atomic { if - :: kek_ref != 6 && kek_ref != 7 -> goto Deny_request + :: kek_ref < 6 -> goto Deny_request :: else -> skip fi - assert((kek_ref == 6 && tenant_id == 1) || (kek_ref == 7 && tenant_id == 2)) + if - :: tenant_id == 1 && (kek_ref != assigned_1) -> goto Deny_request - :: tenant_id == 2 && (kek_ref != assigned_2) -> + :: tenant_id == 1 && (kek_ref != assigned_1 && kek_ref != assigned_1 + 2) -> goto Deny_request + :: tenant_id == 2 && (kek_ref != assigned_2 && kek_ref != assigned_2 + 2) -> if :: grant == VALID_GRANT && assigned_1 == kek_ref && msg == d_DEK -> skip :: else -> goto Deny_request fi :: else -> skip fi - // printf("AC: %d\n", temp_e_dek.id) + + if + :: MODEL == 2 -> + ac2k_buff < AC2K_MAX + ac2k!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, 0, step+1 + ac2k_buff++ + :: else -> skip + fi ac2k_buff < AC2K_MAX ac2k!msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 ac2k_buff++ @@ -1128,8 +1249,8 @@ proctype AccessControl() Cleanup: atomic { - // db_active = false - auth = 0 + + auth_ac = 0 msg = deny dek_id = 0 kek_ref = 0 @@ -1140,6 +1261,6 @@ proctype AccessControl() grant = 0 step = 0 - goto Select_state + goto Receive } } From 4d4dbb1b305905e20b28d2bdcdcf712c755d8241 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Tue, 4 Jun 2024 13:16:49 +0200 Subject: [PATCH 22/30] Verified --- SPIN-verification/README.md | 38 +- SPIN-verification/dist_coms.pml | 934 -------------------------------- SPIN-verification/model.pml | 104 ++-- 3 files changed, 62 insertions(+), 1014 deletions(-) delete mode 100644 SPIN-verification/dist_coms.pml diff --git a/SPIN-verification/README.md b/SPIN-verification/README.md index a135205..be0a86a 100644 --- a/SPIN-verification/README.md +++ b/SPIN-verification/README.md @@ -1,29 +1,37 @@ # A Functional Verification of the KMS in SPIN -Currently models tenant and keystore interaction where 2 tenants can encrypt DEKs and request assignment of KEKs from the Keystore.
+Verification in SPIN that verifies the functionality of KEK assignment, encryption, decryption and re-encryption.
-When Tenant 1 has encrypted a DEK, it is sent to Tenant 2 together with a *grant* token. Tenant 2 will store encrypted DEKs from Tenant 1 and send them for decryption with the token *grant*. The token is controlled with constants **GRANT** and **VALID_GRANT**. Only when the two are equal, will Tenant 2 be able to decrypt enncrypted DEKs received from Tenant 1.
+There are 4 different models that each verify different operations.
-By flagging **SAME_KEK_ASSIGNED** as true the max number of KEKs assigned will be set to 1 and both Tenants will be assigned the same KEK from the Keystore. This alternative model introduces a faulty behavior to observe verification failure.
+## Models -On set intervals defined as constants, KEKs will be rotated in the database and signals will be sent to the tenants assigned those KEKs. Tenants will then re-encrypt those encrypted DEKs in order to rotate the encryption.
+Model can be set by changing the MODEL constant.
+ +1=A 2=B 3=C 4=D In the paper.
+ +2: Assignemnt and Encryption.
+3: Decryption after assignment and encryption has been finalized.
+4: Re-Encryption of envelopes after assignment and encryption has been finalized.
+5: Tenant 1 assignment and encryption then invalid credentials, Tenant 2 only Decrypts envelopes received from Tenant 1 with different grants.
+ +If MODEL == 1 then IS_MODEL_1 == 1
+If MODEL != 1 then IS_MODEL_1 == 0
## To Run and Verify -Most of this can be done with an external tool such as iSpin, additional information found [here](https://spinroot.com/spin/Man/README.html).
+Most of this can be done with an external tool such as iSSPIN, additional information found [here](https://spinroot.com/spin/Man/README.html).
**Run Code**
-spin -T dist_coms.pml - Regular run that will halt on error and print any statements in the code.
-spin -T -a dist_coms.pml - generates pan.c for verification.
+spin -T model.pml - Regular run that will halt on error and print any statements in the code.
+spin -a model.pml - generates pan.c for verification.
**Compile pan.c**
-gcc -w -o pan pan.c - (semi-)optional flags used currently (-DMEMLIM=12000 -O2 -DVECTORSZ=1280 -DXUSAFE )
+gcc -DMEMLIM=N -O2 -DXUSAFE -DCOLLAPSE -DNFAIR=3 (-DSAFETY) -w -o pan pan.c
-**Verify**
-./pan -m100000000 -a -c1
+-DSAFETY used when verifying safety.
+**Verify**
+./pan -mN (-a -f (-N claim) )
+In -mN, N is an integer for max depth, however -N is a flag to specify which claim to verify. +Parenthesis used when verifying liveness.
-## Some Default Values -Number of Tenants: 2
-Number of DEKs per Tenant: 2
-Number of KEKs in Keystore: 4
-Max number of KEKs per Tenant: 2 diff --git a/SPIN-verification/dist_coms.pml b/SPIN-verification/dist_coms.pml deleted file mode 100644 index 224a5d1..0000000 --- a/SPIN-verification/dist_coms.pml +++ /dev/null @@ -1,934 +0,0 @@ -#define NUM_DEKS 2 -#define NUM_KEKS 4 -#define NUM_TENANTS 2 -#define T2K_MAX 1 -#define K2T_MAX 0 -#define K2AC_MAX 0 -#define AC2K_MAX 0 -#define K2DB_MAX 1 -#define DB2K_MAX 0 -#define DB2T_MAX 2 -#define T_SEND_MAX 2 -#define ASS_MAX 2 -#define SAME_KEK_MAX 1 -#define GRANT 1 -#define VALID_GRANT 1 -#define ENC_DUMMY 5 -#define EMPTY_PASS 0 -#define ROT_KEK_1 400000 -#define ROT_KEK_2 240000 -#define ROT_KEK_3 210000 -#define ROT_KEK_4 440000 -#define CACHE_CLEAR 4000 -#define SAME_KEK_ASSIGNED false - -typedef KEK { /* Unencrypted */ - unsigned id : 3 - int version - unsigned assigned_to : 2 -} - -typedef E_Key { /* Encrypted */ - unsigned id : 4 - int version - unsigned ref_id : 4 - int ref_version -} - -mtype = { e_DEK, d_DEK, re_DEK, ass_KEK, rot_KEK, send_e_DEK, deny, ack } - -// t: Tenant -// k: Keystore -// ac: Access Control -// db: Database - -// { message type, DEK_ID, KEK_ID, E_KEY-ID, E_KEY-VERSION, E_KEY-REF_V, TENANT_ID, (GRANT) } -// KEK_ID shares index to E_KEY-REF-ID in channels to reduce channel width -chan t12k = [T2K_MAX] of { mtype, byte, byte, byte, int, int, byte } // Tenant 1 -> Keystore -chan t22k = [T2K_MAX] of { mtype, byte, byte, byte, int, int, byte, byte } // Tenant 2 -> Keystore, added byte field for grant token from Tenant 1 -chan k2t1 = [K2T_MAX] of { mtype, byte, byte, byte, int, int } // Keystore -> Tenant 1 -chan k2t2 = [K2T_MAX] of { mtype, byte, byte, byte, int, int } // Keystore -> Tenant 2 - -// { message type, E_KEY-ID, E_KEY-VERSION, E_KEY-REF_ID, E_KEY-REF_V, GRANT } -chan t12t2 = [T_SEND_MAX] of { mtype, byte, int, byte, int, byte } // Tenant 1 -> Tenant 2 - -// { message type, KEK_ID, TENANT_ID, GRANT} -chan k2ac = [K2AC_MAX] of { mtype, byte, byte, byte } // Keystore -> Access Control -chan ac2k = [AC2K_MAX] of { mtype } // Access Control -> Keystore - -// { message type, KEK_ID, TENANT_ID} -chan k2db = [K2DB_MAX] of { mtype, byte, byte } // Keystore -> Database -// { message type, KEK_ID, KEK-VERSION, KEK-ASS_TO } -chan db2k = [DB2K_MAX] of { mtype, byte, int, byte } // Database -> Keystore - -// This channel emulates an external component notifying -// the tenant when a rotation has taken place -// { message type, KEK_ID } -chan db2t1 = [DB2T_MAX] of { mtype, byte } // Database -> Tenant 1 -chan db2t2 = [DB2T_MAX] of { mtype, byte } // Database -> Tenant 2 - -chan a = [0] of {int} -int timer -bool clear_cache, done -// LTL variables -unsigned enc_1 : 4 = 15, u_enc_1 : 4 = 14, enc_2 : 4 = 15, u_enc_2 : 4 = 14, sent : 2 - - -// LTL claims -// ltl { [] conf } -// ltl Confidentiality { [] (enc_1 != u_enc_1 && enc_2 != u_enc_2 && enc_1 > 4 && enc_2 > 4 && (u_enc_1 == 14||u_enc_1 < 5) && (u_enc_2 == 14 || u_enc_2 < 5)) } -// bool ps_confidentiality, ps_integrity, ps_authentication, ps_authorization, ps_consistency, pl_confidentiality, pl_integrity, pl_authentication, pl_authorization, pl_consistency -// TRY TO VIOLATE LTL -init { - atomic { - timer = 0 - clear_cache = false - - unsigned i : 2 - - for (i : 1 .. NUM_TENANTS) { - run Tenant(i) - } - run Database() - run Keystore() - run AccessControl() - } -} - - -proctype Tenant(unsigned id : 2) -{ - mtype msg - unsigned temp_key : 3, i : 3, ass_idx : 2, recrypt_idx : 4 - bit grant - byte assigned_KEKs[NUM_KEKS/2], DEKs[NUM_DEKS] - E_Key temp_e_key - E_Key encrypted_DEKs[NUM_DEKS], received_e_DEK - bool sent2tenant - - atomic { - for (i : 0 .. NUM_DEKS-1) { - DEKs[i] = i + 1 + NUM_DEKS*(id-1) - } - } - - Select_state: - enc_1 = u_enc_1 - atomic{ - - if - :: SAME_KEK_ASSIGNED -> assert(assigned_KEKs[1] == 0) - :: else -> skip - fi - // Receive rotation update ping - if - :: id == 1 -> - // printf("encrypted_DEKs[%d]: %d\n", 0, encrypted_DEKs[0].id) - // printf("encrypted_DEKs[%d]: %d\n", 1, encrypted_DEKs[1].id) - if - :: db2t1?[msg, recrypt_idx] -> db2t1?msg, recrypt_idx -> - goto Recrypt - :: else -> skip - fi - :: else -> - if - :: db2t2?[msg, recrypt_idx] -> db2t2?msg, recrypt_idx -> - goto Recrypt - :: else -> skip - fi - fi - // Receive from tenant 1 - if - :: id == 2 -> - - if - :: t12t2?[msg, temp_e_key.id, temp_e_key.version, temp_e_key.ref_id, temp_e_key.ref_version, grant] -> - t12t2?msg, temp_e_key.id, temp_e_key.version, temp_e_key.ref_id, temp_e_key.ref_version, grant -> - assert(temp_e_key.id-ENC_DUMMY-1 < 2) - received_e_DEK.id = temp_e_key.id - received_e_DEK.version = temp_e_key.version - received_e_DEK.ref_id = temp_e_key.ref_id - received_e_DEK.ref_version = temp_e_key.ref_version - :: else -> skip - fi - :: else -> skip - fi - } - - - - - // if - // :: id == 1 -> printf("HERE\n") - // :: else -> skip - // fi - - // Main selection loop - do - :: goto Encrypt - :: goto Decrypt - :: goto Request_KEK - od - - Encrypt: - - if - :: id == 1 -> - atomic { - do - :: t12k!e_DEK, DEKs[0], assigned_KEKs[0], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id -> break - :: t12k!e_DEK, DEKs[0], assigned_KEKs[1], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id -> break - :: t12k!e_DEK, DEKs[1], assigned_KEKs[0], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id -> break - :: t12k!e_DEK, DEKs[1], assigned_KEKs[1], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id -> break - od - } - :: else -> - atomic { - do - :: t22k!e_DEK, DEKs[0], assigned_KEKs[0], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant -> break - :: t22k!e_DEK, DEKs[0], assigned_KEKs[1], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant -> break - :: t22k!e_DEK, DEKs[1], assigned_KEKs[0], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant -> break - :: t22k!e_DEK, DEKs[1], assigned_KEKs[1], EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant -> break - od - } - fi - - goto Receive - - Decrypt: - - atomic { - if - :: id == 1 -> - if - :: encrypted_DEKs[0].id != 0 -> - t12k!d_DEK, EMPTY_PASS, encrypted_DEKs[0].ref_id, encrypted_DEKs[0].id, encrypted_DEKs[0].version, encrypted_DEKs[0].ref_version, id - :: encrypted_DEKs[1].id != 0 -> - t12k!d_DEK, EMPTY_PASS, encrypted_DEKs[1].ref_id, encrypted_DEKs[1].id, encrypted_DEKs[1].version, encrypted_DEKs[1].ref_version, id - :: else -> goto Select_state - fi - :: else -> - if - :: encrypted_DEKs[0].id != 0 -> - t22k!d_DEK, EMPTY_PASS, encrypted_DEKs[0].ref_id, encrypted_DEKs[0].id, encrypted_DEKs[0].version, encrypted_DEKs[0].ref_version, id, grant - :: encrypted_DEKs[1].id != 0 -> - t22k!d_DEK, EMPTY_PASS, encrypted_DEKs[1].ref_id, encrypted_DEKs[1].id, encrypted_DEKs[1].version, encrypted_DEKs[1].ref_version, id, grant - :: received_e_DEK.id != 0 -> - t22k!d_DEK, EMPTY_PASS, received_e_DEK.ref_id, received_e_DEK.id, received_e_DEK.version, received_e_DEK.ref_version, id, grant - :: else -> goto Select_state - fi - fi - } - - goto Receive - - Recrypt: - - i = 0 - for (i : 0 .. NUM_DEKS-1) { - - if - :: encrypted_DEKs[i].ref_id == recrypt_idx -> - if // Send and Receive - :: id == 1 -> - t12k!re_DEK, EMPTY_PASS, encrypted_DEKs[i].ref_id, encrypted_DEKs[i].id, encrypted_DEKs[i].version, encrypted_DEKs[i].ref_version, id - k2t1?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version - :: else -> - t22k!re_DEK, EMPTY_PASS, encrypted_DEKs[i].ref_id, encrypted_DEKs[i].id, encrypted_DEKs[i].version, encrypted_DEKs[i].ref_version, id, grant - k2t2?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version - fi - - d_step { - if - :: msg != deny -> - assert(temp_e_key.version > encrypted_DEKs[i].version) - assert(temp_e_key.ref_version >= encrypted_DEKs[i].ref_version) - assert(encrypted_DEKs[i].id == temp_e_key.id) - assert(recrypt_idx == temp_e_key.ref_id) - encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].id = temp_e_key.id - encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].version = temp_e_key.version - encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].ref_id = temp_e_key.ref_id - encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].ref_version = temp_e_key.ref_version - :: else -> skip - fi - } - :: else -> skip - fi - } - - goto Select_state - - Request_KEK: - - atomic { - if - :: id == 1 -> t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id - :: else -> t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant - fi - } - - goto Receive - - - Receive: - - if - :: !done -> - if - :: id == 1 -> - k2t1?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version - :: else -> - k2t2?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version - fi - :: else -> - msg = deny - if - :: id == 1 -> - if - :: atomic { k2t1?[msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version] -> - k2t1?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version} - :: else -> skip - fi - :: else -> - if - :: atomic { k2t2?[msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version] -> - k2t2?msg, temp_key, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version} - :: else -> skip - fi - fi - fi - - atomic { - if - :: msg == ass_KEK -> - assigned_KEKs[ass_idx] = temp_e_key.ref_id - // printf("ass[%d]: %d\n", ass_idx, assigned_KEKs[ass_idx] ) - ass_idx++ - :: msg == d_DEK -> - assert(temp_key == DEKs[(temp_key-1)%2] || (temp_key == received_e_DEK.id-ENC_DUMMY && grant == VALID_GRANT)) - assert(DEKs[0] != received_e_DEK.id-ENC_DUMMY) - assert(DEKs[1] != received_e_DEK.id-ENC_DUMMY) - if - :: id == 1 -> - enc_1 = encrypted_DEKs[(temp_key-1)%2].id - u_enc_1 = temp_key - // printf("enc_1: %d, u_enc_1: %d\n", enc_1, u_enc_1) - :: else -> - enc_2 = encrypted_DEKs[(temp_key-1)%2].id - u_enc_2 = temp_key - if - :: temp_key == encrypted_DEKs[(temp_key-1)%2].id-ENC_DUMMY -> - assert(temp_key == enc_2-ENC_DUMMY) - :: else -> skip - fi - // printf("enc_2: %d, u_enc_2: %d\n", enc_2, u_enc_2) - enc_2 = received_e_DEK.id - // printf("enc_2: %d, u_enc_2: %d\n", enc_2, u_enc_2) - if - :: temp_key == received_e_DEK.id-ENC_DUMMY -> - assert(temp_key == enc_2-ENC_DUMMY) - :: else -> skip - fi - fi - :: msg == deny -> skip - :: msg == e_DEK -> - assert(temp_e_key.version > encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].version) - if - :: id == 1 -> - enc_1 = temp_e_key.id - u_enc_1 = DEKs[(temp_e_key.id-ENC_DUMMY-1)%2] - :: else -> - enc_2 = temp_e_key.id - u_enc_2 = DEKs[(temp_e_key.id-ENC_DUMMY-1)%2] - fi - encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].id = temp_e_key.id - encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].version = temp_e_key.version - encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].ref_id = temp_e_key.ref_id - encrypted_DEKs[(temp_e_key.id-ENC_DUMMY-1)%2].ref_version = temp_e_key.ref_version - if - :: id == 1 && !sent2tenant -> goto Send_to_tenant - :: else -> skip - fi - fi - // enc_1 = 15 - // u_enc_1 = 14 - // enc_2 = 15 - // u_enc_2 = 14 - } - // enc_1 = 15 - // u_enc_1 = 15 - // enc_2 = 15 - // u_enc_2 = 15 - - goto Select_state - - Send_to_tenant: - - atomic { - t12t2!send_e_DEK, temp_e_key.id, temp_e_key.version, temp_e_key.ref_id, temp_e_key.ref_version, GRANT - sent2tenant = true - sent++ - // enc_1 = 15 - // u_enc_1 = 14 - // enc_2 = 15 - // u_enc_2 = 14 - } - - goto Select_state -} - -proctype Keystore() -{ - mtype msg, enc_msg - int version // , receive - unsigned dek_id : 3, kek_id : 3, kek_ref : 4, i : 3, tenant_id : 2, id : 3, is_case : 2, kek_idx : 3, assigned_to : 2 - bit grant - bool valid, received - - KEK temp_key - E_Key temp_e_key - - KEK v_KEKs[NUM_KEKS] - - Select_state: - - atomic { - if // Clear Cache - :: clear_cache -> - i = 0 - for (i : 0 .. NUM_KEKS-1) { - v_KEKs[i].id = 0 - v_KEKs[i].version = 0 - v_KEKs[i].assigned_to = 0 - } - clear_cache = false - :: else -> skip - fi - } - - goto Receive - - Receive: - - atomic { - // receive++ - // if - // :: !done && receive > 20 ->// && sent > 1 -> - // //printf("BTB: %d\n", timer) - // done == true - // :: else -> skip - // fi - received = false - - if - :: t12k?[msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, tenant_id] -> - t12k?msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, tenant_id -> - received = true - if - :: kek_ref > 0 -> kek_id = kek_ref-ENC_DUMMY - :: else -> skip - fi - :: t22k?[msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, tenant_id, grant] -> - t22k?msg, dek_id, kek_ref, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version, tenant_id, grant -> - received = true - if - :: kek_ref > 0 -> kek_id = kek_ref-ENC_DUMMY - :: else -> skip - fi - :: else -> skip - fi - } - - if - :: received -> - if - :: msg == e_DEK || msg == re_DEK -> goto Encrypt - :: msg == d_DEK -> goto Decrypt - :: msg == ass_KEK -> goto Assign_KEK - :: else -> skip - fi - :: else -> skip - fi - - goto Select_state - - Assign_KEK: - - k2db!ass_KEK, kek_idx+1, tenant_id - db2k?msg, id, version, assigned_to - - if - :: msg == deny -> goto Deny_request - :: else -> skip - fi - - atomic { - v_KEKs[kek_idx].id = id - v_KEKs[kek_idx].version = version - v_KEKs[kek_idx].assigned_to = assigned_to - - k2ac!msg, id, tenant_id, grant - } - - ac2k?msg - - if - :: msg == deny -> goto Deny_request - :: else -> skip - fi - - atomic { - if - :: tenant_id == 1 -> k2t1!ass_KEK, EMPTY_PASS, v_KEKs[kek_idx].id+ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS - :: else -> k2t2!ass_KEK, EMPTY_PASS, v_KEKs[kek_idx].id+ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS - fi - - if - :: !SAME_KEK_ASSIGNED -> kek_idx++ - :: else -> skip - fi - } - - goto Select_state - - Decrypt: - - atomic { - valid = true - } - - k2ac!msg, kek_id, tenant_id, grant - ac2k?msg - - if - :: msg == deny -> goto Deny_request - :: else -> skip - fi - - d_step { - if - :: v_KEKs[kek_id-1].id == 0 -> is_case = 1 - :: v_KEKs[kek_id-1].id == kek_id -> is_case = 2 - :: else -> is_case = 0 -> valid = false - fi - } - - if - :: is_case == 1 -> - k2db!d_DEK, kek_id, tenant_id - db2k?msg, id, version, assigned_to - - d_step { - if - :: msg != deny -> - v_KEKs[id-1].id = id - v_KEKs[id-1].version = version - - if - :: v_KEKs[kek_id-1].version < temp_e_key.ref_version -> valid = false - :: else -> skip - fi - :: else -> valid = false - fi - } - :: is_case == 2 - if - :: v_KEKs[kek_id-1].version >= temp_e_key.ref_version -> - skip - :: else -> - k2db!d_DEK, kek_id, tenant_id - db2k?msg, id, version, assigned_to - - d_step { - v_KEKs[id-1].version = id - v_KEKs[id-1].version = version - - if - :: v_KEKs[id-1].version < temp_e_key.ref_version -> valid = false - :: else -> skip - fi - } - fi - :: else -> skip - fi - - if - :: valid -> assert(v_KEKs[kek_id-1].version >= temp_e_key.ref_version) - :: else -> goto Deny_request - fi - - atomic { - if - :: tenant_id == 1 -> k2t1!d_DEK, temp_e_key.id-ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS - :: else -> k2t2!d_DEK, temp_e_key.id-ENC_DUMMY, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS - fi - } - - goto Select_state - - Encrypt: - - atomic { - if - :: msg == re_DEK -> enc_msg = re_DEK - :: else -> enc_msg = e_DEK - fi - } - - k2ac!msg, kek_id, tenant_id, grant - ac2k?msg - - if - :: msg == deny -> goto Deny_request - :: else -> skip - fi - - k2db!e_DEK, kek_id, tenant_id - db2k?msg, id, version, assigned_to - - if - :: msg != deny -> - d_step { - v_KEKs[id-1].id = id - v_KEKs[id-1].version = version - v_KEKs[id-1].assigned_to = assigned_to - } - :: else -> goto Deny_request - fi - - assert(kek_id > 0 && kek_id <= NUM_KEKS) - - d_step { - if - :: enc_msg == re_DEK -> - assert(temp_e_key.ref_version <= v_KEKs[kek_id-1].version && temp_e_key.ref_version > v_KEKs[kek_id-1].version-2) - :: else -> - // if - // :: tenant_id == 1 -> printf("P1 DEK: %d\n", dek_id) - // :: else -> printf("P2 DEK: %d\n", dek_id) - // fi - temp_e_key.id = dek_id+ENC_DUMMY - fi - temp_e_key.version = timer - temp_e_key.ref_id = v_KEKs[kek_id-1].id+ENC_DUMMY - temp_e_key.ref_version = v_KEKs[kek_id-1].version - } - - atomic { - if - :: tenant_id == 1 -> k2t1!enc_msg, EMPTY_PASS, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version - :: else -> k2t2!enc_msg, EMPTY_PASS, temp_e_key.ref_id, temp_e_key.id, temp_e_key.version, temp_e_key.ref_version - fi - } - - goto Select_state - - Deny_request: - - atomic { - if - :: tenant_id == 1 -> k2t1!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS - :: else -> k2t2!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS - fi - } - - goto Select_state -} - -/** - The Database contains a timer that acts as a clock sending signals to - tenants when rotation has been executed. Rotation is not time-sensitive - such that it is affected by distributed clock-sync issues, so it could - also be seen as a tenant quering a clock to see if the scheduled rotation - that could be part of the metadata in the KEK information available to - the tenant has taken place. - */ -proctype Database() { - - mtype msg - unsigned kek_id : 3, i : 3, tenant_id : 2 - KEK p_KEKs[NUM_KEKS] - bool accessed - - atomic { - i = 0 - for (i : 0 .. NUM_KEKS-1) { - p_KEKs[i].id = i+1 - p_KEKs[i].version = 1 - } - } - - Main: - - atomic { - if - :: !done -> timer++ - :: else -> skip - fi - - if // Cache timer - :: timer%CACHE_CLEAR == 0 -> - clear_cache = true - :: else -> skip - fi - - if // Rotation 1 - :: timer%ROT_KEK_1 == 0 -> - p_KEKs[0].version++ - - if - :: p_KEKs[0].assigned_to == 1 -> - db2t1!rot_KEK, p_KEKs[0].id+ENC_DUMMY - :: p_KEKs[0].assigned_to == 2 -> - db2t2!rot_KEK, p_KEKs[0].id+ENC_DUMMY - :: p_KEKs[0].assigned_to == 3 -> - db2t2!rot_KEK, p_KEKs[0].id+ENC_DUMMY - db2t1!rot_KEK, p_KEKs[0].id+ENC_DUMMY - :: else -> skip - fi - :: else -> skip - fi - - if // Rotation 2 - :: timer%ROT_KEK_2 == 0 -> - p_KEKs[1].version++ - - if - :: p_KEKs[1].assigned_to == 1 -> - db2t1!rot_KEK, p_KEKs[1].id+ENC_DUMMY - :: p_KEKs[1].assigned_to == 2 -> - db2t2!rot_KEK, p_KEKs[1].id+ENC_DUMMY - :: p_KEKs[1].assigned_to == 3 -> - db2t2!rot_KEK, p_KEKs[1].id+ENC_DUMMY - db2t1!rot_KEK, p_KEKs[1].id+ENC_DUMMY - :: else -> skip - fi - :: else -> skip - fi - - if // Rotation 3 - :: timer%ROT_KEK_3 == 0 -> - p_KEKs[2].version++ - - if - :: p_KEKs[2].assigned_to == 1 -> - db2t1!rot_KEK, p_KEKs[2].id+ENC_DUMMY - :: p_KEKs[2].assigned_to == 2 -> - db2t2!rot_KEK, p_KEKs[2].id+ENC_DUMMY - :: p_KEKs[2].assigned_to == 3 -> - db2t2!rot_KEK, p_KEKs[2].id+ENC_DUMMY - db2t1!rot_KEK, p_KEKs[2].id+ENC_DUMMY - :: else -> skip - fi - :: else -> skip - fi - - if // Rotation 4 - :: timer%ROT_KEK_4 == 0 -> - p_KEKs[3].version++ - - if - :: p_KEKs[3].assigned_to == 1 -> - db2t1!rot_KEK, p_KEKs[3].id+ENC_DUMMY - :: p_KEKs[3].assigned_to == 2 -> - db2t2!rot_KEK, p_KEKs[3].id+ENC_DUMMY - :: p_KEKs[3].assigned_to == 3 -> - db2t2!rot_KEK, p_KEKs[3].id+ENC_DUMMY - db2t1!rot_KEK, p_KEKs[3].id+ENC_DUMMY - :: else -> skip - fi - :: else -> skip - fi - } - - if - :: atomic{ k2db?[msg, kek_id, tenant_id] -> k2db?msg, kek_id, tenant_id } -> - if - :: (msg == e_DEK || msg == d_DEK || msg == ass_KEK || msg == re_DEK) -> goto Access_KEK - :: else -> goto Deny_request - fi - :: else -> skip - fi - - goto Main - - Access_KEK: - - atomic { - accessed = false - i = 0 - for (i : 0 .. NUM_KEKS-1) { - if - :: p_KEKs[i].id == kek_id -> - - timer++ - - if - :: msg == ass_KEK -> - if - :: p_KEKs[i].assigned_to > 0 -> p_KEKs[i].assigned_to = 3 - :: else -> p_KEKs[i].assigned_to = tenant_id - fi - :: else -> skip - fi - - db2k!msg, p_KEKs[i].id, p_KEKs[i].version, p_KEKs[i].assigned_to - accessed = true - :: else -> skip - fi - } - } - - if - :: accessed -> goto Main - :: else -> goto Deny_request - fi - - Deny_request: - - atomic { db2k!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS } - - goto Main - -} - -/* - ## Access Control Info ## - - tenant_x_kek - Relations between tenants and KEKs - - 0 - No relation - 1 - KEK relation exists - - Indexation is a 2d array inside a single array - -*/ - -proctype AccessControl() -{ - mtype msg - unsigned kek_id : 3, tenant_id : 2, idx : 4, i : 3, num_assigned : 3 - bit grant - bool authorized - byte tnt_x_kek[NUM_TENANTS*NUM_KEKS] - - Select_state: - - k2ac?msg, kek_id, tenant_id, grant - // do - // :: k2ac?msg, kek_id, tenant_id, grant -> break - // :: timeout -> goto Select_state - // od - - if - :: msg == ass_KEK -> goto Assign_KEK - :: msg == d_DEK || msg == e_DEK || msg == re_DEK -> goto Authorize - // :: else -> goto Deny_request - :: else -> skip - fi - - goto Select_state - - Assign_KEK: - - atomic { - num_assigned = 0 - i = 0 - authorized = true - do - :: i < NUM_KEKS -> i++ - if - :: tnt_x_kek[(tenant_id-1)*NUM_KEKS+i-1] > 0 -> num_assigned++ - :: else -> skip - fi - - if - :: num_assigned >= ASS_MAX -> authorized = false -> break - :: SAME_KEK_ASSIGNED && num_assigned >= SAME_KEK_MAX -> authorized = false -> break - :: else -> skip - fi - :: else -> break - od - num_assigned = 0 - i = 0 - } - - if - :: !authorized -> goto Deny_request - :: else -> skip - fi - - d_step { - idx = (tenant_id - 1) * NUM_KEKS + (kek_id - 1) - - if - :: tnt_x_kek[idx] > 1 -> authorized = false - :: else -> tnt_x_kek[idx] = 1 - fi - idx = 0 - } - - if - :: !authorized -> goto Deny_request - :: else -> skip - fi - - goto Ack_request - - Authorize: - - atomic { - if - :: kek_id == 0 -> authorized = false - :: else -> skip - fi - - if - :: authorized -> - idx = (tenant_id - 1) * NUM_KEKS + (kek_id - 1) - - if - :: idx >= 0 && idx < NUM_TENANTS*NUM_KEKS -> - if - :: tnt_x_kek[idx] < 1 -> - if - :: grant == VALID_GRANT -> - idx = kek_id - 1 - if - :: tnt_x_kek[idx] < 1 -> authorized = false - :: else -> skip - fi - :: else -> authorized = false - fi - :: else -> skip - fi - :: else -> authorized = false - fi - :: else -> skip - fi - - idx = 0 - } - - if - :: !authorized -> goto Deny_request - :: else -> skip - fi - - goto Ack_request - - Ack_request: - - atomic { ac2k!ack } - - goto Select_state - - Deny_request: - - atomic { ac2k!deny } - - goto Select_state - - Terminate: - -} diff --git a/SPIN-verification/model.pml b/SPIN-verification/model.pml index 9b14bbc..9033f5d 100644 --- a/SPIN-verification/model.pml +++ b/SPIN-verification/model.pml @@ -25,19 +25,18 @@ THE SOFTWARE. /** MODELS - 1=Initial Model with some modifications 2=A 3=B 4=C 5=D In the paper. + 1=A 2=B 3=C 4=D In the paper. - 1: Full operations. 2: Assignemnt and Encryption. - 3: Decryption - 4: Re-Encryption of encrypted DEKs - 5: Tenant 1 assignment and encryption, Tenant 2 only Decrypts encrypted DEKs received from Tenant 1 with different grants. + 3: Decryption after assignment and encryption has been finalized + 4: Re-Encryption of envelopes after assignment and encryption has been finalized + 5: Tenant 1 assignment and encryption then invalid credentials, Tenant 2 only Decrypts envelopes received from Tenant 1 with different grants. - If MODEL == 2 then IS_MODEL_2 == 1 - If MODEL != 2 then IS_MODEL_2 == 0 + If MODEL == 1 then IS_MODEL_1 == 1 + If MODEL != 1 then IS_MODEL_1 == 0 */ -#define MODEL 4 -#define IS_MODEL_2 0 +#define MODEL 2 +#define IS_MODEL_1 0 #define NUM_DEKS 1 #define NUM_KEKS 2 @@ -51,7 +50,7 @@ THE SOFTWARE. #define K2T_MAX 1 // MODEL 2 -#if IS_MODEL_2 +#if IS_MODEL_1 #define K2AC_MAX 2 #define AC2K_MAX 2 #define K2DB_MAX 2 @@ -67,7 +66,6 @@ THE SOFTWARE. #define REQ_MAX 2 - typedef KEK { unsigned id : 3 bit version @@ -120,19 +118,19 @@ local bool cache_cleared bool p_assigned_1, p_assigned_2, p_enc_1 bool p_conf = true, p_int = true, p_sync = true, p_protocol = true, p_cache = true local bool p_rotated_1 , p_rotated_2, p_enc_2, auth_ks, auth_db, auth_ac, auth_t1, auth_t2, grant_t2 -local unsigned m4_KEK_t1 : 4, m4_KEK_t2 : 4 +local unsigned m3_KEK_t1 : 4, m3_KEK_t2 : 4 // LTL claims -// ltl safety { [](p_conf && p_int && p_protocol && p_sync && p_cache && !p_authentic && (Tenant_1[1]@Decrypt_receive -> p_enc_1) && -// (Tenant_2[2]@Decrypt_receive -> (p_enc_2 || (grant_t2 && p_enc_1))) && (p_enc_1 -> p_assigned_1) && (p_enc_2 -> p_assigned_2 )) && -// (Tenant_1[1]@Recrypt_Receive -> p_enc_1) && (Tenant_2[2]@Recrypt_Receive -> p_enc_2) -// } +ltl safety { [](p_conf && p_int && p_protocol && p_sync && p_cache && !p_authentic && (Tenant_1[1]@Decrypt_receive -> p_enc_1) && + (Tenant_2[2]@Decrypt_receive -> (p_enc_2 || (grant_t2 && p_enc_1))) && (p_enc_1 -> p_assigned_1) && (p_enc_2 -> p_assigned_2 )) && + (Tenant_1[1]@Recrypt_Receive -> p_enc_1) && (Tenant_2[2]@Recrypt_Receive -> p_enc_2) + } -// ltl liveness_model_2 { ([]<>(p_rotated_1) && []<>(!p_rotated_1)) && ([]<>(p_rotated_2) && []<>(!p_rotated_2)) } -ltl liveness_model_4 { ([]<>(m4_KEK_t1 == 6) && []<>(m4_KEK_t1 == 8)) && ([]<>(m4_KEK_t2 == 7) && []<>(m4_KEK_t2 == 9)) } -// ltl liveness_model_3 { ([]<>(Tenant_2[2]@Decrypt_receive) && []<>(Tenant_1[1]@Decrypt_receive)) && ((Database[3]@Access_KEK) -> <>(Database[3]@Cleanup)) } -// ltl liveness_model_5 {<>[]!(Tenant_1[1]@Encrypt_receive || Tenant_1[1]@Assign_KEK_receive) && []<>(Tenant_2[2]@Decrypt_receive) && ((Database[3]@Access_KEK) -> <>(Database[3]@Cleanup))} +ltl liveness_model_2 { ([]<>(p_rotated_1) && []<>(!p_rotated_1)) && ([]<>(p_rotated_2) && []<>(!p_rotated_2)) } +ltl liveness_model_4 { ([]<>(m3_KEK_t1 == 6) && []<>(m3_KEK_t1 == 8)) && ([]<>(m3_KEK_t2 == 7) && []<>(m3_KEK_t2 == 9)) } +ltl liveness_model_3 { ([]<>(Tenant_2[2]@Decrypt_receive) && []<>(Tenant_1[1]@Decrypt_receive)) && ((Database[3]@Access_KEK) -> <>(Database[3]@Cleanup)) } +ltl liveness_model_5 {<>[]!(Tenant_1[1]@Encrypt_receive || Tenant_1[1]@Assign_KEK_receive) && []<>(Tenant_2[2]@Decrypt_receive) && ((Database[3]@Access_KEK) -> <>(Database[3]@Cleanup))} @@ -189,18 +187,6 @@ proctype Tenant_1() do :: MODEL == 1 -> - do - :: !(denied && p_assigned_1) -> - t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, 1 -> break - :: !(denied && !p_assigned_1) -> - t12k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, 1 -> break - :: !(denied && !p_enc_1) -> - t12k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.ref_version, id, 1 -> break - :: !(denied && !p_enc_1) -> - t12k!re_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, EMPTY_PASS, id, 1 -> break - od - break - :: MODEL == 2 -> do :: !(denied && p_assigned_1) -> t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, 1 -> break @@ -210,7 +196,7 @@ proctype Tenant_1() t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, 0, 1 -> break od break - :: MODEL == 3 -> + :: MODEL == 2 -> if :: p_enc_1 -> encrypted_DEK.ref_version = !encrypted_DEK.ref_version @@ -226,17 +212,17 @@ proctype Tenant_1() t12k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.ref_version, id, 1 -> break od break - :: MODEL == 4 -> + :: MODEL == 3 -> do :: !p_assigned_1 -> t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, 1 -> break :: p_assigned_1 && !p_enc_1 -> t12k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, 1 -> break :: !(denied && !p_enc_1) -> - t12k!re_DEK, EMPTY_PASS, m4_KEK_t1, encrypted_DEK.id, encrypted_DEK.ref_version, id, 1 -> break + t12k!re_DEK, EMPTY_PASS, m3_KEK_t1, encrypted_DEK.id, encrypted_DEK.ref_version, id, 1 -> break od break - :: MODEL == 5 -> + :: MODEL == 4 -> do :: !p_assigned_1 -> t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, 1 -> break @@ -335,7 +321,7 @@ proctype Tenant_1() encrypted_DEK.ref_version = temp_e_dek.ref_version if - :: MODEL == 4 -> m4_KEK_t1 = encrypted_DEK.ref_id + :: MODEL == 3 -> m3_KEK_t1 = encrypted_DEK.ref_id :: else -> skip fi @@ -362,10 +348,10 @@ proctype Tenant_1() encrypted_DEK.ref_version = temp_e_dek.ref_version if - :: MODEL == 4 -> + :: MODEL == 3 -> if - :: encrypted_DEK.ref_id == 6 -> m4_KEK_t1 = 8 - :: else -> m4_KEK_t1 = 6 + :: encrypted_DEK.ref_id == 6 -> m3_KEK_t1 = 8 + :: else -> m3_KEK_t1 = 6 fi :: else -> skip fi @@ -423,18 +409,6 @@ proctype Tenant_2() do :: MODEL == 1 -> - do - :: !(denied && p_assigned_2) -> - t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant_t2, 1 -> break - :: !(denied && !p_assigned_2) -> - t22k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, grant_t2, 1 -> break - :: !(denied && !p_enc_2) -> - t22k!d_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, encrypted_DEK.ref_version, id, grant_t2, 1 -> break - :: !(denied && !p_enc_2) -> - t22k!re_DEK, EMPTY_PASS, encrypted_DEK.ref_id, encrypted_DEK.id, EMPTY_PASS, id, grant_t2, 1 -> break - od - break - :: MODEL == 2 -> do :: !(denied && p_assigned_2) -> t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant_t2, 1 -> break @@ -444,7 +418,7 @@ proctype Tenant_2() t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, 0, grant_t2, 1 -> break od break - :: MODEL == 3 -> + :: MODEL == 2 -> if :: p_enc_2 -> encrypted_DEK.ref_version = !encrypted_DEK.ref_version @@ -461,17 +435,17 @@ proctype Tenant_2() od break - :: MODEL == 4 -> + :: MODEL == 3 -> do :: !p_assigned_2 -> t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant_t2, 1 -> break :: p_assigned_2 && !p_enc_2 -> t22k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, grant_t2, 1 -> break :: !(denied && !p_enc_2) - t22k!re_DEK, EMPTY_PASS, m4_KEK_t2, encrypted_DEK.id, encrypted_DEK.ref_version, id, grant_t2, 1 -> break + t22k!re_DEK, EMPTY_PASS, m3_KEK_t2, encrypted_DEK.id, encrypted_DEK.ref_version, id, grant_t2, 1 -> break od break - :: MODEL == 5 -> + :: MODEL == 4 -> received_e_DEK.ref_version = !received_e_DEK.ref_version @@ -579,7 +553,7 @@ proctype Tenant_2() encrypted_DEK.ref_version = temp_e_dek.ref_version if - :: MODEL == 4 -> m4_KEK_t2 = encrypted_DEK.ref_id + :: MODEL == 3 -> m3_KEK_t2 = encrypted_DEK.ref_id :: else -> skip fi @@ -607,10 +581,10 @@ proctype Tenant_2() encrypted_DEK.ref_version = temp_e_dek.ref_version if - :: MODEL == 4 -> + :: MODEL == 3 -> if - :: encrypted_DEK.ref_id == 7 -> m4_KEK_t2 = 9 - :: else -> m4_KEK_t2 = 7 + :: encrypted_DEK.ref_id == 7 -> m3_KEK_t2 = 9 + :: else -> m3_KEK_t2 = 7 fi :: else -> skip fi @@ -657,7 +631,7 @@ proctype Keystore() do - :: MODEL == 3 || MODEL == 5 -> cache_cleared = !cache_cleared -> break + :: MODEL == 2 || MODEL == 4 -> cache_cleared = !cache_cleared -> break :: else -> cache_cleared = cache_cleared -> break od // exit_atomic = true @@ -777,7 +751,7 @@ proctype Keystore() atomic { if - :: MODEL == 2 -> + :: MODEL == 1 -> k2ac_buff < K2AC_MAX k2ac!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, 0, step+1 k2ac_buff++ @@ -795,7 +769,7 @@ proctype Keystore() atomic { if - :: MODEL == 2 -> + :: MODEL == 1 -> k2db_buff < K2DB_MAX k2db!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, 0, step+1 k2db_buff++ @@ -1054,7 +1028,7 @@ proctype Database() { p_KEKs[i].version = !p_KEKs[i].version if - :: MODEL == 2 -> + :: MODEL == 1 -> db2k_buff < DB2K_MAX db2k!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, 0, step+1 db2k_buff++ @@ -1208,7 +1182,7 @@ proctype AccessControl() fi if - :: MODEL == 2 -> + :: MODEL == 1 -> ac2k_buff < AC2K_MAX ac2k!deny, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, 0, step+1 ac2k_buff++ From 91b9e022f4c87efb517dc89882ed17e72d9c3062 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Tue, 4 Jun 2024 13:19:09 +0200 Subject: [PATCH 23/30] edited README --- SPIN-verification/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SPIN-verification/README.md b/SPIN-verification/README.md index be0a86a..e3d0d27 100644 --- a/SPIN-verification/README.md +++ b/SPIN-verification/README.md @@ -30,8 +30,8 @@ gcc -DMEMLIM=N -O2 -DXUSAFE -DCOLLAPSE -DNFAIR=3 (-DSAFETY) -w -o pan pan.c
**Verify**
-./pan -mN (-a -f (-N claim) )
-In -mN, N is an integer for max depth, however -N is a flag to specify which claim to verify. -Parenthesis used when verifying liveness.
+./pan -mN (-a -f) (-N claim)
+In -mN, N is an integer for max depth, however -N is a flag to specify which claim to verify, e.g ./pan -m1000000 -N safety
+-a -f used when verifying liveness.
From 5187adc7447339aa84db599bcfcac31351896de1 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Tue, 4 Jun 2024 13:19:46 +0200 Subject: [PATCH 24/30] typo in README --- SPIN-verification/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SPIN-verification/README.md b/SPIN-verification/README.md index e3d0d27..1f77bfe 100644 --- a/SPIN-verification/README.md +++ b/SPIN-verification/README.md @@ -18,7 +18,7 @@ If MODEL == 1 then IS_MODEL_1 == 1
If MODEL != 1 then IS_MODEL_1 == 0
## To Run and Verify -Most of this can be done with an external tool such as iSSPIN, additional information found [here](https://spinroot.com/spin/Man/README.html).
+Most of this can be done with an external tool such as iSPIN, additional information found [here](https://spinroot.com/spin/Man/README.html).
**Run Code**
spin -T model.pml - Regular run that will halt on error and print any statements in the code.
From 00b7f20113b52c2e927ef00c43a4b4983a7d7b08 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Tue, 4 Jun 2024 13:22:07 +0200 Subject: [PATCH 25/30] changed names of liveness claims --- SPIN-verification/model.pml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SPIN-verification/model.pml b/SPIN-verification/model.pml index 9033f5d..0746e17 100644 --- a/SPIN-verification/model.pml +++ b/SPIN-verification/model.pml @@ -127,10 +127,10 @@ ltl safety { [](p_conf && p_int && p_protocol && p_sync && p_cache && !p_authent } -ltl liveness_model_2 { ([]<>(p_rotated_1) && []<>(!p_rotated_1)) && ([]<>(p_rotated_2) && []<>(!p_rotated_2)) } -ltl liveness_model_4 { ([]<>(m3_KEK_t1 == 6) && []<>(m3_KEK_t1 == 8)) && ([]<>(m3_KEK_t2 == 7) && []<>(m3_KEK_t2 == 9)) } -ltl liveness_model_3 { ([]<>(Tenant_2[2]@Decrypt_receive) && []<>(Tenant_1[1]@Decrypt_receive)) && ((Database[3]@Access_KEK) -> <>(Database[3]@Cleanup)) } -ltl liveness_model_5 {<>[]!(Tenant_1[1]@Encrypt_receive || Tenant_1[1]@Assign_KEK_receive) && []<>(Tenant_2[2]@Decrypt_receive) && ((Database[3]@Access_KEK) -> <>(Database[3]@Cleanup))} +ltl liveness_model_1 { ([]<>(p_rotated_1) && []<>(!p_rotated_1)) && ([]<>(p_rotated_2) && []<>(!p_rotated_2)) } +ltl liveness_model_2 { ([]<>(Tenant_2[2]@Decrypt_receive) && []<>(Tenant_1[1]@Decrypt_receive)) && ((Database[3]@Access_KEK) -> <>(Database[3]@Cleanup)) } +ltl liveness_model_3 { ([]<>(m3_KEK_t1 == 6) && []<>(m3_KEK_t1 == 8)) && ([]<>(m3_KEK_t2 == 7) && []<>(m3_KEK_t2 == 9)) } +ltl liveness_model_4 {<>[]!(Tenant_1[1]@Encrypt_receive || Tenant_1[1]@Assign_KEK_receive) && []<>(Tenant_2[2]@Decrypt_receive) && ((Database[3]@Access_KEK) -> <>(Database[3]@Cleanup))} From 603ce57a546d10ae61e3d66a5b8e8547420a982d Mon Sep 17 00:00:00 2001 From: kibasaur Date: Sat, 8 Jun 2024 11:34:06 +0200 Subject: [PATCH 26/30] model 2 and 4 reverified --- SPIN-verification/model.pml | 95 ++++++++++++++++++++++++++++++++----- 1 file changed, 84 insertions(+), 11 deletions(-) diff --git a/SPIN-verification/model.pml b/SPIN-verification/model.pml index 0746e17..f041758 100644 --- a/SPIN-verification/model.pml +++ b/SPIN-verification/model.pml @@ -34,6 +34,8 @@ THE SOFTWARE. If MODEL == 1 then IS_MODEL_1 == 1 If MODEL != 1 then IS_MODEL_1 == 0 + + Model 3 uses dek_id field in messages as an additional kek_ref field. */ #define MODEL 2 #define IS_MODEL_1 0 @@ -128,9 +130,9 @@ ltl safety { [](p_conf && p_int && p_protocol && p_sync && p_cache && !p_authent ltl liveness_model_1 { ([]<>(p_rotated_1) && []<>(!p_rotated_1)) && ([]<>(p_rotated_2) && []<>(!p_rotated_2)) } -ltl liveness_model_2 { ([]<>(Tenant_2[2]@Decrypt_receive) && []<>(Tenant_1[1]@Decrypt_receive)) && ((Database[3]@Access_KEK) -> <>(Database[3]@Cleanup)) } +ltl liveness_model_2 { ([]<>(Tenant_2[2]@Decrypt_receive) && []<>(Tenant_1[1]@Decrypt_receive)) && ((Database[3]@Cleanup) -> <>(db2k == 0)) } ltl liveness_model_3 { ([]<>(m3_KEK_t1 == 6) && []<>(m3_KEK_t1 == 8)) && ([]<>(m3_KEK_t2 == 7) && []<>(m3_KEK_t2 == 9)) } -ltl liveness_model_4 {<>[]!(Tenant_1[1]@Encrypt_receive || Tenant_1[1]@Assign_KEK_receive) && []<>(Tenant_2[2]@Decrypt_receive) && ((Database[3]@Access_KEK) -> <>(Database[3]@Cleanup))} +ltl liveness_model_4 {<>[]!(Tenant_1[1]@Encrypt_receive || Tenant_1[1]@Assign_KEK_receive) && []<>(Tenant_1[1]@Receive) && []<>(Tenant_2[2]@Decrypt_receive) && ((Database[3]@Cleanup) -> <>(db2k == 0))} @@ -219,7 +221,7 @@ proctype Tenant_1() :: p_assigned_1 && !p_enc_1 -> t12k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, 1 -> break :: !(denied && !p_enc_1) -> - t12k!re_DEK, EMPTY_PASS, m3_KEK_t1, encrypted_DEK.id, encrypted_DEK.ref_version, id, 1 -> break + t12k!re_DEK, encrypted_DEK.ref_id, m3_KEK_t1, encrypted_DEK.id, encrypted_DEK.ref_version, id, 1 -> break od break :: MODEL == 4 -> @@ -442,7 +444,7 @@ proctype Tenant_2() :: p_assigned_2 && !p_enc_2 -> t22k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, grant_t2, 1 -> break :: !(denied && !p_enc_2) - t22k!re_DEK, EMPTY_PASS, m3_KEK_t2, encrypted_DEK.id, encrypted_DEK.ref_version, id, grant_t2, 1 -> break + t22k!re_DEK, encrypted_DEK.ref_id, m3_KEK_t2, encrypted_DEK.id, encrypted_DEK.ref_version, id, grant_t2, 1 -> break od break :: MODEL == 4 -> @@ -612,13 +614,13 @@ proctype Tenant_2() proctype Keystore() { mtype msg = deny - unsigned dek_id : 3, kek_id : 3, kek_ref : 4, tenant_id : 3, grant : 2, kek_version : 1, step : 3, array_size : 3 = 4 + unsigned dek_id : 4, kek_id : 3, kek_ref : 4, tenant_id : 3, grant : 2, kek_version : 1, step : 3, array_size : 3 = 4 bit id = 1 bit last_enc_1, last_enc_2, turn bool db_skip_1, db_skip_2 if - :: MODEL != 4 -> + :: MODEL != 3 -> array_size = NUM_KEKS :: else -> skip fi @@ -767,7 +769,10 @@ proctype Keystore() Send_to_Database: atomic { - + if + :: msg == re_DEK -> dek_id = dek_id-ENC_DUMMY + :: else -> skip + fi if :: MODEL == 1 -> k2db_buff < K2DB_MAX @@ -824,7 +829,7 @@ proctype Keystore() Decrypt_return: atomic { - + if :: tenant_id == 1 -> k2t1_buff < K2T_MAX @@ -863,6 +868,7 @@ proctype Keystore() goto Cleanup } + //Also used for Recrypt Encrypt_return: // From Database to Tenant @@ -870,6 +876,33 @@ proctype Keystore() if :: msg == e_DEK -> temp_e_dek.id = dek_id+ENC_DUMMY + :: msg == re_DEK && dek_id != kek_id -> + db2k_buff > 0 + db2k?msg, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, kek_version, auth_ks, step + db2k_buff-- + // Update KEKs + if + :: msg == deny -> goto Deny_request + :: else -> + v_KEKs[kek_id-1].id = kek_id + v_KEKs[kek_id-1].version = kek_version + fi + + // ROTATION CHECK + if + :: tenant_id == 1 -> + if + :: v_KEKs[kek_id-1].version == 0 -> + p_rotated_1 = true + :: else -> p_rotated_1 = false + fi + :: tenant_id == 2 -> + if + :: v_KEKs[kek_id-1].version == 0 -> + p_rotated_2 = true + :: else -> p_rotated_2 = false + fi + fi :: else -> skip fi @@ -967,7 +1000,7 @@ proctype Database() { bit id = 1 if - :: MODEL != 4 -> + :: MODEL != 3 -> array_size = NUM_KEKS :: else -> skip fi @@ -1013,7 +1046,11 @@ proctype Database() { i = 0 for (i : 0 .. array_size-1) { if - :: p_KEKs[i].id == kek_id -> goto Send + :: p_KEKs[i].id == kek_id -> + if + :: msg == re_DEK -> goto Send_Recrypt + :: else -> goto Send + fi :: else -> skip fi } @@ -1041,6 +1078,30 @@ proctype Database() { goto Cleanup } + Send_Recrypt: + atomic { + + if + :: dek_id != kek_id && i > 1 -> i = i-2 + :: dek_id != kek_id && i < 2 -> i = i+2 + :: else -> goto Send + fi + + p_KEKs[i].version = !p_KEKs[i].version + + db2k_buff < DB2K_MAX + db2k!msg, kek_id, p_KEKs[i].id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, p_KEKs[i].version, id, step+1 + db2k_buff++ + + if + :: dek_id != kek_id && i > 1 -> i = i-2 + :: dek_id != kek_id && i < 2 -> i = i+2 + :: else -> skip + fi + + goto Send + } + Deny_request: atomic { @@ -1078,7 +1139,7 @@ proctype Database() { proctype AccessControl() { mtype msg = deny - unsigned kek_ref : 4, tenant_id : 3, dek_id : 3, grant : 1, assigned_1 : 3, assigned_2 : 3, step : 3 + unsigned kek_ref : 4, tenant_id : 3, dek_id : 4, grant : 1, assigned_1 : 3, assigned_2 : 3, step : 3 bit id = 1 E_DEK temp_e_dek @@ -1171,6 +1232,18 @@ proctype AccessControl() :: else -> skip fi + if + :: msg == re_DEK -> + if + :: tenant_id == 1 && (kek_ref != assigned_1 && dek_id != assigned_1 + 2 && dek_id != assigned_1 && kek_ref != assigned_1 + 2) -> + goto Deny_request + :: tenant_id == 2 && (kek_ref != assigned_2 && dek_id != assigned_2 + 2 && dek_id != assigned_2 && kek_ref != assigned_2 + 2) -> + goto Deny_request + :: else -> skip + fi + :: else -> skip + fi + if :: tenant_id == 1 && (kek_ref != assigned_1 && kek_ref != assigned_1 + 2) -> goto Deny_request :: tenant_id == 2 && (kek_ref != assigned_2 && kek_ref != assigned_2 + 2) -> From 5fbdff6f18ace14d1e7ed8e0ec11913ab8b54484 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Fri, 26 Jul 2024 13:15:47 +0200 Subject: [PATCH 27/30] Message vocabulary changed, cache exclusive or added, keystore database step edited --- SPIN-verification/model.pml | 123 ++++++++++++++++++++---------------- 1 file changed, 69 insertions(+), 54 deletions(-) diff --git a/SPIN-verification/model.pml b/SPIN-verification/model.pml index f041758..6c24d86 100644 --- a/SPIN-verification/model.pml +++ b/SPIN-verification/model.pml @@ -37,8 +37,8 @@ THE SOFTWARE. Model 3 uses dek_id field in messages as an additional kek_ref field. */ -#define MODEL 2 -#define IS_MODEL_1 0 +#define MODEL 1 +#define IS_MODEL_1 1 #define NUM_DEKS 1 #define NUM_KEKS 2 @@ -49,7 +49,6 @@ THE SOFTWARE. // CHANNEL CAPS #define T2K_MAX 1 -#define K2T_MAX 1 // MODEL 2 #if IS_MODEL_1 @@ -57,11 +56,13 @@ THE SOFTWARE. #define AC2K_MAX 2 #define K2DB_MAX 2 #define DB2K_MAX 2 + #define K2T_MAX 2 #else #define K2AC_MAX 1 #define AC2K_MAX 1 #define K2DB_MAX 1 #define DB2K_MAX 1 + #define K2T_MAX 1 #endif // REQUEST LIMIT OF CONCURRENT PROCESSING IN KEYSTORE @@ -81,7 +82,7 @@ typedef E_DEK { /* Encrypted */ bit ref_version } -mtype = { e_DEK, d_DEK, re_DEK, ass_KEK, ass_KEK2, deny } +mtype = { e_DEK, d_DEK, re_DEK, a_KEK, a_KEK2, deny } // t1: Tenant 1 // t2: Tenant 2 @@ -115,7 +116,7 @@ local bool cache_cleared // LTL variables #define p_authentic (((Keystore[4]@Send_to_Access_Control || Keystore[4]@Send_to_Database || Keystore[4]@Encrypt_return || Keystore[4]@Decrypt_return || Keystore[4]@Assign_KEK_return) && !auth_ks) || \ - (Database[3]@Access_KEK && !auth_db) || (AccessControl[5]@Select_state && !auth_ac) || (Tenant_1[1]@Receive && !auth_t1) || (Tenant_2[2]@Receive && !auth_t2)) + (Database[3]@Access_KEK && !auth_db) || (AccessControl[5]@Select_state && !auth_ac)) bool p_assigned_1, p_assigned_2, p_enc_1 bool p_conf = true, p_int = true, p_sync = true, p_protocol = true, p_cache = true @@ -130,9 +131,9 @@ ltl safety { [](p_conf && p_int && p_protocol && p_sync && p_cache && !p_authent ltl liveness_model_1 { ([]<>(p_rotated_1) && []<>(!p_rotated_1)) && ([]<>(p_rotated_2) && []<>(!p_rotated_2)) } -ltl liveness_model_2 { ([]<>(Tenant_2[2]@Decrypt_receive) && []<>(Tenant_1[1]@Decrypt_receive)) && ((Database[3]@Cleanup) -> <>(db2k == 0)) } +ltl liveness_model_2 { ([]<>(Tenant_2[2]@Decrypt_receive) && []<>(Tenant_1[1]@Decrypt_receive)) && ((Database[3]@Access_KEK) -> <>(Database[3]@Cleanup)) && ((Database[3]@Cleanup) -> <>(db2k == 0)) } ltl liveness_model_3 { ([]<>(m3_KEK_t1 == 6) && []<>(m3_KEK_t1 == 8)) && ([]<>(m3_KEK_t2 == 7) && []<>(m3_KEK_t2 == 9)) } -ltl liveness_model_4 {<>[]!(Tenant_1[1]@Encrypt_receive || Tenant_1[1]@Assign_KEK_receive) && []<>(Tenant_1[1]@Receive) && []<>(Tenant_2[2]@Decrypt_receive) && ((Database[3]@Cleanup) -> <>(db2k == 0))} +ltl liveness_model_4 {<>[]!(Tenant_1[1]@Encrypt_receive || Tenant_1[1]@Assign_KEK_receive) && []<>(Tenant_1[1]@Receive) && []<>(Tenant_2[2]@Decrypt_receive) && ((Database[3]@Access_KEK) -> <>(Database[3]@Cleanup)) && ((Database[3]@Cleanup) -> <>(db2k == 0))} @@ -191,11 +192,11 @@ proctype Tenant_1() :: MODEL == 1 -> do :: !(denied && p_assigned_1) -> - t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, 1 -> break + t12k!a_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, 1 -> break :: !(denied && !p_assigned_1) -> t12k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, 1 -> break :: !denied -> - t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, 0, 1 -> break + t12k!a_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, 0, 1 -> break od break :: MODEL == 2 -> @@ -207,7 +208,7 @@ proctype Tenant_1() do :: !p_assigned_1 -> - t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, 1 -> break + t12k!a_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, 1 -> break :: p_assigned_1 && !p_enc_1 -> t12k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, 1 -> break :: !(denied && !p_enc_1) -> @@ -217,7 +218,7 @@ proctype Tenant_1() :: MODEL == 3 -> do :: !p_assigned_1 -> - t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, 1 -> break + t12k!a_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, 1 -> break :: p_assigned_1 && !p_enc_1 -> t12k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, 1 -> break :: !(denied && !p_enc_1) -> @@ -227,11 +228,11 @@ proctype Tenant_1() :: MODEL == 4 -> do :: !p_assigned_1 -> - t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, 1 -> break + t12k!a_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, 1 -> break :: p_assigned_1 && !p_enc_1 -> t12k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, 1 -> break :: p_enc_1 -> - t12k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, 0, 1 -> break + t12k!a_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, 0, 1 -> break od break od @@ -251,19 +252,19 @@ proctype Tenant_1() if :: msg == deny -> - denied = true + denied = true - if - :: (step % 2) != 0 -> p_protocol = false - :: else -> skip - fi + if + :: (step % 2) != 0 -> p_protocol = false + :: else -> skip + fi :: else -> denied = false if - :: msg == ass_KEK -> goto Assign_KEK_receive + :: msg == a_KEK -> goto Assign_KEK_receive :: msg == d_DEK -> goto Decrypt_receive :: msg == e_DEK -> goto Encrypt_receive :: msg == re_DEK -> goto Recrypt_Receive @@ -413,11 +414,11 @@ proctype Tenant_2() :: MODEL == 1 -> do :: !(denied && p_assigned_2) -> - t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant_t2, 1 -> break + t22k!a_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant_t2, 1 -> break :: !(denied && !p_assigned_2) -> t22k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, grant_t2, 1 -> break :: !denied -> - t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, 0, grant_t2, 1 -> break + t22k!a_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, 0, grant_t2, 1 -> break od break :: MODEL == 2 -> @@ -429,7 +430,7 @@ proctype Tenant_2() do :: !p_assigned_2 -> - t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant_t2, 1 -> break + t22k!a_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant_t2, 1 -> break :: p_assigned_2 && !p_enc_2 -> t22k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, grant_t2, 1 -> break :: !(denied & !p_enc_2) -> @@ -440,7 +441,7 @@ proctype Tenant_2() :: MODEL == 3 -> do :: !p_assigned_2 -> - t22k!ass_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant_t2, 1 -> break + t22k!a_KEK, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, grant_t2, 1 -> break :: p_assigned_2 && !p_enc_2 -> t22k!e_DEK, dek_id, assigned_KEK, EMPTY_PASS, EMPTY_PASS, id, grant_t2, 1 -> break :: !(denied && !p_enc_2) @@ -494,7 +495,7 @@ proctype Tenant_2() denied = false if - :: msg == ass_KEK -> goto Assign_KEK_receive + :: msg == a_KEK -> goto Assign_KEK_receive :: msg == d_DEK -> goto Decrypt_receive :: msg == e_DEK -> goto Encrypt_receive :: msg == re_DEK -> goto Recrypt_Receive @@ -529,7 +530,7 @@ proctype Tenant_2() // PROTOCOL OR INTEGRITY VIOLATION if :: step != 4 && step != 6 -> p_protocol = false - :: !(dek_id == temp_dek || (grant_t2 && temp_dek == 1))-> p_int = false + :: !(dek_id == temp_dek || (grant_t2 && temp_dek == 1)) -> p_int = false :: else -> skip fi @@ -636,12 +637,11 @@ proctype Keystore() :: MODEL == 2 || MODEL == 4 -> cache_cleared = !cache_cleared -> break :: else -> cache_cleared = cache_cleared -> break od - // exit_atomic = true atomic { do //FROM AC - :: ac2k_buff > 0 && db2k_buff == 0-> ac2k?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, auth_ks, step -> ac2k_buff-- -> + :: ac2k_buff > 0 && db2k_buff == 0 -> ac2k?msg, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, auth_ks, step -> ac2k_buff-- -> // PROTOCOL OR AUTHENTICATION VIOLATION if @@ -649,8 +649,8 @@ proctype Keystore() :: else -> skip fi if - :: msg == ass_KEK2 && step != 7 -> p_protocol = false - :: msg != ass_KEK2 && msg != deny && step != 3 -> p_protocol = false + :: msg == a_KEK2 && step != 7 -> p_protocol = false + :: msg != a_KEK2 && msg != deny && step != 3 -> p_protocol = false :: msg == deny && step != 7 && step != 3 -> p_protocol = false :: else -> skip fi @@ -661,14 +661,14 @@ proctype Keystore() fi do - :: msg == ass_KEK2 -> goto Assign_KEK_return + :: msg == a_KEK2 -> goto Assign_KEK_return :: msg == d_DEK -> goto Decrypt_Database_Check :: msg == deny -> goto Deny_request - :: msg == ass_KEK -> kek_id = tenant_id -> break - :: else -> break + :: msg == a_KEK -> kek_id = tenant_id -> goto Send_to_Database + :: else -> goto Send_to_Database od - goto Send_to_Database + //FROM DB :: db2k_buff > 0 -> db2k?msg, dek_id, kek_id, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, kek_version, auth_ks, step -> db2k_buff-- -> @@ -705,8 +705,8 @@ proctype Keystore() fi do - :: msg == ass_KEK -> - msg = ass_KEK2 + :: msg == a_KEK -> + msg = a_KEK2 kek_ref = kek_id+ENC_DUMMY goto Send_to_Access_Control :: msg == d_DEK -> goto Decrypt_return @@ -810,8 +810,8 @@ proctype Keystore() if :: !(v_KEKs[kek_id-1].version == 1 && temp_e_dek.ref_version == 0) -> if - :: tenant_id == 1 -> p_cache = (db_skip_1 || cache_cleared) - :: tenant_id == 2 -> p_cache = (db_skip_2 || cache_cleared) + :: tenant_id == 1 -> p_cache = (db_skip_1 || cache_cleared) && !(db_skip_1 && cache_cleared) + :: tenant_id == 2 -> p_cache = (db_skip_2 || cache_cleared) && !(db_skip_2 && cache_cleared) fi :: else -> skip fi @@ -856,19 +856,33 @@ proctype Keystore() if :: tenant_id == 1 -> + if + :: MODEL == 1 -> k2t1_buff < K2T_MAX - k2t1!ass_KEK, EMPTY_PASS, kek_ref, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, step+1 + k2t1!a_KEK, EMPTY_PASS, kek_ref, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, 0, step+1 k2t1_buff++ + :: else -> skip + fi + k2t1_buff < K2T_MAX + k2t1!a_KEK, EMPTY_PASS, kek_ref, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, id, step+1 + k2t1_buff++ :: else -> + if + :: MODEL == 1 -> k2t2_buff < K2T_MAX - k2t2!ass_KEK, EMPTY_PASS, kek_ref, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, grant, id, step+1 + k2t2!a_KEK, EMPTY_PASS, kek_ref, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, grant, 0, step+1 k2t2_buff++ + :: else -> skip + fi + k2t2_buff < K2T_MAX + k2t2!a_KEK, EMPTY_PASS, kek_ref, EMPTY_PASS, EMPTY_PASS, EMPTY_PASS, grant, id, step+1 + k2t2_buff++ fi goto Cleanup } - //Also used for Recrypt + // Also used for Recrypt Encrypt_return: // From Database to Tenant @@ -944,7 +958,7 @@ proctype Keystore() :: p_assigned_1 && MODEL == 1 -> // SYNCHRONIZATION VIOLATION if - :: (msg != ass_KEK || msg != ass_KEK2) && kek_ref == 6 -> p_sync = false + :: (msg != a_KEK || msg != a_KEK2) && kek_ref == 6 -> p_sync = false :: else -> skip fi :: else -> skip @@ -957,7 +971,7 @@ proctype Keystore() :: p_assigned_2 && MODEL == 1 -> // SYNCHRONIZATION VIOLATION if - :: (msg != ass_KEK || msg != ass_KEK2) && kek_ref == 7 -> p_sync = false + :: (msg != a_KEK || msg != a_KEK2) && kek_ref == 7 -> p_sync = false :: else -> skip fi :: else -> skip @@ -1029,12 +1043,11 @@ proctype Database() { if :: step != 4 -> p_protocol = false - :: kek_id < 1 && kek_id > 4 -> p_int = false :: else -> skip fi do - :: (msg == e_DEK || msg == d_DEK || msg == ass_KEK || msg == re_DEK) -> goto Access_KEK + :: (msg == e_DEK || msg == d_DEK || msg == a_KEK || msg == re_DEK) -> goto Access_KEK :: else -> goto Deny_request od @@ -1043,6 +1056,7 @@ proctype Database() { Access_KEK: atomic { + i = 0 for (i : 0 .. array_size-1) { if @@ -1060,6 +1074,7 @@ proctype Database() { } Send: + atomic { p_KEKs[i].version = !p_KEKs[i].version @@ -1079,6 +1094,7 @@ proctype Database() { } Send_Recrypt: + atomic { if @@ -1094,9 +1110,8 @@ proctype Database() { db2k_buff++ if - :: dek_id != kek_id && i > 1 -> i = i-2 - :: dek_id != kek_id && i < 2 -> i = i+2 - :: else -> skip + :: i > 1 -> i = i-2 + :: i < 2 -> i = i+2 fi goto Send @@ -1163,8 +1178,8 @@ proctype AccessControl() :: temp_e_dek.id > 0 && temp_e_dek.id < ENC_DUMMY -> p_conf = false :: kek_ref > 0 && kek_ref < ENC_DUMMY -> p_conf = false :: !auth_ac -> goto Cleanup - :: msg != ass_KEK2 && step != 2 -> p_protocol = false - :: msg == ass_KEK2 && step != 6 -> p_protocol = false + :: msg != a_KEK2 && step != 2 -> p_protocol = false + :: msg == a_KEK2 && step != 6 -> p_protocol = false :: else -> skip fi @@ -1175,8 +1190,8 @@ proctype AccessControl() atomic { if - :: msg == ass_KEK -> goto Assign_KEK_authorize - :: msg == ass_KEK2 -> goto Assign_KEK2_authorize + :: msg == a_KEK -> goto Assign_KEK_authorize + :: msg == a_KEK2 -> goto Assign_KEK2_authorize :: (msg == d_DEK || msg == e_DEK || msg == re_DEK) -> goto Authorize :: else -> goto Deny_request fi @@ -1198,7 +1213,7 @@ proctype AccessControl() fi ac2k_buff < AC2K_MAX - ac2k!ass_KEK, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 + ac2k!a_KEK, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 ac2k_buff++ goto Cleanup @@ -1216,7 +1231,7 @@ proctype AccessControl() fi ac2k_buff < AC2K_MAX - ac2k!ass_KEK2, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 + ac2k!a_KEK2, dek_id, kek_ref, temp_e_dek.id, temp_e_dek.ref_version, tenant_id, grant, id, step+1 ac2k_buff++ goto Cleanup @@ -1228,7 +1243,7 @@ proctype AccessControl() atomic { if - :: kek_ref < 6 -> goto Deny_request + :: kek_ref == 0 -> goto Deny_request :: else -> skip fi From 4c39bfeca6e41cfa904a388d0db39f968f62f6b3 Mon Sep 17 00:00:00 2001 From: kibasaur Date: Fri, 9 Aug 2024 16:05:58 +0200 Subject: [PATCH 28/30] added some documentation to README --- SPIN-verification/README.md | 58 +- SPIN-verification/model.pml | 8 +- crates/keystore/src/gen/valv.keystore.v1.rs | 605 ++++++++++++++++++++ 3 files changed, 663 insertions(+), 8 deletions(-) create mode 100644 crates/keystore/src/gen/valv.keystore.v1.rs diff --git a/SPIN-verification/README.md b/SPIN-verification/README.md index 1f77bfe..c315b0f 100644 --- a/SPIN-verification/README.md +++ b/SPIN-verification/README.md @@ -9,10 +9,10 @@ Model can be set by changing the MODEL constant.
1=A 2=B 3=C 4=D In the paper.
-2: Assignemnt and Encryption.
-3: Decryption after assignment and encryption has been finalized.
-4: Re-Encryption of envelopes after assignment and encryption has been finalized.
-5: Tenant 1 assignment and encryption then invalid credentials, Tenant 2 only Decrypts envelopes received from Tenant 1 with different grants.
+1: Assignemnt and Encryption.
+2: Decryption after assignment and encryption has been finalized.
+3: Re-Encryption of envelopes after assignment and encryption has been finalized.
+4: Tenant 1 assignment and encryption then invalid credentials, Tenant 2 only Decrypts envelopes received from Tenant 1 with different grants.
If MODEL == 1 then IS_MODEL_1 == 1
If MODEL != 1 then IS_MODEL_1 == 0
@@ -34,4 +34,54 @@ gcc -DMEMLIM=N -O2 -DXUSAFE -DCOLLAPSE -DNFAIR=3 (-DSAFETY) -w -o pan pan.c
-a -f used when verifying liveness.
+# Additional Documentation + +This project implements a key management service (KMS) based on the design and formal verification described in the master's thesis "Formally Verifying a Key Management Service" by Sebastian Owuya. While the implementation is still in progress, it aims to realize key concepts from the thesis. + +## Current Implementation Status + +### Architecture + +The current implementation in the Valv repository does not yet fully reflect the layered architecture described in the thesis. Instead, it implements a single-layer structure with envelope encryption, where a KEK is used to encrypt data or a DEK (see encrypt() in `crates/keystore/src/lib.rs`). + +### Protocol Operations + +The verified protocol operations are partially implemented: + +1. **KEK Assignment**: Implemented in `crates/keystore/src/lib.rs` in the `create_crypto_key()` function of the `KeystoreAPI` trait. The `ValvAPI` struct in `crates/valv/src/main.rs` exposes this functionality. + +2. **Encryption**: Core encryption logic is in `crates/keystore/src/lib.rs` in the `encrypt()` function of the `KeystoreAPI` trait. The `ValvAPI` in `crates/valv/src/main.rs` will expose this through the `encrypt` method (currently unimplemented). + +3. **Decryption**: Implemented in `crates/keystore/src/lib.rs` in the `decrypt()` function of the `KeystoreAPI` trait. The `ValvAPI` will expose this through the `decrypt` method in `crates/valv/src/main.rs` (currently unimplemented). + +4. **Re-encryption**: Not explicitly implemented yet, but the foundation exists within the encryption and decryption functions. + +### Components + +The implementation separates the following components: +- Tenant +- Keystore +- Database + +However, the Access Control component is currently missing. The assumptions around the tenant and the inductivity of how a keystore can be seen as a tenant would benefit from a more fleshed out implementation where tests can be constructed to simulate a "layered" structure. + +### Message Passing + +Message passing between components is implemented through function calls. For example, any call to `self.db` is treated as an asynchronously passed message. However, the storage of `self.master_key` directly within the Keystore may need reconsideration to better align with the thesis design. + +## Alignment with Thesis and Future Work + +While the current implementation incorporates key concepts from the thesis, there are areas that require further development to fully realize the verified design: + +1. **Layered Architecture**: Implement the full layered structure as described in the thesis. +2. **Access Control**: Add the missing Access Control component. +3. **Complete Protocol Operations**: Fully implement all operations, including re-encryption. +4. **Refine Component Separation**: Ensure clear separation of concerns, especially regarding key storage. +5. **Testing**: Develop tests to verify the "layered" structure and component interactions. + +It's important to note that while the implemented protocol is based on the verified model from the thesis, the current implementation may not yet fully adhere to all the requirements verified in the thesis. Further work is needed to ensure that the implementation preserves all the properties proven in the formal verification. + +As development continues, this documentation should be updated to reflect progress and maintain traceability to the thesis. Any deviations from or extensions to the verified design should be carefully considered and documented. + + diff --git a/SPIN-verification/model.pml b/SPIN-verification/model.pml index 6c24d86..751ad1f 100644 --- a/SPIN-verification/model.pml +++ b/SPIN-verification/model.pml @@ -27,10 +27,10 @@ THE SOFTWARE. 1=A 2=B 3=C 4=D In the paper. - 2: Assignemnt and Encryption. - 3: Decryption after assignment and encryption has been finalized - 4: Re-Encryption of envelopes after assignment and encryption has been finalized - 5: Tenant 1 assignment and encryption then invalid credentials, Tenant 2 only Decrypts envelopes received from Tenant 1 with different grants. + 1: Assignemnt and Encryption. + 2: Decryption after assignment and encryption has been finalized + 3: Re-Encryption of envelopes after assignment and encryption has been finalized + 4: Tenant 1 assignment and encryption then invalid credentials, Tenant 2 only Decrypts envelopes received from Tenant 1 with different grants. If MODEL == 1 then IS_MODEL_1 == 1 If MODEL != 1 then IS_MODEL_1 == 0 diff --git a/crates/keystore/src/gen/valv.keystore.v1.rs b/crates/keystore/src/gen/valv.keystore.v1.rs new file mode 100644 index 0000000..af1c869 --- /dev/null +++ b/crates/keystore/src/gen/valv.keystore.v1.rs @@ -0,0 +1,605 @@ +// @generated +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MasterKey { + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, + #[prost(message, optional, tag="2")] + pub create_time: ::core::option::Option<::prost_types::Timestamp>, + #[prost(message, optional, tag="3")] + pub primary: ::core::option::Option, + #[prost(message, optional, tag="4")] + pub rotation_period: ::core::option::Option<::prost_types::Duration>, + #[prost(message, optional, tag="5")] + pub destroy_scheduled_duration: ::core::option::Option<::prost_types::Duration>, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MasterKeyVersion { + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, + #[prost(enumeration="master_key_version::MasterKeyVersionState", tag="2")] + pub state: i32, + #[prost(message, optional, tag="3")] + pub create_time: ::core::option::Option<::prost_types::Timestamp>, + #[prost(message, optional, tag="4")] + pub scheduled_destroy_time: ::core::option::Option<::prost_types::Timestamp>, + #[prost(message, optional, tag="5")] + pub destroy_time: ::core::option::Option<::prost_types::Timestamp>, +} +/// Nested message and enum types in `MasterKeyVersion`. +pub mod master_key_version { + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[repr(i32)] + pub enum MasterKeyVersionState { + Unspecified = 0, + Enabled = 1, + Disabled = 2, + Destroyed = 3, + DestroyScheduled = 4, + Primary = 5, + } + impl MasterKeyVersionState { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + MasterKeyVersionState::Unspecified => "MASTER_KEY_VERSION_STATE_UNSPECIFIED", + MasterKeyVersionState::Enabled => "MASTER_KEY_VERSION_STATE_ENABLED", + MasterKeyVersionState::Disabled => "MASTER_KEY_VERSION_STATE_DISABLED", + MasterKeyVersionState::Destroyed => "MASTER_KEY_VERSION_STATE_DESTROYED", + MasterKeyVersionState::DestroyScheduled => "MASTER_KEY_VERSION_STATE_DESTROY_SCHEDULED", + MasterKeyVersionState::Primary => "MASTER_KEY_VERSION_STATE_PRIMARY", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "MASTER_KEY_VERSION_STATE_UNSPECIFIED" => Some(Self::Unspecified), + "MASTER_KEY_VERSION_STATE_ENABLED" => Some(Self::Enabled), + "MASTER_KEY_VERSION_STATE_DISABLED" => Some(Self::Disabled), + "MASTER_KEY_VERSION_STATE_DESTROYED" => Some(Self::Destroyed), + "MASTER_KEY_VERSION_STATE_DESTROY_SCHEDULED" => Some(Self::DestroyScheduled), + "MASTER_KEY_VERSION_STATE_PRIMARY" => Some(Self::Primary), + _ => None, + } + } + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CreateMasterKeyRequest { + #[prost(string, tag="1")] + pub master_key_id: ::prost::alloc::string::String, + #[prost(message, optional, tag="2")] + pub master_key: ::core::option::Option, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ListMasterKeysRequest { +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ListMasterKeyVersionsRequest { +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CreateMasterKeyVersionRequest { + #[prost(string, tag="1")] + pub master_key_id: ::prost::alloc::string::String, + #[prost(message, optional, tag="2")] + pub master_key_version: ::core::option::Option, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DestroyMasterKeyVersionRequest { + #[prost(string, tag="1")] + pub master_key_id: ::prost::alloc::string::String, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct EncryptRequest { + #[prost(string, tag="1")] + pub master_key_id: ::prost::alloc::string::String, + #[prost(bytes="bytes", tag="2")] + pub plaintext: ::prost::bytes::Bytes, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DecryptRequest { + #[prost(string, tag="1")] + pub master_key_id: ::prost::alloc::string::String, + #[prost(bytes="bytes", tag="2")] + pub ciphertext: ::prost::bytes::Bytes, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ListMasterKeysResponse { + #[prost(message, repeated, tag="1")] + pub master_keys: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CreateMasterKeyResponse { + #[prost(message, optional, tag="1")] + pub master_key: ::core::option::Option, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ListMasterKeyVersionsResponse { + #[prost(message, repeated, tag="1")] + pub master_key_versions: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CreateMasterKeyVersionResponse { + #[prost(message, optional, tag="1")] + pub master_key_version: ::core::option::Option, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DestroyMasterKeyVersionResponse { + #[prost(message, optional, tag="1")] + pub master_key_version: ::core::option::Option, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct EncryptResponse { + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, + #[prost(bytes="bytes", tag="2")] + pub ciphertext: ::prost::bytes::Bytes, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DecryptResponse { + #[prost(bytes="bytes", tag="1")] + pub plaintext: ::prost::bytes::Bytes, +} +/// Encoded file descriptor set for the `valv.keystore.v1` package +pub const FILE_DESCRIPTOR_SET: &[u8] = &[ + 0x0a, 0x81, 0x14, 0x0a, 0x20, 0x76, 0x61, 0x6c, 0x76, 0x2f, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, + 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd5, 0x02, 0x0a, 0x09, 0x4d, 0x61, + 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12, 0x18, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x03, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x41, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x03, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x54, 0x69, 0x6d, 0x65, 0x12, 0x42, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, + 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x03, 0x52, + 0x07, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x48, 0x0a, 0x0f, 0x72, 0x6f, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x04, 0xe2, 0x41, + 0x01, 0x01, 0x52, 0x0e, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x69, + 0x6f, 0x64, 0x12, 0x5d, 0x0a, 0x1a, 0x64, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x5f, 0x73, 0x63, + 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x05, 0x52, 0x18, 0x64, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, + 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x22, 0xf1, 0x04, 0x0a, 0x10, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x03, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x54, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x38, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x03, 0x52, + 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x41, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x03, 0x52, 0x0a, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x56, 0x0a, 0x16, 0x73, 0x63, 0x68, + 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x03, 0x52, 0x14, 0x73, 0x63, 0x68, + 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x54, 0x69, 0x6d, + 0x65, 0x12, 0x43, 0x0a, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x03, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x72, + 0x6f, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x8c, 0x02, 0x0a, 0x15, 0x4d, 0x61, 0x73, 0x74, 0x65, + 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x12, 0x28, 0x0a, 0x24, 0x4d, 0x41, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x56, + 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x24, 0x0a, 0x20, 0x4d, 0x41, + 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x45, 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x01, + 0x12, 0x25, 0x0a, 0x21, 0x4d, 0x41, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x56, + 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x44, 0x49, 0x53, + 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x12, 0x26, 0x0a, 0x22, 0x4d, 0x41, 0x53, 0x54, 0x45, + 0x52, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x45, 0x5f, 0x44, 0x45, 0x53, 0x54, 0x52, 0x4f, 0x59, 0x45, 0x44, 0x10, 0x03, 0x12, + 0x2e, 0x0a, 0x2a, 0x4d, 0x41, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x56, 0x45, + 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x44, 0x45, 0x53, 0x54, + 0x52, 0x4f, 0x59, 0x5f, 0x53, 0x43, 0x48, 0x45, 0x44, 0x55, 0x4c, 0x45, 0x44, 0x10, 0x04, 0x12, + 0x24, 0x0a, 0x20, 0x4d, 0x41, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x56, 0x45, + 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x50, 0x52, 0x49, 0x4d, + 0x41, 0x52, 0x59, 0x10, 0x05, 0x42, 0x88, 0x01, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x61, + 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0e, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, + 0xa2, 0x02, 0x03, 0x56, 0x4b, 0x58, 0xaa, 0x02, 0x10, 0x56, 0x61, 0x6c, 0x76, 0x2e, 0x4b, 0x65, + 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x10, 0x56, 0x61, 0x6c, 0x76, + 0x5c, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1c, 0x56, + 0x61, 0x6c, 0x76, 0x5c, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5c, 0x56, 0x31, 0x5c, + 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x12, 0x56, 0x61, + 0x6c, 0x76, 0x3a, 0x3a, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x3a, 0x3a, 0x56, 0x31, + 0x4a, 0x89, 0x0a, 0x0a, 0x06, 0x12, 0x04, 0x00, 0x00, 0x31, 0x01, 0x0a, 0x08, 0x0a, 0x01, 0x0c, + 0x12, 0x03, 0x00, 0x00, 0x12, 0x0a, 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, 0x02, 0x00, 0x19, 0x0a, + 0x09, 0x0a, 0x02, 0x03, 0x00, 0x12, 0x03, 0x04, 0x00, 0x28, 0x0a, 0x09, 0x0a, 0x02, 0x03, 0x01, + 0x12, 0x03, 0x05, 0x00, 0x29, 0x0a, 0x09, 0x0a, 0x02, 0x03, 0x02, 0x12, 0x03, 0x06, 0x00, 0x29, + 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x08, 0x00, 0x17, 0x01, 0x0a, 0x0a, 0x0a, 0x03, + 0x04, 0x00, 0x01, 0x12, 0x03, 0x08, 0x08, 0x11, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x00, + 0x12, 0x04, 0x09, 0x02, 0x0a, 0x30, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x05, 0x12, + 0x03, 0x09, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x09, + 0x09, 0x0d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x09, 0x10, 0x11, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x08, 0x12, 0x03, 0x0a, 0x04, 0x2f, 0x0a, 0x0f, + 0x0a, 0x08, 0x04, 0x00, 0x02, 0x00, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x0a, 0x05, 0x2e, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0x0c, 0x02, 0x0d, 0x30, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x00, 0x02, 0x01, 0x06, 0x12, 0x03, 0x0c, 0x02, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x0c, 0x1c, 0x27, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, + 0x01, 0x03, 0x12, 0x03, 0x0c, 0x2a, 0x2b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x08, + 0x12, 0x03, 0x0d, 0x04, 0x2f, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x00, 0x02, 0x01, 0x08, 0x9c, 0x08, + 0x00, 0x12, 0x03, 0x0d, 0x05, 0x2e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x02, 0x12, 0x04, + 0x0f, 0x02, 0x10, 0x30, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x06, 0x12, 0x03, 0x0f, + 0x02, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x0f, 0x13, 0x1a, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x03, 0x12, 0x03, 0x0f, 0x1d, 0x1e, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x08, 0x12, 0x03, 0x10, 0x04, 0x2f, 0x0a, 0x0f, 0x0a, 0x08, + 0x04, 0x00, 0x02, 0x02, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x10, 0x05, 0x2e, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x00, 0x02, 0x03, 0x12, 0x04, 0x12, 0x02, 0x13, 0x2d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x00, 0x02, 0x03, 0x06, 0x12, 0x03, 0x12, 0x02, 0x1a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, + 0x03, 0x01, 0x12, 0x03, 0x12, 0x1b, 0x2a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x03, 0x03, + 0x12, 0x03, 0x12, 0x2d, 0x2e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x03, 0x08, 0x12, 0x03, + 0x13, 0x04, 0x2c, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x00, 0x02, 0x03, 0x08, 0x9c, 0x08, 0x00, 0x12, + 0x03, 0x13, 0x05, 0x2b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x04, 0x12, 0x04, 0x15, 0x02, + 0x16, 0x2e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x04, 0x06, 0x12, 0x03, 0x15, 0x02, 0x1a, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x04, 0x01, 0x12, 0x03, 0x15, 0x1b, 0x35, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x00, 0x02, 0x04, 0x03, 0x12, 0x03, 0x15, 0x38, 0x39, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x00, 0x02, 0x04, 0x08, 0x12, 0x03, 0x16, 0x04, 0x2d, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x00, + 0x02, 0x04, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x16, 0x05, 0x2c, 0x0a, 0x0a, 0x0a, 0x02, 0x04, + 0x01, 0x12, 0x04, 0x19, 0x00, 0x31, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x01, 0x01, 0x12, 0x03, + 0x19, 0x08, 0x18, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x00, 0x12, 0x04, 0x1b, 0x02, 0x1c, + 0x30, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x05, 0x12, 0x03, 0x1b, 0x02, 0x08, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x1b, 0x09, 0x0d, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x1b, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x01, 0x02, 0x00, 0x08, 0x12, 0x03, 0x1c, 0x04, 0x2f, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x01, 0x02, + 0x00, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x1c, 0x05, 0x2e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x01, + 0x04, 0x00, 0x12, 0x04, 0x1e, 0x02, 0x25, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x04, 0x00, + 0x01, 0x12, 0x03, 0x1e, 0x07, 0x1c, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x00, + 0x12, 0x03, 0x1f, 0x04, 0x2d, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, + 0x12, 0x03, 0x1f, 0x04, 0x28, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x00, 0x02, + 0x12, 0x03, 0x1f, 0x2b, 0x2c, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x01, 0x12, + 0x03, 0x20, 0x04, 0x29, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, + 0x03, 0x20, 0x04, 0x24, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, + 0x03, 0x20, 0x27, 0x28, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x02, 0x12, 0x03, + 0x21, 0x04, 0x2a, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, + 0x21, 0x04, 0x25, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, 0x03, + 0x21, 0x28, 0x29, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x03, 0x12, 0x03, 0x22, + 0x04, 0x2b, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, 0x03, 0x22, + 0x04, 0x26, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x03, 0x02, 0x12, 0x03, 0x22, + 0x29, 0x2a, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x04, 0x12, 0x03, 0x23, 0x04, + 0x33, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x04, 0x01, 0x12, 0x03, 0x23, 0x04, + 0x2e, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x04, 0x02, 0x12, 0x03, 0x23, 0x31, + 0x32, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x05, 0x12, 0x03, 0x24, 0x04, 0x29, + 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x05, 0x01, 0x12, 0x03, 0x24, 0x04, 0x24, + 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x05, 0x02, 0x12, 0x03, 0x24, 0x27, 0x28, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x01, 0x12, 0x04, 0x26, 0x02, 0x27, 0x30, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x06, 0x12, 0x03, 0x26, 0x02, 0x17, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x01, 0x02, 0x01, 0x01, 0x12, 0x03, 0x26, 0x18, 0x1d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, + 0x02, 0x01, 0x03, 0x12, 0x03, 0x26, 0x20, 0x21, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, + 0x08, 0x12, 0x03, 0x27, 0x04, 0x2f, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x01, 0x02, 0x01, 0x08, 0x9c, + 0x08, 0x00, 0x12, 0x03, 0x27, 0x05, 0x2e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x02, 0x12, + 0x04, 0x29, 0x02, 0x2a, 0x30, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x06, 0x12, 0x03, + 0x29, 0x02, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x01, 0x12, 0x03, 0x29, 0x1c, + 0x27, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x03, 0x12, 0x03, 0x29, 0x2a, 0x2b, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x08, 0x12, 0x03, 0x2a, 0x04, 0x2f, 0x0a, 0x0f, 0x0a, + 0x08, 0x04, 0x01, 0x02, 0x02, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x2a, 0x05, 0x2e, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x01, 0x02, 0x03, 0x12, 0x04, 0x2c, 0x02, 0x2d, 0x30, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x01, 0x02, 0x03, 0x06, 0x12, 0x03, 0x2c, 0x02, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, + 0x02, 0x03, 0x01, 0x12, 0x03, 0x2c, 0x1c, 0x32, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, + 0x03, 0x12, 0x03, 0x2c, 0x35, 0x36, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x08, 0x12, + 0x03, 0x2d, 0x04, 0x2f, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x01, 0x02, 0x03, 0x08, 0x9c, 0x08, 0x00, + 0x12, 0x03, 0x2d, 0x05, 0x2e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x04, 0x12, 0x04, 0x2f, + 0x02, 0x30, 0x30, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x04, 0x06, 0x12, 0x03, 0x2f, 0x02, + 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x04, 0x01, 0x12, 0x03, 0x2f, 0x1c, 0x28, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x04, 0x03, 0x12, 0x03, 0x2f, 0x2b, 0x2c, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x01, 0x02, 0x04, 0x08, 0x12, 0x03, 0x30, 0x04, 0x2f, 0x0a, 0x0f, 0x0a, 0x08, 0x04, + 0x01, 0x02, 0x04, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x30, 0x05, 0x2e, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, 0x0a, 0xf1, 0x22, 0x0a, 0x1e, 0x76, 0x61, 0x6c, 0x76, 0x2f, 0x6b, 0x65, + 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, + 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, + 0x76, 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x76, 0x61, 0x6c, 0x76, + 0x2f, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x84, 0x01, 0x0a, + 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0d, 0x6d, 0x61, 0x73, 0x74, 0x65, + 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, + 0xe2, 0x41, 0x01, 0x02, 0x52, 0x0b, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x49, + 0x64, 0x12, 0x40, 0x0a, 0x0a, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, + 0x65, 0x79, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x02, 0x52, 0x09, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, + 0x4b, 0x65, 0x79, 0x22, 0x17, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x73, 0x74, 0x65, + 0x72, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x1e, 0x0a, 0x1c, + 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xa1, 0x01, 0x0a, + 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, + 0x0a, 0x0d, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x02, 0x52, 0x0b, 0x6d, 0x61, 0x73, + 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x56, 0x0a, 0x12, 0x6d, 0x61, 0x73, 0x74, + 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, + 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x02, 0x52, 0x10, + 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x22, 0x4a, 0x0a, 0x1e, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x4d, 0x61, 0x73, 0x74, 0x65, + 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0d, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x02, 0x52, + 0x0b, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x22, 0x5e, 0x0a, 0x0e, + 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, + 0x0a, 0x0d, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x02, 0x52, 0x0b, 0x6d, 0x61, 0x73, + 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x69, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x04, 0xe2, 0x41, 0x01, + 0x02, 0x52, 0x09, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x60, 0x0a, 0x0e, + 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, + 0x0a, 0x0d, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x02, 0x52, 0x0b, 0x6d, 0x61, 0x73, + 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0a, 0x63, 0x69, 0x70, 0x68, + 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x04, 0xe2, 0x41, + 0x01, 0x02, 0x52, 0x0a, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x22, 0x56, + 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x0b, 0x6d, 0x61, 0x73, 0x74, + 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, + 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x52, 0x0a, 0x6d, 0x61, 0x73, 0x74, + 0x65, 0x72, 0x4b, 0x65, 0x79, 0x73, 0x22, 0x55, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x3a, 0x0a, 0x0a, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, + 0x65, 0x79, 0x52, 0x09, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x22, 0x73, 0x0a, + 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x52, + 0x0a, 0x13, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x76, 0x61, + 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, + 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x11, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x22, 0x72, 0x0a, 0x1e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x74, + 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x12, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6b, + 0x65, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x22, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x73, 0x0a, 0x1f, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, + 0x79, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x12, 0x6d, 0x61, 0x73, + 0x74, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, + 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x6d, 0x61, 0x73, 0x74, 0x65, + 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x51, 0x0a, 0x0f, 0x45, + 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xe2, 0x41, + 0x01, 0x02, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0a, 0x63, 0x69, 0x70, 0x68, + 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x04, 0xe2, 0x41, + 0x01, 0x02, 0x52, 0x0a, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x22, 0x35, + 0x0a, 0x0f, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x22, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x02, 0x52, 0x09, 0x70, 0x6c, 0x61, 0x69, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x32, 0x80, 0x06, 0x0a, 0x1a, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, + 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x66, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, + 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12, 0x28, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, + 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x29, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x74, 0x65, + 0x72, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x0e, + 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x27, + 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, + 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, + 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x78, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, + 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2e, 0x2e, 0x76, 0x61, 0x6c, + 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x76, 0x61, 0x6c, + 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7b, 0x0a, 0x16, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, + 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, + 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x17, 0x44, 0x65, 0x73, 0x74, + 0x72, 0x6f, 0x79, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x4d, 0x61, + 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, + 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x07, 0x45, 0x6e, 0x63, 0x72, + 0x79, 0x70, 0x74, 0x12, 0x20, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x07, 0x44, 0x65, 0x63, 0x72, + 0x79, 0x70, 0x74, 0x12, 0x20, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x86, 0x01, 0x0a, 0x14, 0x63, 0x6f, 0x6d, + 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, + 0x31, 0x42, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0xa2, 0x02, 0x03, 0x56, 0x4b, 0x58, 0xaa, 0x02, 0x10, 0x56, 0x61, 0x6c, 0x76, 0x2e, 0x4b, + 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x10, 0x56, 0x61, 0x6c, + 0x76, 0x5c, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1c, + 0x56, 0x61, 0x6c, 0x76, 0x5c, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5c, 0x56, 0x31, + 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x12, 0x56, + 0x61, 0x6c, 0x76, 0x3a, 0x3a, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x3a, 0x3a, 0x56, + 0x31, 0x4a, 0xdc, 0x10, 0x0a, 0x06, 0x12, 0x04, 0x00, 0x00, 0x5b, 0x01, 0x0a, 0x08, 0x0a, 0x01, + 0x0c, 0x12, 0x03, 0x00, 0x00, 0x12, 0x0a, 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, 0x02, 0x00, 0x19, + 0x0a, 0x09, 0x0a, 0x02, 0x03, 0x00, 0x12, 0x03, 0x04, 0x00, 0x29, 0x0a, 0x09, 0x0a, 0x02, 0x03, + 0x01, 0x12, 0x03, 0x05, 0x00, 0x2a, 0x0a, 0x0a, 0x0a, 0x02, 0x06, 0x00, 0x12, 0x04, 0x07, 0x00, + 0x11, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x06, 0x00, 0x01, 0x12, 0x03, 0x07, 0x08, 0x22, 0x0a, 0x0b, + 0x0a, 0x04, 0x06, 0x00, 0x02, 0x00, 0x12, 0x03, 0x08, 0x02, 0x50, 0x0a, 0x0c, 0x0a, 0x05, 0x06, + 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x08, 0x06, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, + 0x00, 0x02, 0x12, 0x03, 0x08, 0x16, 0x2c, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x00, 0x03, + 0x12, 0x03, 0x08, 0x37, 0x4e, 0x0a, 0x0b, 0x0a, 0x04, 0x06, 0x00, 0x02, 0x01, 0x12, 0x03, 0x09, + 0x02, 0x4d, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x09, 0x06, 0x14, + 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x01, 0x02, 0x12, 0x03, 0x09, 0x15, 0x2a, 0x0a, 0x0c, + 0x0a, 0x05, 0x06, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x09, 0x35, 0x4b, 0x0a, 0x0b, 0x0a, 0x04, + 0x06, 0x00, 0x02, 0x02, 0x12, 0x03, 0x0b, 0x02, 0x62, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, + 0x02, 0x01, 0x12, 0x03, 0x0b, 0x06, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x02, 0x02, + 0x12, 0x03, 0x0b, 0x1c, 0x38, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x02, 0x03, 0x12, 0x03, + 0x0b, 0x43, 0x60, 0x0a, 0x0b, 0x0a, 0x04, 0x06, 0x00, 0x02, 0x03, 0x12, 0x03, 0x0c, 0x02, 0x65, + 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x03, 0x01, 0x12, 0x03, 0x0c, 0x06, 0x1c, 0x0a, 0x0c, + 0x0a, 0x05, 0x06, 0x00, 0x02, 0x03, 0x02, 0x12, 0x03, 0x0c, 0x1d, 0x3a, 0x0a, 0x0c, 0x0a, 0x05, + 0x06, 0x00, 0x02, 0x03, 0x03, 0x12, 0x03, 0x0c, 0x45, 0x63, 0x0a, 0x0b, 0x0a, 0x04, 0x06, 0x00, + 0x02, 0x04, 0x12, 0x03, 0x0d, 0x02, 0x68, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x04, 0x01, + 0x12, 0x03, 0x0d, 0x06, 0x1d, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x04, 0x02, 0x12, 0x03, + 0x0d, 0x1e, 0x3c, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x04, 0x03, 0x12, 0x03, 0x0d, 0x47, + 0x66, 0x0a, 0x0b, 0x0a, 0x04, 0x06, 0x00, 0x02, 0x05, 0x12, 0x03, 0x0f, 0x02, 0x38, 0x0a, 0x0c, + 0x0a, 0x05, 0x06, 0x00, 0x02, 0x05, 0x01, 0x12, 0x03, 0x0f, 0x06, 0x0d, 0x0a, 0x0c, 0x0a, 0x05, + 0x06, 0x00, 0x02, 0x05, 0x02, 0x12, 0x03, 0x0f, 0x0e, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, + 0x02, 0x05, 0x03, 0x12, 0x03, 0x0f, 0x27, 0x36, 0x0a, 0x0b, 0x0a, 0x04, 0x06, 0x00, 0x02, 0x06, + 0x12, 0x03, 0x10, 0x02, 0x38, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x06, 0x01, 0x12, 0x03, + 0x10, 0x06, 0x0d, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x06, 0x02, 0x12, 0x03, 0x10, 0x0e, + 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x06, 0x03, 0x12, 0x03, 0x10, 0x27, 0x36, 0x0a, + 0x0a, 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x13, 0x00, 0x19, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, + 0x00, 0x01, 0x12, 0x03, 0x13, 0x08, 0x1e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x00, 0x12, + 0x04, 0x14, 0x02, 0x15, 0x2d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, + 0x14, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x14, 0x09, + 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x14, 0x19, 0x1a, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x08, 0x12, 0x03, 0x15, 0x04, 0x2c, 0x0a, 0x0f, 0x0a, + 0x08, 0x04, 0x00, 0x02, 0x00, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x15, 0x05, 0x2b, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0x17, 0x02, 0x18, 0x2d, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x00, 0x02, 0x01, 0x06, 0x12, 0x03, 0x17, 0x02, 0x0b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, + 0x02, 0x01, 0x01, 0x12, 0x03, 0x17, 0x0c, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, + 0x03, 0x12, 0x03, 0x17, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x08, 0x12, + 0x03, 0x18, 0x04, 0x2c, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x00, 0x02, 0x01, 0x08, 0x9c, 0x08, 0x00, + 0x12, 0x03, 0x18, 0x05, 0x2b, 0x0a, 0x09, 0x0a, 0x02, 0x04, 0x01, 0x12, 0x03, 0x1b, 0x00, 0x20, + 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x01, 0x01, 0x12, 0x03, 0x1b, 0x08, 0x1d, 0x0a, 0x09, 0x0a, 0x02, + 0x04, 0x02, 0x12, 0x03, 0x1d, 0x00, 0x27, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x02, 0x01, 0x12, 0x03, + 0x1d, 0x08, 0x24, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x03, 0x12, 0x04, 0x1f, 0x00, 0x25, 0x01, 0x0a, + 0x0a, 0x0a, 0x03, 0x04, 0x03, 0x01, 0x12, 0x03, 0x1f, 0x08, 0x25, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x03, 0x02, 0x00, 0x12, 0x04, 0x20, 0x02, 0x21, 0x2d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, + 0x00, 0x05, 0x12, 0x03, 0x20, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x01, + 0x12, 0x03, 0x20, 0x09, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x03, 0x12, 0x03, + 0x20, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x08, 0x12, 0x03, 0x21, 0x04, + 0x2c, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x03, 0x02, 0x00, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x21, + 0x05, 0x2b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x03, 0x02, 0x01, 0x12, 0x04, 0x23, 0x02, 0x24, 0x2d, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x06, 0x12, 0x03, 0x23, 0x02, 0x12, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x12, 0x03, 0x23, 0x13, 0x25, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x03, 0x02, 0x01, 0x03, 0x12, 0x03, 0x23, 0x28, 0x29, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, + 0x02, 0x01, 0x08, 0x12, 0x03, 0x24, 0x04, 0x2c, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x03, 0x02, 0x01, + 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x24, 0x05, 0x2b, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x04, 0x12, + 0x04, 0x27, 0x00, 0x2a, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x04, 0x01, 0x12, 0x03, 0x27, 0x08, + 0x26, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x04, 0x02, 0x00, 0x12, 0x04, 0x28, 0x02, 0x29, 0x2d, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x04, 0x02, 0x00, 0x05, 0x12, 0x03, 0x28, 0x02, 0x08, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x04, 0x02, 0x00, 0x01, 0x12, 0x03, 0x28, 0x09, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x04, 0x02, 0x00, 0x03, 0x12, 0x03, 0x28, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x04, 0x02, + 0x00, 0x08, 0x12, 0x03, 0x29, 0x04, 0x2c, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x04, 0x02, 0x00, 0x08, + 0x9c, 0x08, 0x00, 0x12, 0x03, 0x29, 0x05, 0x2b, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x05, 0x12, 0x04, + 0x2c, 0x00, 0x32, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x05, 0x01, 0x12, 0x03, 0x2c, 0x08, 0x16, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x05, 0x02, 0x00, 0x12, 0x04, 0x2d, 0x02, 0x2e, 0x2d, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x05, 0x02, 0x00, 0x05, 0x12, 0x03, 0x2d, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x05, 0x02, 0x00, 0x01, 0x12, 0x03, 0x2d, 0x09, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, + 0x02, 0x00, 0x03, 0x12, 0x03, 0x2d, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x00, + 0x08, 0x12, 0x03, 0x2e, 0x04, 0x2c, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x05, 0x02, 0x00, 0x08, 0x9c, + 0x08, 0x00, 0x12, 0x03, 0x2e, 0x05, 0x2b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x05, 0x02, 0x01, 0x12, + 0x04, 0x30, 0x02, 0x31, 0x2d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x01, 0x05, 0x12, 0x03, + 0x30, 0x02, 0x07, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x01, 0x01, 0x12, 0x03, 0x30, 0x08, + 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x01, 0x03, 0x12, 0x03, 0x30, 0x14, 0x15, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x01, 0x08, 0x12, 0x03, 0x31, 0x04, 0x2c, 0x0a, 0x0f, 0x0a, + 0x08, 0x04, 0x05, 0x02, 0x01, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x31, 0x05, 0x2b, 0x0a, 0x0a, + 0x0a, 0x02, 0x04, 0x06, 0x12, 0x04, 0x34, 0x00, 0x3a, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x06, + 0x01, 0x12, 0x03, 0x34, 0x08, 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x06, 0x02, 0x00, 0x12, 0x04, + 0x35, 0x02, 0x36, 0x2d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, 0x05, 0x12, 0x03, 0x35, + 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, 0x01, 0x12, 0x03, 0x35, 0x09, 0x16, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, 0x03, 0x12, 0x03, 0x35, 0x19, 0x1a, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, 0x08, 0x12, 0x03, 0x36, 0x04, 0x2c, 0x0a, 0x0f, 0x0a, 0x08, + 0x04, 0x06, 0x02, 0x00, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x36, 0x05, 0x2b, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x06, 0x02, 0x01, 0x12, 0x04, 0x38, 0x02, 0x39, 0x2d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x06, 0x02, 0x01, 0x05, 0x12, 0x03, 0x38, 0x02, 0x07, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x06, 0x02, + 0x01, 0x01, 0x12, 0x03, 0x38, 0x08, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x01, 0x03, + 0x12, 0x03, 0x38, 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x01, 0x08, 0x12, 0x03, + 0x39, 0x04, 0x2c, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x06, 0x02, 0x01, 0x08, 0x9c, 0x08, 0x00, 0x12, + 0x03, 0x39, 0x05, 0x2b, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x07, 0x12, 0x04, 0x3c, 0x00, 0x3e, 0x01, + 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x07, 0x01, 0x12, 0x03, 0x3c, 0x08, 0x1e, 0x0a, 0x0b, 0x0a, 0x04, + 0x04, 0x07, 0x02, 0x00, 0x12, 0x03, 0x3d, 0x02, 0x25, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, + 0x00, 0x04, 0x12, 0x03, 0x3d, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x00, 0x06, + 0x12, 0x03, 0x3d, 0x0b, 0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x00, 0x01, 0x12, 0x03, + 0x3d, 0x15, 0x20, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x00, 0x03, 0x12, 0x03, 0x3d, 0x23, + 0x24, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x08, 0x12, 0x04, 0x40, 0x00, 0x42, 0x01, 0x0a, 0x0a, 0x0a, + 0x03, 0x04, 0x08, 0x01, 0x12, 0x03, 0x40, 0x08, 0x1f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x08, 0x02, + 0x00, 0x12, 0x03, 0x41, 0x02, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x00, 0x06, 0x12, + 0x03, 0x41, 0x02, 0x0b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x00, 0x01, 0x12, 0x03, 0x41, + 0x0c, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x00, 0x03, 0x12, 0x03, 0x41, 0x19, 0x1a, + 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x09, 0x12, 0x04, 0x44, 0x00, 0x46, 0x01, 0x0a, 0x0a, 0x0a, 0x03, + 0x04, 0x09, 0x01, 0x12, 0x03, 0x44, 0x08, 0x25, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x09, 0x02, 0x00, + 0x12, 0x03, 0x45, 0x02, 0x34, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x00, 0x04, 0x12, 0x03, + 0x45, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x00, 0x06, 0x12, 0x03, 0x45, 0x0b, + 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x00, 0x01, 0x12, 0x03, 0x45, 0x1c, 0x2f, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x00, 0x03, 0x12, 0x03, 0x45, 0x32, 0x33, 0x0a, 0x0a, 0x0a, + 0x02, 0x04, 0x0a, 0x12, 0x04, 0x48, 0x00, 0x4a, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x0a, 0x01, + 0x12, 0x03, 0x48, 0x08, 0x26, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x00, 0x12, 0x03, 0x49, + 0x02, 0x2a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x00, 0x06, 0x12, 0x03, 0x49, 0x02, 0x12, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x00, 0x01, 0x12, 0x03, 0x49, 0x13, 0x25, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x00, 0x03, 0x12, 0x03, 0x49, 0x28, 0x29, 0x0a, 0x0a, 0x0a, 0x02, + 0x04, 0x0b, 0x12, 0x04, 0x4c, 0x00, 0x4e, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x0b, 0x01, 0x12, + 0x03, 0x4c, 0x08, 0x27, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x0b, 0x02, 0x00, 0x12, 0x03, 0x4d, 0x02, + 0x2a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x00, 0x06, 0x12, 0x03, 0x4d, 0x02, 0x12, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x00, 0x01, 0x12, 0x03, 0x4d, 0x13, 0x25, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x0b, 0x02, 0x00, 0x03, 0x12, 0x03, 0x4d, 0x28, 0x29, 0x0a, 0x0a, 0x0a, 0x02, 0x04, + 0x0c, 0x12, 0x04, 0x50, 0x00, 0x56, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x0c, 0x01, 0x12, 0x03, + 0x50, 0x08, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0c, 0x02, 0x00, 0x12, 0x04, 0x51, 0x02, 0x52, + 0x2d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x00, 0x05, 0x12, 0x03, 0x51, 0x02, 0x08, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x00, 0x01, 0x12, 0x03, 0x51, 0x09, 0x0d, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x0c, 0x02, 0x00, 0x03, 0x12, 0x03, 0x51, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x0c, 0x02, 0x00, 0x08, 0x12, 0x03, 0x52, 0x04, 0x2c, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x0c, 0x02, + 0x00, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x52, 0x05, 0x2b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0c, + 0x02, 0x01, 0x12, 0x04, 0x54, 0x02, 0x55, 0x2d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x01, + 0x05, 0x12, 0x03, 0x54, 0x02, 0x07, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x01, 0x01, 0x12, + 0x03, 0x54, 0x08, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x01, 0x03, 0x12, 0x03, 0x54, + 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x01, 0x08, 0x12, 0x03, 0x55, 0x04, 0x2c, + 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x0c, 0x02, 0x01, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x55, 0x05, + 0x2b, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x0d, 0x12, 0x04, 0x58, 0x00, 0x5b, 0x01, 0x0a, 0x0a, 0x0a, + 0x03, 0x04, 0x0d, 0x01, 0x12, 0x03, 0x58, 0x08, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0d, 0x02, + 0x00, 0x12, 0x04, 0x59, 0x02, 0x5a, 0x2d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x00, 0x05, + 0x12, 0x03, 0x59, 0x02, 0x07, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x00, 0x01, 0x12, 0x03, + 0x59, 0x08, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x00, 0x03, 0x12, 0x03, 0x59, 0x14, + 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x00, 0x08, 0x12, 0x03, 0x5a, 0x04, 0x2c, 0x0a, + 0x0f, 0x0a, 0x08, 0x04, 0x0d, 0x02, 0x00, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x5a, 0x05, 0x2b, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +]; +include!("valv.keystore.v1.tonic.rs"); +// @@protoc_insertion_point(module) \ No newline at end of file From a829f473855766affb68e19af7638c5bb8ce1bf6 Mon Sep 17 00:00:00 2001 From: Jonathan Grahl Date: Wed, 2 Oct 2024 15:16:11 +0200 Subject: [PATCH 29/30] fix: this file shouldnt be committed --- crates/keystore/src/gen/valv.keystore.v1.rs | 605 -------------------- 1 file changed, 605 deletions(-) delete mode 100644 crates/keystore/src/gen/valv.keystore.v1.rs diff --git a/crates/keystore/src/gen/valv.keystore.v1.rs b/crates/keystore/src/gen/valv.keystore.v1.rs deleted file mode 100644 index af1c869..0000000 --- a/crates/keystore/src/gen/valv.keystore.v1.rs +++ /dev/null @@ -1,605 +0,0 @@ -// @generated -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct MasterKey { - #[prost(string, tag="1")] - pub name: ::prost::alloc::string::String, - #[prost(message, optional, tag="2")] - pub create_time: ::core::option::Option<::prost_types::Timestamp>, - #[prost(message, optional, tag="3")] - pub primary: ::core::option::Option, - #[prost(message, optional, tag="4")] - pub rotation_period: ::core::option::Option<::prost_types::Duration>, - #[prost(message, optional, tag="5")] - pub destroy_scheduled_duration: ::core::option::Option<::prost_types::Duration>, -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct MasterKeyVersion { - #[prost(string, tag="1")] - pub name: ::prost::alloc::string::String, - #[prost(enumeration="master_key_version::MasterKeyVersionState", tag="2")] - pub state: i32, - #[prost(message, optional, tag="3")] - pub create_time: ::core::option::Option<::prost_types::Timestamp>, - #[prost(message, optional, tag="4")] - pub scheduled_destroy_time: ::core::option::Option<::prost_types::Timestamp>, - #[prost(message, optional, tag="5")] - pub destroy_time: ::core::option::Option<::prost_types::Timestamp>, -} -/// Nested message and enum types in `MasterKeyVersion`. -pub mod master_key_version { - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] - #[repr(i32)] - pub enum MasterKeyVersionState { - Unspecified = 0, - Enabled = 1, - Disabled = 2, - Destroyed = 3, - DestroyScheduled = 4, - Primary = 5, - } - impl MasterKeyVersionState { - /// String value of the enum field names used in the ProtoBuf definition. - /// - /// The values are not transformed in any way and thus are considered stable - /// (if the ProtoBuf definition does not change) and safe for programmatic use. - pub fn as_str_name(&self) -> &'static str { - match self { - MasterKeyVersionState::Unspecified => "MASTER_KEY_VERSION_STATE_UNSPECIFIED", - MasterKeyVersionState::Enabled => "MASTER_KEY_VERSION_STATE_ENABLED", - MasterKeyVersionState::Disabled => "MASTER_KEY_VERSION_STATE_DISABLED", - MasterKeyVersionState::Destroyed => "MASTER_KEY_VERSION_STATE_DESTROYED", - MasterKeyVersionState::DestroyScheduled => "MASTER_KEY_VERSION_STATE_DESTROY_SCHEDULED", - MasterKeyVersionState::Primary => "MASTER_KEY_VERSION_STATE_PRIMARY", - } - } - /// Creates an enum from field names used in the ProtoBuf definition. - pub fn from_str_name(value: &str) -> ::core::option::Option { - match value { - "MASTER_KEY_VERSION_STATE_UNSPECIFIED" => Some(Self::Unspecified), - "MASTER_KEY_VERSION_STATE_ENABLED" => Some(Self::Enabled), - "MASTER_KEY_VERSION_STATE_DISABLED" => Some(Self::Disabled), - "MASTER_KEY_VERSION_STATE_DESTROYED" => Some(Self::Destroyed), - "MASTER_KEY_VERSION_STATE_DESTROY_SCHEDULED" => Some(Self::DestroyScheduled), - "MASTER_KEY_VERSION_STATE_PRIMARY" => Some(Self::Primary), - _ => None, - } - } - } -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct CreateMasterKeyRequest { - #[prost(string, tag="1")] - pub master_key_id: ::prost::alloc::string::String, - #[prost(message, optional, tag="2")] - pub master_key: ::core::option::Option, -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ListMasterKeysRequest { -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ListMasterKeyVersionsRequest { -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct CreateMasterKeyVersionRequest { - #[prost(string, tag="1")] - pub master_key_id: ::prost::alloc::string::String, - #[prost(message, optional, tag="2")] - pub master_key_version: ::core::option::Option, -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct DestroyMasterKeyVersionRequest { - #[prost(string, tag="1")] - pub master_key_id: ::prost::alloc::string::String, -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct EncryptRequest { - #[prost(string, tag="1")] - pub master_key_id: ::prost::alloc::string::String, - #[prost(bytes="bytes", tag="2")] - pub plaintext: ::prost::bytes::Bytes, -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct DecryptRequest { - #[prost(string, tag="1")] - pub master_key_id: ::prost::alloc::string::String, - #[prost(bytes="bytes", tag="2")] - pub ciphertext: ::prost::bytes::Bytes, -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ListMasterKeysResponse { - #[prost(message, repeated, tag="1")] - pub master_keys: ::prost::alloc::vec::Vec, -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct CreateMasterKeyResponse { - #[prost(message, optional, tag="1")] - pub master_key: ::core::option::Option, -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ListMasterKeyVersionsResponse { - #[prost(message, repeated, tag="1")] - pub master_key_versions: ::prost::alloc::vec::Vec, -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct CreateMasterKeyVersionResponse { - #[prost(message, optional, tag="1")] - pub master_key_version: ::core::option::Option, -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct DestroyMasterKeyVersionResponse { - #[prost(message, optional, tag="1")] - pub master_key_version: ::core::option::Option, -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct EncryptResponse { - #[prost(string, tag="1")] - pub name: ::prost::alloc::string::String, - #[prost(bytes="bytes", tag="2")] - pub ciphertext: ::prost::bytes::Bytes, -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct DecryptResponse { - #[prost(bytes="bytes", tag="1")] - pub plaintext: ::prost::bytes::Bytes, -} -/// Encoded file descriptor set for the `valv.keystore.v1` package -pub const FILE_DESCRIPTOR_SET: &[u8] = &[ - 0x0a, 0x81, 0x14, 0x0a, 0x20, 0x76, 0x61, 0x6c, 0x76, 0x2f, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, - 0x72, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, - 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, - 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd5, 0x02, 0x0a, 0x09, 0x4d, 0x61, - 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12, 0x18, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x03, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x41, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x03, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x54, 0x69, 0x6d, 0x65, 0x12, 0x42, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, - 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x03, 0x52, - 0x07, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x48, 0x0a, 0x0f, 0x72, 0x6f, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x04, 0xe2, 0x41, - 0x01, 0x01, 0x52, 0x0e, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x69, - 0x6f, 0x64, 0x12, 0x5d, 0x0a, 0x1a, 0x64, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x5f, 0x73, 0x63, - 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x05, 0x52, 0x18, 0x64, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, - 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x22, 0xf1, 0x04, 0x0a, 0x10, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x03, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x54, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x38, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x03, 0x52, - 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x41, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x03, 0x52, 0x0a, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x56, 0x0a, 0x16, 0x73, 0x63, 0x68, - 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x03, 0x52, 0x14, 0x73, 0x63, 0x68, - 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x54, 0x69, 0x6d, - 0x65, 0x12, 0x43, 0x0a, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x5f, 0x74, 0x69, 0x6d, - 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x03, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x72, - 0x6f, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x8c, 0x02, 0x0a, 0x15, 0x4d, 0x61, 0x73, 0x74, 0x65, - 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x12, 0x28, 0x0a, 0x24, 0x4d, 0x41, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x56, - 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, - 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x24, 0x0a, 0x20, 0x4d, 0x41, - 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, - 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x45, 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x01, - 0x12, 0x25, 0x0a, 0x21, 0x4d, 0x41, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x56, - 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x44, 0x49, 0x53, - 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x12, 0x26, 0x0a, 0x22, 0x4d, 0x41, 0x53, 0x54, 0x45, - 0x52, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x45, 0x5f, 0x44, 0x45, 0x53, 0x54, 0x52, 0x4f, 0x59, 0x45, 0x44, 0x10, 0x03, 0x12, - 0x2e, 0x0a, 0x2a, 0x4d, 0x41, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x56, 0x45, - 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x44, 0x45, 0x53, 0x54, - 0x52, 0x4f, 0x59, 0x5f, 0x53, 0x43, 0x48, 0x45, 0x44, 0x55, 0x4c, 0x45, 0x44, 0x10, 0x04, 0x12, - 0x24, 0x0a, 0x20, 0x4d, 0x41, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x56, 0x45, - 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x50, 0x52, 0x49, 0x4d, - 0x41, 0x52, 0x59, 0x10, 0x05, 0x42, 0x88, 0x01, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x61, - 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0e, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, - 0xa2, 0x02, 0x03, 0x56, 0x4b, 0x58, 0xaa, 0x02, 0x10, 0x56, 0x61, 0x6c, 0x76, 0x2e, 0x4b, 0x65, - 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x10, 0x56, 0x61, 0x6c, 0x76, - 0x5c, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1c, 0x56, - 0x61, 0x6c, 0x76, 0x5c, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5c, 0x56, 0x31, 0x5c, - 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x12, 0x56, 0x61, - 0x6c, 0x76, 0x3a, 0x3a, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x3a, 0x3a, 0x56, 0x31, - 0x4a, 0x89, 0x0a, 0x0a, 0x06, 0x12, 0x04, 0x00, 0x00, 0x31, 0x01, 0x0a, 0x08, 0x0a, 0x01, 0x0c, - 0x12, 0x03, 0x00, 0x00, 0x12, 0x0a, 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, 0x02, 0x00, 0x19, 0x0a, - 0x09, 0x0a, 0x02, 0x03, 0x00, 0x12, 0x03, 0x04, 0x00, 0x28, 0x0a, 0x09, 0x0a, 0x02, 0x03, 0x01, - 0x12, 0x03, 0x05, 0x00, 0x29, 0x0a, 0x09, 0x0a, 0x02, 0x03, 0x02, 0x12, 0x03, 0x06, 0x00, 0x29, - 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x08, 0x00, 0x17, 0x01, 0x0a, 0x0a, 0x0a, 0x03, - 0x04, 0x00, 0x01, 0x12, 0x03, 0x08, 0x08, 0x11, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x00, - 0x12, 0x04, 0x09, 0x02, 0x0a, 0x30, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x05, 0x12, - 0x03, 0x09, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x09, - 0x09, 0x0d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x09, 0x10, 0x11, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x08, 0x12, 0x03, 0x0a, 0x04, 0x2f, 0x0a, 0x0f, - 0x0a, 0x08, 0x04, 0x00, 0x02, 0x00, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x0a, 0x05, 0x2e, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0x0c, 0x02, 0x0d, 0x30, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x00, 0x02, 0x01, 0x06, 0x12, 0x03, 0x0c, 0x02, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x0c, 0x1c, 0x27, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, - 0x01, 0x03, 0x12, 0x03, 0x0c, 0x2a, 0x2b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x08, - 0x12, 0x03, 0x0d, 0x04, 0x2f, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x00, 0x02, 0x01, 0x08, 0x9c, 0x08, - 0x00, 0x12, 0x03, 0x0d, 0x05, 0x2e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x02, 0x12, 0x04, - 0x0f, 0x02, 0x10, 0x30, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x06, 0x12, 0x03, 0x0f, - 0x02, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x0f, 0x13, 0x1a, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x03, 0x12, 0x03, 0x0f, 0x1d, 0x1e, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x08, 0x12, 0x03, 0x10, 0x04, 0x2f, 0x0a, 0x0f, 0x0a, 0x08, - 0x04, 0x00, 0x02, 0x02, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x10, 0x05, 0x2e, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x00, 0x02, 0x03, 0x12, 0x04, 0x12, 0x02, 0x13, 0x2d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x00, 0x02, 0x03, 0x06, 0x12, 0x03, 0x12, 0x02, 0x1a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, - 0x03, 0x01, 0x12, 0x03, 0x12, 0x1b, 0x2a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x03, 0x03, - 0x12, 0x03, 0x12, 0x2d, 0x2e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x03, 0x08, 0x12, 0x03, - 0x13, 0x04, 0x2c, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x00, 0x02, 0x03, 0x08, 0x9c, 0x08, 0x00, 0x12, - 0x03, 0x13, 0x05, 0x2b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x04, 0x12, 0x04, 0x15, 0x02, - 0x16, 0x2e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x04, 0x06, 0x12, 0x03, 0x15, 0x02, 0x1a, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x04, 0x01, 0x12, 0x03, 0x15, 0x1b, 0x35, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x00, 0x02, 0x04, 0x03, 0x12, 0x03, 0x15, 0x38, 0x39, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x00, 0x02, 0x04, 0x08, 0x12, 0x03, 0x16, 0x04, 0x2d, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x00, - 0x02, 0x04, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x16, 0x05, 0x2c, 0x0a, 0x0a, 0x0a, 0x02, 0x04, - 0x01, 0x12, 0x04, 0x19, 0x00, 0x31, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x01, 0x01, 0x12, 0x03, - 0x19, 0x08, 0x18, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x00, 0x12, 0x04, 0x1b, 0x02, 0x1c, - 0x30, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x05, 0x12, 0x03, 0x1b, 0x02, 0x08, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x1b, 0x09, 0x0d, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x1b, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x01, 0x02, 0x00, 0x08, 0x12, 0x03, 0x1c, 0x04, 0x2f, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x01, 0x02, - 0x00, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x1c, 0x05, 0x2e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x01, - 0x04, 0x00, 0x12, 0x04, 0x1e, 0x02, 0x25, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x04, 0x00, - 0x01, 0x12, 0x03, 0x1e, 0x07, 0x1c, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x00, - 0x12, 0x03, 0x1f, 0x04, 0x2d, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, - 0x12, 0x03, 0x1f, 0x04, 0x28, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x00, 0x02, - 0x12, 0x03, 0x1f, 0x2b, 0x2c, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x01, 0x12, - 0x03, 0x20, 0x04, 0x29, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, - 0x03, 0x20, 0x04, 0x24, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, - 0x03, 0x20, 0x27, 0x28, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x02, 0x12, 0x03, - 0x21, 0x04, 0x2a, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, - 0x21, 0x04, 0x25, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, 0x03, - 0x21, 0x28, 0x29, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x03, 0x12, 0x03, 0x22, - 0x04, 0x2b, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, 0x03, 0x22, - 0x04, 0x26, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x03, 0x02, 0x12, 0x03, 0x22, - 0x29, 0x2a, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x04, 0x12, 0x03, 0x23, 0x04, - 0x33, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x04, 0x01, 0x12, 0x03, 0x23, 0x04, - 0x2e, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x04, 0x02, 0x12, 0x03, 0x23, 0x31, - 0x32, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x05, 0x12, 0x03, 0x24, 0x04, 0x29, - 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x05, 0x01, 0x12, 0x03, 0x24, 0x04, 0x24, - 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x05, 0x02, 0x12, 0x03, 0x24, 0x27, 0x28, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x01, 0x12, 0x04, 0x26, 0x02, 0x27, 0x30, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x06, 0x12, 0x03, 0x26, 0x02, 0x17, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x01, 0x02, 0x01, 0x01, 0x12, 0x03, 0x26, 0x18, 0x1d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, - 0x02, 0x01, 0x03, 0x12, 0x03, 0x26, 0x20, 0x21, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, - 0x08, 0x12, 0x03, 0x27, 0x04, 0x2f, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x01, 0x02, 0x01, 0x08, 0x9c, - 0x08, 0x00, 0x12, 0x03, 0x27, 0x05, 0x2e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x02, 0x12, - 0x04, 0x29, 0x02, 0x2a, 0x30, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x06, 0x12, 0x03, - 0x29, 0x02, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x01, 0x12, 0x03, 0x29, 0x1c, - 0x27, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x03, 0x12, 0x03, 0x29, 0x2a, 0x2b, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x08, 0x12, 0x03, 0x2a, 0x04, 0x2f, 0x0a, 0x0f, 0x0a, - 0x08, 0x04, 0x01, 0x02, 0x02, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x2a, 0x05, 0x2e, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x01, 0x02, 0x03, 0x12, 0x04, 0x2c, 0x02, 0x2d, 0x30, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x01, 0x02, 0x03, 0x06, 0x12, 0x03, 0x2c, 0x02, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, - 0x02, 0x03, 0x01, 0x12, 0x03, 0x2c, 0x1c, 0x32, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, - 0x03, 0x12, 0x03, 0x2c, 0x35, 0x36, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x08, 0x12, - 0x03, 0x2d, 0x04, 0x2f, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x01, 0x02, 0x03, 0x08, 0x9c, 0x08, 0x00, - 0x12, 0x03, 0x2d, 0x05, 0x2e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x04, 0x12, 0x04, 0x2f, - 0x02, 0x30, 0x30, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x04, 0x06, 0x12, 0x03, 0x2f, 0x02, - 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x04, 0x01, 0x12, 0x03, 0x2f, 0x1c, 0x28, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x04, 0x03, 0x12, 0x03, 0x2f, 0x2b, 0x2c, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x01, 0x02, 0x04, 0x08, 0x12, 0x03, 0x30, 0x04, 0x2f, 0x0a, 0x0f, 0x0a, 0x08, 0x04, - 0x01, 0x02, 0x04, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x30, 0x05, 0x2e, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, 0x0a, 0xf1, 0x22, 0x0a, 0x1e, 0x76, 0x61, 0x6c, 0x76, 0x2f, 0x6b, 0x65, - 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, - 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, - 0x76, 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x76, 0x61, 0x6c, 0x76, - 0x2f, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x84, 0x01, 0x0a, - 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0d, 0x6d, 0x61, 0x73, 0x74, 0x65, - 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, - 0xe2, 0x41, 0x01, 0x02, 0x52, 0x0b, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x49, - 0x64, 0x12, 0x40, 0x0a, 0x0a, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, - 0x65, 0x79, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x02, 0x52, 0x09, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, - 0x4b, 0x65, 0x79, 0x22, 0x17, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x73, 0x74, 0x65, - 0x72, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x1e, 0x0a, 0x1c, - 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xa1, 0x01, 0x0a, - 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, - 0x0a, 0x0d, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x02, 0x52, 0x0b, 0x6d, 0x61, 0x73, - 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x56, 0x0a, 0x12, 0x6d, 0x61, 0x73, 0x74, - 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, - 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, - 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x02, 0x52, 0x10, - 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x22, 0x4a, 0x0a, 0x1e, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x4d, 0x61, 0x73, 0x74, 0x65, - 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0d, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x02, 0x52, - 0x0b, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x22, 0x5e, 0x0a, 0x0e, - 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, - 0x0a, 0x0d, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x02, 0x52, 0x0b, 0x6d, 0x61, 0x73, - 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x69, - 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x04, 0xe2, 0x41, 0x01, - 0x02, 0x52, 0x09, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x60, 0x0a, 0x0e, - 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, - 0x0a, 0x0d, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x02, 0x52, 0x0b, 0x6d, 0x61, 0x73, - 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0a, 0x63, 0x69, 0x70, 0x68, - 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x04, 0xe2, 0x41, - 0x01, 0x02, 0x52, 0x0a, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x22, 0x56, - 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x0b, 0x6d, 0x61, 0x73, 0x74, - 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, - 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x52, 0x0a, 0x6d, 0x61, 0x73, 0x74, - 0x65, 0x72, 0x4b, 0x65, 0x79, 0x73, 0x22, 0x55, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x3a, 0x0a, 0x0a, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, - 0x65, 0x79, 0x52, 0x09, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x22, 0x73, 0x0a, - 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x52, - 0x0a, 0x13, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x76, 0x61, - 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, - 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, - 0x11, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x22, 0x72, 0x0a, 0x1e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x74, - 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x12, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6b, - 0x65, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x22, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x73, 0x0a, 0x1f, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, - 0x79, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x12, 0x6d, 0x61, 0x73, - 0x74, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, - 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x6d, 0x61, 0x73, 0x74, 0x65, - 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x51, 0x0a, 0x0f, 0x45, - 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xe2, 0x41, - 0x01, 0x02, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0a, 0x63, 0x69, 0x70, 0x68, - 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x04, 0xe2, 0x41, - 0x01, 0x02, 0x52, 0x0a, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x22, 0x35, - 0x0a, 0x0f, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x22, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x02, 0x52, 0x09, 0x70, 0x6c, 0x61, 0x69, - 0x6e, 0x74, 0x65, 0x78, 0x74, 0x32, 0x80, 0x06, 0x0a, 0x1a, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, - 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x12, 0x66, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, - 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12, 0x28, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, - 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x29, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x74, 0x65, - 0x72, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x0e, - 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x27, - 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, - 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, - 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x78, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, - 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2e, 0x2e, 0x76, 0x61, 0x6c, - 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x76, 0x61, 0x6c, - 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7b, 0x0a, 0x16, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, - 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, - 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x17, 0x44, 0x65, 0x73, 0x74, - 0x72, 0x6f, 0x79, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, - 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x4d, 0x61, - 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, - 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x07, 0x45, 0x6e, 0x63, 0x72, - 0x79, 0x70, 0x74, 0x12, 0x20, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, - 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x07, 0x44, 0x65, 0x63, 0x72, - 0x79, 0x70, 0x74, 0x12, 0x20, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, - 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x86, 0x01, 0x0a, 0x14, 0x63, 0x6f, 0x6d, - 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, - 0x31, 0x42, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, - 0x01, 0xa2, 0x02, 0x03, 0x56, 0x4b, 0x58, 0xaa, 0x02, 0x10, 0x56, 0x61, 0x6c, 0x76, 0x2e, 0x4b, - 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x10, 0x56, 0x61, 0x6c, - 0x76, 0x5c, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1c, - 0x56, 0x61, 0x6c, 0x76, 0x5c, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5c, 0x56, 0x31, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x12, 0x56, - 0x61, 0x6c, 0x76, 0x3a, 0x3a, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x3a, 0x3a, 0x56, - 0x31, 0x4a, 0xdc, 0x10, 0x0a, 0x06, 0x12, 0x04, 0x00, 0x00, 0x5b, 0x01, 0x0a, 0x08, 0x0a, 0x01, - 0x0c, 0x12, 0x03, 0x00, 0x00, 0x12, 0x0a, 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, 0x02, 0x00, 0x19, - 0x0a, 0x09, 0x0a, 0x02, 0x03, 0x00, 0x12, 0x03, 0x04, 0x00, 0x29, 0x0a, 0x09, 0x0a, 0x02, 0x03, - 0x01, 0x12, 0x03, 0x05, 0x00, 0x2a, 0x0a, 0x0a, 0x0a, 0x02, 0x06, 0x00, 0x12, 0x04, 0x07, 0x00, - 0x11, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x06, 0x00, 0x01, 0x12, 0x03, 0x07, 0x08, 0x22, 0x0a, 0x0b, - 0x0a, 0x04, 0x06, 0x00, 0x02, 0x00, 0x12, 0x03, 0x08, 0x02, 0x50, 0x0a, 0x0c, 0x0a, 0x05, 0x06, - 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x08, 0x06, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, - 0x00, 0x02, 0x12, 0x03, 0x08, 0x16, 0x2c, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x00, 0x03, - 0x12, 0x03, 0x08, 0x37, 0x4e, 0x0a, 0x0b, 0x0a, 0x04, 0x06, 0x00, 0x02, 0x01, 0x12, 0x03, 0x09, - 0x02, 0x4d, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x09, 0x06, 0x14, - 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x01, 0x02, 0x12, 0x03, 0x09, 0x15, 0x2a, 0x0a, 0x0c, - 0x0a, 0x05, 0x06, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x09, 0x35, 0x4b, 0x0a, 0x0b, 0x0a, 0x04, - 0x06, 0x00, 0x02, 0x02, 0x12, 0x03, 0x0b, 0x02, 0x62, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, - 0x02, 0x01, 0x12, 0x03, 0x0b, 0x06, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x02, 0x02, - 0x12, 0x03, 0x0b, 0x1c, 0x38, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x02, 0x03, 0x12, 0x03, - 0x0b, 0x43, 0x60, 0x0a, 0x0b, 0x0a, 0x04, 0x06, 0x00, 0x02, 0x03, 0x12, 0x03, 0x0c, 0x02, 0x65, - 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x03, 0x01, 0x12, 0x03, 0x0c, 0x06, 0x1c, 0x0a, 0x0c, - 0x0a, 0x05, 0x06, 0x00, 0x02, 0x03, 0x02, 0x12, 0x03, 0x0c, 0x1d, 0x3a, 0x0a, 0x0c, 0x0a, 0x05, - 0x06, 0x00, 0x02, 0x03, 0x03, 0x12, 0x03, 0x0c, 0x45, 0x63, 0x0a, 0x0b, 0x0a, 0x04, 0x06, 0x00, - 0x02, 0x04, 0x12, 0x03, 0x0d, 0x02, 0x68, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x04, 0x01, - 0x12, 0x03, 0x0d, 0x06, 0x1d, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x04, 0x02, 0x12, 0x03, - 0x0d, 0x1e, 0x3c, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x04, 0x03, 0x12, 0x03, 0x0d, 0x47, - 0x66, 0x0a, 0x0b, 0x0a, 0x04, 0x06, 0x00, 0x02, 0x05, 0x12, 0x03, 0x0f, 0x02, 0x38, 0x0a, 0x0c, - 0x0a, 0x05, 0x06, 0x00, 0x02, 0x05, 0x01, 0x12, 0x03, 0x0f, 0x06, 0x0d, 0x0a, 0x0c, 0x0a, 0x05, - 0x06, 0x00, 0x02, 0x05, 0x02, 0x12, 0x03, 0x0f, 0x0e, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, - 0x02, 0x05, 0x03, 0x12, 0x03, 0x0f, 0x27, 0x36, 0x0a, 0x0b, 0x0a, 0x04, 0x06, 0x00, 0x02, 0x06, - 0x12, 0x03, 0x10, 0x02, 0x38, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x06, 0x01, 0x12, 0x03, - 0x10, 0x06, 0x0d, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x06, 0x02, 0x12, 0x03, 0x10, 0x0e, - 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x06, 0x03, 0x12, 0x03, 0x10, 0x27, 0x36, 0x0a, - 0x0a, 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x13, 0x00, 0x19, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, - 0x00, 0x01, 0x12, 0x03, 0x13, 0x08, 0x1e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x00, 0x12, - 0x04, 0x14, 0x02, 0x15, 0x2d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, - 0x14, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x14, 0x09, - 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x14, 0x19, 0x1a, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x08, 0x12, 0x03, 0x15, 0x04, 0x2c, 0x0a, 0x0f, 0x0a, - 0x08, 0x04, 0x00, 0x02, 0x00, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x15, 0x05, 0x2b, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0x17, 0x02, 0x18, 0x2d, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x00, 0x02, 0x01, 0x06, 0x12, 0x03, 0x17, 0x02, 0x0b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, - 0x02, 0x01, 0x01, 0x12, 0x03, 0x17, 0x0c, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, - 0x03, 0x12, 0x03, 0x17, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x08, 0x12, - 0x03, 0x18, 0x04, 0x2c, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x00, 0x02, 0x01, 0x08, 0x9c, 0x08, 0x00, - 0x12, 0x03, 0x18, 0x05, 0x2b, 0x0a, 0x09, 0x0a, 0x02, 0x04, 0x01, 0x12, 0x03, 0x1b, 0x00, 0x20, - 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x01, 0x01, 0x12, 0x03, 0x1b, 0x08, 0x1d, 0x0a, 0x09, 0x0a, 0x02, - 0x04, 0x02, 0x12, 0x03, 0x1d, 0x00, 0x27, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x02, 0x01, 0x12, 0x03, - 0x1d, 0x08, 0x24, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x03, 0x12, 0x04, 0x1f, 0x00, 0x25, 0x01, 0x0a, - 0x0a, 0x0a, 0x03, 0x04, 0x03, 0x01, 0x12, 0x03, 0x1f, 0x08, 0x25, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x03, 0x02, 0x00, 0x12, 0x04, 0x20, 0x02, 0x21, 0x2d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, - 0x00, 0x05, 0x12, 0x03, 0x20, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x01, - 0x12, 0x03, 0x20, 0x09, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x03, 0x12, 0x03, - 0x20, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x08, 0x12, 0x03, 0x21, 0x04, - 0x2c, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x03, 0x02, 0x00, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x21, - 0x05, 0x2b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x03, 0x02, 0x01, 0x12, 0x04, 0x23, 0x02, 0x24, 0x2d, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x06, 0x12, 0x03, 0x23, 0x02, 0x12, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x12, 0x03, 0x23, 0x13, 0x25, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x03, 0x02, 0x01, 0x03, 0x12, 0x03, 0x23, 0x28, 0x29, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, - 0x02, 0x01, 0x08, 0x12, 0x03, 0x24, 0x04, 0x2c, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x03, 0x02, 0x01, - 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x24, 0x05, 0x2b, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x04, 0x12, - 0x04, 0x27, 0x00, 0x2a, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x04, 0x01, 0x12, 0x03, 0x27, 0x08, - 0x26, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x04, 0x02, 0x00, 0x12, 0x04, 0x28, 0x02, 0x29, 0x2d, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x04, 0x02, 0x00, 0x05, 0x12, 0x03, 0x28, 0x02, 0x08, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x04, 0x02, 0x00, 0x01, 0x12, 0x03, 0x28, 0x09, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x04, 0x02, 0x00, 0x03, 0x12, 0x03, 0x28, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x04, 0x02, - 0x00, 0x08, 0x12, 0x03, 0x29, 0x04, 0x2c, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x04, 0x02, 0x00, 0x08, - 0x9c, 0x08, 0x00, 0x12, 0x03, 0x29, 0x05, 0x2b, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x05, 0x12, 0x04, - 0x2c, 0x00, 0x32, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x05, 0x01, 0x12, 0x03, 0x2c, 0x08, 0x16, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x05, 0x02, 0x00, 0x12, 0x04, 0x2d, 0x02, 0x2e, 0x2d, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x05, 0x02, 0x00, 0x05, 0x12, 0x03, 0x2d, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x05, 0x02, 0x00, 0x01, 0x12, 0x03, 0x2d, 0x09, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, - 0x02, 0x00, 0x03, 0x12, 0x03, 0x2d, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x00, - 0x08, 0x12, 0x03, 0x2e, 0x04, 0x2c, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x05, 0x02, 0x00, 0x08, 0x9c, - 0x08, 0x00, 0x12, 0x03, 0x2e, 0x05, 0x2b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x05, 0x02, 0x01, 0x12, - 0x04, 0x30, 0x02, 0x31, 0x2d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x01, 0x05, 0x12, 0x03, - 0x30, 0x02, 0x07, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x01, 0x01, 0x12, 0x03, 0x30, 0x08, - 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x01, 0x03, 0x12, 0x03, 0x30, 0x14, 0x15, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x01, 0x08, 0x12, 0x03, 0x31, 0x04, 0x2c, 0x0a, 0x0f, 0x0a, - 0x08, 0x04, 0x05, 0x02, 0x01, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x31, 0x05, 0x2b, 0x0a, 0x0a, - 0x0a, 0x02, 0x04, 0x06, 0x12, 0x04, 0x34, 0x00, 0x3a, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x06, - 0x01, 0x12, 0x03, 0x34, 0x08, 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x06, 0x02, 0x00, 0x12, 0x04, - 0x35, 0x02, 0x36, 0x2d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, 0x05, 0x12, 0x03, 0x35, - 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, 0x01, 0x12, 0x03, 0x35, 0x09, 0x16, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, 0x03, 0x12, 0x03, 0x35, 0x19, 0x1a, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, 0x08, 0x12, 0x03, 0x36, 0x04, 0x2c, 0x0a, 0x0f, 0x0a, 0x08, - 0x04, 0x06, 0x02, 0x00, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x36, 0x05, 0x2b, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x06, 0x02, 0x01, 0x12, 0x04, 0x38, 0x02, 0x39, 0x2d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x06, 0x02, 0x01, 0x05, 0x12, 0x03, 0x38, 0x02, 0x07, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x06, 0x02, - 0x01, 0x01, 0x12, 0x03, 0x38, 0x08, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x01, 0x03, - 0x12, 0x03, 0x38, 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x01, 0x08, 0x12, 0x03, - 0x39, 0x04, 0x2c, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x06, 0x02, 0x01, 0x08, 0x9c, 0x08, 0x00, 0x12, - 0x03, 0x39, 0x05, 0x2b, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x07, 0x12, 0x04, 0x3c, 0x00, 0x3e, 0x01, - 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x07, 0x01, 0x12, 0x03, 0x3c, 0x08, 0x1e, 0x0a, 0x0b, 0x0a, 0x04, - 0x04, 0x07, 0x02, 0x00, 0x12, 0x03, 0x3d, 0x02, 0x25, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, - 0x00, 0x04, 0x12, 0x03, 0x3d, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x00, 0x06, - 0x12, 0x03, 0x3d, 0x0b, 0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x00, 0x01, 0x12, 0x03, - 0x3d, 0x15, 0x20, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x00, 0x03, 0x12, 0x03, 0x3d, 0x23, - 0x24, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x08, 0x12, 0x04, 0x40, 0x00, 0x42, 0x01, 0x0a, 0x0a, 0x0a, - 0x03, 0x04, 0x08, 0x01, 0x12, 0x03, 0x40, 0x08, 0x1f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x08, 0x02, - 0x00, 0x12, 0x03, 0x41, 0x02, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x00, 0x06, 0x12, - 0x03, 0x41, 0x02, 0x0b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x00, 0x01, 0x12, 0x03, 0x41, - 0x0c, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x00, 0x03, 0x12, 0x03, 0x41, 0x19, 0x1a, - 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x09, 0x12, 0x04, 0x44, 0x00, 0x46, 0x01, 0x0a, 0x0a, 0x0a, 0x03, - 0x04, 0x09, 0x01, 0x12, 0x03, 0x44, 0x08, 0x25, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x09, 0x02, 0x00, - 0x12, 0x03, 0x45, 0x02, 0x34, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x00, 0x04, 0x12, 0x03, - 0x45, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x00, 0x06, 0x12, 0x03, 0x45, 0x0b, - 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x00, 0x01, 0x12, 0x03, 0x45, 0x1c, 0x2f, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x00, 0x03, 0x12, 0x03, 0x45, 0x32, 0x33, 0x0a, 0x0a, 0x0a, - 0x02, 0x04, 0x0a, 0x12, 0x04, 0x48, 0x00, 0x4a, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x0a, 0x01, - 0x12, 0x03, 0x48, 0x08, 0x26, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x00, 0x12, 0x03, 0x49, - 0x02, 0x2a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x00, 0x06, 0x12, 0x03, 0x49, 0x02, 0x12, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x00, 0x01, 0x12, 0x03, 0x49, 0x13, 0x25, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x00, 0x03, 0x12, 0x03, 0x49, 0x28, 0x29, 0x0a, 0x0a, 0x0a, 0x02, - 0x04, 0x0b, 0x12, 0x04, 0x4c, 0x00, 0x4e, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x0b, 0x01, 0x12, - 0x03, 0x4c, 0x08, 0x27, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x0b, 0x02, 0x00, 0x12, 0x03, 0x4d, 0x02, - 0x2a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x00, 0x06, 0x12, 0x03, 0x4d, 0x02, 0x12, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x00, 0x01, 0x12, 0x03, 0x4d, 0x13, 0x25, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x0b, 0x02, 0x00, 0x03, 0x12, 0x03, 0x4d, 0x28, 0x29, 0x0a, 0x0a, 0x0a, 0x02, 0x04, - 0x0c, 0x12, 0x04, 0x50, 0x00, 0x56, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x0c, 0x01, 0x12, 0x03, - 0x50, 0x08, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0c, 0x02, 0x00, 0x12, 0x04, 0x51, 0x02, 0x52, - 0x2d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x00, 0x05, 0x12, 0x03, 0x51, 0x02, 0x08, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x00, 0x01, 0x12, 0x03, 0x51, 0x09, 0x0d, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x0c, 0x02, 0x00, 0x03, 0x12, 0x03, 0x51, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x0c, 0x02, 0x00, 0x08, 0x12, 0x03, 0x52, 0x04, 0x2c, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x0c, 0x02, - 0x00, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x52, 0x05, 0x2b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0c, - 0x02, 0x01, 0x12, 0x04, 0x54, 0x02, 0x55, 0x2d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x01, - 0x05, 0x12, 0x03, 0x54, 0x02, 0x07, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x01, 0x01, 0x12, - 0x03, 0x54, 0x08, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x01, 0x03, 0x12, 0x03, 0x54, - 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x01, 0x08, 0x12, 0x03, 0x55, 0x04, 0x2c, - 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x0c, 0x02, 0x01, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x55, 0x05, - 0x2b, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x0d, 0x12, 0x04, 0x58, 0x00, 0x5b, 0x01, 0x0a, 0x0a, 0x0a, - 0x03, 0x04, 0x0d, 0x01, 0x12, 0x03, 0x58, 0x08, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0d, 0x02, - 0x00, 0x12, 0x04, 0x59, 0x02, 0x5a, 0x2d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x00, 0x05, - 0x12, 0x03, 0x59, 0x02, 0x07, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x00, 0x01, 0x12, 0x03, - 0x59, 0x08, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x00, 0x03, 0x12, 0x03, 0x59, 0x14, - 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x00, 0x08, 0x12, 0x03, 0x5a, 0x04, 0x2c, 0x0a, - 0x0f, 0x0a, 0x08, 0x04, 0x0d, 0x02, 0x00, 0x08, 0x9c, 0x08, 0x00, 0x12, 0x03, 0x5a, 0x05, 0x2b, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -]; -include!("valv.keystore.v1.tonic.rs"); -// @@protoc_insertion_point(module) \ No newline at end of file From 614d3e5e584145335f7a63d7d014cbd2df2848e9 Mon Sep 17 00:00:00 2001 From: Jonathan Grahl Date: Wed, 2 Oct 2024 15:21:02 +0200 Subject: [PATCH 30/30] docs: rename and correction of docs --- .../LICENSE.txt | 0 .../README.md | 58 +++++++++---------- .../model.pml | 0 3 files changed, 29 insertions(+), 29 deletions(-) rename {SPIN-verification => formal-verification}/LICENSE.txt (100%) rename {SPIN-verification => formal-verification}/README.md (71%) rename {SPIN-verification => formal-verification}/model.pml (100%) diff --git a/SPIN-verification/LICENSE.txt b/formal-verification/LICENSE.txt similarity index 100% rename from SPIN-verification/LICENSE.txt rename to formal-verification/LICENSE.txt diff --git a/SPIN-verification/README.md b/formal-verification/README.md similarity index 71% rename from SPIN-verification/README.md rename to formal-verification/README.md index c315b0f..8c7c136 100644 --- a/SPIN-verification/README.md +++ b/formal-verification/README.md @@ -1,38 +1,40 @@ # A Functional Verification of the KMS in SPIN -Verification in SPIN that verifies the functionality of KEK assignment, encryption, decryption and re-encryption.
-There are 4 different models that each verify different operations.
+Verification in SPIN that verifies the functionality of KEK assignment, encryption, decryption and re-encryption. + +There are 4 different models that each verify different operations. ## Models -Model can be set by changing the MODEL constant.
- -1=A 2=B 3=C 4=D In the paper.
+Model can be set by changing the MODEL constant. + +1=A 2=B 3=C 4=D In the paper. -1: Assignemnt and Encryption.
-2: Decryption after assignment and encryption has been finalized.
-3: Re-Encryption of envelopes after assignment and encryption has been finalized.
-4: Tenant 1 assignment and encryption then invalid credentials, Tenant 2 only Decrypts envelopes received from Tenant 1 with different grants.
+1: Assignemnt and Encryption. +2: Decryption after assignment and encryption has been finalized. +3: Re-Encryption of envelopes after assignment and encryption has been finalized. +4: Tenant 1 assignment and encryption then invalid credentials, Tenant 2 only Decrypts envelopes received from Tenant 1 with different grants. -If MODEL == 1 then IS_MODEL_1 == 1
-If MODEL != 1 then IS_MODEL_1 == 0
+If MODEL == 1 then IS_MODEL_1 == 1 +If MODEL != 1 then IS_MODEL_1 == 0 ## To Run and Verify -Most of this can be done with an external tool such as iSPIN, additional information found [here](https://spinroot.com/spin/Man/README.html).
-**Run Code**
-spin -T model.pml - Regular run that will halt on error and print any statements in the code.
-spin -a model.pml - generates pan.c for verification.
+Most of this can be done with an external tool such as iSPIN, additional information found [here](https://spinroot.com/spin/Man/README.html). -**Compile pan.c**
-gcc -DMEMLIM=N -O2 -DXUSAFE -DCOLLAPSE -DNFAIR=3 (-DSAFETY) -w -o pan pan.c
+**Run Code** +spin -T model.pml - Regular run that will halt on error and print any statements in the code. +spin -a model.pml - generates pan.c for verification. --DSAFETY used when verifying safety.
+**Compile pan.c** +gcc -DMEMLIM=N -O2 -DXUSAFE -DCOLLAPSE -DNFAIR=3 (-DSAFETY) -w -o pan pan.c -**Verify**
-./pan -mN (-a -f) (-N claim)
-In -mN, N is an integer for max depth, however -N is a flag to specify which claim to verify, e.g ./pan -m1000000 -N safety
--a -f used when verifying liveness.
+-DSAFETY used when verifying safety. + +**Verify** +./pan -mN (-a -f) (-N claim) +In -mN, N is an integer for max depth, however -N is a flag to specify which claim to verify, e.g ./pan -m1000000 -N safety +-a -f used when verifying liveness. # Additional Documentation @@ -42,23 +44,24 @@ This project implements a key management service (KMS) based on the design and f ### Architecture -The current implementation in the Valv repository does not yet fully reflect the layered architecture described in the thesis. Instead, it implements a single-layer structure with envelope encryption, where a KEK is used to encrypt data or a DEK (see encrypt() in `crates/keystore/src/lib.rs`). +The current implementation in the Valv repository does not yet fully reflect the layered architecture described in the thesis. Instead, it implements a single-layer structure with envelope encryption, where a KEK is used to encrypt data or a DEK (see encrypt() in `crates/valv/src/lib.rs`). ### Protocol Operations The verified protocol operations are partially implemented: -1. **KEK Assignment**: Implemented in `crates/keystore/src/lib.rs` in the `create_crypto_key()` function of the `KeystoreAPI` trait. The `ValvAPI` struct in `crates/valv/src/main.rs` exposes this functionality. +1. **KEK Assignment**: Implemented in `crates/valv/src/lib.rs` in the `create_crypto_key()` function of the `ValvAPI` trait. The `API` struct in `crates/valv/src/api/server.rs` exposes this functionality. -2. **Encryption**: Core encryption logic is in `crates/keystore/src/lib.rs` in the `encrypt()` function of the `KeystoreAPI` trait. The `ValvAPI` in `crates/valv/src/main.rs` will expose this through the `encrypt` method (currently unimplemented). +2. **Encryption**: Core encryption logic is in `crates/valv/src/lib.rs` in the `encrypt()` function of the `ValvAPI` trait. The `API` struct in `crates/valv/src/api/server.rs` exposes this functionality. -3. **Decryption**: Implemented in `crates/keystore/src/lib.rs` in the `decrypt()` function of the `KeystoreAPI` trait. The `ValvAPI` will expose this through the `decrypt` method in `crates/valv/src/main.rs` (currently unimplemented). +3. **Decryption**: Implemented in `crates/valv/src/lib.rs` in the `decrypt()` function of the `ValvAPI` trait. The `API` struct in `crates/valv/src/api/server.rs` exposes this functionality. 4. **Re-encryption**: Not explicitly implemented yet, but the foundation exists within the encryption and decryption functions. ### Components The implementation separates the following components: + - Tenant - Keystore - Database @@ -82,6 +85,3 @@ While the current implementation incorporates key concepts from the thesis, ther It's important to note that while the implemented protocol is based on the verified model from the thesis, the current implementation may not yet fully adhere to all the requirements verified in the thesis. Further work is needed to ensure that the implementation preserves all the properties proven in the formal verification. As development continues, this documentation should be updated to reflect progress and maintain traceability to the thesis. Any deviations from or extensions to the verified design should be carefully considered and documented. - - - diff --git a/SPIN-verification/model.pml b/formal-verification/model.pml similarity index 100% rename from SPIN-verification/model.pml rename to formal-verification/model.pml