2163 words
11 minutes
Option 2 — Required:WHQL (Windows Hardware Quality Labs Certification)

Option 2 — Required (Windows Hardware Quality Labs Certification)#


Table of Contents#

  1. What It Does
  2. Why It Exists
  3. Visual Anatomy — Policy Evaluation Stack
  4. How to Set It (PowerShell)
  5. XML Representation
  6. Interaction with Other Options
  7. When to Enable vs Disable
  8. Real-World Scenario — End-to-End Walkthrough
  9. What Happens If You Get It Wrong
  10. Valid for Supplemental Policies?
  11. OS Version Requirements
  12. Summary Table

1. What It Does#

Required:WHQL tightens the kernel-mode driver signing standard from the broader Microsoft-signed requirement to the stricter Windows Hardware Quality Labs (WHQL) certification standard. By default, WDAC (and Windows Driver Signing policy in general) allows any kernel-mode driver that carries a valid Microsoft signature — including drivers cross-signed by third-party Certificate Authorities under the legacy cross-signing program. When Required:WHQL is enabled, that broader acceptance is revoked: only drivers that have been formally submitted to, tested by, and signed through the Windows Hardware Developer Center (WHDC) portal and the Hardware Lab Kit (HLK) certification pipeline are permitted to load. This effectively eliminates legacy cross-signed drivers and imposes a strict quality and security gate at the kernel boundary. Every kernel driver loading on the machine must carry an authentic Microsoft WHQL signature to pass the Code Integrity check.


2. Why It Exists#

The Driver Supply-Chain Problem#

Kernel-mode drivers operate at the highest privilege level in Windows — Ring 0. A malicious or compromised driver can read any memory, disable security software, intercept system calls, and persist invisibly across reboots. The kernel attack surface is the primary target for:

  • BYOVD (Bring Your Own Vulnerable Driver) attacks — Attackers package legitimate but vulnerable signed drivers and exploit them to escalate privileges or kill EDR/AV processes.
  • Kernel-mode rootkits — Malware that signs drivers through stolen or fraudulently obtained certificates and abuses the legacy cross-signing pathway.
  • Driver-based persistence — Implants that survive OS reinstalls by hiding in driver storage.

Why the Legacy Cross-Signing System Is a Risk#

Before 2015, Microsoft allowed hardware vendors to sign their own drivers with certificates issued by trusted third-party CAs (Symantec, DigiCert, etc.) without submitting to WHQL testing. This “cross-signed” driver model had two problems:

  1. No quality gate. Cross-signed drivers were not tested by Microsoft’s HLK suite. Vendors could ship unstable, insecure, or intentionally malicious drivers and they would load on Windows.
  2. Certificate theft/abuse. Malware authors obtained (or stole) valid cross-signing certificates and used them to legitimately sign rootkits and BYOVD payloads.

Microsoft deprecated new cross-signed drivers for 64-bit Windows 10+ in 2015, requiring WHQL submission for new drivers. However, pre-existing cross-signed drivers grandfathered under the old system remain trusted by default. Required:WHQL revokes that grandfather clause for the machines where it is deployed.

WHQL Security Properties#

flowchart TD
classDef secure fill:#0d1f12,color:#86efac,stroke:#166534
classDef weak fill:#1f0d0d,color:#fca5a5,stroke:#7f1d1d
classDef neutral fill:#162032,color:#58a6ff,stroke:#1e3a5f
subgraph WHQL_Certified["WHQL Certified Driver"]
direction TB
A1([Submitted to WHDC portal]):::secure
A2([Tested against HLK suite]):::secure
A3([Microsoft reviews submission]):::secure
A4([Signed with Microsoft WHQL\ncertificate chain]):::secure
A5([Listed in Windows Update catalog]):::secure
A1 --> A2 --> A3 --> A4 --> A5
end
subgraph Legacy_Cross["Legacy Cross-Signed Driver"])"]
direction TB
B1([Vendor self-signs]):::weak
B2([No HLK testing required]):::weak
B3([No Microsoft review]):::weak
B4([Signed by third-party CA\nunder cross-sign program]):::weak
B5([Not in WHDC catalog]):::weak
B1 --> B2 --> B3 --> B4 --> B5
end

3. Visual Anatomy — Policy Evaluation Stack#

