Preamble
A disclaimer that CPU security is not my main area of expertise. I also understand that this name has almost no contributions tied to it, but I would like to request that the proposal be evaluated on its merits rather than contribution history.
I am proposing a change to the default CPU configuration for the libvirt XML templates. Specifically, moving the Workstation to <cpu mode='host-model'/> while keeping the Gateway config as <cpu mode='host-passthrough'/>.
Adopting this would, in my view, widen the anonymity set of Whonix KVM users against local fingerprinting and suspect pool narrowing, while also ensuring that security mitigations remain as effective as they are currently with host-passthrough.
Context / background
At the moment, both the Gateway & Workstation XMLs use <cpu mode='host-passthrough'/>. This exposes the exact CPU and its associated details to the VM. If one uses Whonix KVM on uncommon hardware, the Workstation permits locally running code to obtain substantially more CPU identifying information. This information degrades that person’s anonymity set to a degree that is significant and provides a fingerprinting vector that permits an adversary to more easily narrow down a suspect pool and/or link pseudonyms, as well as allowing them to potentially draw conclusions between physical devices owned by an individual and the cpuinfo results gathered from a previously compromised Workstation.
Historically, Whonix used <cpu mode='custom'><model>qemu64</model> in an attempt to make all CPUs appear uniform. However, as was correctly identified during the 2018 Spectre/Meltdown chaos, frozen named models like qemu64 did not expose the necessary mitigation flags (IBRS, STIBP, SSBD, etc). Consequently, using qemu64 for longer would have left guest kernels vulnerable, and host-passthrough was probably the right choice at the time to ensure reasonable protection from speculative execution vulns.
Why host-model is now safe
The reason why I would contend that Whonix should now move to host-model, and that it is safe to do so, is because of the maturation of libvirt’s CPU feature mapping, and secondly for the other benefits it provides.
I’ll quote the documentation to support my first point (I can’t post links but it is trivial to paste into a search engine):
“Libvirt supports a third way to configure CPU models known as ‘Host model’. This uses the QEMU ‘Named model’ feature, automatically picking a CPU model that is similar the host CPU, and then adding extra features to approximate the host model as closely as possible… gives much of the benefit of passthrough, while making live migration safe.”
Insofar as the mitigation flags that caused the move away from qemu64, the documentation states:
“The following are important CPU features that should be used on Intel x86 hosts… In general all of these features are included if using ‘Host passthrough’ or ‘Host model’.”
The features that are listed underneath that sentence are the set of mitigations that Whonix requires such as: pcid, spec-ctrl (IBRS/IBPB), stibp, ssbd, md-clear (MDS), as well as the MSR-based “not vulnerable” hints (mds-no, taa-no, bhi-no, gds-no, rfds-no). As QEMU refuses to expose feature bits the host cannot honor, host-model shouldn’t create fake mitigations.
Threat model
Remote websites generally cannot read the CPU model directly without relying on techniques like benchmarking (which is probably still a threat despite efforts taken by TBB to prevent it from occurring). The realistic threat is a local CPUID or equivalent instruction from locally running applications, for instance malware via a browser exploit or installed but untrusted software that, while operationally necessary to use, may contain telemetry or whose proprietary nature makes it difficult to audit without spending time in IDA.
Using Whonix-Gateway to network untrusted proprietary operating systems like Windows in a watertight fashion also falls into the threat model, as telemetry is gathered mercilessly.
Benefits
Using host-model is a substantial reduction in direct CPU-identifying information exposed to the Workstation as it replaces exact SKUs with more generic values such as Skylake-Client or EPYC models. As touched on previously, this provides several concrete benefits:
- Raising the cost of some suspect pool narrowing: If a hypothetical adversary is to break into one’s Workstation or backend, they obtain telemetry that contains exact CPU steppings. If a candidate physical machine is seized after further inquiries, comparison of those values may be used to the detriment of the user. Or, in the case of expensive bespoke hardware, it greatly assists an adversary in their attempts to narrow down the possible locality of a user; this kind of hardware is distributed by a handful of companies and purchased by a handful of individuals. Even for those who are typical users, having the exact CPU model revealed provides bits of entropy that are unnecessary to give away so easily. Under host-model, the telemetry becomes “EPYC Genoa” or “EPYC-Milan” or “Skylake-Client” (or similar), which is a description that is effectively useless as it is shared by many Whonix users with AMD/Intel CPUs.
- An uncommon physical CPU config substantially reduces the number of plausible hosts consistent with telemetry whereas a more commonly shared virtual CPU model increases that candidate set.
- There are also benefits to raising the cost of cross-pseudonym linkage, but they will not be detailed for the sake of brevity.
However, these gains only really exist if host-model is to become the uniform default for all users. If it is offered as an optional opt-in, the small subset of users that are likely to enable it become more unique in a similar fashion as presenting a rare CPU SKU, which also degrades the anonymity set and singles out the users who choose to mask. It needs to ship as the default.
Honest Limitations
At the same time, host-model only removes the overt identifier, and a highly motivated local adversary with sufficient technical capability can perhaps use timing/benchmarking side channels to attempt to discover information about the real CPU. Regardless, this change lowers entropy, increases the difficulty of an attack to gain this information in the first place and reduces one particularly direct and high quality source of identifying information.
Adopting host-model also still exposes the Vendor string (GenuineIntel / AuthenticAMD), MSR bits, TSC freq & core count. Regardless, it is still substantially better than the current configuration.
Rationale for the Gateway remaining the same
I also contend that the Gateway can and probably should remain <cpu mode='host-passthrough'/>. It handles heavy crypto loads and doesn’t deal with arbitrary user facing content. If an adversary is capable of obtaining CPUID from one’s Gateway, the target has much larger problems than CPU exposure. Cloaking it provides no real benefit.
Proposed XML Changes
For Whonix-Workstation.xml:
One liner change to : <cpu mode='host-model'/>
For Whonix-Gateway.xml:
Same as before.
Conclusion
Moving to host-model for the Workstation is the correct choice in my opinion. It would provide a reduction in the specificity of the CPU fingerprint that may be derived from the Workstation (or, at minimum, raise the difficulty of doing so by a significant amount), while also leaving the Gateway optimized for its specific workload. It also does not require sacrificing the security that motivated the adoption of host-passthrough. Let me know your thoughts.