[DISCUSSION] Custom Kernel Signer

Discussion in 'Windows 11' started by mkfsxbinkes, Feb 27, 2026.

  1. mkfsxbinkes

    mkfsxbinkes MDL Novice

    Jun 1, 2023
    2
    5
    0
    #1 mkfsxbinkes, Feb 27, 2026
    Last edited: Feb 28, 2026
    The biggest difference of EnterpriseG edition with other editions is that Microsoft allow administrators with access to UEFI PK to be able to replace default kernel mode signing policy with a custom one signed by a certificate that chains to UEFI PK.

    By contrast, Microsoft is tightening their driver signing policy to make sure only the ones that have a EV certificate and register to Windows Partner Center then pass the review can get their driver signed.

    System integrity policy (they call it WDAC policy now) signed by a key that has it's certificate chain ends in UEFI PK will replace the default driver signing policy of the kernel.

    Microsoft has released a tool (GITHUB/MicrosoftDocs/WDAC-Toolkit) and documentation about WDAC policy.

    This is controlled by product policy "CodeIntegrity-AllowConfigurablePolicy-CustomKernelSigners" which is only set in EnterpriseG edition as far as I know.

    Geoff Chappell had written a great blog (geoffchappell/notes/windows/license/customkernelsigners.htm) article for this feature.

    There are also a driver (GITHUB/valinet/ssde) for keeping it enabled in editions that does not have this policy enabled by modifing product policy whenever sppsvc reloads it.

    I would like to share some experience with the feature here.

    There are some changes since the article was written, KEK seems to be accepted as well now. (According to analysis of bootmgrfw.efi, if the policy is signed by KEK, a new flag (0x10) is set to the policy.)

    For this feature to work, Secure Boot must be enabled as mentioned in above article.

    UEFI PK:

    For UEFI PK, as the above article noted, must either be root or issued by a root.

    More specifically, the certificate chain must ends with the PK.
    The reason of why PK can be issued by a root is that SignTool.exe will not append root CA certificate to the resulting PKCS#7 structure. So MinCrypt library embedded to the bootloader will not be able to find the root CA. It's similar to the case where PK is root except the KnownRoot will be UNKNOWN (01) instead of SELFSIGNED (02).

    But If you append the root certificate to the resulting signed policy, it will cease to work. CKS will be enabled in the early stage (bootloader) so drivers with startType 'boot' can be loaded (by bootloader), but not drivers loaded by NT kernel (would fail with
    Code:
    SYSTEM_INTEGRITY_POLICY_VIOLATION
    ). The policy is no more special, just a normal system integrity policy.

    Bootloader options:

    • bootmenupolicy must be Standard
    • bootems must be disabled (likely enabled in Server edition installation)

    The reason is in either case, code path of this feature will not be reached if boot menu style is Windows 7 style.

    Driver signer certificate PKI hierarchy:

    For certificate for signing kernel drivers, it's better to have a 2 tier one rather than 1 tier. This is due to the behavior of SignTool.exe mentioned above, if the signing certificate is issued by a root CA directly, SignTool.exe will not embedded the root certificate to the signature. Kernel code integrity module (CI.dll) will not able to verify the driver unless you add the TBS hash of the signing certificate to the policy which is inflexible. If you have a 2 tier PKI, you can add the TBS hash of the SubCA to the policy and any certificate issued by that SubCA will be allowed. If you add the root certificate to the signature (by a third party tool or modify ASN.1 by hand which is tedious and error prone), it would work though.

    Generate and Install PK, KEK, DB certificates and keys:

    The easiest approach is set the SecureBoot mode to Setup mode and use sbctl (GITHUB/Foxboron/sbctl) to generate PK, KEK, DB certificates and keys for you and enroll them and motherboard manufacturer DB certificates and MS KEK, DB certificates as well.

    Minimal policy sample:
    Code:
    <?xml version="1.0" encoding="utf-8"?>
    <SiPolicy xmlns="urn:schemas-microsoft-com:sipolicy">
      <VersionEx>10.0.0.0</VersionEx>
      <PolicyTypeID>{A244370E-44C9-4C06-B551-F6016E563076}</PolicyTypeID>
      <PlatformID>{2E07F7E4-194C-4D20-B7C9-6F4AA6C5A234}</PlatformID>
      <Rules>
        <Rule>
          <Option>Enabled:Advanced Boot Options Menu</Option>
        </Rule>
        <!-- 1709 and later -->
        <Rule>
          <Option>Enabled:Update Policy No Reboot</Option>
        </Rule>
      </Rules>
      <EKUs />
      <FileRules />
      <Signers>
        <Signer Name="MincryptKnownRootMicrosoftProductRoot1997" ID="ID_SIGNER_MICROSOFT_PRODUCT_1997">
          <CertRoot Type="Wellknown" Value="04" />
        </Signer>
        <Signer Name="MincryptKnownRootMicrosoftProductRoot2001" ID="ID_SIGNER_MICROSOFT_PRODUCT_2001">
          <CertRoot Type="Wellknown" Value="05" />
        </Signer>
        <Signer Name="MincryptKnownRootMicrosoftProductRoot2010" ID="ID_SIGNER_MICROSOFT_PRODUCT_2010">
          <CertRoot Type="Wellknown" Value="06" />
        </Signer>
        <!-- Cross signing -->
        <Signer Name="MincryptKnownRootMicrosoftCodeVerificationRoot2006" ID="ID_SIGNER_MICROSOFT_CODEVERIFICATION_2006">
          <CertRoot Type="Wellknown" Value="08" />
        </Signer>
        <!-- Insider Builds -->
        <Signer Name="MincryptKnownRootMicrosoftFlightRoot2014" ID="ID_SIGNER_MICROSOFT_FLIGHT_2014">
          <CertRoot Type="Wellknown" Value="0E" />
        </Signer>
        <!-- Add TBS hash of your signing CA / signer certificate / policy signer here -->
      </Signers>
      <SigningScenarios>
        <SigningScenario Value="131" ID="ID_SIGNINGSCENARIO_KMCI" FriendlyName="Kernel Mode Signing Scenario">
          <ProductSigners>
            <AllowedSigners>
              <AllowedSigner SignerId="ID_SIGNER_MICROSOFT_PRODUCT_1997" />
              <AllowedSigner SignerId="ID_SIGNER_MICROSOFT_PRODUCT_2001" />
              <AllowedSigner SignerId="ID_SIGNER_MICROSOFT_PRODUCT_2010" />
              <AllowedSigner SignerId="ID_SIGNER_MICROSOFT_CODEVERIFICATION_2006" />
              <AllowedSigner SignerId="ID_SIGNER_MICROSOFT_FLIGHT_2014" />
            </AllowedSigners>
          </ProductSigners>
        </SigningScenario>
      </SigningScenarios>
      <UpdatePolicySigners>
      <!-- Add your policy signer here -->
        <UpdatePolicySigner SignerId="ID_SIGNER_MY_POLICY_SIGNER" />
      </UpdatePolicySigners>
      <CiSigners />
      <HvciOptions>0</HvciOptions>
      <Settings>
        <Setting Provider="PolicyInfo" Key="Information" ValueName="Name">
          <Value>
            <String>Policy Name</String>
          </Value>
        </Setting>
        <Setting Provider="PolicyInfo" Key="Information" ValueName="Id">
          <Value>
            <String>Policy Version</String>
          </Value>
        </Setting>
      </Settings>
    </SiPolicy>
    
    You should add your signer certificate TBS hash to the Signers node. Reference them in ProductSigners node if they / or certificate issued by them will be used to sign kernel mode binary. Reference them in UpdatePolicySigners node if they or certificate issued by them will be used to sign the policy file.

    It's not recommended to add 'Enabled:Audit Mode' option because it does not work when HVCI enabled according to testing.

    'Enabled:Unsigned System Integrity Policy' is not recommended also as you have to sign the policy anyway and allow other system policy unsigned does not make sense when you have signing key. Instead, add certificate TBS hash of your policy signer to Signers node and reference it in UpdatePolicySigners node.

    You can use Add-SignerRule cmdlet to add signer, it will calculate TBS hash for you or you can get it by parsing certificate.
    To convert the xml policy to binary, use ConvertFrom-CIPolicy cmdlet.

    Note all cmdlets mentioned above only support PowerShell 5.

    Sign the policy with
    Code:
    /p7co 1.3.6.1.4.1.311.79.1 /p7 "the resulting binary path"
    switch of SignTool.exe and you policy signer certificate.
    then copy the resulting binary to EFI\Microsoft\Boot\SiPolicy.p7b. Bootloader will load this policy file if
    Code:
    HKLM\System\CurrentControlSet\Control\CI\Protected\Licensed
    is 1.

    By the way, it will affect servicing stack too. Servicing stack (CbsCore, wcp, UpdateAgent...) will check catalog of package / CompDB against ConfigCI trust provider instead of normal Authenticode trust provider and Microsoft Root check. If ConfigCI trust provider returns 0 or Result of ProviderData is 'CCPI_RESULT_AUDIT (3)', the signature will seen as valid just like Microsoft ones. TestRoot hack is no longer required for custom CBS package.

    I'm not able to figure out how to make ConfigCI return 0 though, it'll return 0xD0E90002 with Result 3 if allowed signer is listed in ProductSigners node of kernel signing scenario (servcing stack specifically set dwScenario of ProviderData to 131) and Result 2 (CCPI_RESULT_DENY) in other cases.