flowchart TD
classDef kernel fill:#162032,color:#58a6ff,stroke:#1e3a5f
classDef option fill:#1a1a0d,color:#fde68a,stroke:#713f12
classDef allow fill:#0d1f12,color:#86efac,stroke:#166534
classDef block fill:#1f0d0d,color:#fca5a5,stroke:#7f1d1d
classDef neutral fill:#1c1c2e,color:#a5b4fc,stroke:#3730a3
A([Driver Load Request\nfrom OS or Service]) --> B[Kernel Code Integrity\nCI.dll]:::kernel
B --> C{Is driver a\nkernel-mode binary?}
C -- No --> D([User-mode check\nsee Option 0 UMCI]):::neutral
C -- Yes --> E{Option 2\nRequired:WHQL\nenabled?}:::option
E -- No --> F{Driver has any valid\nMicrosoft signature?}
F -- Yes WHQL or cross-signed --> G([Driver loads]):::allow
F -- No --> H([Driver blocked]):::block
E -- Yes --> I{Driver has WHQL\ncertification signature?}:::kernel
I -- Yes --> J{Signature chain leads\nto Microsoft WHQL root?}
J -- Yes --> K([Driver loads]):::allow
J -- No --> L([Driver blocked\nEvent ID 3082]):::block
I -- No --> M{Is it a cross-signed\nlegacy driver?}
M -- Yes --> N([BLOCKED — legacy\ncross-sign rejected]):::block
M -- No, unsigned --> O([BLOCKED — unsigned\ndriver rejected]):::block

Driver Signing Hierarchy#

flowchart LR
classDef kernel fill:#162032,color:#58a6ff,stroke:#1e3a5f
classDef allow fill:#0d1f12,color:#86efac,stroke:#166534
classDef block fill:#1f0d0d,color:#fca5a5,stroke:#7f1d1d
classDef option fill:#1a1a0d,color:#fde68a,stroke:#713f12
MSRoot([Microsoft Root CA]) --> WHQL_CA([Microsoft WHQL\nCode Signing CA]):::allow
MSRoot --> CrossSign_CA([Third-Party CA\nCross-Sign])
WHQL_CA --> WHQL_Driver([WHQL Certified Driver\nAllowed by Option 2]):::allow
CrossSign_CA --> Legacy_Driver([Legacy Cross-Signed Driver\nBLOCKED by Option 2]):::block
CrossSign_CA --> Stolen_Cert([Stolen/Abused Cert\nBLOCKED by Option 2]):::block
Unsigned([Unsigned Driver\nBLOCKED by any WDAC]):::block
WHQL_Driver --> Kernel([Kernel]):::kernel
Legacy_Driver -.->|"Blocked at CI gate"| Kernel
Stolen_Cert -.->|"Blocked at CI gate"| Kernel
Unsigned -.->|"Blocked at CI gate"| Kernel

4. How to Set It (PowerShell)#

Enable WHQL Requirement#

Terminal window
# Require WHQL certification for all kernel drivers
Set-RuleOption -FilePath "C:\Policies\MyBasePolicy.xml" -Option 2

Remove WHQL Requirement (Revert to Any Microsoft-Signed)#

Terminal window
# Allow any Microsoft-signed driver (including cross-signed legacy)
Set-RuleOption -FilePath "C:\Policies\MyBasePolicy.xml" -Option 2 -Delete

Audit Drivers Before Enabling WHQL Requirement#

Terminal window
# Find all currently loaded drivers and check for WHQL certification
$Drivers = Get-WindowsDriver -Online -All | Where-Object { $_.Driver -like "*.sys" }
foreach ($Driver in $Drivers) {
$SigInfo = Get-AuthenticodeSignature -FilePath "C:\Windows\System32\drivers\$($Driver.OriginalFileName)" -ErrorAction SilentlyContinue
if ($SigInfo) {
[PSCustomObject]@{
Driver = $Driver.Driver
Status = $SigInfo.Status
Signer = $SigInfo.SignerCertificate.Subject
WHQLSigned = $SigInfo.SignerCertificate.Subject -match "Microsoft Windows Hardware Compatibility"
}
}
} | Export-Csv "$env:USERPROFILE\Desktop\driver_audit.csv" -NoTypeInformation

Identify Non-WHQL Drivers That Would Be Blocked#

Terminal window
# Check for drivers NOT bearing the WHQL certificate chain
Get-WinEvent -LogName "Microsoft-Windows-CodeIntegrity/Operational" |
Where-Object { $_.Id -in @(3033, 3034, 3082) } |
Select-Object TimeCreated, Id, Message |
Format-Table -AutoSize

Full Policy Creation with WHQL Enforcement#

