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: >> >+SGX_IOCTL_ENCLAVE_INIT >> >+ >> >+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.) > > 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. --Andy -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html