Re: [PATCH 5/6] intel_sgx: driver documentation

From: Jarkko Sakkinen
Date: Fri May 06 2016 - 07:35:39 EST

On Thu, May 05, 2016 at 05:52:31PM -0700, Andy Lutomirski wrote:
> On Thu, May 5, 2016 at 3:45 PM, Jarkko Sakkinen
> <jarkko.sakkinen@xxxxxxxxxxxxxxx> wrote:
> > On Mon, Apr 25, 2016 at 01:01:06PM -0700, Andy Lutomirski wrote:
> >> On 04/25/2016 10:34 AM, Jarkko Sakkinen wrote:
> >> >+
> >> >+Initializes an enclave given by SIGSTRUCT and EINITTOKEN. Executes EINIT leaf
> >> >+instruction that will check that the measurement matches the one SIGSTRUCT and
> >> >+EINITTOKEN. EINITTOKEN is a data blob given by a special enclave called Launch
> >> >+Enclave and it is signed with a CPU's Launch Key.
> >> >
> >>
> >> Having thought about this for ten minutes, I have the following thought:
> >>
> >> I think that we should seriously consider not allowing user code to supply
> >> EINITTOKEN at all. Here's why:
> >>
> >> 1. The nominal purpose of this thing is "launch control." I think that the
> >> decision of whether to launch an enclave belongs in the kernel to the extent
> >> that the kernel has the ability to control this.
> >
> > I'm not sure why you would want to do this especially when you can use
> > your own key pair for launch control in future.
> Here are my thoughts. There are a few ways the system (firmware, MSR,
> and Intel policy) could be configured:
> +++ status quo +++
> Applications that ship enclaves come bundled with signatures and
> possibly certificate chains. They call into some SDK API to request
> launch permission. The SDK says "ok". Then the application asks the
> SDK to launch it. It's entirely unclear to me how Intel distributes
> the LE versions that make this work on Windows. I'm guessing they're
> bundled in the SDK, but for all I know, they're in the kernel.
> I think that Linux should possibly refuse to support this mode
> upstream. If Linux were to support it, then it might actually match
> ISV-expected behavior better if the LE was bundled with the kernel --
> after all, the ISV already has very little visibility into where the
> LE comes from, and it seems more like a system policy thing.
> +++ current Skylakes with hypothetical Intel "launch anything" policy +++
> If the combination of Intel policy and firmware configuration were to
> allow anything to launch, then the OS should either impose its own
> policy or allow anything to launch. I can easily imagine the
> implementation of this involving a channel by which the kernel proves
> to the LE that firmware/platform config is intended to allow "launch
> anything". In this case, I think this belongs either in the kernel or
> in a privileged daemon, and putting it in the kernel is probably much
> more straightforward. In any event, applications shouldn't need to
> worry about the nitty gritty details of where exactly their EINITTOKEN
> comes from.
> +++ future chips with unlocked IA32_SGXLEPUBKEYHASH +++
> The firmware policy really is "launch anything" in this case, and it's
> the kernel's job to restrict that further if it likes (by programming
> the MSRs and/or filtering EINIT). I think that the most natural way
> to implement this would be for the kernel to implement whatever policy
> it likes and to either ship an LE that accepts anything as part of the
> kernel image that's signed by a key where everyone knows the *private*
> key or to generate a random key pair at build time, build the enclave
> along with the kernel, and include the public key and the LE in the
> kernel image. In either case, I don't think that apps should need to
> ship this special LE -- the kernel should handle it.
> If admins want to impose additional launch policy, then by all means
> Linux should offer that. I'm just not at all convinced that fiddling
> with the MSRs in new and complicated ways is the right way to do that
> -- I think the kernel should implement more advanced policy by
> filtering EINIT.
> Keep in mind that, if the kernel is compromised, then the attacker can
> launch anything no matter what the kernel tries to do because the
> attacker controls the MSRs.
> +++ future chips with IA32_SGXLEPUBKEYHASH set to a non-default value +++
> I don't see a valid use case for this other than snake oil. One may
> well exist, but, if so, it hasn't been explained to me. If someone
> comes up with one, then, by all means, we could support it in the
> kernel. Nonetheless, an SGX-aware app that is designed to work under
> the status quo policy or in a "launch anything" regime should still
> work if the special local policy intends for it to work, and I don't
> think that app should need to possess a copy of the bespoke signed LE
> in order to function. IOW, to allow the same app to run here if
> policy is okay with it, I think we *have* to delegate EINITTOKEN
> generation to something other than the SGX-using app.
> My intuition is that either the Windows approach to this is going to
> end up being a mess and very unpleasant for ISVs to work with or that
> Windows will move to a configuration in which EINITTOKEN generation is
> delegated to the kernel or to a privileged daemon that ships with the
> OS. I think that Linux should do that as well to avoid
> unpleasantness. If Linux ends up being easier to develop SGX
> applications on than Windows, then that's means that Linux did
> something right.
> Also, in the unlocked-MSR case, I think that the kernel *must*
> implement EINIT filtering. The kernel should not allow an untrusted
> LE to run, because that LE might leak the raw EGETKEY output to a
> malicious party, and the implications of that might not be so nice.
> This is yet another argument in favor of having the kernel supply the
> LE so that the kernel can trust the LE. (Obviously, extracting raw
> *debug* EGETKEY output is possible even on Windows on current systems,
> but that raw output isn't particularly useful.)

MSR does not work when it is unlocked.

> >
> > This would degrade the security of the SGX to the level of the running
> > kernel binary.
> How so? SGX is supposed to be secure even under the assumption that
> anyone can launch anything they want and even under the assumption
> that the kernel is malicious. If SGX fails at that, then it would be
> odd to blame kernel policy for that.

Maybe I understood this incorrectly somhow but IMHO launch control
policy really should reside in an enclave because there it cannot be
tampered by malicious code.

The code cannot be tampered at run-time but launch control policy
could be if the LE is just in allow all mode.

> --Andy