Terminal window
$PolicyPath = "C:\Policies\WHQL_Enforced.xml"
# Copy the DefaultWindows base
Copy-Item "$env:SystemRoot\schemas\CodeIntegrity\ExamplePolicies\DefaultWindows_Enforced.xml" $PolicyPath
# Enable UMCI (Option 0) and WHQL (Option 2)
Set-RuleOption -FilePath $PolicyPath -Option 0 # UMCI
Set-RuleOption -FilePath $PolicyPath -Option 2 # WHQL
Set-RuleOption -FilePath $PolicyPath -Option 3 # Audit mode (safe rollout)
# Set policy identity
Set-CIPolicyIdInfo -FilePath $PolicyPath -PolicyName "Corp WHQL Baseline" -PolicyId (New-Guid).Guid
# Compile and deploy
$BinPath = "C:\Policies\WHQL_Enforced.cip"
ConvertFrom-CIPolicy -XmlFilePath $PolicyPath -BinaryFilePath $BinPath
# Deploy to test systems first
Copy-Item $BinPath "C:\Windows\System32\CodeIntegrity\CiPolicies\Active\{<PolicyGUID>}.cip"

5. XML Representation#

Option 2 Enabled in Policy XML#

<?xml version="1.0" encoding="utf-8"?>
<SiPolicy xmlns="urn:schemas-microsoft-com:sipolicy" PolicyType="Base Policy">
<VersionEx>10.0.0.0</VersionEx>
<PolicyTypeID>{A244370E-44C9-4C06-B551-F6016E563076}</PolicyTypeID>
<PlatformID>{2E07F7E4-194C-4D20-B96C-1498495910E7}</PlatformID>
<Rules>
<Rule>
<Option>Enabled:UMCI</Option>
</Rule>
<Rule>
<Option>Required:WHQL</Option>
</Rule>
<Rule>
<Option>Enabled:Audit Mode</Option>
</Rule>
</Rules>
</SiPolicy>

WHQL Signer Entry (For Reference)#

When allowing WHQL-signed drivers, the policy typically relies on the built-in Microsoft WHQL signers that are pre-defined in the DefaultWindows templates. They appear in the <Signers> section as:

<Signers>
<Signer ID="ID_SIGNER_WINDOWS_PRODUCTION" Name="Microsoft Product Root 2010 Windows WHQL">
<CertRoot Type="TBS" Value="..." />
<CertEKU ID="ID_EKU_WINDOWS" />
</Signer>
</Signers>

6. Interaction with Other Options#

Option Relationship Matrix#

OptionNameRelationship with WHQL
0EnabledCompanion — UMCI extends enforcement to user-mode; WHQL tightens kernel-mode
3Enabled ModeCompanion during rollout — log blocked non-WHQL drivers before enforcing
4Disabled SigningSynergistic — both restrict non-production binaries
6Enabled System Integrity PolicyUnrelated — affects policy signing, not driver signing
14Enabled IntelligenceIndependent — cloud reputation check for user-mode
16Enabled Policy No RebootDeployment helper — neutral to WHQL

WHQL and UMCI Layered Enforcement#

flowchart TD
classDef kernel fill:#162032,color:#58a6ff,stroke:#1e3a5f
classDef usermode fill:#0d1f12,color:#86efac,stroke:#166534
classDef option fill:#1a1a0d,color:#fde68a,stroke:#713f12
A([Binary or Driver Execution]) --> B{Kernel-mode?}
B -- Yes --> C["Option 2: Required:WHQL\nKernel enforcement layer"]:::option
C --> D{WHQL cert?}
D -- Yes --> E([Kernel driver loads]):::kernel
D -- No --> F([Kernel driver blocked]):::kernel
B -- No --> G["Option 0: Enabled:UMCI\nUser-mode enforcement layer"]:::option
G --> H{Policy allow rule?}
H -- Yes --> I([User binary executes]):::usermode
H -- No --> J([User binary blocked]):::usermode

7. When to Enable vs Disable#

flowchart TD
classDef yes fill:#0d1f12,color:#86efac,stroke:#166534
classDef no fill:#1f0d0d,color:#fca5a5,stroke:#7f1d1d
classDef warn fill:#1a1a0d,color:#fde68a,stroke:#713f12
classDef question fill:#162032,color:#58a6ff,stroke:#1e3a5f
Start([Should I enable Option 2 WHQL?]) --> Q1{Are all deployed drivers\nWindows 10-era or newer?}:::question
Q1 -- Yes --> Q2{No legacy hardware\n pre-2015 drivers?}:::question
Q2 -- Yes --> Q3{Is BYOVD defense\na concern?}:::question
Q3 -- Yes --> ENABLE([Enable Required:WHQL\nStrong BYOVD mitigation]):::yes
Q3 -- No --> ENABLE2([Enable Required:WHQL\nGood hygiene regardless]):::yes
Q2 -- No --> AUDIT([Audit first with Option 3\nIdentify legacy driver blockers]):::warn
Q1 -- No --> WARN1([High risk of legacy driver breaks\nAudit extensively before enabling]):::warn
AUDIT --> CHECK{Any legacy drivers\ncritical to operations?}:::question
CHECK -- Yes --> PLAN([Plan legacy driver replacement\nor hardware refresh]):::warn
CHECK -- No --> ENABLE3([Enable Required:WHQL]):::yes
PLAN --> DEFER([Defer Option 2 until\nhardware refreshed]):::no

