On 5/18/21 10:52 AM, Sean Christopherson wrote: > On Tue, May 18, 2021, Andy Lutomirski wrote: >> On 5/17/21 11:21 AM, Bae, Chang Seok wrote: >>> First of all, there is an RFC series for KVM [2]. >>> >>> Each CPU has one internal key state so it needs to reload it between guest and >>> host if both are enabled. The proposed approach enables it exclusively; expose >>> it to guests only when disabled in a host. Then, I guess a guest may enable it. >> >> I read that series. This is not a good solution. >> >> I can think of at least a few reasonable ways that a host and a guest >> can cooperate to, potentially, make KL useful. >> >> a) Host knows that the guest will never migrate, and guest delegates >> IWKEY management to the host. The host generates a random key and does >> not permit the guest to use LOADIWKEY. The guest shares the random key >> with the host. Of course, this means that a host key handle that leaks >> to a guest can be used within the guest. > > If the guest and host share a random key, then they also share the key handle. > And that handle+key would also need to be shared across all guests. I doubt this > option is acceptable on the security front. > Indeed. Oddly, SGX has the exact same problem for any scenario in which SGX is used for HSM-like functionality, and people still use SGX. However, I suspect that there will be use cases in which exactly one VM is permitted to use KL. Qubes might want that (any Qubes people around?) > Using multiple random keys is a non-starter because they can't be restored via > LOADIWKEY. > > Using multiple software-defined keys will have moderate overhead because of the > possibility of using KL from soft IRQ context, i.e. KVM would have to do > LOADIWKEY on every VM-Enter _and_ VM-Exit. It sounds like LOADIWKEY has latency > similar to WRMSR, so it's not a deal-breaker, but the added latency on top of the > restrictions on how the host can use KL certainly lessen the appeal. Indeed. This stinks. > >> b) Host may migrate the guest. Guest delegates IWKEY management to the >> host, and the host generates and remembers a key for the guest. On >> migration, the host forwards the key to the new host. The host can >> still internally any type of key, but context switches may be quite slow. > > Migrating is sketchy because the IWKEY has to be exposed to host userspace. > But, I think the migration aspect is a secondary discussion. > >> c) Guest wants to manage its own non-random key. Host lets it and >> context switches it. > > This is essentially a variant of (b). In both cases, the host has full control > over the guest's key. > >> d) Guest does not need KL and leaves CR4.KL clear. Host does whatever >> it wants with no overhead. >> >> All of these have tradeoffs. >> >> My current thought is that, if Linux is going to support Key Locker, >> then this all needs to be explicitly controlled. On initial boot, Linux >> should not initialize Key Locker. Upon explicit administrator request >> (via sysfs?), Linux will initialize Key Locker in the mode requested by >> the administrator. > > Deferring KL usage to post-boot can work, but KVM shouldn't be allowed to expose > KL to a guest until KL has been explicitly configured in the host. If KVM can > spawn KL guests before the host is configured, the sysfs knob would have to deal > with the case where the desired configuration is incompatible with exposing KL > to a guest. There could be a host configuration "guest_only", perhaps. > >> Modes could include: >> >> native_random_key: Use a random key per the ISA. >> >> native_kernel_key_remember: Use a random key but load it as a non-random >> key. Remember the key in kernel memory and use it for S3 resume, etc. > > What would be the motivation for this mode? It largely defeats the value > proposition of KL, no? It lets userspace use KL with some degree of security. > >> native_kernel_key_backup: Use a random key, put it in the backup >> storage, and forget it. Use the backup for resume, etc. >> >> native_kernel_key_norestore: Use a random key. The key is lost on any >> power transition that forgets the key. Backup is not used. >> >> paravirt_any: Ask the hypervisor to handle keying. Any mechanism is >> acceptable. >> >> paravirt_random: Ask the hypervisor for a random key. Only succeeds if >> we get an actual random key. > > AFAIK, there's no way for the guest to verify that it got a truly random key. > Hell, the guest can't even easily verify that KL is even supported. The host > can lie about CPUID and CR4.KL, and intercept all KL instructions via #UD by > running the guest with CR4.KL=0. The guest can use TDX. Oh wait, TDX doesn't support KL. That being said, a host attack on the guest of this sort would be quite slow. > > I also don't see any reason to define a paravirt interface for a truly random > key. Using a random key all but requires a single guest to have exclusive access > to KL, and in that case the host can simply expose KL to only that guest. > >> Does this make sense? > > I really want to use see concrete guest use cases before we start adding paravirt > interfaces. > I want to see concrete guest use cases before we start adding *any* guest support. And this cuts both ways -- I think that, until the guest use cases are at least somewhat worked out, Linux should certainly not initialize KL by default on boot if the CPUID hypervisor bit is set.