The first part is what most people fixate on when they first look at Conclave. But an equally important thing is actually the second part - remote attestation.
The thing a lot of people seem to miss is that for most non-mobile-phone use-cases, running code inside an enclave is only really valuable if there is a _user_ somewhere who needs to interact with it and who needs to be able to reason about what will happen to their information when they send it to the enclave.
So it's not enough to write an enclave, you also have to "wire" it to the users, who will typically be different people/organisations from the organisation that is hosting the enclave. And there needs to be an intuitive/way to for them to encode their preferences - eg "I will only connect to an enclave that is running this specific code (that I have audited)" or "I will only connect to enclaves that have been signed by three of the following five firms whom I trust to have verified the enclave's behaviour".. that sort of thing.
Like I have service A and service B. A is going to talk to B, and has some secret that identifies it (maybe a private key for mTLS). I'd like for A to be able to talk to B without having access to that secret - so it would pass a message into the enclave, get a signed message out of it, and then proceed as normal.
Would that not be reasonable? Or I guess maybe I'd want to attest that the signing service is what I expect?
Exactly. If you have a threat-model where you want to limit access to your secrets from a limited code path, you need to attest that only specific, signed code is running within the enclave that can access the secrets. You might only need this to satisfy your own curiosity, but in practice it probably is something you need to prove to your internal security team, third-party auditor, or even direct to a customer.
Thanks for clearing that up.
And the idea, therefore, is that A sends the secret to an enclave, which inspects the secret and, if correct, signs a message to say "I, the enclave, have verified that A does indeed know the secret". (Apologies if I've oversimplified or got this wrong).
But assuming the above is roughly correct then, without remote attestation, you have a problem, and it comes down to the question of who's running the verification code, I think.
If A is running the checker, why should B believe what it says? If A is running the code, they can just change it so that it signs the statement irrespective of whether it's true.
But If B is running the checker, then A will have just sent their secret to a service run by B, violating the requirement that A doesn't send the secret to B!
You could ask a third party to run it of course. But if you don't want to introduce that third party then this is where remote attestation comes in:
If A is running the checker in an enclave then RA allows B to verify that the "A knows the secret" message really did come from a codepath that has actually done the right thing. In this scenario, B is the "user" of the enclave from the perspective of reliance on Remote Attestation. (Aside: I know it's weird to think of an actor that doesn't interact with a system to be a user of it, so I'm probably using poor terminology when I say 'user'... it's more that, in this scenario, B is _relying_ on properties of the enclave such as its attestation)
And if B is running the checker then RA allows A to verify that it won't just turn around and reveal the secret to B.
The secret never leaves the enclave.
The goal here is that if an attacker can execute code within A's operating system that they can not exfiltrate the password. They might be able to get the enclave to sign on their behalf, but that's significantly better than an exposed secret - simply removing the attacker from the box would be sufficient to remediate, vs having to rotate the secret.
To mitigate impersonation, I suppose one could do a number of things involving a second key, but I think that this simple version demonstrates the value of having a signing oracle. This is actually not an atypical approach, just not using sgx - I know companies that keep their signing keys in separate processes, which are mutually seccomp'd such that they can only pipe messages to each other for signing purposes of apps before publishing. But in the sgx case you have a much stronger guarantee than just seccomp.
So to me the only problem that attestation solves here is if the attacker is somehow in the SGX enclave, but actually the much more likely scenario is that they aren't, and that they just ask the oracle to sign on their behalf - because B can't verify that A is the one asking to sign. Given that there is a single entity deploying both the software in the enclave and the service that interacts with it at least, that seems to be the case to me - like, in this scenario A, B, and the software in the enclave are all deployed by me, barring malicious action to interfere with that - but again, the most likely scenario is the attacker just owned the box and has a regular user on there.
But... also also, A can prevent impersonation via tricking the oracle by having another keypair shared between it and the enclave, and then it becomes a matter of protecting that memory from an attacker who can almost certainly scrape your memory - a hard thing to do.
So you end up with:
System 0, A: Key 0 System 0, Enclave: Key 1, Key 0 System 1, B: Key 1
Key 0 is used to 'auth' A to Enclave. Key 1 is used to auth A to B (via enclave oracle).
This is just my perspective on it.
We don't presently support it in Conclave but SGX (which we use) does, I believe, support the idea of, in effect, packaging up a secret in a program and then encrypting it so it can only run in an enclave and hence keep the secret safe even when running on malicious hosts. I'd need to check but I suspect you're right that there are situations there where RA isn't required.
But to take your specific example (and maybe I'm still misunderstanding), does your scheme actually work in practice? Let's assume a simple model where the enclave runs on A's machine. So we can assume that requests to sign something come from A. This avoids us having to worry about A having to authenticate to the enclave, which just leads us to a circularity (how does A protect the key it uses for authentication, etc)?
And now we introduce the attacker, as in your scenario. As you say, eliminating the attacker removes their ongoing ability to interact with the enclave, since it expects to communicate only with locally running processes.
Except... if the attacker is on your box, they could simply take a copy of the enclave! And simply run it on their own machine. It's possible SGX contains the ability to lock an enclave to a specific CPU, in which case your scheme seems like it should work (to my untutored eye... I lead the Conclave team but am by no means an expert)... but I'm not actually sure it works that way. I'll look in to it.
Yeah this is the part I'm assuming isn't possible, perhaps out of ignorance. I believe that, at least in SGX's case, this is possible because SGX exposes per-CPU keys, and the ability to derive secrets from those keys. So if you moved the enclave (I actually have no idea how moving an enclave works either fwiw) it would no longer be valid.
But yeah, this all kinda goes to "I have no idea what I'm doing with enclaves" lol, this is just the use case I have - keeping a secret stored in one so that an attacker can not exfiltrate it.
..
> While Secretive uses the Secure Enclave for key storage, it still relies on Keychain APIs to access them. Keychain restricts reads of keys to the app (and specifically, the bundle ID) that created them.
Doesn't that mean the keys leave the enclave?
https://developer.apple.com/documentation/security/certifica...
"When you store a private key in the Secure Enclave, you never actually handle the key, making it difficult for the key to become compromised. Instead, you instruct the Secure Enclave to create the key, securely store it, and perform operations with it. You receive only the output of these operations, such as encrypted data or a cryptographic signature verification outcome."
Thus I find most analysis and comments like this, based only on motivation and incentives, very lacking.
Add to that, to be more specific to this particular topic, secure enclaves are designed not only for DRM but for many other critical applications (that are actually far more important than DRM and are/were the key motivating use cases) - it, or the general concept, is the basis of the security guarantee for iPhone's fingerprint or face ID, or the confidentiality of the key materials in various end-to-end encryption, which allows things like the-phone-as-a-security-key.
You might want to check out Parsec (also from Arm).
https://developer.arm.com/solutions/infrastructure/developer...
a) How the hell I'm supposed to do so? It seems fairly arcane and in need of some higher level abstractions. fortanix[0] seems like it could be good here?
b) What the implications are. What's it like to maintain an enclave? What do I lose in terms of portability, debug-ability, etc?
It reminds me of GPU to some extent - it's this thing in my computer that's super cool and every time I think about using it it looks like a pain in the ass.