Decision Reference Table#

ScenarioRecommendation
Modern corporate laptop fleet (post-2019)Enable WHQL — safe, strong security gain
Legacy manufacturing/OT hardwareAudit first — older industrial drivers may lack WHQL
Domain controller / serverEnable WHQL — critical asset, minimal driver variety
Dev/build machine with custom driversAudit first — in-house driver builds need WHQL or exception
BYOVD attack mitigation priorityEnable WHQL — directly addresses BYOVD vector
Printer/scanner heavy environmentAudit first — many legacy printer drivers lack WHQL

8. Real-World Scenario — End-to-End Walkthrough#

Scenario: BYOVD Attack Blocked by WHQL Requirement#

An EDR vendor’s vulnerable driver (RTCore64.sys — a known BYOVD target) is used by an attacker to kill the EDR process. Without Required:WHQL, the driver loads because it has a valid (if old) Microsoft cross-signature. With Required:WHQL, the cross-signed driver is rejected.

sequenceDiagram
autonumber
actor Attacker
participant Malware as Malware Process
participant SCM as Service Control Manager
participant KernelCI as Kernel Code Integrity
participant PolicyEng as WDAC Policy Engine
participant EventLog as Windows Event Log
participant EDR as EDR Process
Note over Attacker,EDR: WITHOUT Required:WHQL (Default)
Attacker ->> Malware: Execute attack tool with embedded RTCore64.sys
Malware ->> SCM: sc.exe create RTCore64 binPath=RTCore64.sys type=kernel
SCM ->> KernelCI: Request driver load
KernelCI ->> PolicyEng: Check RTCore64.sys signature
PolicyEng -->> KernelCI: Cross-signed by DigiCert — ALLOWED (no WHQL req)
KernelCI -->> SCM: Driver approved
SCM -->> Malware: Driver loaded
Malware ->> EDR: Kill EDR via kernel IOCTL
EDR -->> Attacker: EDR terminated — attack continues undetected
Note over Attacker,EDR: WITH Required:WHQL (Option 2 Enabled)
Attacker ->> Malware: Execute attack tool with embedded RTCore64.sys
Malware ->> SCM: sc.exe create RTCore64 binPath=RTCore64.sys type=kernel
SCM ->> KernelCI: Request driver load
KernelCI ->> PolicyEng: Check RTCore64.sys signature
PolicyEng -->> KernelCI: Cross-signed only — WHQL cert MISSING — BLOCK
KernelCI -->> SCM: STATUS_ACCESS_DENIED
SCM -->> Malware: Driver load failed
KernelCI ->> EventLog: Event ID 3082 — non-WHQL driver blocked
EventLog -->> EDR: Alert forwarded to SIEM

WHQL Rollout Sequence#

sequenceDiagram
autonumber
actor Admin
participant PolicyXML as Policy XML
participant TestMachines as Test Fleet (10 VMs)
participant AuditLog as CodeIntegrity Event Log
participant DriverStore as Windows Driver Store
participant ProdFleet as Production Fleet (1000 Endpoints)
Admin ->> PolicyXML: Set Option 2 + Option 3 (WHQL + Audit)
Admin ->> PolicyXML: ConvertFrom-CIPolicy → audit_whql.cip
Admin ->> TestMachines: Deploy audit_whql.cip via Intune test ring
TestMachines ->> AuditLog: Generate Event 3082 for non-WHQL drivers
Admin ->> AuditLog: Collect and analyze 3082 events
AuditLog -->> Admin: List of 3 non-WHQL drivers found
Admin ->> DriverStore: Check Windows Update catalog for WHQL versions
DriverStore -->> Admin: 2 of 3 have WHQL updates available
Admin ->> PolicyXML: Update driver inventory; update hardware for 1 exception
Admin ->> PolicyXML: Remove Option 3 (Audit) — keep Option 2 (WHQL)
Admin ->> PolicyXML: ConvertFrom-CIPolicy → enforced_whql.cip
Admin ->> ProdFleet: Staged rollout: 100 → 500 → 1000 endpoints
ProdFleet -->> Admin: Zero driver blocks reported — rollout successful

