diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 10c6976c4f..692ffdd86e 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -381,9 +381,10 @@ func (ak *SecretAppKeepers) InitCustomKeepers( reg.EnclaveApi{}, homePath, bootstrap, + app, ) ak.RegKeeper = ®Keeper - ak.CronKeeper.SetRegKeeper(regKeeper) + ak.CronKeeper.SetRegKeeper(®Keeper) // Assaf: // Rules: @@ -539,6 +540,7 @@ func (ak *SecretAppKeepers) InitCustomKeepers( ak.TransferKeeper, ak.IbcKeeper.ChannelKeeper, ak.IbcSwitchKeeper, + ak.RegKeeper, app.MsgServiceRouter(), app.GRPCQueryRouter(), computeDir, diff --git a/cmd/secretd/attestation.go b/cmd/secretd/attestation.go index de0809c067..2ab31fdda6 100644 --- a/cmd/secretd/attestation.go +++ b/cmd/secretd/attestation.go @@ -35,6 +35,7 @@ const ( flag_no_epid = "no-epid" flag_no_dcap = "no-dcap" flag_is_migration_report = "migration" + flag_unbound_attestation = "unbound-attestation" ) const ( @@ -47,6 +48,47 @@ const ( pulsarRegistrationService = "https://registration-service-testnet.azurewebsites.net/api/registernode" ) +type PrivValidatorKey struct { + PrivKey struct { + Value string `json:"value"` + } `json:"priv_key"` +} + +func CreateAttestationReportEx(cmd *cobra.Command, is_migration_report bool) error { + var ext_sk []byte + + unbound_attestation, _ := cmd.Flags().GetBool(flag_unbound_attestation) + if !unbound_attestation { + path := app.DefaultNodeHome + "/config/priv_validator_key.json" + + data, err := os.ReadFile(path) + if err != nil { + fmt.Errorf("couldn't read the validator key: %w", err) + return err + } + + var key PrivValidatorKey + if err := json.Unmarshal(data, &key); err != nil { + fmt.Errorf("couldn't decode the validator key: %w", err) + return err + } + + decoded, err := base64.StdEncoding.DecodeString(key.PrivKey.Value) + if err != nil { + fmt.Errorf("couldn't decode the validator key: %w", err) + return err + } + + ext_sk = decoded[:32] + } + + _, err := api.CreateAttestationReport(ext_sk, is_migration_report) + if err != nil { + return fmt.Errorf("failed to create attestation report: %w", err) + } + return err +} + func InitAttestation() *cobra.Command { cmd := &cobra.Command{ Use: "init-enclave [output-file]", @@ -96,8 +138,7 @@ blockchain. Writes the certificate in DER format to ~/attestation_cert } is_migration_report, _ := cmd.Flags().GetBool(flag_is_migration_report) - - _, err = api.CreateAttestationReport(is_migration_report) + err = CreateAttestationReportEx(cmd, is_migration_report) if err != nil { return fmt.Errorf("failed to create attestation report: %w", err) } @@ -108,6 +149,7 @@ blockchain. Writes the certificate in DER format to ~/attestation_cert cmd.Flags().Bool(flag_no_epid, false, "Optional flag to disable EPID attestation") cmd.Flags().Bool(flag_no_dcap, false, "Optional flag to disable DCAP attestation") cmd.Flags().Bool(flag_is_migration_report, false, "Create migration report rather then attestation") + cmd.Flags().Bool(flag_unbound_attestation, false, "Optional flag to disable attestation to user binding") return cmd } @@ -490,7 +532,7 @@ Please report any issues with this command } } - _, err = api.CreateAttestationReport(false) + err = CreateAttestationReportEx(cmd, false) if err != nil { return fmt.Errorf("failed to create attestation report: %w", err) } @@ -638,6 +680,7 @@ Please report any issues with this command cmd.Flags().Bool(flag_no_epid, false, "Optional flag to disable EPID attestation") cmd.Flags().Bool(flag_no_dcap, false, "Optional flag to disable DCAP attestation") + cmd.Flags().Bool(flag_unbound_attestation, false, "Optional flag to disable attestation to user binding") return cmd } diff --git a/cosmwasm/enclaves/Cargo.lock b/cosmwasm/enclaves/Cargo.lock index 07a2360370..121f585095 100644 --- a/cosmwasm/enclaves/Cargo.lock +++ b/cosmwasm/enclaves/Cargo.lock @@ -1010,6 +1010,12 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + [[package]] name = "home" version = "0.5.9" @@ -1807,6 +1813,7 @@ dependencies = [ "enclave_crypto", "enclave_utils", "hex", + "hex-literal", "httparse", "itertools 0.8.2", "lazy_static", @@ -2206,7 +2213,7 @@ dependencies = [ [[package]] name = "tendermint" version = "0.38.0" -source = "git+https://github.com/scrtlabs/tendermint-rs?tag=v0.38.0-secret.7-beta#945e948889ddc56414d081efd56a7b7ca7449aa4" +source = "git+https://github.com/scrtlabs/tendermint-rs?tag=v0.38.0-secret.7#cebe0ae2b16f0f4876abb2a90903ddce1cbfe7d0" dependencies = [ "bytes 1.7.1", "digest 0.10.7", @@ -2234,7 +2241,7 @@ dependencies = [ [[package]] name = "tendermint-light-client-verifier" version = "0.38.0" -source = "git+https://github.com/scrtlabs/tendermint-rs?tag=v0.38.0-secret.7-beta#945e948889ddc56414d081efd56a7b7ca7449aa4" +source = "git+https://github.com/scrtlabs/tendermint-rs?tag=v0.38.0-secret.7#cebe0ae2b16f0f4876abb2a90903ddce1cbfe7d0" dependencies = [ "derive_more", "flex-error", @@ -2246,7 +2253,7 @@ dependencies = [ [[package]] name = "tendermint-proto" version = "0.38.0" -source = "git+https://github.com/scrtlabs/tendermint-rs?tag=v0.38.0-secret.7-beta#945e948889ddc56414d081efd56a7b7ca7449aa4" +source = "git+https://github.com/scrtlabs/tendermint-rs?tag=v0.38.0-secret.7#cebe0ae2b16f0f4876abb2a90903ddce1cbfe7d0" dependencies = [ "bytes 1.7.1", "flex-error", diff --git a/cosmwasm/enclaves/execute/Cargo.toml b/cosmwasm/enclaves/execute/Cargo.toml index 2ae245340e..3c2d6da1bb 100644 --- a/cosmwasm/enclaves/execute/Cargo.toml +++ b/cosmwasm/enclaves/execute/Cargo.toml @@ -95,7 +95,7 @@ tendermint-proto = { git = "https://github.com/scrtlabs/tendermint-rs", tag = "v tendermint-light-client-verifier = { git = "https://github.com/scrtlabs/tendermint-rs", tag = "v0.38.0-secret.7", default-features = false, features = ["rust-crypto"] } rsa = { version = "0.9", default-features = false, features = ["sha2"] } base64ct = { version = "1.6", default-features = false, features = ["alloc"] } - +hex-literal = "0.4" [dependencies.webpki] git = "https://github.com/mesalock-linux/webpki" diff --git a/cosmwasm/enclaves/execute/Enclave.edl b/cosmwasm/enclaves/execute/Enclave.edl index b26ac9ae55..ef7d704a63 100644 --- a/cosmwasm/enclaves/execute/Enclave.edl +++ b/cosmwasm/enclaves/execute/Enclave.edl @@ -51,12 +51,20 @@ enclave { public sgx_status_t ecall_onchain_approve_machine_id( [in, count=n_id] const uint8_t* p_id, - uint32_t n_id, - [in, out, count=32] uint8_t* p_proof, - bool is_on_chain + uint32_t n_id + ); + + public sgx_status_t ecall_submit_machine_swap( + uint32_t index, + [in, count=n_machine_info] const uint8_t* p_machine_info, + uint32_t n_machine_info, + [in, count=n_proof] const uint8_t* p_proof, + uint32_t n_proof ); public sgx_status_t ecall_get_attestation_report( + [in, count=n_sk] const uint8_t* p_sk, + uint32_t n_sk, uint32_t flags ); @@ -65,7 +73,9 @@ enclave { uintptr_t cert_len, [out, count=n_seeds] uint8_t* p_seeds, uintptr_t n_seeds, - [out] uintptr_t* p_seeds_size + [out] uintptr_t* p_seeds_size, + [in, count=20] const uint8_t* p_machine_pop, + [out, count=52] uint8_t* p_machine_info ); public NodeAuthResult ecall_check_patch_level( diff --git a/cosmwasm/enclaves/execute/src/registration/attestation.rs b/cosmwasm/enclaves/execute/src/registration/attestation.rs index 189b646ebf..57c87207cd 100644 --- a/cosmwasm/enclaves/execute/src/registration/attestation.rs +++ b/cosmwasm/enclaves/execute/src/registration/attestation.rs @@ -106,6 +106,113 @@ impl KnownJwtKeys { } } +pub mod allow_list { + + use enclave_utils::KEY_MANAGER; + use log::*; + use std::collections::HashMap; + + use crate::registration::attestation::SELF_MACHINE_ID; + + pub const MACHINE_ID_LEN: usize = 20; + pub const OWNER_LEN: usize = 32; + + pub type MachineID = [u8; MACHINE_ID_LEN]; + pub type Owner = [u8; OWNER_LEN]; + + pub struct Data { + pub m_to_o: HashMap, + } + + impl Data { + fn log_machine_change(machine: &MachineID, owner: &Owner) { + println!( + "machine {} owner set to {}", + hex::encode(machine), + hex::encode(owner) + ); + } + + fn on_machine_changed(machine: &MachineID, added: bool, silent: bool) { + if !silent { + let action = if added { "added" } else { "deleted" }; + println!("machine {} {}", hex::encode(machine), action); + } + + if let Some(my_machine) = SELF_MACHINE_ID.as_ref() { + if my_machine == machine { + println!("Self machine included: {}", added); + + let mut extra = KEY_MANAGER.extra_data.lock().unwrap(); + extra.machine_allowed = added; + } + } + } + + pub fn update( + &mut self, + machine: &MachineID, + owner: &Owner, + machine_pop: &MachineID, + ) -> bool { + let is_same_machine = + (*machine_pop == [0u8; MACHINE_ID_LEN]) || (*machine_pop == *machine); + if is_same_machine { + let x = match self.m_to_o.get_mut(machine) { + Some(x) => x, + None => { + error!("unknown machine {}", hex::encode(machine)); + return false; + } + }; + + if x == owner { + return false; // no error, just no effect + } + + *x = *owner; // replace the owner of + } else { + if let Some(x) = self.m_to_o.get(machine_pop) { + if *x != *owner { + error!( + "unknown machine {} not owned by this actor", + hex::encode(machine_pop) + ); + return false; + } + } else { + error!("unknown machine {}", hex::encode(machine_pop)); + return false; + } + + if self.m_to_o.contains_key(machine) { + error!("machine {} already exists", hex::encode(machine)); + return false; + } + + self.m_to_o.remove(machine_pop); + self.m_to_o.insert(*machine, *owner); + + Self::on_machine_changed(machine_pop, false, false); + Self::on_machine_changed(machine, true, false); + } + + Self::log_machine_change(machine, owner); + true + } + + pub fn add_new(&mut self, machine: MachineID, silent: bool) -> bool { + if let std::collections::hash_map::Entry::Vacant(e) = self.m_to_o.entry(machine) { + e.insert([0u8; OWNER_LEN]); + Self::on_machine_changed(&machine, true, silent); + true + } else { + false + } + } + } +} + lazy_static::lazy_static! { static ref KNOWN_JWT_KEYS: KnownJwtKeys = { @@ -140,156 +247,164 @@ lazy_static::lazy_static! { keys }; - pub static ref PPID_WHITELIST: SgxMutex> = { - let mut set: HashSet<[u8; 20]> = HashSet::new(); - - set.insert([0x01,0x50,0x7c,0x95,0x77,0x89,0xb7,0xc1,0xaf,0xde,0x97,0x2d,0x67,0xf1,0xfd,0xd5,0x3a,0xf1,0xa8,0xda]); - set.insert([0x03,0x37,0x2b,0x2a,0x39,0xe0,0x71,0x3c,0x96,0x5a,0x08,0x76,0xb5,0xe8,0x07,0xb4,0x1d,0x50,0x95,0x38]); - set.insert([0x04,0xf0,0x14,0x07,0xb7,0x62,0xaf,0x16,0xdb,0x04,0xac,0x64,0x8a,0xee,0x5f,0xeb,0x24,0xcf,0x6e,0xb8]); - set.insert([0x05,0x04,0x30,0x40,0x8a,0x4c,0xea,0xe5,0xd0,0xb9,0xd9,0x57,0x21,0xd6,0x51,0x22,0x2c,0xbd,0x83,0xd3]); - set.insert([0x05,0x1f,0x83,0xeb,0x42,0xdf,0xdd,0x78,0x50,0x08,0x6c,0xf5,0x69,0x6f,0xbb,0x36,0x53,0xf8,0x83,0xae]); - set.insert([0x09,0xe9,0x87,0x5e,0xd7,0xac,0xd4,0x2c,0x7d,0xd1,0x9d,0x72,0xa3,0x95,0x24,0xf6,0xae,0x3e,0x87,0xfa]); - set.insert([0x11,0x21,0xe6,0xd9,0xa7,0x70,0xc9,0xe5,0x62,0xae,0x42,0x30,0x12,0x08,0x0e,0x52,0x76,0x5e,0xcf,0x71]); - set.insert([0x13,0xf1,0x08,0xbd,0xf8,0xfd,0x3f,0x11,0xe7,0x50,0x26,0xd9,0x8e,0xd1,0x80,0x30,0x75,0x25,0x73,0x54]); - set.insert([0x14,0xd1,0x23,0x60,0x33,0xfd,0xe3,0x1e,0x0b,0xcd,0x57,0x0c,0x32,0x91,0xea,0xa9,0xbd,0xb7,0xe2,0x5e]); - set.insert([0x16,0x32,0xea,0x13,0x05,0x1c,0xc4,0xd3,0x92,0xcb,0x8d,0x3e,0x01,0x6e,0xb5,0x61,0x7d,0x8e,0x8b,0x2a]); - set.insert([0x18,0x81,0x20,0xcd,0x27,0xf6,0x58,0xa7,0x29,0x2c,0x46,0x6f,0x6c,0x7d,0xf5,0xaf,0x6c,0xdb,0x96,0x6e]); - set.insert([0x1a,0x24,0x25,0xc4,0x95,0x55,0x55,0xf0,0xea,0x8c,0x03,0x15,0xe1,0x16,0xe0,0x13,0x5f,0x3a,0x04,0xc9]); - set.insert([0x1a,0xe4,0xfb,0x51,0x62,0x6d,0x0d,0x27,0x4c,0x0b,0xd3,0x85,0x1e,0x5a,0x04,0xde,0xe0,0xb0,0xd5,0x3b]); - set.insert([0x1b,0x3a,0xad,0xe4,0x41,0xad,0xd6,0x58,0xf9,0xf9,0x5c,0x10,0xce,0x0f,0x3d,0x75,0x4f,0x92,0xa3,0x27]); - set.insert([0x1c,0x8b,0xe8,0x11,0xc0,0x91,0x85,0xa9,0xf6,0xc7,0xdc,0x3f,0xba,0x81,0xe8,0x78,0xa5,0x8d,0x0a,0x1b]); - set.insert([0x20,0x59,0x8f,0xcb,0x4b,0xa5,0x79,0xc5,0xa0,0x9e,0x8c,0x1a,0x42,0xec,0x9c,0x02,0x10,0xcb,0x43,0xf3]); - set.insert([0x20,0x87,0x68,0x85,0x22,0x96,0x5e,0xb0,0x4c,0x9a,0xe9,0xf3,0x3e,0xa9,0x4b,0xbf,0x82,0x08,0x78,0xf1]); - set.insert([0x21,0x1f,0x0f,0x55,0x70,0xf7,0xaa,0xbf,0xe6,0xa8,0xb7,0xcf,0x77,0xde,0xc8,0xd3,0x3d,0xd5,0xfe,0xea]); - set.insert([0x21,0xca,0xe8,0x22,0x31,0x4c,0x17,0x72,0x16,0x77,0xc4,0x1c,0xd8,0x42,0x34,0x64,0x98,0x35,0x53,0xc1]); - set.insert([0x22,0x1c,0xd8,0x23,0x4e,0x36,0x9e,0xf1,0x9d,0xfd,0xad,0x94,0xf4,0x37,0xd3,0xa1,0x90,0xcb,0x26,0x73]); - set.insert([0x24,0x91,0xb9,0xa2,0x2f,0x4b,0x3d,0x45,0x82,0xaf,0x20,0x92,0x19,0x19,0xbc,0x27,0x71,0xc8,0x0f,0xde]); - set.insert([0x26,0x67,0x1a,0x09,0x31,0xeb,0xde,0x25,0x27,0x37,0x36,0xbf,0x6b,0x4b,0x2e,0xd1,0x03,0x8c,0x44,0x43]); - set.insert([0x28,0x04,0x9f,0x3f,0x69,0xf6,0x55,0x83,0x24,0xe5,0x2d,0x44,0xec,0xde,0xf8,0x97,0xb1,0xa3,0xb3,0x90]); - set.insert([0x28,0x54,0xe3,0xe3,0x89,0x49,0x86,0x16,0x8e,0x90,0xce,0x3a,0x01,0x7b,0xfe,0xcf,0x65,0xce,0x79,0x11]); - set.insert([0x29,0xf3,0xc4,0x1b,0xbf,0x0d,0xbd,0x38,0xfd,0x4b,0x05,0x2d,0x27,0xca,0x64,0x86,0xa9,0x06,0x68,0x8d]); - set.insert([0x2a,0x00,0x3f,0x2b,0x90,0x8b,0x08,0x47,0x6b,0xe2,0x5d,0x01,0x1c,0x57,0xfe,0x11,0xfc,0x68,0x92,0xf9]); - set.insert([0x30,0x7b,0xbc,0xfb,0x24,0xab,0xdb,0x94,0xa6,0xb7,0xca,0xba,0xdd,0xb9,0x19,0x04,0x64,0x03,0xff,0xe6]); - set.insert([0x31,0x5d,0xb0,0x4d,0xf6,0x69,0x89,0x4a,0x3e,0x35,0x42,0x96,0x91,0xb8,0xb3,0x50,0xd8,0xcb,0xcd,0xe2]); - set.insert([0x32,0xea,0x0b,0xc9,0x08,0x31,0xa8,0xfb,0x98,0x8c,0x20,0x8e,0x53,0x28,0xac,0x7b,0x64,0xeb,0x29,0x8d]); - set.insert([0x34,0x6d,0xf4,0xcc,0xe9,0xf2,0x7b,0x23,0xc5,0xf0,0x82,0x3e,0xe9,0xd2,0x60,0xc1,0x66,0xfe,0xd3,0xdb]); - set.insert([0x35,0x99,0xc4,0x8a,0x2a,0x1b,0xbf,0xf8,0x74,0xda,0xc4,0x6d,0x98,0x6a,0x51,0x2f,0x69,0xfb,0xc8,0xd0]); - set.insert([0x36,0xa3,0x75,0x06,0xdc,0xc6,0x2a,0x21,0x53,0xae,0x3d,0xa7,0x41,0xf5,0x6a,0x01,0xbe,0xd5,0x42,0x67]); - set.insert([0x3e,0x68,0x30,0xd6,0xa2,0xd8,0x39,0xbf,0x36,0xbb,0x10,0x8c,0xa8,0xcc,0xc2,0x5a,0x16,0x78,0xf8,0x2f]); - set.insert([0x40,0x83,0x2a,0x64,0xb2,0x7c,0x12,0xc7,0xab,0xe6,0xbe,0x09,0x47,0x16,0x3e,0xe4,0x83,0x47,0x8c,0x61]); - set.insert([0x41,0x01,0xa8,0x18,0x7d,0x20,0x88,0x9c,0x4f,0xd2,0x47,0xb4,0xc8,0x27,0x9b,0x66,0x31,0x8e,0xf0,0x91]); - set.insert([0x42,0x26,0xd0,0x78,0x02,0x9b,0x9b,0xe4,0xf3,0x2a,0x61,0x5e,0x92,0x90,0xdb,0xcd,0xe3,0xd5,0x5f,0x76]); - set.insert([0x44,0x3b,0x01,0xf0,0x77,0x19,0xd7,0xce,0x6c,0xbd,0xe8,0x61,0x08,0x2a,0x33,0x18,0x1b,0xb2,0x4e,0x4c]); - set.insert([0x44,0xe1,0x05,0x97,0xb4,0x2e,0x57,0x14,0x23,0x91,0x53,0x85,0xfe,0x85,0xce,0xd0,0xe8,0x40,0x85,0x0c]); - set.insert([0x46,0x1b,0xe5,0xde,0x74,0xce,0x83,0x3d,0x38,0x28,0xfc,0xb5,0x7c,0x24,0x3b,0x60,0x15,0xd7,0x6d,0x7f]); - set.insert([0x48,0x82,0x28,0x89,0x4e,0x72,0x65,0xff,0x74,0xd9,0x74,0x95,0xd2,0xd5,0x36,0xb9,0xc7,0xf5,0x74,0x11]); - set.insert([0x4a,0xf5,0xd9,0x4e,0x22,0x81,0xe2,0xa4,0xc2,0x3e,0xd8,0x4c,0x4a,0x05,0xaa,0x5e,0x7a,0x31,0x78,0xd2]); - set.insert([0x4e,0x09,0x78,0x81,0x59,0x00,0x8f,0x91,0xd7,0xf3,0xd6,0x8b,0x1a,0xf2,0x35,0x5b,0x3c,0x17,0x72,0xcc]); - set.insert([0x4f,0xf7,0xe9,0x72,0x4d,0x98,0xc5,0x0d,0x61,0x18,0xf6,0x5f,0x30,0x04,0xa1,0xfc,0xcd,0xed,0x1a,0xd8]); - set.insert([0x50,0x0f,0x64,0x49,0xb9,0x7e,0x2b,0xe1,0xe6,0x8f,0x0c,0xb1,0xed,0x59,0xde,0xe3,0xc8,0xe6,0xd9,0xc0]); - set.insert([0x51,0xc1,0xed,0xe1,0x8e,0x73,0xfc,0x7e,0x00,0xe8,0xfc,0x01,0x8e,0xde,0x53,0x63,0x2f,0x8b,0xb6,0xd9]); - set.insert([0x53,0x54,0x3f,0x1a,0x7d,0x08,0xc1,0x3d,0x69,0x38,0x5b,0x81,0x20,0x56,0x2a,0x76,0xb8,0x71,0xf8,0xec]); - set.insert([0x57,0x19,0x8e,0xb3,0x6e,0x5c,0x99,0x68,0x63,0xb6,0x26,0xeb,0x6f,0x23,0xe3,0x87,0x7c,0xb2,0xed,0x17]); - set.insert([0x57,0xa6,0x87,0x7d,0x0e,0x96,0xce,0x77,0xa3,0xfa,0xfb,0x0c,0x2f,0x7e,0x9e,0xd9,0xe2,0x8f,0xb0,0x37]); - set.insert([0x5a,0xf0,0xf7,0x3c,0x1e,0x99,0xf5,0x5f,0x27,0xd0,0x22,0x40,0x0f,0x5c,0x4b,0x92,0x16,0x59,0x35,0x32]); - set.insert([0x5d,0x73,0xa5,0x89,0xb3,0x57,0xf4,0xe7,0xad,0x59,0x9b,0x4a,0x4a,0x7e,0x43,0x38,0xcd,0x73,0x30,0x18]); - set.insert([0x60,0x8a,0x11,0xe7,0xce,0x88,0xe1,0xab,0xd1,0xc5,0x4a,0x35,0x66,0xcc,0x7b,0x63,0x32,0xbe,0x05,0xb5]); - set.insert([0x61,0x89,0x7d,0x03,0x10,0x11,0x02,0x14,0x03,0x5b,0xcb,0xad,0x0f,0x7a,0x46,0xff,0x44,0x7e,0xc0,0xe7]); - set.insert([0x67,0x44,0x97,0x91,0x8b,0x42,0x04,0xd3,0xe6,0x86,0xba,0x23,0x40,0x8a,0x9a,0xa2,0x16,0xb2,0x22,0x7a]); - set.insert([0x68,0x92,0x8a,0xa2,0xc3,0x16,0x7d,0x75,0xd5,0x66,0xe5,0x4b,0x47,0x54,0x62,0xaa,0x28,0x72,0xcb,0x2f]); - set.insert([0x69,0x25,0xe6,0x6c,0x41,0xbb,0x7e,0x7f,0x5e,0xc3,0x80,0x8f,0x7a,0xe7,0xa0,0x5c,0x41,0x9f,0xec,0xc4]); - set.insert([0x6a,0x81,0xac,0x2a,0x32,0xcc,0x2e,0xac,0x4b,0x97,0x4b,0x18,0x19,0xed,0x2b,0x75,0x68,0xc8,0x3c,0x04]); - set.insert([0x6c,0xe7,0x2a,0xa2,0x20,0x18,0x62,0x2c,0x24,0xa2,0xc0,0xaa,0xc4,0x5f,0x14,0x61,0x7a,0xec,0x59,0xe5]); - set.insert([0x70,0xb9,0x31,0x35,0x3e,0x39,0x25,0xbb,0xf3,0xdd,0x70,0x04,0x6f,0x32,0x91,0x1c,0x97,0x61,0xfc,0xa6]); - set.insert([0x74,0x02,0xb6,0x3c,0x09,0xf3,0x52,0x09,0x31,0xda,0xc2,0xf9,0xf7,0x02,0xce,0x16,0x50,0x3d,0x36,0x48]); - set.insert([0x78,0x27,0x70,0x25,0x3c,0x0a,0xe7,0x2e,0xdd,0x91,0x13,0x8a,0xd0,0x01,0x7c,0xdb,0x9a,0x7d,0x8d,0xba]); - set.insert([0x79,0x17,0x73,0xaa,0x0b,0x8a,0xe2,0xdc,0x8c,0xb7,0x5e,0xb9,0xd5,0x64,0xa0,0xd5,0x98,0x12,0x55,0x72]); - set.insert([0x7a,0x89,0xc9,0xdd,0x73,0x83,0xdd,0xe2,0x74,0x19,0xb3,0x6e,0x2c,0x6d,0x0d,0x94,0x2e,0xee,0x85,0xd9]); - set.insert([0x7d,0x0a,0xf9,0xbb,0xd9,0x4b,0xc0,0xcc,0xa2,0x26,0x84,0xe8,0x6a,0xc6,0x2b,0x58,0xe5,0x13,0x42,0x23]); - set.insert([0x7f,0x1c,0x69,0x94,0x72,0x96,0x37,0xe3,0xfd,0x4c,0xc2,0xf5,0xfa,0xae,0xb9,0xbf,0xfb,0x17,0xc1,0xa2]); - set.insert([0x80,0x3b,0xce,0xe8,0xa4,0x72,0x47,0xaa,0x76,0x2a,0x29,0xd9,0xed,0x59,0xd6,0x3d,0xef,0xc5,0xf8,0x61]); - set.insert([0x80,0xfc,0xb4,0xf6,0xf0,0x86,0xe6,0xbb,0xd8,0x32,0x50,0x0c,0x2b,0x72,0x9c,0x26,0xb3,0xbf,0x1a,0xd2]); - set.insert([0x81,0x3b,0xf8,0x20,0xfd,0x54,0x35,0xd0,0x3d,0xb7,0xbb,0xeb,0x04,0xd2,0xc3,0x42,0x17,0xf2,0xf9,0x49]); - set.insert([0x84,0xca,0x01,0x28,0x46,0x31,0x54,0x15,0x12,0x65,0x21,0xd8,0xaf,0xdf,0x5d,0xda,0x5f,0x77,0x53,0x06]); - set.insert([0x87,0x96,0xf5,0x16,0xe2,0x3e,0x15,0x62,0x4e,0x50,0xe6,0xd3,0x4a,0x3a,0xb4,0xd8,0x12,0xfd,0xca,0x7e]); - set.insert([0x8f,0x06,0xc7,0xf4,0xf5,0xf8,0x68,0x42,0xae,0xe7,0x84,0x33,0x70,0x21,0xeb,0xd5,0x9d,0x4a,0xf9,0xf1]); - set.insert([0x8f,0xc9,0x82,0x1d,0xbf,0xa8,0x3b,0x21,0x7f,0x8f,0x61,0xf1,0xf4,0x1f,0x05,0x74,0x25,0xdc,0xd3,0xb6]); - set.insert([0x8f,0xfb,0xc5,0xef,0x59,0xef,0x9f,0x22,0x89,0xe7,0x4a,0x37,0x45,0x03,0x9d,0x90,0x0f,0xba,0x30,0xfe]); - set.insert([0x90,0x48,0xc1,0x42,0xde,0x1f,0xe7,0x0d,0x3e,0xf4,0xa9,0x10,0x7c,0xcf,0xbe,0x23,0x5d,0xf5,0x36,0xc0]); - set.insert([0x92,0x16,0x6c,0x98,0x8e,0x5e,0x02,0x18,0x4b,0xf2,0xd5,0xb3,0xb9,0x7a,0x1e,0x76,0xbd,0x61,0x12,0xfe]); - set.insert([0x93,0xbd,0x0a,0x2c,0x4b,0x01,0xd3,0xfb,0x0f,0x21,0xb0,0x72,0xc0,0x4f,0xee,0xea,0x7e,0x64,0x9a,0xe2]); - set.insert([0x97,0x58,0x7e,0x41,0x8d,0xc1,0xaf,0xbc,0xa9,0x93,0x9c,0x06,0xcc,0xb9,0x7f,0x31,0x15,0xc5,0x8c,0x65]); - set.insert([0x98,0xcb,0x37,0x1d,0x43,0x68,0x2e,0xb8,0x7d,0x6f,0xb1,0xac,0x1c,0x95,0x89,0xd7,0x9f,0xcd,0x69,0xce]); - set.insert([0x9a,0xce,0x47,0xea,0xcb,0xe6,0xab,0x51,0x12,0xbd,0x6d,0x8e,0xbc,0x55,0x5b,0x0f,0xef,0x9f,0x23,0x32]); - set.insert([0x9c,0x80,0xbc,0x6b,0xf4,0x58,0x6e,0xdb,0x26,0x89,0xc3,0x09,0x3a,0x9a,0x0a,0xec,0xa3,0x01,0x48,0x05]); - set.insert([0x9d,0x08,0x17,0x1e,0xc1,0xca,0xe6,0xce,0x1e,0xa0,0xce,0x3f,0x36,0x74,0xfa,0x5d,0x01,0xf6,0xf1,0xb3]); - set.insert([0x9d,0x3f,0x11,0x60,0xd2,0x15,0xe9,0x43,0x8a,0x60,0x1c,0x87,0x71,0xa9,0x72,0xbc,0xeb,0xe0,0x97,0xf0]); - set.insert([0x9e,0x83,0x20,0x46,0x27,0x33,0xed,0x8a,0x12,0x4f,0xc9,0x7d,0x7f,0xdf,0x33,0x84,0x0b,0x6e,0x3a,0x2c]); - set.insert([0x9e,0xbd,0x6f,0x9e,0x55,0x0f,0x0d,0x6d,0xd0,0x0d,0xe5,0x25,0x5f,0x03,0xde,0xd6,0x1e,0x17,0xe2,0xc7]); - set.insert([0xa0,0x2f,0x25,0xaf,0xce,0x5e,0xea,0xb3,0x21,0xa4,0xe7,0x69,0x43,0xe5,0x6d,0x6e,0x9a,0xa7,0x3f,0xe4]); - set.insert([0xa0,0x41,0x7d,0x62,0x7d,0x22,0x5e,0x21,0x54,0x3c,0xf9,0xa9,0x1b,0x2d,0x83,0xb9,0x5f,0x09,0x1d,0xc6]); - set.insert([0xa4,0x0b,0x94,0x76,0xfb,0x30,0x5c,0x1d,0x39,0x75,0x2f,0xd4,0x85,0x48,0xc5,0xfa,0x3c,0x37,0x15,0x71]); - set.insert([0xa4,0x68,0x49,0x55,0x2c,0x73,0x63,0x28,0x5b,0xae,0xdb,0x5a,0x6b,0x68,0x14,0x80,0x9a,0x59,0xed,0x92]); - set.insert([0xa6,0xad,0xab,0xb2,0xa2,0x5d,0x23,0x3c,0x62,0xaf,0xd1,0xfc,0x0e,0x99,0x1d,0x25,0x13,0xdc,0x11,0xd4]); - set.insert([0xac,0x47,0xf3,0x11,0x51,0x09,0xba,0xeb,0x98,0xde,0xaf,0xdc,0xbd,0x98,0x01,0x17,0xb4,0xe2,0x86,0xba]); - set.insert([0xaf,0x15,0x78,0xfb,0xef,0x76,0x67,0x2f,0xef,0x3b,0x92,0x50,0xb3,0x0c,0xef,0x40,0x7e,0x78,0xfd,0x26]); - set.insert([0xb2,0xed,0x08,0x99,0x4a,0xe4,0xd6,0xdb,0x46,0xb3,0x16,0xd3,0x84,0x38,0x0f,0x69,0x63,0x64,0x04,0xfa]); - set.insert([0xb2,0xfb,0xe8,0xa9,0xd6,0xb1,0x7f,0x9a,0xf5,0x11,0x0a,0xb5,0x56,0xd8,0xb1,0x44,0xbc,0x74,0x96,0x4d]); - set.insert([0xb3,0xc0,0xa1,0x40,0x68,0x94,0xe9,0x31,0x96,0x1e,0x0f,0xe3,0x4a,0x68,0xbd,0x01,0x48,0x33,0x7e,0x58]); - set.insert([0xb4,0xcd,0xc2,0xe6,0x62,0x0d,0xfd,0x8c,0x5d,0x56,0x50,0x41,0x28,0x47,0x14,0xc3,0x80,0x79,0xc7,0x4c]); - set.insert([0xb7,0xed,0x7f,0x4a,0x12,0x88,0xc9,0x8c,0x49,0xb4,0x6a,0x6a,0xf8,0x56,0x53,0x2e,0x65,0xea,0xed,0xab]); - set.insert([0xbb,0x98,0x12,0x7d,0x89,0xb2,0xe3,0xf4,0xf9,0xdb,0x41,0x0b,0x06,0x0e,0x0a,0xff,0xa4,0x8e,0x07,0xef]); - set.insert([0xbb,0xed,0x9a,0xc0,0xc3,0xb9,0x20,0x3d,0x4d,0xa1,0x9c,0xab,0x34,0xfb,0xfb,0x8c,0xe6,0xa4,0x41,0x1c]); - set.insert([0xbd,0x55,0xe8,0x13,0xdb,0x24,0x5b,0x64,0xf2,0x26,0x9f,0xc7,0x67,0xee,0x1d,0xb1,0x0a,0xd9,0xdf,0x94]); - set.insert([0xbf,0x10,0x1c,0x4d,0xe9,0x0c,0xdc,0x2e,0x66,0x74,0x44,0x38,0x39,0x1f,0x60,0xce,0xa9,0x77,0xc9,0xcc]); - set.insert([0xc1,0x33,0xf0,0xc3,0x75,0x1a,0x90,0x85,0x84,0xdc,0xdf,0x32,0x2d,0x72,0xb5,0x17,0x7c,0x12,0xe7,0x32]); - set.insert([0xc2,0xf7,0xf3,0xb6,0x0a,0xcd,0xe8,0xdd,0xff,0x16,0x71,0x04,0xc5,0x6e,0x1e,0xd5,0xa1,0xe3,0xeb,0x74]); - set.insert([0xc3,0x10,0x8f,0xa4,0x05,0xef,0x44,0xa7,0x1a,0x5d,0x88,0x03,0x21,0xe0,0x9a,0x62,0x0f,0x7f,0x4f,0x76]); - set.insert([0xc3,0x1a,0x7d,0x5c,0x50,0x80,0xd9,0x0a,0x62,0x0d,0x36,0x48,0x54,0xba,0x33,0x6d,0xc8,0x2c,0xb2,0xc1]); - set.insert([0xc4,0xad,0x39,0x80,0xab,0x87,0x72,0xd4,0xd6,0x3b,0x0a,0x7f,0x51,0xba,0xdf,0x00,0x65,0xdc,0x09,0x5a]); - set.insert([0xc4,0xc1,0x07,0x66,0xc4,0x48,0x9b,0x71,0x77,0xcf,0x5a,0x21,0xa0,0xdc,0x48,0xe6,0x89,0x99,0x9a,0xe8]); - set.insert([0xc4,0xc2,0xef,0x79,0x5e,0x37,0x11,0x16,0xee,0xa7,0xfe,0x8b,0x98,0x1e,0x38,0xb7,0xe0,0xcf,0x10,0x17]); - set.insert([0xc6,0x45,0xec,0xce,0xbc,0x5a,0xa8,0x19,0x3b,0x4b,0xe8,0x5c,0x71,0xec,0x55,0x0f,0x6e,0x0b,0xf6,0xe9]); - set.insert([0xc6,0x65,0x51,0xe2,0xc5,0x57,0x6b,0x91,0xe2,0x95,0x4d,0xca,0x76,0x79,0xa9,0x26,0x65,0xf5,0x89,0x4c]); - set.insert([0xc8,0x63,0x8d,0xc5,0xe9,0x29,0x33,0x70,0x9f,0x64,0x7c,0xa7,0xab,0x78,0xee,0xb3,0x9d,0x39,0x95,0x75]); - set.insert([0xc9,0xb2,0x52,0x64,0x1d,0xfc,0xbd,0xf9,0x58,0x78,0xb1,0xcc,0x03,0x19,0x21,0x2c,0x74,0x1c,0xfe,0xad]); - set.insert([0xcb,0xfd,0xda,0x92,0x33,0x07,0xf8,0xab,0x91,0x89,0x71,0x31,0xb6,0x13,0xb7,0xd8,0xe7,0xd6,0x22,0xe2]); - set.insert([0xcd,0xd1,0x28,0x05,0x6d,0x8f,0x6b,0xb1,0xcb,0x31,0x17,0xf3,0x7f,0x0a,0xea,0xdc,0x1a,0x51,0xf2,0x9b]); - set.insert([0xce,0x8a,0x5c,0x63,0x01,0xb1,0x8a,0xac,0xde,0x48,0xff,0x4c,0x83,0x8b,0x59,0xe3,0x87,0x63,0xe6,0x05]); - set.insert([0xd0,0xc4,0x65,0x7e,0xb4,0x0a,0xdc,0x66,0x23,0x78,0xad,0x0b,0x6b,0x25,0x13,0xc6,0x13,0x8e,0xf5,0x51]); - set.insert([0xd2,0x9e,0x7c,0x5a,0x8b,0x1c,0xbd,0xf6,0x36,0x29,0xf0,0x86,0x28,0x93,0xa8,0xf8,0x90,0x77,0xb4,0x1a]); - set.insert([0xd4,0x1b,0x6b,0x7f,0xda,0x64,0xdc,0x1e,0x48,0x10,0xa7,0x79,0xf9,0x77,0x97,0xc0,0x5f,0xed,0x4e,0x80]); - set.insert([0xd7,0x54,0xcb,0xa1,0x3f,0xc2,0xe3,0x7b,0x0b,0x8f,0x92,0x10,0x65,0x21,0x45,0x0c,0x78,0x24,0xe8,0x5a]); - set.insert([0xd7,0xda,0x52,0x0c,0xcc,0x85,0xd5,0x6c,0x19,0x25,0x6f,0xe6,0x78,0x52,0xe8,0x7a,0x3d,0x09,0x9d,0xe6]); - set.insert([0xd9,0x14,0xc2,0xa4,0x9c,0xf1,0x94,0x85,0xef,0x47,0x28,0xe4,0x7c,0xeb,0x66,0x04,0x30,0x40,0xe0,0xff]); - set.insert([0xd9,0x63,0xe8,0x1a,0xcf,0x29,0x1c,0x7a,0xee,0xb5,0xfa,0x0f,0xf6,0x15,0x91,0xef,0xb8,0x6d,0x30,0xd2]); - set.insert([0xda,0xc4,0xc2,0x91,0x87,0x0c,0xbd,0x89,0x8a,0xf5,0x3e,0xcc,0x29,0x86,0x26,0x47,0x4b,0x9b,0x5e,0x9d]); - set.insert([0xdb,0x76,0x94,0xa4,0x75,0xe9,0xd6,0xaf,0x40,0x09,0xb6,0x0c,0x4b,0xe0,0xec,0x87,0xad,0x1a,0x6e,0xc6]); - set.insert([0xdd,0x14,0xdb,0x55,0xa2,0x49,0x43,0x8d,0x2e,0xc6,0xd1,0xbe,0x1f,0x7c,0x1d,0x57,0x96,0x6b,0x9a,0xe8]); - set.insert([0xdf,0x25,0xed,0x09,0xfc,0xa7,0x7a,0x19,0xd8,0x86,0xad,0x4f,0x2b,0xca,0x26,0x63,0xc0,0xa5,0xc1,0x13]); - set.insert([0xe0,0xae,0x16,0xc0,0x87,0x51,0x05,0xd0,0xde,0x9c,0xa5,0xfe,0x53,0xa9,0x4c,0x93,0xa4,0x01,0xc9,0xb1]); - set.insert([0xe0,0xd1,0x22,0xf6,0x11,0xe3,0x79,0x5b,0x28,0xa2,0x41,0x57,0xa9,0xc0,0x10,0x8b,0xca,0x57,0x92,0xf4]); - set.insert([0xe1,0x42,0xdf,0x5d,0x19,0x0e,0x4c,0x77,0xda,0x81,0xea,0xab,0x6c,0x81,0x88,0x6a,0x9a,0xd7,0x61,0x39]); - set.insert([0xe2,0x55,0x63,0x2d,0xa8,0xcb,0x96,0x8a,0x9b,0x8a,0x7c,0xcc,0xb6,0xcf,0x02,0x0c,0xce,0xca,0xfe,0x22]); - set.insert([0xe3,0x5a,0x36,0xf5,0xa1,0xee,0x2b,0xa8,0xfc,0x85,0x69,0x05,0x29,0x9c,0x84,0xf7,0x5b,0x61,0xe8,0x30]); - set.insert([0xe5,0x71,0x83,0xd0,0xf0,0x63,0x54,0x86,0x89,0xc5,0xa1,0x4d,0x3b,0x72,0xd8,0x77,0x12,0x14,0x41,0xf1]); - set.insert([0xe5,0x89,0xcf,0xb3,0xfc,0x64,0xc0,0xa6,0x9a,0x66,0xf3,0x13,0xcb,0xa7,0xd1,0x9e,0x8b,0x86,0xcf,0x46]); - set.insert([0xe6,0x80,0x2c,0xc0,0x7c,0xa9,0xdc,0xc9,0x1e,0xde,0xa1,0xd5,0xa8,0x8a,0x59,0xa2,0x01,0x09,0x06,0x11]); - set.insert([0xe8,0xbf,0x93,0x90,0xba,0x54,0xcd,0x80,0x00,0x13,0x08,0xc6,0xe2,0x57,0xac,0x77,0xd0,0x3c,0x61,0x8c]); - set.insert([0xed,0xbb,0x72,0x73,0xc0,0x23,0x8a,0x72,0xf8,0x91,0xb6,0x75,0xb6,0x87,0x5f,0xa8,0xe6,0x6e,0x09,0x9c]); - set.insert([0xed,0xbe,0x8c,0xf5,0x9a,0x64,0x2b,0xac,0xd1,0x89,0xe4,0xe0,0x05,0x62,0xdf,0xab,0xae,0xfd,0x11,0x20]); - set.insert([0xed,0xe9,0x0d,0xdf,0xdc,0x82,0xcb,0x63,0xea,0x76,0xf7,0x15,0x89,0x96,0x63,0xd2,0x89,0xf4,0x51,0xe4]); - set.insert([0xee,0x90,0xd9,0x8f,0x77,0x3e,0xf0,0x92,0x04,0x86,0x3f,0xb6,0xf2,0xaf,0x33,0x5d,0x33,0x93,0x2f,0xbd]); - set.insert([0xf0,0x2c,0x4e,0xef,0x50,0xb2,0xb4,0x66,0x0d,0x29,0x1c,0x81,0x36,0xa8,0x46,0x34,0x2f,0x79,0x0b,0x9d]); - set.insert([0xf2,0x28,0xe8,0xbb,0x0a,0xea,0x2e,0x37,0x06,0x6f,0x93,0xdb,0x5c,0xbf,0xd9,0x34,0x2d,0x8f,0xff,0x0d]); - set.insert([0xf3,0xdc,0x48,0x8e,0xa5,0xf4,0x11,0x56,0xd4,0x97,0xcf,0x0f,0xec,0x05,0x44,0x9d,0x18,0xaa,0x2a,0x49]); - set.insert([0xf4,0xe1,0x2f,0x72,0xac,0xcd,0xc8,0x3e,0xa3,0xe1,0x6b,0x73,0x07,0x79,0x69,0x0b,0x4a,0x9e,0x0b,0xed]); - set.insert([0xf8,0xe6,0x1a,0x4a,0x80,0xc7,0x70,0x28,0xbe,0xb3,0x3a,0xe4,0xc4,0x6e,0x69,0xe6,0xf4,0x90,0x4e,0x61]); - set.insert([0xf9,0x63,0xa2,0xbd,0x05,0x71,0x6c,0x42,0x9d,0x66,0x64,0x7b,0x6e,0xf1,0x53,0x87,0x47,0xcc,0xe5,0x5c]); - set.insert([0xfb,0xeb,0x13,0x69,0x09,0x16,0x3a,0x11,0x5f,0x42,0x3e,0xf4,0xc3,0x5d,0x4c,0xdc,0xcc,0xfe,0x33,0x6d]); - set.insert([0xfc,0x2c,0x11,0xc9,0x5a,0x5a,0xad,0xfd,0x35,0x00,0x89,0x1e,0xce,0x06,0x65,0x1c,0x0b,0x4e,0xe0,0xe5]); - set.insert([0xfe,0xc9,0x34,0x2e,0x9e,0xe4,0x18,0x64,0x53,0xf8,0xa7,0xe0,0x27,0xfa,0xc8,0xc2,0x4e,0x7c,0x0c,0x60]); - set.insert([0xff,0xf4,0xfe,0x67,0xc5,0x2b,0x8d,0x0d,0x42,0x5d,0x2b,0x97,0x72,0xe7,0xa4,0xff,0xcd,0x9d,0xac,0xf3]); + pub static ref PPID_WHITELIST: SgxMutex = { + macro_rules! add_machine { + ($set:expr, $hex:literal) => { + $set.add_new(hex_literal::hex!($hex), true); + }; + } + + let mut set = allow_list::Data { + m_to_o: HashMap::new(), + }; + + add_machine!(set, "01507c957789b7c1afde972d67f1fdd53af1a8da"); + add_machine!(set, "03372b2a39e0713c965a0876b5e807b41d509538"); + add_machine!(set, "04f01407b762af16db04ac648aee5feb24cf6eb8"); + add_machine!(set, "050430408a4ceae5d0b9d95721d651222cbd83d3"); + add_machine!(set, "051f83eb42dfdd7850086cf5696fbb3653f883ae"); + add_machine!(set, "09e9875ed7acd42c7dd19d72a39524f6ae3e87fa"); + add_machine!(set, "1121e6d9a770c9e562ae423012080e52765ecf71"); + add_machine!(set, "13f108bdf8fd3f11e75026d98ed1803075257354"); + add_machine!(set, "14d1236033fde31e0bcd570c3291eaa9bdb7e25e"); + add_machine!(set, "1632ea13051cc4d392cb8d3e016eb5617d8e8b2a"); + add_machine!(set, "188120cd27f658a7292c466f6c7df5af6cdb966e"); + add_machine!(set, "1a2425c4955555f0ea8c0315e116e0135f3a04c9"); + add_machine!(set, "1ae4fb51626d0d274c0bd3851e5a04dee0b0d53b"); + add_machine!(set, "1b3aade441add658f9f95c10ce0f3d754f92a327"); + add_machine!(set, "1c8be811c09185a9f6c7dc3fba81e878a58d0a1b"); + add_machine!(set, "20598fcb4ba579c5a09e8c1a42ec9c0210cb43f3"); + add_machine!(set, "2087688522965eb04c9ae9f33ea94bbf820878f1"); + add_machine!(set, "211f0f5570f7aabfe6a8b7cf77dec8d33dd5feea"); + add_machine!(set, "21cae822314c17721677c41cd8423464983553c1"); + add_machine!(set, "221cd8234e369ef19dfdad94f437d3a190cb2673"); + add_machine!(set, "2491b9a22f4b3d4582af20921919bc2771c80fde"); + add_machine!(set, "26671a0931ebde25273736bf6b4b2ed1038c4443"); + add_machine!(set, "28049f3f69f6558324e52d44ecdef897b1a3b390"); + add_machine!(set, "2854e3e3894986168e90ce3a017bfecf65ce7911"); + add_machine!(set, "29f3c41bbf0dbd38fd4b052d27ca6486a906688d"); + add_machine!(set, "2a003f2b908b08476be25d011c57fe11fc6892f9"); + add_machine!(set, "307bbcfb24abdb94a6b7cabaddb919046403ffe6"); + add_machine!(set, "315db04df669894a3e35429691b8b350d8cbcde2"); + add_machine!(set, "32ea0bc90831a8fb988c208e5328ac7b64eb298d"); + add_machine!(set, "346df4cce9f27b23c5f0823ee9d260c166fed3db"); + add_machine!(set, "3599c48a2a1bbff874dac46d986a512f69fbc8d0"); + add_machine!(set, "36a37506dcc62a2153ae3da741f56a01bed54267"); + add_machine!(set, "3e6830d6a2d839bf36bb108ca8ccc25a1678f82f"); + add_machine!(set, "40832a64b27c12c7abe6be0947163ee483478c61"); + add_machine!(set, "4101a8187d20889c4fd247b4c8279b66318ef091"); + add_machine!(set, "4226d078029b9be4f32a615e9290dbcde3d55f76"); + add_machine!(set, "443b01f07719d7ce6cbde861082a33181bb24e4c"); + add_machine!(set, "44e10597b42e571423915385fe85ced0e840850c"); + add_machine!(set, "461be5de74ce833d3828fcb57c243b6015d76d7f"); + add_machine!(set, "488228894e7265ff74d97495d2d536b9c7f57411"); + add_machine!(set, "4af5d94e2281e2a4c23ed84c4a05aa5e7a3178d2"); + add_machine!(set, "4e09788159008f91d7f3d68b1af2355b3c1772cc"); + add_machine!(set, "4ff7e9724d98c50d6118f65f3004a1fccded1ad8"); + add_machine!(set, "500f6449b97e2be1e68f0cb1ed59dee3c8e6d9c0"); + add_machine!(set, "51c1ede18e73fc7e00e8fc018ede53632f8bb6d9"); + add_machine!(set, "53543f1a7d08c13d69385b8120562a76b871f8ec"); + add_machine!(set, "57198eb36e5c996863b626eb6f23e3877cb2ed17"); + add_machine!(set, "57a6877d0e96ce77a3fafb0c2f7e9ed9e28fb037"); + add_machine!(set, "5af0f73c1e99f55f27d022400f5c4b9216593532"); + add_machine!(set, "5d73a589b357f4e7ad599b4a4a7e4338cd733018"); + add_machine!(set, "608a11e7ce88e1abd1c54a3566cc7b6332be05b5"); + add_machine!(set, "61897d0310110214035bcbad0f7a46ff447ec0e7"); + add_machine!(set, "674497918b4204d3e686ba23408a9aa216b2227a"); + add_machine!(set, "68928aa2c3167d75d566e54b475462aa2872cb2f"); + add_machine!(set, "6925e66c41bb7e7f5ec3808f7ae7a05c419fecc4"); + add_machine!(set, "6a81ac2a32cc2eac4b974b1819ed2b7568c83c04"); + add_machine!(set, "6ce72aa22018622c24a2c0aac45f14617aec59e5"); + add_machine!(set, "70b931353e3925bbf3dd70046f32911c9761fca6"); + add_machine!(set, "7402b63c09f3520931dac2f9f702ce16503d3648"); + add_machine!(set, "782770253c0ae72edd91138ad0017cdb9a7d8dba"); + add_machine!(set, "791773aa0b8ae2dc8cb75eb9d564a0d598125572"); + add_machine!(set, "7a89c9dd7383dde27419b36e2c6d0d942eee85d9"); + add_machine!(set, "7d0af9bbd94bc0cca22684e86ac62b58e5134223"); + add_machine!(set, "7f1c6994729637e3fd4cc2f5faaeb9bffb17c1a2"); + add_machine!(set, "803bcee8a47247aa762a29d9ed59d63defc5f861"); + add_machine!(set, "80fcb4f6f086e6bbd832500c2b729c26b3bf1ad2"); + add_machine!(set, "813bf820fd5435d03db7bbeb04d2c34217f2f949"); + add_machine!(set, "84ca012846315415126521d8afdf5dda5f775306"); + add_machine!(set, "8796f516e23e15624e50e6d34a3ab4d812fdca7e"); + add_machine!(set, "8f06c7f4f5f86842aee784337021ebd59d4af9f1"); + add_machine!(set, "8fc9821dbfa83b217f8f61f1f41f057425dcd3b6"); + add_machine!(set, "8ffbc5ef59ef9f2289e74a3745039d900fba30fe"); + add_machine!(set, "9048c142de1fe70d3ef4a9107ccfbe235df536c0"); + add_machine!(set, "92166c988e5e02184bf2d5b3b97a1e76bd6112fe"); + add_machine!(set, "93bd0a2c4b01d3fb0f21b072c04feeea7e649ae2"); + add_machine!(set, "97587e418dc1afbca9939c06ccb97f3115c58c65"); + add_machine!(set, "98cb371d43682eb87d6fb1ac1c9589d79fcd69ce"); + add_machine!(set, "9ace47eacbe6ab5112bd6d8ebc555b0fef9f2332"); + add_machine!(set, "9c80bc6bf4586edb2689c3093a9a0aeca3014805"); + add_machine!(set, "9d08171ec1cae6ce1ea0ce3f3674fa5d01f6f1b3"); + add_machine!(set, "9d3f1160d215e9438a601c8771a972bcebe097f0"); + add_machine!(set, "9e8320462733ed8a124fc97d7fdf33840b6e3a2c"); + add_machine!(set, "9ebd6f9e550f0d6dd00de5255f03ded61e17e2c7"); + add_machine!(set, "a02f25afce5eeab321a4e76943e56d6e9aa73fe4"); + add_machine!(set, "a0417d627d225e21543cf9a91b2d83b95f091dc6"); + add_machine!(set, "a40b9476fb305c1d39752fd48548c5fa3c371571"); + add_machine!(set, "a46849552c7363285baedb5a6b6814809a59ed92"); + add_machine!(set, "a6adabb2a25d233c62afd1fc0e991d2513dc11d4"); + add_machine!(set, "ac47f3115109baeb98deafdcbd980117b4e286ba"); + add_machine!(set, "af1578fbef76672fef3b9250b30cef407e78fd26"); + add_machine!(set, "b2ed08994ae4d6db46b316d384380f69636404fa"); + add_machine!(set, "b2fbe8a9d6b17f9af5110ab556d8b144bc74964d"); + add_machine!(set, "b3c0a1406894e931961e0fe34a68bd0148337e58"); + add_machine!(set, "b4cdc2e6620dfd8c5d565041284714c38079c74c"); + add_machine!(set, "b7ed7f4a1288c98c49b46a6af856532e65eaedab"); + add_machine!(set, "bb98127d89b2e3f4f9db410b060e0affa48e07ef"); + add_machine!(set, "bbed9ac0c3b9203d4da19cab34fbfb8ce6a4411c"); + add_machine!(set, "bd55e813db245b64f2269fc767ee1db10ad9df94"); + add_machine!(set, "bf101c4de90cdc2e66744438391f60cea977c9cc"); + add_machine!(set, "c133f0c3751a908584dcdf322d72b5177c12e732"); + add_machine!(set, "c2f7f3b60acde8ddff167104c56e1ed5a1e3eb74"); + add_machine!(set, "c3108fa405ef44a71a5d880321e09a620f7f4f76"); + add_machine!(set, "c31a7d5c5080d90a620d364854ba336dc82cb2c1"); + add_machine!(set, "c4ad3980ab8772d4d63b0a7f51badf0065dc095a"); + add_machine!(set, "c4c10766c4489b7177cf5a21a0dc48e689999ae8"); + add_machine!(set, "c4c2ef795e371116eea7fe8b981e38b7e0cf1017"); + add_machine!(set, "c645eccebc5aa8193b4be85c71ec550f6e0bf6e9"); + add_machine!(set, "c66551e2c5576b91e2954dca7679a92665f5894c"); + add_machine!(set, "c8638dc5e92933709f647ca7ab78eeb39d399575"); + add_machine!(set, "c9b252641dfcbdf95878b1cc0319212c741cfead"); + add_machine!(set, "cbfdda923307f8ab91897131b613b7d8e7d622e2"); + add_machine!(set, "cdd128056d8f6bb1cb3117f37f0aeadc1a51f29b"); + add_machine!(set, "ce8a5c6301b18aacde48ff4c838b59e38763e605"); + add_machine!(set, "d0c4657eb40adc662378ad0b6b2513c6138ef551"); + add_machine!(set, "d29e7c5a8b1cbdf63629f0862893a8f89077b41a"); + add_machine!(set, "d41b6b7fda64dc1e4810a779f97797c05fed4e80"); + add_machine!(set, "d754cba13fc2e37b0b8f92106521450c7824e85a"); + add_machine!(set, "d7da520ccc85d56c19256fe67852e87a3d099de6"); + add_machine!(set, "d914c2a49cf19485ef4728e47ceb66043040e0ff"); + add_machine!(set, "d963e81acf291c7aeeb5fa0ff61591efb86d30d2"); + add_machine!(set, "dac4c291870cbd898af53ecc298626474b9b5e9d"); + add_machine!(set, "db7694a475e9d6af4009b60c4be0ec87ad1a6ec6"); + add_machine!(set, "dd14db55a249438d2ec6d1be1f7c1d57966b9ae8"); + add_machine!(set, "df25ed09fca77a19d886ad4f2bca2663c0a5c113"); + add_machine!(set, "e0ae16c0875105d0de9ca5fe53a94c93a401c9b1"); + add_machine!(set, "e0d122f611e3795b28a24157a9c0108bca5792f4"); + add_machine!(set, "e142df5d190e4c77da81eaab6c81886a9ad76139"); + add_machine!(set, "e255632da8cb968a9b8a7cccb6cf020ccecafe22"); + add_machine!(set, "e35a36f5a1ee2ba8fc856905299c84f75b61e830"); + add_machine!(set, "e57183d0f063548689c5a14d3b72d877121441f1"); + add_machine!(set, "e589cfb3fc64c0a69a66f313cba7d19e8b86cf46"); + add_machine!(set, "e6802cc07ca9dcc91edea1d5a88a59a201090611"); + add_machine!(set, "e8bf9390ba54cd80001308c6e257ac77d03c618c"); + add_machine!(set, "edbb7273c0238a72f891b675b6875fa8e66e099c"); + add_machine!(set, "edbe8cf59a642bacd189e4e00562dfabaefd1120"); + add_machine!(set, "ede90ddfdc82cb63ea76f715899663d289f451e4"); + add_machine!(set, "ee90d98f773ef09204863fb6f2af335d33932fbd"); + add_machine!(set, "f02c4eef50b2b4660d291c8136a846342f790b9d"); + add_machine!(set, "f228e8bb0aea2e37066f93db5cbfd9342d8fff0d"); + add_machine!(set, "f3dc488ea5f41156d497cf0fec05449d18aa2a49"); + add_machine!(set, "f4e12f72accdc83ea3e16b730779690b4a9e0bed"); + add_machine!(set, "f8e61a4a80c77028beb33ae4c46e69e6f4904e61"); + add_machine!(set, "f963a2bd05716c429d66647b6ef1538747cce55c"); + add_machine!(set, "fbeb136909163a115f423ef4c35d4cdcccfe336d"); + add_machine!(set, "fc2c11c95a5aadfd3500891ece06651c0b4ee0e5"); + add_machine!(set, "fec9342e9ee4186453f8a7e027fac8c24e7c0c60"); + add_machine!(set, "fff4fe67c52b8d0d425d2b9772e7a4ffcd9dacf3"); SgxMutex::new(set) }; @@ -310,6 +425,33 @@ lazy_static::lazy_static! { "20806EB70000", "20906EC10000", ]); + + pub static ref SELF_QUOTE_UNTESTED: Result = { + #[cfg(feature = "SGX_MODE_HW")] + { + get_quote_ecdsa_untested(&[]) + } + + #[cfg(not(feature = "SGX_MODE_HW"))] + { + Err(sgx_types::sgx_status_t::SGX_ERROR_NO_DEVICE) + } + }; + + pub static ref SELF_QUOTE_PPID: Option> = { + match &*SELF_QUOTE_UNTESTED { + Ok(x) => unsafe { x.extract_cpu_cert() }, + _ => None + } + }; + + pub static ref SELF_MACHINE_ID: Option = { + let ppid = SELF_QUOTE_PPID.as_ref()?; + let machine_id = crate::registration::offchain::calculate_truncated_hash(&ppid); + trace!("Self machine_id = {}", hex::encode(&machine_id)); + Some(machine_id) + }; + } unsafe fn extract_fmspc_from_collateral(vec_coll: &[u8]) -> Option { @@ -661,11 +803,17 @@ impl AttestationCombined { } } +pub struct VerifiedSgxQuote { + pub body: sgx_report_body_t, + pub qv_result: sgx_ql_qv_result_t, + pub machine_id_hash: Option, +} + pub fn verify_quote_sgx( attestation: &AttestationCombined, time_s: i64, check_ppid_wl: bool, -) -> Result<(sgx_report_body_t, sgx_ql_qv_result_t), sgx_status_t> { +) -> sgx_types::SgxResult { let qv_result = verify_quote_any(&attestation.quote, &attestation.coll, time_s)?; if attestation.quote.len() < mem::size_of::() { @@ -681,21 +829,25 @@ pub fn verify_quote_sgx( trace!("Unrecognized quote version: {}", version); Err(sgx_status_t::SGX_ERROR_UNEXPECTED) } else { - let report_body = (*my_p_quote).report_body; - if !attestation.verify_fmspc() { return Err(sgx_status_t::SGX_ERROR_UNEXPECTED); } - let is_in_wl = match attestation.extract_cpu_cert() { - Some(ppid) => { - let ppid_addr = crate::registration::offchain::calculate_truncated_hash(&ppid); + let machine_id_opt = if let Some(ppid) = attestation.extract_cpu_cert() { + Some(crate::registration::offchain::calculate_truncated_hash( + &ppid, + )) + } else { + None + }; + let is_in_wl = match &machine_id_opt { + Some(machine_id_hash) => { let wl = PPID_WHITELIST.lock().unwrap(); - if wl.contains(&ppid_addr) { + if wl.m_to_o.contains_key(machine_id_hash) { true } else { - println!("Unknown Machine ID: {}", orig_hex::encode(ppid_addr)); + println!("Unknown Machine ID: {}", orig_hex::encode(machine_id_hash)); false } } @@ -719,7 +871,11 @@ pub fn verify_quote_sgx( return Err(sgx_status_t::SGX_ERROR_UNEXPECTED); } - Ok((report_body, qv_result)) + Ok(VerifiedSgxQuote { + body: (*my_p_quote).report_body, + qv_result: qv_result, + machine_id_hash: machine_id_opt, + }) } } } @@ -861,11 +1017,11 @@ pub fn get_quote_ecdsa(pub_k: &[u8]) -> Result { + Ok(res) => { trace!("Self quote verified ok"); - if r.1 != sgx_ql_qv_result_t::SGX_QL_QV_RESULT_OK { + if res.qv_result != sgx_ql_qv_result_t::SGX_QL_QV_RESULT_OK { // TODO: strict policy wrt own quote verification - trace!("WARNING: {}", r.1); + trace!("WARNING: {}", res.qv_result); } } Err(e) => { diff --git a/cosmwasm/enclaves/execute/src/registration/check_patch_level.rs b/cosmwasm/enclaves/execute/src/registration/check_patch_level.rs index c09593b01d..5d4761a264 100644 --- a/cosmwasm/enclaves/execute/src/registration/check_patch_level.rs +++ b/cosmwasm/enclaves/execute/src/registration/check_patch_level.rs @@ -8,10 +8,9 @@ use enclave_ffi_types::NodeAuthResult; use enclave_utils::validate_const_ptr; #[cfg(feature = "SGX_MODE_HW")] -use crate::registration::attestation::get_quote_ecdsa_untested; - -#[cfg(feature = "SGX_MODE_HW")] -use crate::registration::attestation::verify_quote_sgx; +use crate::registration::attestation::{ + get_quote_ecdsa_untested, verify_quote_sgx, SELF_QUOTE_PPID, SELF_QUOTE_UNTESTED, +}; #[cfg(feature = "SGX_MODE_HW")] use enclave_utils::storage::write_to_untrusted; @@ -39,19 +38,17 @@ pub unsafe extern "C" fn ecall_check_patch_level( } #[cfg(feature = "SGX_MODE_HW")] -unsafe fn check_patch_level_dcap(pub_k: &[u8; 32]) -> (NodeAuthResult, Option>) { - match get_quote_ecdsa_untested(pub_k) { +unsafe fn check_patch_level_dcap() -> NodeAuthResult { + match &*SELF_QUOTE_UNTESTED { Ok(attestation) => { match verify_quote_sgx(&attestation, 0, false) { - Ok(r) => { - if r.1 != sgx_ql_qv_result_t::SGX_QL_QV_RESULT_OK { - println!("WARNING: {}", r.1); + Ok(res) => { + if res.qv_result != sgx_ql_qv_result_t::SGX_QL_QV_RESULT_OK { + println!("WARNING: {}", res.qv_result); } - let ppid = attestation.extract_cpu_cert(); - println!("DCAP attestation obtained and verified ok"); - return (NodeAuthResult::Success, ppid); + return NodeAuthResult::Success; } Err(e) => { println!("DCAP quote obtained, but failed to verify it: {}", e); @@ -65,7 +62,7 @@ unsafe fn check_patch_level_dcap(pub_k: &[u8; 32]) -> (NodeAuthResult, Option SgxResult { - return Ok(body); + Ok(res) => { + return Ok(res.body); } Err(e) => { error!("Can't verify remote quote: {}", e); @@ -339,8 +346,12 @@ fn get_verified_migration_report_body(check_ppid_wl: bool) -> SgxResult sgx_status_t { - let mut report_data: [u8; 48] = [0; 48]; +pub unsafe extern "C" fn ecall_get_attestation_report( + p_sk: *const u8, + n_sk: u32, + flags: u32, +) -> sgx_status_t { + let mut report_data = [0_u8; sgx_types::SGX_REPORT_DATA_SIZE]; let (kp, is_migration_report) = match 0x10 & flags { 0x10 => { @@ -370,7 +381,19 @@ pub unsafe extern "C" fn ecall_get_attestation_report(flags: u32) -> sgx_status_ }; let attestation = { - report_data[0..32].copy_from_slice(&kp.get_pubkey()); + let pk_len = 32 as usize; + report_data[0..pk_len].copy_from_slice(&kp.get_pubkey()); + + if n_sk == 32 { + let sk = ed25519_dalek::SecretKey::from_bytes(std::slice::from_raw_parts( + p_sk, + n_sk as usize, + )) + .unwrap(); + + let pk = ed25519_dalek::PublicKey::from(&sk); + report_data[pk_len..pk_len + pk_len].copy_from_slice(&pk.to_bytes()); + } match get_attestation_report_dcap(&report_data) { Ok(x) => x, @@ -474,7 +497,7 @@ pub unsafe extern "C" fn ecall_get_genesis_seed( ); let seeds = KEY_MANAGER.get_consensus_seed().unwrap(); - let res: Vec = encrypt_seed(target_public_key, &seeds.arr[0], true) + let res: Vec = encrypt_seed(&target_public_key, &seeds.arr[0], true) .map_err(|_| sgx_status_t::SGX_ERROR_UNEXPECTED)?; Ok(res) @@ -555,7 +578,7 @@ pub unsafe extern "C" fn ecall_migration_op(opcode: u32) -> sgx_types::sgx_statu println!("Create self migration report"); export_local_migration_report(); - ecall_get_attestation_report(0x10) // migration + ecall_get_attestation_report(core::ptr::null(), 0, 0x10) // migration } 2 => { println!("Export encrypted data to the next aurhorized enclave"); @@ -679,20 +702,6 @@ pub unsafe extern "C" fn ecall_onchain_approve_upgrade( sgx_types::sgx_status_t::SGX_SUCCESS } -fn calculate_machine_id_evidence(machine_id: &[u8]) -> [u8; HASH_SIZE] { - let mut hasher = Sha256::new(); - - let magic = [b'm', b'i', b'd']; - hasher.update(magic); - - hasher.update(SELF_REPORT_BODY.mr_enclave.m); - hasher.update(machine_id); - - let mut ret = [0_u8; HASH_SIZE]; - ret.copy_from_slice(&hasher.finalize()); - ret -} - struct ProtobufParser<'a> { pub cursor: &'a [u8], } @@ -837,48 +846,230 @@ fn check_machine_id_in_block(_msg_slice: &[u8]) -> bool { pub unsafe extern "C" fn ecall_onchain_approve_machine_id( p_id: *const u8, n_id: u32, - p_proof: *mut u8, - is_on_chain: bool, ) -> sgx_types::sgx_status_t { validate_const_ptr!(p_id, n_id as usize, sgx_status_t::SGX_ERROR_UNEXPECTED); - validate_mut_ptr!(p_proof, 32, sgx_status_t::SGX_ERROR_UNEXPECTED); - if n_id != 20 { + if n_id as usize != allow_list::MACHINE_ID_LEN { println!("machine_id wrong len"); return sgx_types::sgx_status_t::SGX_ERROR_UNEXPECTED; } let machine_id = slice::from_raw_parts(p_id, n_id as usize); - let proof = calculate_machine_id_evidence(machine_id); + let machine_id_str = hex::encode(machine_id); - if is_on_chain { - let machine_id_str = hex::encode(machine_id); + if !check_machine_id_in_block(machine_id_str.as_bytes()) { + error!("machine ID not approved"); + return sgx_types::sgx_status_t::SGX_ERROR_UNEXPECTED; + } - if !check_machine_id_in_block(machine_id_str.as_bytes()) { - error!("machine ID not approved"); - return sgx_types::sgx_status_t::SGX_ERROR_UNEXPECTED; + { + let mut allow_list = PPID_WHITELIST.lock().unwrap(); + + let machine_id: &allow_list::MachineID = machine_id.try_into().unwrap(); + + allow_list.add_new(*machine_id, false); + } + + sgx_types::sgx_status_t::SGX_SUCCESS +} + +struct MerkleProcessor<'a> { + cursor: io::Cursor<&'a [u8]>, +} + +impl<'a> MerkleProcessor<'a> { + fn new(data: &'a [u8]) -> Self { + Self { + cursor: io::Cursor::new(data), } + } - // TODO: ensure message was in the signed block - slice::from_raw_parts_mut(p_proof, HASH_SIZE).copy_from_slice(&proof); - } else { - // compare - if proof != slice::from_raw_parts(p_proof, HASH_SIZE) { - error!("machine ID not approved earlier"); - return sgx_types::sgx_status_t::SGX_ERROR_UNEXPECTED; + fn read_slice_n(&mut self, n: usize) -> io::Result<&'a [u8]> { + let pos = self.cursor.position() as usize; + let buf = self.cursor.get_ref(); + + if pos + n > buf.len() { + return Err(io::Error::new( + io::ErrorKind::UnexpectedEof, + "not enough bytes", + )); } + + let out = &buf[pos..pos + n]; + self.cursor.set_position((pos + n) as u64); + Ok(out) } - { - let mut set = crate::registration::attestation::PPID_WHITELIST - .lock() + fn read_slice(&mut self) -> io::Result<&'a [u8]> { + let n = Keychain::read_u32(&mut self.cursor)? as usize; + self.read_slice_n(n) + } + + fn hash_var_uint(hasher: &mut Sha256, mut x: usize) { + loop { + if x < 0x80 { + let b = x as u8; + hasher.update([b]); + break; + } + + let b = 0x80 | ((x & 0x7f) as u8); + hasher.update([b]); + x >>= 7; + } + } + + fn hash_leaf_iavl(&mut self, key: &[u8], val: &[u8]) -> io::Result<[u8; 32]> { + let prefix = self.read_slice()?; + + let valhash: [u8; 32] = { + let mut hasher = Sha256::new(); + hasher.update(val); + hasher.finalize().into() + }; + + let mut hasher = Sha256::new(); + hasher.update(prefix); // prefix len isn't required + Self::hash_var_uint(&mut hasher, key.len()); + hasher.update(key); + Self::hash_var_uint(&mut hasher, valhash.len()); + hasher.update(&valhash); + + Ok(hasher.finalize().into()) + } + + fn interpret_sub_path(&mut self, hash_value: &mut [u8; 32]) -> io::Result<()> { + //println!("*** leaf hash: {}", hex::encode(&hash_value)); + + let n = Keychain::read_u32(&mut self.cursor)?; + for _i in 0..n { + let mut hasher = Sha256::new(); + hasher.update(self.read_slice()?); // prefix + hasher.update(&hash_value); + hasher.update(self.read_slice()?); // suffix + *hash_value = hasher.finalize().into(); + //println!("*** next hash: {}", hex::encode(&hash_value)); + } + + Ok(()) + } +} + +#[no_mangle] +pub unsafe extern "C" fn ecall_submit_machine_swap( + index: u32, + p_machine_info: *const u8, + n_machine_info: u32, + p_proof: *const u8, + n_proof: u32, +) -> sgx_types::sgx_status_t { + validate_const_ptr!( + p_machine_info, + n_machine_info as usize, + sgx_status_t::SGX_ERROR_UNEXPECTED + ); + validate_const_ptr!( + p_proof, + n_proof as usize, + sgx_status_t::SGX_ERROR_UNEXPECTED + ); + + let merkle_proof_result = (|| -> io::Result<()> { + // verify merkle proof + + let apphash = { + let extra = KEY_MANAGER.extra_data.lock().unwrap(); + extra.apphash + }; + + //println!("expected apphash: {}", hex::encode(&apphash)); + + let mut merkle = MerkleProcessor::new(slice::from_raw_parts(p_proof, n_proof as usize)); + + let proof_parts = Keychain::read_u32(&mut merkle.cursor)?; + if proof_parts != 2 { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "proof wrong len", + )); + } + + // leaf + let mut hash_val = { + let mut k = [0u8; 5]; + k[0] = 0x03; // RegistrationMachinePrefix + k[1..5].copy_from_slice(&index.to_le_bytes()); + + let v = slice::from_raw_parts(p_machine_info, n_machine_info as usize); + + merkle.hash_leaf_iavl(&k, v)? + }; + + merkle.interpret_sub_path(&mut hash_val)?; + + hash_val = { + let k = b"register"; + merkle.hash_leaf_iavl(k, &hash_val)? + }; + + merkle.interpret_sub_path(&mut hash_val)?; + + if apphash != hash_val { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "apphash mismatch", + )); + } + + Ok(()) + })(); + + if let Err(e) = merkle_proof_result { + println!("Merkle proof failed: {}", e); + return sgx_types::sgx_status_t::SGX_ERROR_UNEXPECTED; + } + + const MACHINE_SWAP_INFO_LEN: usize = + allow_list::OWNER_LEN + allow_list::MACHINE_ID_LEN + allow_list::MACHINE_ID_LEN; + + let (swap_info_opt, p_machine_id) = match n_machine_info as usize { + MACHINE_SWAP_INFO_LEN => { + let owner: &allow_list::Owner = + slice::from_raw_parts(p_machine_info, allow_list::OWNER_LEN) + .try_into() + .unwrap(); + + let machine_id_pop: &allow_list::MachineID = slice::from_raw_parts( + p_machine_info.add(allow_list::OWNER_LEN + allow_list::MACHINE_ID_LEN), + allow_list::MACHINE_ID_LEN, + ) + .try_into() + .unwrap(); + + ( + Some((owner, machine_id_pop)), + p_machine_info.add(allow_list::OWNER_LEN), + ) + } + allow_list::MACHINE_ID_LEN => (None, p_machine_info), + _ => { + println!("machine_info wrong len"); + return sgx_types::sgx_status_t::SGX_ERROR_UNEXPECTED; + } + }; + + let machine_id: &allow_list::MachineID = + slice::from_raw_parts(p_machine_id, allow_list::MACHINE_ID_LEN) + .try_into() .unwrap(); - let arg: &[u8; 20] = machine_id.try_into().unwrap(); + { + let mut allow_list = PPID_WHITELIST.lock().unwrap(); - if !set.contains(arg) { - println!("Onchain added machine ID: {}", hex::encode(arg)); - set.insert(*arg); + if let Some(swap_info) = swap_info_opt { + allow_list.update(machine_id, swap_info.0, swap_info.1); + } else { + allow_list.add_new(*machine_id, false); } } diff --git a/cosmwasm/enclaves/execute/src/registration/onchain.rs b/cosmwasm/enclaves/execute/src/registration/onchain.rs index c1c6dee1e9..f641071487 100644 --- a/cosmwasm/enclaves/execute/src/registration/onchain.rs +++ b/cosmwasm/enclaves/execute/src/registration/onchain.rs @@ -6,7 +6,9 @@ use std::panic; use enclave_ffi_types::NodeAuthResult; -use crate::registration::attestation::{verify_quote_sgx, AttestationCombined}; +use crate::registration::attestation::{ + allow_list, verify_quote_sgx, AttestationCombined, VerifiedSgxQuote, +}; use enclave_utils::{ oom_handler::{self, get_then_clear_oom_happened}, @@ -18,6 +20,7 @@ use sgx_types::sgx_ql_qv_result_t; use enclave_crypto::consts::SELF_REPORT_BODY; use super::seed_exchange::encrypt_seed; +use std::convert::TryInto; use std::slice; #[cfg(feature = "light-client-validation")] @@ -40,37 +43,34 @@ fn get_current_block_time_s() -> i64 { fn verify_attestation_dcap( attestation: &AttestationCombined, - pub_key: &mut [u8; 32], -) -> NodeAuthResult { +) -> Result { let tm_s = get_current_block_time_s(); trace!("Current block time: {}", tm_s); - let report_body = match verify_quote_sgx(attestation, tm_s, true) { - Ok(r) => { + let res = match verify_quote_sgx(attestation, tm_s, true) { + Ok(res) => { trace!("Remote quote verified ok"); - if r.1 != sgx_ql_qv_result_t::SGX_QL_QV_RESULT_OK { - trace!("WARNING: {}", r.1); + if res.qv_result != sgx_ql_qv_result_t::SGX_QL_QV_RESULT_OK { + trace!("WARNING: {}", res.qv_result); } - r.0 + res } Err(e) => { trace!("Remote quote verification failed: {}", e); - return NodeAuthResult::InvalidCert; + return Err(NodeAuthResult::InvalidCert); } }; - if (report_body.mr_enclave.m) != SELF_REPORT_BODY.mr_enclave.m { + if (res.body.mr_enclave.m) != SELF_REPORT_BODY.mr_enclave.m { error!( "mrenclave expected={}, actual={}", hex::encode(SELF_REPORT_BODY.mr_enclave.m), - hex::encode(report_body.mr_enclave.m) + hex::encode(res.body.mr_enclave.m) ); - return NodeAuthResult::MrEnclaveMismatch; + return Err(NodeAuthResult::MrEnclaveMismatch); } - pub_key.copy_from_slice(&report_body.report_data.d[..32]); - - NodeAuthResult::Success + Ok(res) } /// @@ -94,6 +94,8 @@ pub unsafe extern "C" fn ecall_authenticate_new_node( p_seeds: *mut u8, n_seeds: u32, p_seeds_size: *mut u32, + p_machine_pop: *const u8, + p_machine_info: *mut u8, ) -> NodeAuthResult { if let Err(_err) = oom_handler::register_oom_handler() { error!("Could not register OOM handler!"); @@ -101,6 +103,16 @@ pub unsafe extern "C" fn ecall_authenticate_new_node( } validate_mut_ptr!(p_seeds, n_seeds as usize, NodeAuthResult::InvalidInput); + validate_const_ptr!( + p_machine_pop, + allow_list::MACHINE_ID_LEN, + NodeAuthResult::InvalidInput + ); + validate_mut_ptr!( + p_machine_info, + allow_list::OWNER_LEN + allow_list::MACHINE_ID_LEN, + NodeAuthResult::InvalidInput + ); validate_const_ptr!(cert, cert_len as usize, NodeAuthResult::InvalidInput); let cert_slice = std::slice::from_raw_parts(cert, cert_len as usize); @@ -110,8 +122,6 @@ pub unsafe extern "C" fn ecall_authenticate_new_node( return NodeAuthResult::SignatureInvalid; } - let mut target_public_key: [u8; 32] = [0u8; 32]; - let attestation = AttestationCombined::from_blob(cert, cert_len as usize); if attestation.quote.is_empty() || attestation.coll.is_empty() { @@ -119,15 +129,19 @@ pub unsafe extern "C" fn ecall_authenticate_new_node( return NodeAuthResult::InvalidCert; } - let res = verify_attestation_dcap(&attestation, &mut target_public_key); - if NodeAuthResult::Success != res { - return res; - } + let verified_quote = match verify_attestation_dcap(&attestation) { + Ok(res) => res, + Err(e) => { + return e; + } + }; + + let target_public_key: &[u8; 32] = verified_quote.body.report_data.d[0..32].try_into().unwrap(); let result = panic::catch_unwind(|| -> Result, NodeAuthResult> { trace!( - "ecall_get_encrypted_seed target_public_key key pk: {:?}", - &target_public_key.to_vec() + "ecall_get_encrypted_seed target_public_key key pk: {}", + hex::encode(target_public_key) ); let seeds = KEY_MANAGER.get_consensus_seed().unwrap(); @@ -150,8 +164,6 @@ pub unsafe extern "C" fn ecall_authenticate_new_node( if let Ok(res) = result { match res { Ok(res) => { - trace!("Done encrypting seed, got {:?}, {:?}", res.len(), res); - let actual_size = res.len() as u32; *p_seeds_size = actual_size; @@ -160,9 +172,36 @@ pub unsafe extern "C" fn ecall_authenticate_new_node( return NodeAuthResult::InvalidInput; } - slice::from_raw_parts_mut(p_seeds, res.len()).copy_from_slice(&res); + if let Some(machine_id_hash) = verified_quote.machine_id_hash { + // handle changes to the SGX allow-list + let mut allow_list = crate::registration::attestation::PPID_WHITELIST + .lock() + .unwrap(); + + let owner: &allow_list::Owner = + &verified_quote.body.report_data.d[32..].try_into().unwrap(); + + let machine_pop: &allow_list::MachineID = + slice::from_raw_parts(p_machine_pop, allow_list::MACHINE_ID_LEN) + .try_into() + .unwrap(); + + // if swap-res failed - never mind. This is probably because the machine was added with proof-of-cloud + if allow_list.update(&machine_id_hash, owner, machine_pop) { + slice::from_raw_parts_mut(p_machine_info, allow_list::OWNER_LEN) + .copy_from_slice(owner); + + slice::from_raw_parts_mut( + p_machine_info.add(allow_list::OWNER_LEN), + allow_list::MACHINE_ID_LEN, + ) + .copy_from_slice(&machine_id_hash); + } + } + slice::from_raw_parts_mut(p_seeds, res.len()).copy_from_slice(&res); trace!("returning with seed: {}, {}", res.len(), hex::encode(&res)); + NodeAuthResult::Success } Err(e) => { diff --git a/cosmwasm/enclaves/execute/src/registration/seed_exchange.rs b/cosmwasm/enclaves/execute/src/registration/seed_exchange.rs index bc2661c134..df1f6166b9 100644 --- a/cosmwasm/enclaves/execute/src/registration/seed_exchange.rs +++ b/cosmwasm/enclaves/execute/src/registration/seed_exchange.rs @@ -7,7 +7,7 @@ use enclave_ffi_types::SINGLE_ENCRYPTED_SEED_SIZE; use enclave_utils::{Keychain, KEY_MANAGER}; pub fn encrypt_seed( - new_node_pk: [u8; PUBLIC_KEY_SIZE], + new_node_pk: &[u8; PUBLIC_KEY_SIZE], seed_to_share: &Seed, is_legacy: bool, ) -> SgxResult> { @@ -21,9 +21,9 @@ pub fn encrypt_seed( KEY_MANAGER.seed_exchange_key().unwrap() }; - let shared_enc_key = base_seed.diffie_hellman(&new_node_pk); + let shared_enc_key = base_seed.diffie_hellman(new_node_pk); - let authenticated_data: Vec<&[u8]> = vec![&new_node_pk]; + let authenticated_data: Vec<&[u8]> = vec![new_node_pk]; // encrypt the seed using the symmetric key derived in the previous stage // genesis seed is passed in registration diff --git a/cosmwasm/enclaves/shared/block-verifier/src/submit_block_signatures.rs b/cosmwasm/enclaves/shared/block-verifier/src/submit_block_signatures.rs index c0dec456e0..8b23e13ec7 100644 --- a/cosmwasm/enclaves/shared/block-verifier/src/submit_block_signatures.rs +++ b/cosmwasm/enclaves/shared/block-verifier/src/submit_block_signatures.rs @@ -16,8 +16,6 @@ macro_rules! unwrap_or_return { use crate::txs::tx_from_bytes; use crate::wasm_messages::VERIFIED_BLOCK_MESSAGES; -use sha2::{Digest, Sha256}; - const MAX_VARIABLE_LENGTH: u32 = 100_000; const MAX_BLOCK_DATA_LENGTH: u32 = 22_020_096; // 21 MiB = max block size const RANDOM_PROOF_LEN: u32 = 80; @@ -63,12 +61,22 @@ pub unsafe fn submit_block_signatures_impl( }; let (validator_set, height) = { - let extra = KEY_MANAGER.extra_data.lock().unwrap(); + let mut extra = KEY_MANAGER.extra_data.lock().unwrap(); + + if extra.last_submitted_header_height == 0 { + extra.last_submitted_header_height = extra.height; + } else { + if (extra.last_submitted_header_height != extra.height) && !extra.machine_allowed { + error!("This machine isn't allowed to run"); + return sgx_status_t::SGX_ERROR_INVALID_PARAMETER; + } + } + let validator_set = match extra.decode_validator_set() { Some(set) => set, None => { error!("Error parsing validator set from proto"); - return sgx_status_t::SGX_SUCCESS; + return sgx_status_t::SGX_ERROR_INVALID_PARAMETER; } }; @@ -133,6 +141,17 @@ pub unsafe fn submit_block_signatures_impl( .copy_from_slice(validator_set_evidence.as_slice()); } + let apphash = header.header().app_hash.as_bytes(); + if apphash.len() == 32 { + //println!("saving apphash: {}", hex::encode(apphash)); + + { + let mut extra = KEY_MANAGER.extra_data.lock().unwrap(); + extra.apphash.copy_from_slice(apphash); + } + KEY_MANAGER.save(); + } + debug!( "Done verifying block height: {:?}", header.header.height.value() diff --git a/cosmwasm/enclaves/shared/utils/src/key_manager.rs b/cosmwasm/enclaves/shared/utils/src/key_manager.rs index b9a64aa535..949ac48504 100644 --- a/cosmwasm/enclaves/shared/utils/src/key_manager.rs +++ b/cosmwasm/enclaves/shared/utils/src/key_manager.rs @@ -39,9 +39,13 @@ use tendermint_proto::Protobuf; // as sha256(key) encrypted with the seed. pub struct KeychainMutableData { pub height: u64, + pub apphash: [u8; 32], pub validator_set_serialized: Vec, pub next_mr_enclave: Option, pub last_block_seed: u16, + // the following is NOT serialized + pub last_submitted_header_height: u64, + pub machine_allowed: bool, } impl KeychainMutableData { @@ -128,6 +132,10 @@ impl Keychain { 2_u8 } else { 0_u8 + }) | (if extra.apphash != [0u8; 32] { + 4_u8 + } else { + 0_u8 }); writer.write_all(&[ex_flag])?; @@ -140,6 +148,10 @@ impl Keychain { writer.write_all(&extra.last_block_seed.to_le_bytes())?; } + if ex_flag & 4_u8 != 0 { + writer.write_all(&extra.apphash)?; + } + Ok(()) } @@ -149,7 +161,7 @@ impl Keychain { Ok(u16::from_le_bytes(buf)) } - fn read_u32(reader: &mut dyn Read) -> std::io::Result { + pub fn read_u32(reader: &mut dyn Read) -> std::io::Result { let mut buf = [0u8; 4]; reader.read_exact(&mut buf)?; Ok(u32::from_le_bytes(buf)) @@ -220,6 +232,12 @@ impl Keychain { extra.last_block_seed = DEF_LAST_BLOCK_SEED; } + if (flag_bytes[0] & 4_u8) != 0 { + reader.read_exact(&mut extra.apphash)?; + } else { + extra.apphash = [0u8; 32]; + } + Ok(()) } @@ -283,9 +301,12 @@ impl Keychain { random_encryption_key: None, extra_data: SgxMutex::new(KeychainMutableData { height: 0, + apphash: [0u8; 32], validator_set_serialized: Vec::new(), next_mr_enclave: None, last_block_seed: DEF_LAST_BLOCK_SEED, + last_submitted_header_height: 0, + machine_allowed: false, }), } } diff --git a/cosmwasm/packages/sgx-vm/src/attestation.rs b/cosmwasm/packages/sgx-vm/src/attestation.rs index 345564f9da..2742da0077 100644 --- a/cosmwasm/packages/sgx-vm/src/attestation.rs +++ b/cosmwasm/packages/sgx-vm/src/attestation.rs @@ -10,6 +10,8 @@ extern "C" { pub fn ecall_get_attestation_report( eid: sgx_enclave_id_t, retval: *mut sgx_status_t, + p_sk: *const u8, + n_sk: u32, flags: u32, ) -> sgx_status_t; pub fn ecall_authenticate_new_node( @@ -20,6 +22,8 @@ extern "C" { p_seeds: *mut u8, n_seeds: u32, p_seeds_size: *mut u32, + p_machine_pop: *const u8, + machine_info: *mut u8, ) -> sgx_status_t; pub fn ecall_get_genesis_seed( eid: sgx_enclave_id_t, @@ -30,7 +34,7 @@ extern "C" { ) -> sgx_status_t; } -pub fn create_attestation_report_u(flags: u32) -> SgxResult<()> { +pub fn create_attestation_report_u(p_sk: *const u8, n_sk: u32, flags: u32) -> SgxResult<()> { // Bind the token to a local variable to ensure its // destructor runs in the end of the function let enclave_access_token = ENCLAVE_DOORBELL @@ -40,7 +44,7 @@ pub fn create_attestation_report_u(flags: u32) -> SgxResult<()> { let eid = enclave.geteid(); let mut retval = sgx_status_t::SGX_SUCCESS; - let status = unsafe { ecall_get_attestation_report(eid, &mut retval, flags) }; + let status = unsafe { ecall_get_attestation_report(eid, &mut retval, p_sk, n_sk, flags) }; if status != sgx_status_t::SGX_SUCCESS { return Err(status); @@ -53,7 +57,10 @@ pub fn create_attestation_report_u(flags: u32) -> SgxResult<()> { Ok(()) } -pub fn untrusted_get_encrypted_seed(cert: &[u8]) -> SgxResult, NodeAuthResult>> { +pub fn untrusted_get_encrypted_seed( + cert: &[u8], + replace_machine: &[u8], +) -> SgxResult, Vec), NodeAuthResult>> { // Bind the token to a local variable to ensure its // destructor runs in the end of the function let enclave_access_token = ENCLAVE_DOORBELL @@ -67,6 +74,7 @@ pub fn untrusted_get_encrypted_seed(cert: &[u8]) -> SgxResult, No seed_buffer.resize(SINGLE_ENCRYPTED_SEED_SIZE * 100, 0); // should be enough. Resize in later version, when approaching the limit let mut seeds_size: u32 = 0; + let mut machine_info = [0_u8; 52]; let status = unsafe { ecall_authenticate_new_node( @@ -77,6 +85,8 @@ pub fn untrusted_get_encrypted_seed(cert: &[u8]) -> SgxResult, No seed_buffer.as_mut_ptr(), seed_buffer.len() as u32, &mut seeds_size, + replace_machine.as_ptr(), + machine_info.as_mut_ptr(), ) }; @@ -96,10 +106,16 @@ pub fn untrusted_get_encrypted_seed(cert: &[u8]) -> SgxResult, No } seed_buffer.resize(seeds_size as usize, 0); - debug!("Done auth, got seed: {}", hex::encode(&seed_buffer)); - Ok(Ok(seed_buffer)) + let is_machine_data_zero = machine_info.iter().all(|&x| x == 0); + let machine_data_arr = if is_machine_data_zero { + Vec::new() + } else { + machine_info.to_vec() + }; + + Ok(Ok((seed_buffer, machine_data_arr))) } pub fn untrusted_get_encrypted_genesis_seed( diff --git a/cosmwasm/packages/sgx-vm/src/lib.rs b/cosmwasm/packages/sgx-vm/src/lib.rs index 3971c8ad2f..322f214a5d 100644 --- a/cosmwasm/packages/sgx-vm/src/lib.rs +++ b/cosmwasm/packages/sgx-vm/src/lib.rs @@ -56,7 +56,8 @@ pub use crate::attestation::{ pub use crate::seed::{ untrusted_approve_machine_id, untrusted_approve_upgrade, untrusted_get_network_pubkey, untrusted_health_check, untrusted_init_bootstrap, untrusted_init_node, untrusted_key_gen, - untrusted_migration_op, untrusted_rotate_store, untrusted_submit_validator_set_evidence, + untrusted_migration_op, untrusted_rotate_store, untrusted_submit_machine_swap, + untrusted_submit_validator_set_evidence, }; pub use crate::random::untrusted_submit_block_signatures; diff --git a/cosmwasm/packages/sgx-vm/src/seed.rs b/cosmwasm/packages/sgx-vm/src/seed.rs index dfa2fe3608..bd1777c115 100644 --- a/cosmwasm/packages/sgx-vm/src/seed.rs +++ b/cosmwasm/packages/sgx-vm/src/seed.rs @@ -61,8 +61,16 @@ extern "C" { retval: *mut sgx_status_t, p_id: *const u8, n_id: u32, - p_proof: *mut u8, - is_on_chain: bool, + ) -> sgx_types::sgx_status_t; + + pub fn ecall_submit_machine_swap( + eid: sgx_enclave_id_t, + retval: *mut sgx_status_t, + index: u32, + p_machine_info: *const u8, + n_machine_info: u32, + p_proof: *const u8, + n_proof: u32, ) -> sgx_types::sgx_status_t; /// Trigger a query method in a wasm contract @@ -273,11 +281,7 @@ pub fn untrusted_approve_upgrade(msg_slice: &[u8]) -> SgxResult<()> { Ok(()) } -pub fn untrusted_approve_machine_id( - machine_id: &[u8], - proof: *mut u8, - is_on_chain: bool, -) -> SgxResult<()> { +pub fn untrusted_approve_machine_id(machine_id: &[u8]) -> SgxResult<()> { // Bind the token to a local variable to ensure its // destructor runs in the end of the function let enclave_access_token = ENCLAVE_DOORBELL @@ -295,8 +299,43 @@ pub fn untrusted_approve_machine_id( &mut ret, machine_id.as_ptr(), machine_id.len() as u32, - proof, - is_on_chain, + ) + }; + + if status != sgx_status_t::SGX_SUCCESS { + return Err(status); + } + + if ret != sgx_status_t::SGX_SUCCESS { + return Err(ret); + } + + Ok(()) +} + +pub fn untrusted_submit_machine_swap( + index: u32, + machine_info: &[u8], + proof: &[u8], +) -> SgxResult<()> { + let enclave_access_token = ENCLAVE_DOORBELL + .get_access(1) // This can never be recursive + .ok_or(sgx_status_t::SGX_ERROR_BUSY)?; + let enclave = (*enclave_access_token)?; + + //info!("Initialized enclave successfully!"); + + let eid = enclave.geteid(); + let mut ret = sgx_status_t::SGX_SUCCESS; + let status = unsafe { + ecall_submit_machine_swap( + eid, + &mut ret, + index, + machine_info.as_ptr(), + machine_info.len() as u32, + proof.as_ptr(), + proof.len() as u32, ) }; diff --git a/go-cosmwasm/api/bindings.h b/go-cosmwasm/api/bindings.h index 7b0baceaf7..d57a7e9964 100644 --- a/go-cosmwasm/api/bindings.h +++ b/go-cosmwasm/api/bindings.h @@ -156,7 +156,7 @@ void configure_enclave_runtime(EnclaveRuntimeConfig config, Buffer *err); Buffer create(cache_t *cache, Buffer wasm, Buffer *err); -bool create_attestation_report(uint32_t flags, Buffer *err); +bool create_attestation_report(Buffer sk, uint32_t flags, Buffer *err); bool emergency_approve_upgrade(Buffer data_dir, Buffer msg); @@ -166,7 +166,7 @@ Buffer get_code(cache_t *cache, Buffer id, Buffer *err); Buffer get_encrypted_genesis_seed(Buffer pk, Buffer *err); -Buffer get_encrypted_seed(Buffer cert, Buffer *err); +TwoBuffers get_encrypted_seed(Buffer cert, Buffer replace_machine, Buffer *err); Buffer get_health_check(Buffer *err); @@ -222,7 +222,7 @@ Buffer migrate(cache_t *cache, bool migration_op(uint32_t opcode); -bool onchain_approve_machine_id(Buffer machine_id, uint8_t *proof, bool is_on_chain); +bool onchain_approve_machine_id(Buffer machine_id); bool onchain_approve_upgrade(Buffer msg); @@ -255,6 +255,8 @@ TwoBuffers submit_block_signatures(Buffer header, Buffer random, Buffer *err); +bool submit_machine_swap(uint32_t index, Buffer machine_info, Buffer proof); + void submit_validator_set_evidence(Buffer evidence, Buffer *err); Buffer update_admin(cache_t *cache, diff --git a/go-cosmwasm/api/lib.go b/go-cosmwasm/api/lib.go index bd6e57c235..68909df7ec 100644 --- a/go-cosmwasm/api/lib.go +++ b/go-cosmwasm/api/lib.go @@ -196,11 +196,11 @@ func OnUpgradeProposalPassed(mrEnclaveHash []byte) error { return nil } -func OnApproveMachineID(machineID []byte, proof *[32]byte, is_on_chain bool) error { +func OnApproveMachineID(machineID []byte) error { msgBuf := sendSlice(machineID) defer freeAfterSend(msgBuf) - ret, err := C.onchain_approve_machine_id(msgBuf, (*C.uint8_t)(unsafe.Pointer(proof)), C.bool(is_on_chain)) + ret, err := C.onchain_approve_machine_id(msgBuf) if err != nil { return err } @@ -211,6 +211,23 @@ func OnApproveMachineID(machineID []byte, proof *[32]byte, is_on_chain bool) err return nil } +func SubmitMachineSwap(index uint32, machineInfo []byte, proof []byte) error { + machineInfoBuf := sendSlice(machineInfo) + defer freeAfterSend(machineInfoBuf) + proofBuf := sendSlice(proof) + defer freeAfterSend(proofBuf) + + ret, err := C.submit_machine_swap(u32(index), machineInfoBuf, proofBuf) + if err != nil { + return err + } + if !ret { + return errors.New("submit_machine_swap failed") + } + + return nil +} + func Create(cache Cache, wasm []byte) ([]byte, error) { code := sendSlice(wasm) defer freeAfterSend(code) @@ -507,7 +524,7 @@ func KeyGen() ([]byte, error) { } // CreateAttestationReport Send request to enclave -func CreateAttestationReport(is_migration_report bool) (bool, error) { +func CreateAttestationReport(ext_sk []byte, is_migration_report bool) (bool, error) { errmsg := C.Buffer{} flags := u32(0) @@ -515,22 +532,27 @@ func CreateAttestationReport(is_migration_report bool) (bool, error) { flags |= u32(0x10) } - _, err := C.create_attestation_report(flags, &errmsg) + skSlice := sendSlice(ext_sk) + defer freeAfterSend(skSlice) + + _, err := C.create_attestation_report(skSlice, flags, &errmsg) if err != nil { return false, errorWithMessage(err, errmsg) } return true, nil } -func GetEncryptedSeed(cert []byte) ([]byte, error) { +func GetEncryptedSeed(cert []byte, replace_machine_id []byte) ([]byte, []byte, error) { errmsg := C.Buffer{} certSlice := sendSlice(cert) defer freeAfterSend(certSlice) - res, err := C.get_encrypted_seed(certSlice, &errmsg) + replace_machine_slice := sendSlice(replace_machine_id) + defer freeAfterSend(replace_machine_slice) + res, err := C.get_encrypted_seed(certSlice, replace_machine_slice, &errmsg) if err != nil { - return nil, errorWithMessage(err, errmsg) + return nil, nil, errorWithMessage(err, errmsg) } - return receiveVector(res), nil + return receiveVector(res.buf1), receiveVector(res.buf2), nil } func GetEncryptedGenesisSeed(pk []byte) ([]byte, error) { diff --git a/go-cosmwasm/api/lib_mock.go b/go-cosmwasm/api/lib_mock.go index c14de5c7dc..34c452a341 100644 --- a/go-cosmwasm/api/lib_mock.go +++ b/go-cosmwasm/api/lib_mock.go @@ -272,7 +272,7 @@ func KeyGen() ([]byte, error) { } // KeyGen Seng KeyGen request to enclave -func CreateAttestationReport(is_migration_report bool) (bool, error) { +func CreateAttestationReport(ext_sk []byte, is_migration_report bool) (bool, error) { //errmsg := C.Buffer{} //_, err := C.create_attestation_report(&errmsg) //if err != nil { @@ -285,7 +285,7 @@ func GetNetworkPubkey(i_seed uint32) ([]byte, []byte) { return nil, nil } -func GetEncryptedSeed(cert []byte) ([]byte, error) { +func GetEncryptedSeed(cert []byte, replace_machine_id []byte) ([]byte, []byte, error) { //errmsg := C.Buffer{} //certSlice := sendSlice(cert) //defer freeAfterSend(certSlice) @@ -294,7 +294,7 @@ func GetEncryptedSeed(cert []byte) ([]byte, error) { // return nil, errorWithMessage(err, errmsg) //} //return receiveVector(res), nil - return nil, nil + return nil, nil, nil } func GetEncryptedGenesisSeed(cert []byte) ([]byte, error) { @@ -316,6 +316,10 @@ func OnUpgradeProposalPassed(mrEnclaveHash []byte) error { return nil } -func OnApproveMachineID(machineID []byte, proof *[32]byte, is_on_chain bool) error { +func OnApproveMachineID(machineID []byte) error { + return nil +} + +func SubmitMachineSwap(index uint32, machineInfo []byte, proof []byte) error { return nil } diff --git a/go-cosmwasm/src/lib.rs b/go-cosmwasm/src/lib.rs index b7293ff1ae..b2e7cc2468 100644 --- a/go-cosmwasm/src/lib.rs +++ b/go-cosmwasm/src/lib.rs @@ -16,7 +16,8 @@ use cosmwasm_sgx_vm::{ untrusted_approve_upgrade, untrusted_get_encrypted_genesis_seed, untrusted_get_encrypted_seed, untrusted_get_network_pubkey, untrusted_health_check, untrusted_init_bootstrap, untrusted_init_node, untrusted_key_gen, untrusted_migration_op, untrusted_rotate_store, - untrusted_submit_validator_set_evidence, Checksum, CosmCache, Extern, + untrusted_submit_machine_swap, untrusted_submit_validator_set_evidence, Checksum, CosmCache, + Extern, }; use ctor::ctor; pub use db::{db_t, DB}; @@ -68,30 +69,41 @@ pub extern "C" fn get_health_check(err: Option<&mut Buffer>) -> Buffer { } #[no_mangle] -pub extern "C" fn get_encrypted_seed(cert: Buffer, err: Option<&mut Buffer>) -> Buffer { +pub extern "C" fn get_encrypted_seed( + cert: Buffer, + replace_machine: Buffer, + err: Option<&mut Buffer>, +) -> TwoBuffers { trace!("Called get_encrypted_seed"); let cert_slice = match unsafe { cert.read() } { None => { set_error(Error::empty_arg("attestation_cert"), err); - return Buffer::default(); + return TwoBuffers::default(); } Some(r) => r, }; + let replace_machine_slice = match unsafe { replace_machine.read() } { + None => &[0u8], + Some(r) => r, + }; trace!("Hello from right before untrusted_get_encrypted_seed"); - match untrusted_get_encrypted_seed(cert_slice) { + match untrusted_get_encrypted_seed(cert_slice, replace_machine_slice) { Err(e) => { // An error happened in the SGX sdk. set_error(Error::enclave_err(e.to_string()), err); - Buffer::default() + TwoBuffers::default() } Ok(Err(e)) => { // An error was returned from the enclave. set_error(Error::enclave_err(e.to_string()), err); - Buffer::default() + TwoBuffers::default() } - Ok(Ok(seed)) => { + Ok(Ok((seed, owner))) => { clear_error(); - Buffer::from_vec(seed.to_vec()) + TwoBuffers { + buf1: Buffer::from_vec(seed.to_vec()), + buf2: Buffer::from_vec(owner.to_vec()), + } } } } @@ -164,8 +176,19 @@ pub extern "C" fn init_node( } #[no_mangle] -pub extern "C" fn create_attestation_report(flags: u32, err: Option<&mut Buffer>) -> bool { - if let Err(status) = create_attestation_report_u(flags) { +pub extern "C" fn create_attestation_report( + sk: Buffer, + flags: u32, + err: Option<&mut Buffer>, +) -> bool { + let sk_slice = match unsafe { sk.read() } { + None => &[], + Some(r) => r, + }; + + if let Err(status) = + create_attestation_report_u(sk_slice.as_ptr(), sk_slice.len() as u32, flags) + { set_error(Error::enclave_err(status.to_string()), err); return false; } @@ -965,11 +988,7 @@ pub extern "C" fn onchain_approve_upgrade(msg: Buffer) -> bool { #[no_mangle] #[allow(deprecated)] -pub extern "C" fn onchain_approve_machine_id( - machine_id: Buffer, - proof: *mut u8, - is_on_chain: bool, -) -> bool { +pub extern "C" fn onchain_approve_machine_id(machine_id: Buffer) -> bool { let machine_id_slice = match unsafe { machine_id.read() } { None => { return false; @@ -977,7 +996,36 @@ pub extern "C" fn onchain_approve_machine_id( Some(r) => r, }; - match untrusted_approve_machine_id(&machine_id_slice, proof, is_on_chain) { + match untrusted_approve_machine_id(machine_id_slice) { + Err(e) => { + set_error(Error::enclave_err(e.to_string()), None); + false + } + Ok(()) => { + clear_error(); + true + } + } +} + +#[no_mangle] +#[allow(deprecated)] +pub extern "C" fn submit_machine_swap(index: u32, machine_info: Buffer, proof: Buffer) -> bool { + let machine_info_slice = match unsafe { machine_info.read() } { + None => { + return false; + } + Some(r) => r, + }; + + let proof_slice = match unsafe { proof.read() } { + None => { + return false; + } + Some(r) => r, + }; + + match untrusted_submit_machine_swap(index, machine_info_slice, proof_slice) { Err(e) => { set_error(Error::enclave_err(e.to_string()), None); false diff --git a/proto/secret/registration/v1beta1/msg.proto b/proto/secret/registration/v1beta1/msg.proto index bff90dad40..71a89ee5c8 100644 --- a/proto/secret/registration/v1beta1/msg.proto +++ b/proto/secret/registration/v1beta1/msg.proto @@ -25,6 +25,8 @@ message RaAuthenticate { "remote_attestation.Certificate", (gogoproto.jsontag) = "ra_cert" ]; + + string replace_machine_id = 3; } message RaAuthenticateResponse { diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index d224fc1394..c755d5aeec 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -56,6 +56,7 @@ import ( v1wasmTypes "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types/v1" cronkeeper "github.com/scrtlabs/SecretNetwork/x/cron/keeper" + "github.com/scrtlabs/SecretNetwork/x/registration" "github.com/scrtlabs/SecretNetwork/x/compute/internal/types" @@ -84,6 +85,7 @@ type Keeper struct { bankKeeper bankkeeper.Keeper portKeeper portkeeper.Keeper capabilityKeeper capabilitykeeper.ScopedKeeper + regKeeper *registration.Keeper cronKeeper cronkeeper.Keeper wasmer wasm.Wasmer queryPlugins QueryPlugins @@ -123,6 +125,7 @@ func NewKeeper( portSource types.ICS20TransferPortSource, channelKeeper channelkeeper.Keeper, ics4Wrapper porttypes.ICS4Wrapper, + regKeeper *registration.Keeper, msgRouter MessageRouter, queryRouter GRPCQueryRouter, homeDir string, @@ -148,6 +151,7 @@ func NewKeeper( cronKeeper: cronKeeper, portKeeper: portKeeper, capabilityKeeper: capabilityKeeper, + regKeeper: regKeeper, messenger: NewMessageHandler( msgRouter, customEncoders, @@ -319,33 +323,6 @@ func (k Keeper) SetEnclaveColdEvidences(ctx sdk.Context) error { _ = api.SubmitValidatorSetEvidence(validator_set_evidence) } - // on-chain approved machines - - prefixKey := types.MachineIDEvidencePrefix - - iterator, _ := store.Iterator(prefixKey, nil) - defer iterator.Close() - - for ; iterator.Valid(); iterator.Next() { - key := iterator.Key() - if !bytes.HasPrefix(key, prefixKey) { - break - } - value := iterator.Value() - - if len(value) == 32 { - var proof [32]byte - copy(proof[:], value) - - id := key[len(prefixKey):] - - err := api.OnApproveMachineID(id, &proof, false) - if err != nil { - fmt.Println("Couldn't approve machine-id ", id) - } - } - } - return nil } @@ -1145,6 +1122,8 @@ func (k Keeper) SetRandomSeed(ctx sdk.Context, random []byte, validator_set_evid if err != nil { ctx.Logger().Error("SetRandomSeed:", err.Error()) } + + k.regKeeper.MaybeSetEnclaveColdData(ctx) } func (k Keeper) GetContractAddress(ctx sdk.Context, label string) sdk.AccAddress { diff --git a/x/compute/internal/keeper/msg_server.go b/x/compute/internal/keeper/msg_server.go index e6d5355cf2..9a62c9f2c5 100644 --- a/x/compute/internal/keeper/msg_server.go +++ b/x/compute/internal/keeper/msg_server.go @@ -373,23 +373,19 @@ func (m msgServer) UpdateMachineWhitelist(goCtx context.Context, msg *types.MsgU sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender), )) - store := m.keeper.storeService.OpenKVStore(ctx) - ids, err := ParseHexList(msg.MachineId) if err != nil { return nil, err } for _, id := range ids { - proof := [32]byte{} - err := api.OnApproveMachineID(id, &proof, true) + err := api.OnApproveMachineID(id) id_txt := hex.EncodeToString(id) if err != nil { fmt.Println("Failed to add machine_id: ", id_txt) } else { fmt.Println("Added machine_id: ", id_txt) - key := append(types.MachineIDEvidencePrefix, id...) - _ = store.Set(key, proof[:]) + _ = m.keeper.regKeeper.OnNewMachine(ctx, id) } } diff --git a/x/compute/internal/keeper/test_common.go b/x/compute/internal/keeper/test_common.go index 5d5033c3ae..139c00d827 100644 --- a/x/compute/internal/keeper/test_common.go +++ b/x/compute/internal/keeper/test_common.go @@ -581,6 +581,16 @@ func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, enc // stakingtypes.RegisterMsgServer(serviceRouter, stakingMsgServer) // distrtypes.RegisterMsgServer(serviceRouter, distrMsgServer) + regKeeper := registration.NewKeeper( + encodingConfig.Codec, + runtime.NewKVStoreService(keys[registration.StoreKey]), + msgRouter, + registration.EnclaveApi{}, + tempDir, + false, + &baseapp.BaseApp{}, + ) + bappTxMngr := baseapp.LastMsgMarkerContainer{} keeper := NewKeeper( @@ -600,6 +610,7 @@ func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, enc MockIBCTransferKeeper{}, ibcKeeper.ChannelKeeper, nil, + ®Keeper, msgRouter, queryRouter, tempDir, diff --git a/x/registration/client/cli/tx.go b/x/registration/client/cli/tx.go index 3ba2a7f194..643f1e939d 100644 --- a/x/registration/client/cli/tx.go +++ b/x/registration/client/cli/tx.go @@ -29,9 +29,9 @@ func GetTxCmd() *cobra.Command { // AuthenticateNodeCmd will upload code to be reused. func AuthenticateNodeCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "auth [cert file]", + Use: "auth attestation_file [replace_machine_id]", Short: "Upload a certificate to authenticate the node", - Args: cobra.ExactArgs(1), + Args: cobra.RangeArgs(1, 2), RunE: func(cmd *cobra.Command, args []string) error { // clientCtx := client.GetClientContextFromCmd(cmd) clientCtx, err := client.GetClientTxContext(cmd) @@ -44,10 +44,17 @@ func AuthenticateNodeCmd() *cobra.Command { return err } + replace_machine_id := "" + + if len(args) > 1 { + replace_machine_id = args[1] + } + // build and sign the transaction, then broadcast to Tendermint msg := types.RaAuthenticate{ - Sender: clientCtx.GetFromAddress(), - Certificate: cert, + Sender: clientCtx.GetFromAddress(), + Certificate: cert, + ReplaceMachineId: replace_machine_id, } err = msg.ValidateBasic() if err != nil { diff --git a/x/registration/handler.go b/x/registration/handler.go index af95d9e0b9..d2ea0e0423 100644 --- a/x/registration/handler.go +++ b/x/registration/handler.go @@ -45,7 +45,7 @@ func handleRaAuthenticate(ctx sdk.Context, k Keeper, msg *types.RaAuthenticate) return nil, err } - encSeed, err := k.RegisterNode(ctx, msg.Certificate) + encSeed, err := k.RegisterNode(ctx, msg.Certificate, msg.ReplaceMachineId) if err != nil { return nil, err } diff --git a/x/registration/internal/keeper/enclave/enclave.go b/x/registration/internal/keeper/enclave/enclave.go index 3613c11fcf..8d58629d3d 100644 --- a/x/registration/internal/keeper/enclave/enclave.go +++ b/x/registration/internal/keeper/enclave/enclave.go @@ -10,8 +10,8 @@ func (Api) LoadSeed(masterKey []byte, seed []byte) (bool, error) { return api.LoadSeedToEnclave(masterKey, seed) } -func (Api) GetEncryptedSeed(masterCert []byte) ([]byte, error) { - return api.GetEncryptedSeed(masterCert) +func (Api) GetEncryptedSeed(masterCert []byte, replace_machine_id []byte) ([]byte, []byte, error) { + return api.GetEncryptedSeed(masterCert, replace_machine_id) } func (Api) GetEncryptedGenesisSeed(pk []byte) ([]byte, error) { diff --git a/x/registration/internal/keeper/enclave_interface.go b/x/registration/internal/keeper/enclave_interface.go index d5f1181761..e576090000 100644 --- a/x/registration/internal/keeper/enclave_interface.go +++ b/x/registration/internal/keeper/enclave_interface.go @@ -2,6 +2,6 @@ package keeper type EnclaveInterface interface { LoadSeed(masterKey []byte, seed []byte) (bool, error) - GetEncryptedSeed(masterCert []byte) ([]byte, error) + GetEncryptedSeed(masterCert []byte, replace_machine_id []byte) ([]byte, []byte, error) GetEncryptedGenesisSeed(pk []byte) ([]byte, error) } diff --git a/x/registration/internal/keeper/keeper.go b/x/registration/internal/keeper/keeper.go index 9170ab4a4a..abeed81678 100644 --- a/x/registration/internal/keeper/keeper.go +++ b/x/registration/internal/keeper/keeper.go @@ -1,16 +1,26 @@ package keeper import ( + "bytes" + "context" "encoding/binary" "encoding/hex" "encoding/json" + "fmt" "path/filepath" "cosmossdk.io/core/store" errorsmod "cosmossdk.io/errors" + "cosmossdk.io/store/prefix" + abci "github.com/cometbft/cometbft/abci/types" + cmtcrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/gogoproto/proto" + ics23 "github.com/cosmos/ics23/go" + "github.com/scrtlabs/SecretNetwork/go-cosmwasm/api" "github.com/scrtlabs/SecretNetwork/x/registration/internal/types" ra "github.com/scrtlabs/SecretNetwork/x/registration/remote_attestation" ) @@ -21,10 +31,12 @@ type Keeper struct { cdc codec.Codec enclave EnclaveInterface router baseapp.MessageRouter + queryer ABCIQueryer + coldDataSet bool } // NewKeeper creates a new contract Keeper instance -func NewKeeper(cdc codec.Codec, storeService store.KVStoreService, router baseapp.MessageRouter, enclave EnclaveInterface, homeDir string, bootstrap bool) Keeper { +func NewKeeper(cdc codec.Codec, storeService store.KVStoreService, router baseapp.MessageRouter, enclave EnclaveInterface, homeDir string, bootstrap bool, q ABCIQueryer) Keeper { if !bootstrap { InitializeNode(homeDir, enclave) } @@ -34,6 +46,8 @@ func NewKeeper(cdc codec.Codec, storeService store.KVStoreService, router baseap cdc: cdc, router: router, enclave: enclave, + queryer: q, + coldDataSet: false, } } @@ -124,7 +138,199 @@ func InitializeNode(homeDir string, enclave EnclaveInterface) { } } -func (k Keeper) RegisterNode(ctx sdk.Context, certificate ra.Certificate) ([]byte, error) { +func (k Keeper) AddMachineSwapInfo(ctx sdk.Context, data []byte) error { + store := k.storeService.OpenKVStore(ctx) + + var next_index [4]byte + + { + bz, _ := store.Get(types.RegistrationMachineIndex) + if bz != nil { + next_index_numeric := binary.BigEndian.Uint32(bz) + 1 + binary.BigEndian.PutUint32(next_index[:], next_index_numeric) + + } + } + + store.Set(types.RegistrationMachineIndex, next_index[:]) + + key := make([]byte, 0, len(types.RegistrationMachinePrefix)+4) + key = append(key, types.RegistrationMachinePrefix...) + key = append(key, next_index[:]...) + + store.Set(key, data) + + return nil +} + +func (k Keeper) OnNewMachine(ctx sdk.Context, id []byte) error { + return k.AddMachineSwapInfo(ctx, id) +} + +type ABCIQueryer interface { + Query(ctx context.Context, req *abci.RequestQuery) (*abci.ResponseQuery, error) +} + +// // Simple protobuf uvarint (VAR_PROTO) encoder +// func encodeUVarint(x uint64) []byte { +// buf := make([]byte, binary.MaxVarintLen64) +// n := binary.PutUvarint(buf, x) +// return buf[:n] +// } + +// func LeafHashIAVL(prefix, key, value []byte) []byte { +// // Prehash key: NO_HASH +// k := key + +// // Prehash value: SHA256 +// vHash := sha256.Sum256(value) +// v := vHash[:] + +// // Length encoding: VAR_PROTO (protobuf uvarint) +// // (for <128, it becomes one byte) +// kLen := encodeUVarint(uint64(len(k))) +// vLen := encodeUVarint(uint64(len(v))) + +// // Build leaf bytes +// leafBytes := make([]byte, 0, len(prefix)+len(kLen)+len(k)+len(vLen)+len(v)) +// leafBytes = append(leafBytes, prefix...) +// leafBytes = append(leafBytes, kLen...) +// leafBytes = append(leafBytes, k...) +// leafBytes = append(leafBytes, vLen...) +// leafBytes = append(leafBytes, v...) + +// // Final leaf hash = SHA256(leafBytes) +// h := sha256.Sum256(leafBytes) +// return h[:] +// } + +func SerializeMerkleProof(ops []cmtcrypto.ProofOp) (error, []byte) { + proof_serialized := new(bytes.Buffer) + + _ = binary.Write(proof_serialized, binary.LittleEndian, uint32(len(ops))) + + // var hash []byte + + for _, op := range ops { + // fmt.Printf("Op #%d:\n", i) + // fmt.Printf(" Type: %s\n", op.Type) + // fmt.Printf(" Key: %s\n", hex.EncodeToString(op.Key)) + + var cp ics23.CommitmentProof + if err := proto.Unmarshal(op.Data, &cp); err != nil { + return fmt.Errorf("failed to unmarshal ICS23 proof: %w", err), nil + } + + switch p := cp.Proof.(type) { + + case *ics23.CommitmentProof_Exist: + ep := p.Exist + // fmt.Printf("ExistenceProof:\n") + // fmt.Printf(" Key: %s\n", hex.EncodeToString(ep.Key)) + // fmt.Printf(" Value: %s\n", hex.EncodeToString(ep.Value)) + + lo := ep.Leaf + // fmt.Printf("LeafOp:\n") + // fmt.Printf(" hash = %v\n", lo.Hash) + // fmt.Printf(" prehash_key = %v\n", lo.PrehashKey) + // fmt.Printf(" prehash_val = %v\n", lo.PrehashValue) + // fmt.Printf(" length = %v\n", lo.Length) + // fmt.Printf(" prefix = %X\n", lo.Prefix) + + // hash = LeafHashIAVL(lo.Prefix, ep.Key, ep.Value) + // fmt.Println("Leaf hash: ", hex.EncodeToString(hash)) + + _ = binary.Write(proof_serialized, binary.LittleEndian, uint32(len(lo.Prefix))) + proof_serialized.Write(lo.Prefix) + + _ = binary.Write(proof_serialized, binary.LittleEndian, uint32(len(ep.Path))) + + for _, innerOp := range ep.Path { + // fmt.Printf(" Prefix: %s\n", hex.EncodeToString(innerOp.Prefix)) + // fmt.Printf(" Suffix: %s\n", hex.EncodeToString(innerOp.Suffix)) + // fmt.Printf(" HashOp: %d\n", innerOp.Hash) + + // hash_inp := append(innerOp.Prefix, hash...) + // hash_inp = append(hash_inp, innerOp.Suffix...) + // h := sha256.Sum256(hash_inp) + // hash = h[:] + + _ = binary.Write(proof_serialized, binary.LittleEndian, uint32(len(innerOp.Prefix))) + proof_serialized.Write(innerOp.Prefix) + _ = binary.Write(proof_serialized, binary.LittleEndian, uint32(len(innerOp.Suffix))) + proof_serialized.Write(innerOp.Suffix) + + // fmt.Printf(" value: %s\n", hex.EncodeToString(hash)) + } + + default: + return fmt.Errorf("unknown ICS23 proof type in CommitmentProof: %w", p), nil + } + } + + return nil, proof_serialized.Bytes() +} + +func (k *Keeper) MaybeSetEnclaveColdData(ctx sdk.Context) error { + if k.coldDataSet { + return nil + } + + k.coldDataSet = true + + // on-chain approved machine migrations + + store := k.storeService.OpenKVStore(ctx) + prefixStore := prefix.NewStore(runtime.KVStoreAdapter(store), types.RegistrationMachinePrefix) + it := prefixStore.Iterator(nil, nil) + defer it.Close() + + // apphash := ctx.BlockHeader().AppHash + // fmt.Println("**** AppHash: ", hex.EncodeToString(apphash)) + + for ; it.Valid(); it.Next() { + key := it.Key() + value := it.Value() + // fmt.Println("K: ", hex.EncodeToString(key)) + // fmt.Println("v: ", hex.EncodeToString(value)) + + index := binary.BigEndian.Uint32(key) + + // fmt.Println("Querying the enclave cold evidence") + + height := ctx.BlockHeight() - 1 + + key = append(types.RegistrationMachinePrefix, key...) + req := &abci.RequestQuery{ + Path: "/store/register/key", // <- your module storeKey + Data: key, // <- the actual key + Height: height, + Prove: true, + } + + resp, err := k.queryer.Query(ctx, req) + + var merkle_proof_serialized []byte = nil + + if err == nil { + if resp != nil { + // fmt.Println("Key: ", hex.EncodeToString(resp.Key)) + // fmt.Println("Value: ", hex.EncodeToString(resp.Value)) + err, merkle_proof_serialized = SerializeMerkleProof(resp.ProofOps.Ops) + } else { + fmt.Println("No Merkle proof for entry: ", hex.EncodeToString(key)) + } + } else { + fmt.Println("Merkle proof query error: ", err) + } + + api.SubmitMachineSwap(index, value, merkle_proof_serialized) + } + + return nil +} + +func (k Keeper) RegisterNode(ctx sdk.Context, certificate ra.Certificate, replace_machine_id string) ([]byte, error) { // fmt.Println("RegisterNode") var encSeed []byte var publicKey []byte @@ -141,19 +347,35 @@ func (k Keeper) RegisterNode(ctx sdk.Context, certificate ra.Certificate) ([]byt publicKey = publicKey_ - isAuth, err := k.isNodeAuthenticated(ctx, publicKey) - if err != nil { - return nil, errorsmod.Wrap(types.ErrAuthenticateFailed, err.Error()) - } - if isAuth { - return k.getRegistrationInfo(ctx, publicKey).EncryptedSeed, nil + // Note: don't skip envoking the enclave even if the node was already registered. + // The enclave may realize the new node ownership + + var replaceMachineID [20]byte // this is by default + + { + decoded, err := hex.DecodeString(replace_machine_id) + if err == nil && len(decoded) == 20 { + copy(replaceMachineID[:], decoded) + } } - encSeed, err = k.enclave.GetEncryptedSeed(certificate) + var machineInfo []byte + encSeed, machineInfo, err = k.enclave.GetEncryptedSeed(certificate, replaceMachineID[:]) if err != nil { // return 0, errorsmod.Wrap(err, "cosmwasm create") return nil, errorsmod.Wrap(types.ErrAuthenticateFailed, err.Error()) } + + if len(machineInfo) == 52 { + + store_swap_info := make([]byte, 72) + copy(store_swap_info[:52], machineInfo[:]) + copy(store_swap_info[52:72], replaceMachineID[:]) + + // last 20 bytes are the machine_id_pop - will be added later + k.AddMachineSwapInfo(ctx, store_swap_info) + } + } regInfo := types.RegistrationNodeInfo{ diff --git a/x/registration/internal/keeper/mock/enclave.go b/x/registration/internal/keeper/mock/enclave.go index 053d81851e..643e1431a5 100644 --- a/x/registration/internal/keeper/mock/enclave.go +++ b/x/registration/internal/keeper/mock/enclave.go @@ -8,8 +8,8 @@ func (MockEnclaveApi) LoadSeed(_ []byte, _ []byte) (bool, error) { return true, nil } -func (MockEnclaveApi) GetEncryptedSeed(_ []byte) ([]byte, error) { - return []byte(""), nil +func (MockEnclaveApi) GetEncryptedSeed(_ []byte, _ []byte) ([]byte, []byte, error) { + return []byte(""), nil, nil } func (MockEnclaveApi) GetEncryptedGenesisSeed(_ []byte) ([]byte, error) { diff --git a/x/registration/internal/keeper/msg_server.go b/x/registration/internal/keeper/msg_server.go index c14a71e9fe..3f58080d26 100644 --- a/x/registration/internal/keeper/msg_server.go +++ b/x/registration/internal/keeper/msg_server.go @@ -41,7 +41,7 @@ func (m msgServer) RegisterAuth(goCtx context.Context, msg *types.RaAuthenticate return nil, err } - encSeed, err := m.keeper.RegisterNode(ctx, msg.Certificate) + encSeed, err := m.keeper.RegisterNode(ctx, msg.Certificate, msg.ReplaceMachineId) if err != nil { return nil, err } diff --git a/x/registration/internal/keeper/test_common.go b/x/registration/internal/keeper/test_common.go index bac1f1d7ec..9a1a20a300 100644 --- a/x/registration/internal/keeper/test_common.go +++ b/x/registration/internal/keeper/test_common.go @@ -136,7 +136,7 @@ func CreateTestInput(t *testing.T, isCheckTx bool, tempDir string, bootstrap boo router := baseapp.NewMsgServiceRouter() // Load default wasm config - keeper := NewKeeper(cdc, runtime.NewKVStoreService(keys[regtypes.StoreKey]), router, registrationmock.MockEnclaveApi{}, tempDir, bootstrap) + keeper := NewKeeper(cdc, runtime.NewKVStoreService(keys[regtypes.StoreKey]), router, registrationmock.MockEnclaveApi{}, tempDir, bootstrap, &baseapp.BaseApp{}) return ctx, keeper } diff --git a/x/registration/internal/types/keys.go b/x/registration/internal/types/keys.go index 0095715781..0700c80ee3 100644 --- a/x/registration/internal/types/keys.go +++ b/x/registration/internal/types/keys.go @@ -20,6 +20,8 @@ const ( var ( RegistrationStorePrefix = []byte{0x01} RegistrationMasterKeyPrefix = []byte{0x02} + RegistrationMachinePrefix = []byte{0x03} + RegistrationMachineIndex = []byte{0x04} ) func RegistrationKeyPrefix(key []byte) []byte { diff --git a/x/registration/internal/types/msg.pb.go b/x/registration/internal/types/msg.pb.go index 9739432699..278ff6cdcf 100644 --- a/x/registration/internal/types/msg.pb.go +++ b/x/registration/internal/types/msg.pb.go @@ -33,8 +33,9 @@ var _ = math.Inf const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type RaAuthenticate struct { - Sender github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,1,opt,name=sender,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"sender,omitempty"` - Certificate github_com_scrtlabs_SecretNetwork_x_registration_remote_attestation.Certificate `protobuf:"bytes,2,opt,name=certificate,proto3,casttype=github.com/scrtlabs/SecretNetwork/x/registration/remote_attestation.Certificate" json:"ra_cert"` + Sender github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,1,opt,name=sender,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"sender,omitempty"` + Certificate github_com_scrtlabs_SecretNetwork_x_registration_remote_attestation.Certificate `protobuf:"bytes,2,opt,name=certificate,proto3,casttype=github.com/scrtlabs/SecretNetwork/x/registration/remote_attestation.Certificate" json:"ra_cert"` + ReplaceMachineId string `protobuf:"bytes,3,opt,name=replace_machine_id,json=replaceMachineId,proto3" json:"replace_machine_id,omitempty"` } func (m *RaAuthenticate) Reset() { *m = RaAuthenticate{} } @@ -194,36 +195,37 @@ func init() { } var fileDescriptor_91e653c4cfa6dfea = []byte{ - // 449 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x52, 0xb1, 0x6e, 0x13, 0x41, - 0x10, 0xbd, 0xc5, 0xc4, 0x91, 0x97, 0x08, 0xa4, 0x55, 0x14, 0x82, 0x91, 0xee, 0x82, 0x25, 0x24, - 0x14, 0x94, 0x5b, 0x99, 0x74, 0x34, 0xc8, 0x81, 0x06, 0xa1, 0x80, 0xb4, 0x74, 0x14, 0x44, 0x7b, - 0x7b, 0xc3, 0xe5, 0xe4, 0xf8, 0xd6, 0xda, 0x99, 0x18, 0xdc, 0xa0, 0x88, 0x8a, 0x92, 0x4f, 0xa0, - 0xa4, 0xcc, 0x67, 0xa4, 0x4c, 0x49, 0x65, 0x81, 0x5d, 0x44, 0x4a, 0x43, 0x9f, 0x0a, 0xdd, 0xde, - 0x21, 0xec, 0x26, 0x92, 0x9b, 0xbb, 0x19, 0xcd, 0xdb, 0x37, 0xef, 0xcd, 0x0c, 0x7f, 0x88, 0x60, - 0x1c, 0x90, 0x74, 0x90, 0xe5, 0x48, 0x4e, 0x53, 0x6e, 0x0b, 0x39, 0xea, 0x26, 0x40, 0xba, 0x2b, - 0x07, 0x98, 0xc5, 0x43, 0x67, 0xc9, 0x8a, 0xfb, 0x15, 0x2c, 0x9e, 0x87, 0xc5, 0x35, 0xac, 0xbd, - 0x9e, 0xd9, 0xcc, 0x7a, 0x9c, 0x2c, 0xa3, 0xea, 0x49, 0xfb, 0xae, 0xb1, 0x38, 0xb0, 0x58, 0x92, - 0xc8, 0xd1, 0x1c, 0x57, 0xe7, 0x0f, 0xe3, 0xb7, 0x95, 0xee, 0x1d, 0xd3, 0x21, 0x14, 0x94, 0x1b, - 0x4d, 0x20, 0x5e, 0xf2, 0x26, 0x42, 0x91, 0x82, 0xdb, 0x64, 0x5b, 0xec, 0xd1, 0xda, 0x5e, 0xf7, - 0x6a, 0x12, 0xed, 0x64, 0x39, 0x1d, 0x1e, 0x27, 0xb1, 0xb1, 0x03, 0x59, 0x53, 0x55, 0xbf, 0x1d, - 0x4c, 0xfb, 0x92, 0xc6, 0x43, 0xc0, 0xb8, 0x67, 0x4c, 0x2f, 0x4d, 0x1d, 0x20, 0xaa, 0x9a, 0x40, - 0x9c, 0x30, 0x7e, 0xcb, 0x80, 0xa3, 0xfc, 0x83, 0xa7, 0xde, 0xbc, 0xe1, 0x09, 0xdf, 0x5f, 0x4e, - 0xa2, 0x55, 0xa7, 0x0f, 0xca, 0xca, 0xd5, 0x24, 0x7a, 0x33, 0xc7, 0x8d, 0xc6, 0xd1, 0x91, 0x4e, - 0x50, 0xbe, 0xf5, 0x16, 0x5f, 0x03, 0x7d, 0xb4, 0xae, 0x2f, 0x3f, 0x2d, 0x8e, 0xc4, 0xc1, 0xc0, - 0x12, 0x1c, 0x68, 0x22, 0x40, 0xaa, 0xec, 0x3f, 0xff, 0xdf, 0x45, 0xcd, 0xb7, 0x7c, 0x7a, 0xe7, - 0xeb, 0xf7, 0x28, 0xf8, 0x72, 0x71, 0xba, 0x5d, 0x6b, 0xea, 0xbc, 0xe0, 0x1b, 0x8b, 0x86, 0x15, - 0xe0, 0xd0, 0x16, 0x08, 0x42, 0xf0, 0x9b, 0xa9, 0x26, 0xed, 0x6d, 0xb7, 0x94, 0x8f, 0xc5, 0x06, - 0x6f, 0xc2, 0x08, 0x0a, 0x42, 0xaf, 0xbd, 0xa5, 0xea, 0xac, 0xf3, 0x80, 0xb7, 0xf6, 0x35, 0x12, - 0xb8, 0x57, 0x30, 0x16, 0xeb, 0x7c, 0x25, 0x19, 0x13, 0x60, 0x35, 0x30, 0x55, 0x25, 0x9d, 0x2d, - 0xde, 0x28, 0x8b, 0xf7, 0x78, 0xa3, 0x0f, 0xe3, 0x7a, 0x96, 0xab, 0x97, 0x93, 0xa8, 0x4c, 0x55, - 0xf9, 0x79, 0xf2, 0x99, 0x37, 0xf6, 0x31, 0x13, 0x43, 0xbe, 0xa6, 0xbc, 0x3d, 0x70, 0xa5, 0x2e, - 0xf1, 0x38, 0xbe, 0x66, 0xc1, 0xf1, 0xa2, 0xf8, 0xf6, 0xee, 0x12, 0xe0, 0x7f, 0x4e, 0xdb, 0x2b, - 0x27, 0x17, 0xa7, 0xdb, 0x6c, 0x4f, 0x9f, 0xfd, 0x0e, 0x83, 0x1f, 0xd3, 0x90, 0x9d, 0x4d, 0x43, - 0x76, 0x3e, 0x0d, 0xd9, 0xaf, 0x69, 0xc8, 0xbe, 0xcd, 0xc2, 0xe0, 0x7c, 0x16, 0x06, 0x3f, 0x67, - 0x61, 0xf0, 0xee, 0xd9, 0xd2, 0xbb, 0xc9, 0x0b, 0x02, 0x57, 0xe8, 0xa3, 0xea, 0x28, 0x92, 0xa6, - 0x3f, 0xb3, 0xdd, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x39, 0x18, 0xd5, 0xdb, 0x02, 0x00, - 0x00, + // 479 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x52, 0x3d, 0x6f, 0xd3, 0x50, + 0x14, 0xb5, 0x1b, 0x9a, 0x2a, 0x8f, 0x0a, 0xd0, 0x53, 0x55, 0x42, 0x90, 0xec, 0x10, 0x09, 0xa9, + 0x2a, 0xd4, 0x56, 0xe8, 0xc6, 0x82, 0x52, 0x58, 0x2a, 0x14, 0x90, 0x1e, 0x1b, 0x03, 0xd1, 0xf3, + 0xf3, 0xc5, 0xb1, 0x12, 0xfb, 0x59, 0xef, 0xde, 0x06, 0xb2, 0xa0, 0x8a, 0x89, 0x91, 0x3f, 0x80, + 0xc4, 0xc8, 0xd8, 0x9f, 0xd1, 0xb1, 0x23, 0x53, 0x04, 0xc9, 0x50, 0xa9, 0x3f, 0xa1, 0x13, 0xf2, + 0x07, 0x22, 0x59, 0x90, 0xb2, 0xd8, 0xf7, 0xea, 0x1c, 0x9f, 0x7b, 0xcf, 0xf1, 0x65, 0x0f, 0x11, + 0x94, 0x01, 0xf2, 0x0d, 0x44, 0x31, 0x92, 0x91, 0x14, 0xeb, 0xd4, 0x9f, 0x74, 0x03, 0x20, 0xd9, + 0xf5, 0x13, 0x8c, 0xbc, 0xcc, 0x68, 0xd2, 0xfc, 0x7e, 0x49, 0xf3, 0x96, 0x69, 0x5e, 0x45, 0x6b, + 0xed, 0x44, 0x3a, 0xd2, 0x05, 0xcf, 0xcf, 0xab, 0xf2, 0x93, 0xd6, 0x5d, 0xa5, 0x31, 0xd1, 0x98, + 0x8b, 0xf8, 0x93, 0x25, 0xad, 0xce, 0xb7, 0x0d, 0x76, 0x4b, 0xc8, 0xde, 0x09, 0x0d, 0x21, 0xa5, + 0x58, 0x49, 0x02, 0x7e, 0xcc, 0xea, 0x08, 0x69, 0x08, 0xa6, 0x69, 0xb7, 0xed, 0xbd, 0xed, 0xa3, + 0xee, 0xf5, 0xcc, 0x3d, 0x88, 0x62, 0x1a, 0x9e, 0x04, 0x9e, 0xd2, 0x89, 0x5f, 0x49, 0x95, 0xaf, + 0x03, 0x0c, 0x47, 0x3e, 0x4d, 0x33, 0x40, 0xaf, 0xa7, 0x54, 0x2f, 0x0c, 0x0d, 0x20, 0x8a, 0x4a, + 0x80, 0x9f, 0xda, 0xec, 0xa6, 0x02, 0x43, 0xf1, 0xfb, 0x42, 0xba, 0xb9, 0x51, 0x08, 0xbe, 0xbb, + 0x9a, 0xb9, 0x5b, 0x46, 0x0e, 0x72, 0xe4, 0x7a, 0xe6, 0xbe, 0x5e, 0xd2, 0x46, 0x65, 0x68, 0x2c, + 0x03, 0xf4, 0xdf, 0x14, 0x16, 0x5f, 0x01, 0x7d, 0xd0, 0x66, 0xe4, 0x7f, 0x5c, 0x8d, 0xc4, 0x40, + 0xa2, 0x09, 0x06, 0x92, 0x08, 0x90, 0x4a, 0xfb, 0xcf, 0xff, 0x4d, 0x11, 0xcb, 0x23, 0xf9, 0x63, + 0xc6, 0x0d, 0x64, 0x63, 0xa9, 0x60, 0x90, 0x48, 0x35, 0x8c, 0x53, 0x18, 0xc4, 0x61, 0xb3, 0xd6, + 0xb6, 0xf7, 0x1a, 0xe2, 0x4e, 0x85, 0xf4, 0x4b, 0xe0, 0x38, 0x7c, 0x7a, 0xfb, 0xcb, 0x77, 0xd7, + 0xfa, 0x7c, 0x79, 0xb6, 0x5f, 0x39, 0xe8, 0xbc, 0x60, 0xbb, 0xab, 0xf1, 0x08, 0xc0, 0x4c, 0xa7, + 0x08, 0x9c, 0xb3, 0x1b, 0xa1, 0x24, 0x59, 0x84, 0xd4, 0x10, 0x45, 0xcd, 0x77, 0x59, 0x1d, 0x26, + 0x90, 0x12, 0x16, 0x4e, 0x1b, 0xa2, 0xea, 0x3a, 0x0f, 0x58, 0xa3, 0x2f, 0x91, 0xc0, 0xbc, 0x84, + 0x29, 0xdf, 0x61, 0x9b, 0xc1, 0x94, 0x00, 0xcb, 0x78, 0x45, 0xd9, 0x74, 0xda, 0xac, 0x96, 0x83, + 0xf7, 0x58, 0x6d, 0x04, 0xd3, 0x2a, 0xf9, 0xad, 0xab, 0x99, 0x9b, 0xb7, 0x22, 0x7f, 0x3c, 0xf9, + 0xc4, 0x6a, 0x7d, 0x8c, 0x78, 0xc6, 0xb6, 0x45, 0x11, 0x06, 0x98, 0x7c, 0x2f, 0xfe, 0xc8, 0xfb, + 0xcf, 0x39, 0x78, 0xab, 0xcb, 0xb7, 0x0e, 0xd7, 0x20, 0xff, 0x75, 0xda, 0xda, 0x3c, 0xbd, 0x3c, + 0xdb, 0xb7, 0x8f, 0xe4, 0xf9, 0x6f, 0xc7, 0xfa, 0x31, 0x77, 0xec, 0xf3, 0xb9, 0x63, 0x5f, 0xcc, + 0x1d, 0xfb, 0xd7, 0xdc, 0xb1, 0xbf, 0x2e, 0x1c, 0xeb, 0x62, 0xe1, 0x58, 0x3f, 0x17, 0x8e, 0xf5, + 0xf6, 0xd9, 0xda, 0x7f, 0x32, 0x4e, 0x09, 0x4c, 0x2a, 0xc7, 0xe5, 0x09, 0x05, 0xf5, 0xe2, 0x28, + 0x0f, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0xf6, 0x9c, 0xf4, 0x2c, 0x09, 0x03, 0x00, 0x00, } func (this *RaAuthenticate) Equal(that interface{}) bool { @@ -251,6 +253,9 @@ func (this *RaAuthenticate) Equal(that interface{}) bool { if !bytes.Equal(this.Certificate, that1.Certificate) { return false } + if this.ReplaceMachineId != that1.ReplaceMachineId { + return false + } return true } func (this *RaAuthenticateResponse) Equal(that interface{}) bool { @@ -431,6 +436,13 @@ func (m *RaAuthenticate) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.ReplaceMachineId) > 0 { + i -= len(m.ReplaceMachineId) + copy(dAtA[i:], m.ReplaceMachineId) + i = encodeVarintMsg(dAtA, i, uint64(len(m.ReplaceMachineId))) + i-- + dAtA[i] = 0x1a + } if len(m.Certificate) > 0 { i -= len(m.Certificate) copy(dAtA[i:], m.Certificate) @@ -570,6 +582,10 @@ func (m *RaAuthenticate) Size() (n int) { if l > 0 { n += 1 + l + sovMsg(uint64(l)) } + l = len(m.ReplaceMachineId) + if l > 0 { + n += 1 + l + sovMsg(uint64(l)) + } return n } @@ -719,6 +735,38 @@ func (m *RaAuthenticate) Unmarshal(dAtA []byte) error { m.Certificate = []byte{} } iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ReplaceMachineId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsg + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsg + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsg + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ReplaceMachineId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipMsg(dAtA[iNdEx:])