apache / incubator-teaclave-sgx-sdk

Apache Teaclave (incubating) SGX SDK helps developers to write Intel SGX applications in the Rust programming language, and also known as Rust SGX SDK.
https://teaclave.apache.org
Apache License 2.0
1.17k stars 263 forks source link

example request: static-data-distribution with sealed rsa key #74

Open brenzi opened 5 years ago

brenzi commented 5 years ago

I've been playing around with sealeddata and static-data-distribution. The latter is a very interesting example but quite meaningless because the rsa key is written to file in cleartext. I've tried to combine this with sealeddata the following way, also solving trusted provisioning:

app calls generate_keys() enclave function, which:

  1. generates rsa keypair
  2. seals keypair
  3. writes sealed keypair to file
  4. returns pubkey

the app can then

  1. encrypt some cleartext with the enclave pubkey
  2. send the ciphertext to enclave which reads the rsa keypair from file and decrypts and prints the ciphertext

IMO this would be meaningful and close to a real use case.

However, I'm struggling with various approaches : try1

//enclave/src/lib.rs
...
    let rsa_keypair = Rsa3072KeyPair::new().unwrap();
    let rsa_key_json = serde_json::to_string(&rsa_keypair).unwrap();
    let result = SgxSealedData::<String>::seal_data(&aad, &rsa_key_json);
    let _sealed_rsa_keypair = match result {
        Ok(x) => x,
        Err(ret) => { return ret; },
    };
    let sealed_rsa_key_json = serde_json::to_string(&_sealed_rsa_keypair).unwrap();
...

sgx_tseal::SgXSealedData doesn't implement traits Serialize, Deserialize, so I can't use json

try2 another approach is to generate rsa keypair deterministically from a seed, but your sgx_crypto_helper functions do not allow this (would be a nice feature ;-).

dingelish commented 5 years ago

The crypto helper is usually cooperating with SgxFs which provides the ability to store secrets safely. Data sealing APIs are more often used to transfer data from one enclave to another.

Rsa3072KeyPair and Rsa2048KeyPair has already derived Serialize and Deserialize. To store a keypair safely onto a disk, one can just serialize it using serde_json (or anything you like) and save the serialized string to SgxFs.

To transfer a key pair (or say "provisioning"), remote attestation based TLS channel is usually required. After a secured TLS channel is established, the serialized keypair could be transfer directly to an enclave.

dingelish commented 5 years ago

I think data sealing APIs are more suitable for sharing data between enclaves with the same MRSIGNER value :-)

brenzi commented 5 years ago

You're amazingly quick! Thank you So my assumption was wrong that fake_provisioning writes the key in cleartext?

So std::sgxfs::SgxFile always writes encrypted data?

dingelish commented 5 years ago

Yeah we do provide two set of fs APIs: (1) protected file system SgxFs, and (2) unprotected file system at std::untrusted::fs. The default path of fs std::fs is manually disabled by us because we want the developers to choose between trusted fs and untrusted fs. But std::fs could be re-opened by a feature untrusted_fs. One should be very careful with it.

dingelish commented 5 years ago

Here are some documents about the protected file system:

(1) https://download.01.org/intel-sgx/linux-2.4/docs/Intel_SGX_Developer_Reference_Linux_2.4_Open_Source.pdf page number starts at 123

(2) https://software.intel.com/en-us/sgx-sdk-dev-reference-intel-protected-file-system-library

brenzi commented 5 years ago

this is all very helpful, thanks again.

dingelish commented 5 years ago

When running the static data distribution example, you can find the saved key file prov_key.bin in the bin dir. It contains the json of RSA keypair. See if you can decrypt it :)

dingelish commented 5 years ago

You're welcome!

dingelish commented 5 years ago

And I will add some more usage of data sealing APIs in the sealing sample tomorrow.

brenzi commented 5 years ago

Rsa3072KeyPair and Rsa2048KeyPair has already derived Serialize and Deserialize.

However, it seems SgxRsaPubKey can't be serialized. It only implements Default and Drop

let _pubkey_json = serde_json::to_string(&_pubkey).unwrap();
    |                        ^^^^^^^^^^^^^^^^^^^^^ the trait `serde::ser::Serialize` is not implemented for `sgx_tcrypto::crypto::SgxRsaPubKey`

Would be nice as I want my enclave to generate an RSA keypair and return to public key with a getter, so an app can provide small encrypted content to the enclave. (I know this could be done with TLS into the enclave, but for my case this seems like an overkill). I'm working on an example to solve Yao's Millionaires' problem

brenzi commented 5 years ago

I've managed to hack my example idea myself: sealedkey However, I couldn't return a SgxRsaPubkey from the enclave, because that object can't be serialized (see above). So I had to return the entire keypair - which of course breaks the whole idea.

dingelish commented 5 years ago

@brenzi sorry for the late reply. i don't have much time for this recently. may be you can implement a rsa pub key structure by yourself for now. i'll add the pub key splitter after get back from vacation. thanks!

brenzi commented 5 years ago

@dingelish No need to apologize, there's no hurry. Enjoy your vacation!