9. What Happens If You Get It Wrong#

Scenario A: Enable WHQL Without Audit Phase#

flowchart TD
classDef block fill:#1f0d0d,color:#fca5a5,stroke:#7f1d1d
classDef warn fill:#1a1a0d,color:#fde68a,stroke:#713f12
A([Enable WHQL without audit]) --> B[Legacy printer driver blocked]:::block
A --> C[Legacy NIC driver blocked]:::block
A --> D[Third-party security tool driver blocked]:::block
B --> E([Printing disabled across fleet]):::block
C --> F([Network connectivity lost on some endpoints]):::block
D --> G([EDR/AV kernel component non-functional]):::block
E --> H([Helpdesk overwhelmed]):::warn
F --> H
G --> H
H --> I([Emergency policy rollback required]):::warn

Scenario B: Disable WHQL on High-Security Asset#

ConsequenceDescriptionSeverity
BYOVD attack surface openLegacy cross-signed vulnerable drivers loadableCritical
Rootkit pathway via stolen certCross-sign certs in attacker hands can load kernel codeCritical
Compliance gapNIST, CIS, ACSC controls may require strict driver signingHigh

Misconfig Consequences Summary#

MistakeImpactSeverity
Skip audit phaseMass driver blocks, operational outageHigh
Assume all vendors have WHQLLegacy hardware peripheral drivers breakHigh
Enable WHQL without inventorySurprise blocks after deploymentMedium-High
Leave WHQL disabled on critical assetsFull kernel BYOVD exposureCritical
Include legacy drivers in allow rules insteadPolicy complexity increases; technical debtMedium

10. Valid for Supplemental Policies?#

No. Required:WHQL is a kernel-layer enforcement directive that sets the minimum signing standard for all kernel-mode drivers. This is a system-wide policy scope that must be established by the base policy. Supplemental policies operate at a higher abstraction layer — they extend the list of allowed applications, publishers, and hashes. They cannot modify the kernel driver signing standard. The base policy’s WHQL setting is authoritative and cannot be overridden or weakened by a supplemental policy.


11. OS Version Requirements#

Windows VersionWHQL Support Status
Windows 10 1507 (TH1)Basic WHQL support present
Windows 10 1607+Full WHQL enforcement via WDAC Option 2
Windows 10 1703+Required for all new kernel drivers (policy or not)
Windows 11 21H2+WHQL enforced by default in Secured-core PCs
Windows Server 2016+Full support
Windows Server 2019+Recommended; HVCI makes Option 2 tamper-resistant
Windows Server 2022Secured-core server; WHQL integral to baseline

WHQL Requirement by Default (Regardless of Option 2): From Windows 10, all new kernel-mode drivers submitted to Microsoft must be WHQL-signed via the WHDC portal. Option 2 adds policy-level enforcement, rejecting even grandfathered legacy cross-signed drivers that Windows would otherwise still permit.


12. Summary Table#

AttributeValue
Rule Option NameRequired:WHQL
Rule Option Index2
Default StateDisabled (cross-signed drivers allowed)
Effect when EnabledOnly WHQL-certified kernel drivers load; cross-signed legacy drivers blocked
Effect when DisabledAny Microsoft-signed driver loads (including legacy cross-signed)
Valid in Base PolicyYes
Valid in Supplemental PolicyNo
Requires Reboot on EnableYes — kernel enforcement change takes effect at next boot
Primary Security GoalBYOVD attack mitigation; kernel driver supply chain integrity
Primary Risk of EnablingLegacy hardware driver compatibility breakage
Audit StrategyEnable Option 3 + Option 2 together; review Event ID 3082
Minimum OS VersionWindows 10 1607 / Server 2016
PowerShell Cmdlet (Enable)Set-RuleOption -FilePath <xml> -Option 2
PowerShell Cmdlet (Disable)Set-RuleOption -FilePath <xml> -Option 2 -Delete
Event ID (Audit/Block)3082 — Non-WHQL kernel driver blocked
Event LogMicrosoft-Windows-CodeIntegrity/Operational
Security Framework AlignmentNIST SP 800-167 (Driver Signing), CIS Control 2.7, ACSC Essential Eight
Key Threat MitigatedBYOVD, rootkits via legacy cross-signed certificates
Option 2 — Required:WHQL (Windows Hardware Quality Labs Certification)
https://mranv.pages.dev/posts/app-control-rule-option-02-whql/
Author
Anubhav Gain
Published at
2026-05-02
License
CC BY-NC-SA 4.0