Search code examples
windowskerneldrivercode-signingdriver-signing

Windows kernel mode code signing problems


Problem summary

My Windows application includes a service that loads a rather simple driver. This driver contains embedded SHA1 as well as SHA256 signatures and includes a cross-signing certificate chain for both of them, as per the KMCS requirements described in the MS Kernel Signing doc for signing a driver without a CAT file.

The driver loads perfectly fine on most Windows installations but fails to load in some rare cases, mostly on Windows 7 x64 and Windows 10 x64. The error is 0x241 (577): Windows cannot verify the digital signature for this file. A recent hardware or software change might have installed a file that is signed incorrectly or damaged, or that might be malicious software from an unknown source.

More info

I've been trying to figure out what might be the cause of this problem for the better part of two weeks. As you'd expect, this error only comes up on the user's machines. I have installed 4 VMs with Windows 7 x64 and another 4 VMs with Windows 10 x64 in various configurations and with various levels of updates. I went as far as completely reproducing a user's setup in one of the Windows 10 VMs - I spent a whole day installing the exact Windows edition with the right language and with all the software they had down to the precise version in an attempt to reproduce the problem. No such luck, though: when installing my application, the driver loaded perfectly fine.

In the hope that someone might have an idea of what might be going on or could at least point me in the right direction, I decided to ask here: what could possibly be causing a driver that is apparently correctly signed to fail validation on some Windows installations?

Further details

I am using a StartCom Class 3 Code Signing certificate. I downloaded the cross-signing StartCom certificate from the Microsoft Cross-Certificates for Kernel Mode Code Signing page.

My certificate is in a pfx file and I am signing the driver as follows:

signtool.exe sign /v /ac "MS_xs_st.crt" /d "Driver description" /du "https://webpage/" /f my_certificate.pfx /t http://timestamp.verisign.com/scripts/timstamp.dll /p %1 driver.sys
signtool.exe sign /v /ac "MS_xs_st.crt" /d "Driver description" /du "https://webpage/" /f my_certificate.pfx /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 /as /p %1 driver.sys

Since this is not a hardware driver that would need to be installed, it does not include a .CAT file or .INF file. It's simply a driver that gets loaded when the service starts and unloaded when the service stops.

As it can be noticed, the SHA256 signature is added after the SHA1 signature (with /as) and it also uses an SHA256 timestamping server. It is dual signed for compatibility with older operating systems, although I must say it fails to load in Vista x64, presumably because my certificate is using SHA256 as the signature algorithm. It's worth noting that the driver loads fine on Windows XP x64. It's also worth mentioning that all users for whom it failed to load report that both signatures are validated fine when inspecting the Digital Signature tab of the file properties. I can live without Vista x64 compatibility, but the Windows 7 and Windows 10 problems are very worrying and force me to keep the application in beta testing.

Out of some 150+ installs across various Windows versions, I've had:

  • 3 users for whom validation failed in Windows 7 x64. One of them didn't have all the updates installed, went ahead and installed some 200 updates after which validation passed and the problem was solved. I recommended updating to the other 2 users having the same problem but I haven't received any feedback so I don't know if the problem was fixed, nor do I even know if their Windows was up to date to begin with or not.
  • 3 users for whom the driver failed to load on Windows 10 x64. All of them were much more responsive than the Windows 7 users and I was able to find out that all of them have all the updates installed. Two of the three users installed using the Windows 10 Anniversary edition installation kit.
  • 1 user for whom the driver failed to load on Windows 2003 R2 x86. I also created a VM with this OS and failed to reproduce the problem.

Every time the driver fails to load, an Audit Failure event is generated in the Security event category with the text: *Code integrity determined that the image hash of a file is not valid. The file could be corrupt due to unauthorized modification or the invalid hash could indicate a potential disk device error.

File Name: \Device\HarddiskVolumeX\Program Files (x86)\path\to\driver.sys*

I get exactly the same error in Vista x64 and enabling the Code Integrity verbose log results in a lot of messages about loading all the .CAT files and nothing else of interest. Naturally, in Vista x64 the Code Integrity operational log includes an Error about the file not getting validated, rather similar to the Audit Error above.

Running

signtool.exe verify /v /kp driver.sys

Results in:

Verifying: driver.sys
Signature Index: 0 (Primary Signature)
Hash of file (sha1): EE2FE2A16395DC66ACCB5264742987D99ECF5A66

Signing Certificate Chain:
    Issued to: StartCom Certification Authority
    Issued by: StartCom Certification Authority
    Expires:   Wed Sep 17 22:46:36 2036
    SHA1 hash: 3E2BF7F2031B96F38CE6C4D8A85D3E2D58476A0F

        Issued to: StartCom Class 3 Object CA
        Issued by: StartCom Certification Authority
        Expires:   Mon Dec 16 04:00:05 2030
        SHA1 hash: E181101EE744817E49B6F97466E14DFA0809BD46

            Issued to: My company
            Issued by: StartCom Class 3 Object CA
            Expires:   Sun Aug 04 16:18:18 2019
            SHA1 hash: 62...E9

The signature is timestamped: Sun Sep 25 12:49:52 2016
Timestamp Verified by:
    Issued to: Thawte Timestamping CA
    Issued by: Thawte Timestamping CA
    Expires:   Fri Jan 01 02:59:59 2021
    SHA1 hash: BE36A4562FB2EE05DBB3D32323ADF445084ED656

        Issued to: Symantec Time Stamping Services CA - G2
        Issued by: Thawte Timestamping CA
        Expires:   Thu Dec 31 02:59:59 2020
        SHA1 hash: 6C07453FFDDA08B83707C09B82FB3D15F35336B1

            Issued to: Symantec Time Stamping Services Signer - G4
            Issued by: Symantec Time Stamping Services CA - G2
            Expires:   Wed Dec 30 02:59:59 2020
            SHA1 hash: 65439929B67973EB192D6FF243E6767ADF0834E4

Cross Certificate Chain:
    Issued to: Microsoft Code Verification Root
    Issued by: Microsoft Code Verification Root
    Expires:   Sat Nov 01 16:54:03 2025
    SHA1 hash: 8FBE4D070EF8AB1BCCAF2A9D5CCAE7282A2C66B3

        Issued to: StartCom Certification Authority
        Issued by: Microsoft Code Verification Root
        Expires:   Thu Apr 15 23:23:19 2021
        SHA1 hash: E6069E048DEA8D817AFC4188B1BEF1D888D0AF17

            Issued to: StartCom Class 3 Object CA
            Issued by: StartCom Certification Authority
            Expires:   Mon Dec 16 04:00:05 2030
            SHA1 hash: E181101EE744817E49B6F97466E14DFA0809BD46

                Issued to: My company
                Issued by: StartCom Class 3 Object CA
                Expires:   Sun Aug 04 16:18:18 2019
                SHA1 hash: 62...E9


Successfully verified: driver.sys

Number of files successfully Verified: 1
Number of warnings: 0
Number of errors: 0

Running

signtool.exe verify /v /pa /all driver.sys

Results in:

Verifying: driver.sys
Signature Index: 0 (Primary Signature)
Hash of file (sha1): EE2FE2A16395DC66ACCB5264742987D99ECF5A66

Signing Certificate Chain:
    Issued to: StartCom Certification Authority
    Issued by: StartCom Certification Authority
    Expires:   Wed Sep 17 22:46:36 2036
    SHA1 hash: 3E2BF7F2031B96F38CE6C4D8A85D3E2D58476A0F

        Issued to: StartCom Class 3 Object CA
        Issued by: StartCom Certification Authority
        Expires:   Mon Dec 16 04:00:05 2030
        SHA1 hash: E181101EE744817E49B6F97466E14DFA0809BD46

            Issued to: My company
            Issued by: StartCom Class 3 Object CA
            Expires:   Sun Aug 04 16:18:18 2019
            SHA1 hash: 62...E9

The signature is timestamped: Sun Sep 25 12:49:52 2016
Timestamp Verified by:
    Issued to: Thawte Timestamping CA
    Issued by: Thawte Timestamping CA
    Expires:   Fri Jan 01 02:59:59 2021
    SHA1 hash: BE36A4562FB2EE05DBB3D32323ADF445084ED656

        Issued to: Symantec Time Stamping Services CA - G2
        Issued by: Thawte Timestamping CA
        Expires:   Thu Dec 31 02:59:59 2020
        SHA1 hash: 6C07453FFDDA08B83707C09B82FB3D15F35336B1

            Issued to: Symantec Time Stamping Services Signer - G4
            Issued by: Symantec Time Stamping Services CA - G2
            Expires:   Wed Dec 30 02:59:59 2020
            SHA1 hash: 65439929B67973EB192D6FF243E6767ADF0834E4

Signature Index: 1
Hash of file (sha256): 79E9A2EF552906EA10F56FF7B2F95A1999B52902BCD9B78DD076157B563E900B

Signing Certificate Chain:
    Issued to: StartCom Certification Authority
    Issued by: StartCom Certification Authority
    Expires:   Wed Sep 17 22:46:36 2036
    SHA1 hash: 3E2BF7F2031B96F38CE6C4D8A85D3E2D58476A0F

        Issued to: StartCom Class 3 Object CA
        Issued by: StartCom Certification Authority
        Expires:   Mon Dec 16 04:00:05 2030
        SHA1 hash: E181101EE744817E49B6F97466E14DFA0809BD46

            Issued to: My company
            Issued by: StartCom Class 3 Object CA
            Expires:   Sun Aug 04 16:18:18 2019
            SHA1 hash: 62...E9

The signature is timestamped: Sun Sep 25 12:49:53 2016
Timestamp Verified by:
    Issued to: UTN-USERFirst-Object
    Issued by: UTN-USERFirst-Object
    Expires:   Tue Jul 09 21:40:36 2019
    SHA1 hash: E12DFB4B41D7D9C32B30514BAC1D81D8385E2D46

        Issued to: COMODO SHA-256 Time Stamping Signer
        Issued by: UTN-USERFirst-Object
        Expires:   Tue Jul 09 21:40:36 2019
        SHA1 hash: 36527D4FA26A68F9EB4596F1D99ABB2C0EA76DFA


Successfully verified: driver.sys

Number of signatures successfully Verified: 2
Number of warnings: 0
Number of errors: 0

What is a bit strange is that verifying with no special switches results in certificate chain errors. Then again, I get the same error when checking a VMWare driver so I guess it's not something to worry about. In any case, running:

signtool.exe verify /v /all driver.sys

Results in:

Verifying: driver.sys
Signature Index: 0 (Primary Signature)
Hash of file (sha1): EE2FE2A16395DC66ACCB5264742987D99ECF5A66

Signing Certificate Chain:
    Issued to: StartCom Certification Authority
    Issued by: StartCom Certification Authority
    Expires:   Wed Sep 17 22:46:36 2036
    SHA1 hash: 3E2BF7F2031B96F38CE6C4D8A85D3E2D58476A0F

        Issued to: StartCom Class 3 Object CA
        Issued by: StartCom Certification Authority
        Expires:   Mon Dec 16 04:00:05 2030
        SHA1 hash: E181101EE744817E49B6F97466E14DFA0809BD46

            Issued to: My company
            Issued by: StartCom Class 3 Object CA
            Expires:   Sun Aug 04 16:18:18 2019
            SHA1 hash: 62...E9

The signature is timestamped: Sun Sep 25 12:49:52 2016
Timestamp Verified by:
    Issued to: Thawte Timestamping CA
    Issued by: Thawte Timestamping CA
    Expires:   Fri Jan 01 02:59:59 2021
    SHA1 hash: BE36A4562FB2EE05DBB3D32323ADF445084ED656

        Issued to: Symantec Time Stamping Services CA - G2
        Issued by: Thawte Timestamping CA
        Expires:   Thu Dec 31 02:59:59 2020
        SHA1 hash: 6C07453FFDDA08B83707C09B82FB3D15F35336B1

            Issued to: Symantec Time Stamping Services Signer - G4
            Issued by: Symantec Time Stamping Services CA - G2
            Expires:   Wed Dec 30 02:59:59 2020
            SHA1 hash: 65439929B67973EB192D6FF243E6767ADF0834E4

SignTool Error: A certificate chain processed, but terminated in a root
        certificate which is not trusted by the trust provider.
Signature Index: 1
Hash of file (sha256): 79E9A2EF552906EA10F56FF7B2F95A1999B52902BCD9B78DD076157B563E900B

Signing Certificate Chain:
    Issued to: StartCom Certification Authority
    Issued by: StartCom Certification Authority
    Expires:   Wed Sep 17 22:46:36 2036
    SHA1 hash: 3E2BF7F2031B96F38CE6C4D8A85D3E2D58476A0F

        Issued to: StartCom Class 3 Object CA
        Issued by: StartCom Certification Authority
        Expires:   Mon Dec 16 04:00:05 2030
        SHA1 hash: E181101EE744817E49B6F97466E14DFA0809BD46

            Issued to: My company
            Issued by: StartCom Class 3 Object CA
            Expires:   Sun Aug 04 16:18:18 2019
            SHA1 hash: 62...E9

The signature is timestamped: Sun Sep 25 12:49:53 2016
Timestamp Verified by:
    Issued to: UTN-USERFirst-Object
    Issued by: UTN-USERFirst-Object
    Expires:   Tue Jul 09 21:40:36 2019
    SHA1 hash: E12DFB4B41D7D9C32B30514BAC1D81D8385E2D46

        Issued to: COMODO SHA-256 Time Stamping Signer
        Issued by: UTN-USERFirst-Object
        Expires:   Tue Jul 09 21:40:36 2019
        SHA1 hash: 36527D4FA26A68F9EB4596F1D99ABB2C0EA76DFA

SignTool Error: A certificate chain processed, but terminated in a root
        certificate which is not trusted by the trust provider.

Number of signatures successfully Verified: 0
Number of warnings: 0
Number of errors: 2

I am using signtool.exe from the 8.1 Windows kit that ships with VS 2015, its version is 6.3.9600.17298. For what it's worth, the driver is compiled with WDK 7.1.0 (7600.13685.1).


Solution

  • As Martin Drab posted above, the problem is twofold. By the way, thanks Martin, your comment helped me sort it out, I was able to reproduce the Windows 10 problem by setting up a VM with Secure Boot enabled.

    For operating systems older than Windows 10, the problem seems to be fixed by installing all the latest updates. If the PC wasn't updated since before 01.11.2015 (when the new Microsoft Code Verification Root certificate was issued), it won't be able to validate because the kernel doesn't recognize the root certificate.

    For Windows 10 there is a new Kernel Mode Code Signining Policy that specifies that all fresh installations of Windows 10 Anniversary Edition will not validate any kernel code that is not signed by the Microsoft Dev Portal (which requires an EV certificate) unless it was signed with a cross-signing certificate issued prior to July 29th 2015 or Secure Boot is disabled.

    The reason the problem was only occurring rarely is that most people don't have Windows 7 machines that haven't been updated in ages and most of those that have Windows 10 at the time of this writing aren't using fresh installs of the Anniversary Edition.

    The only real solution for Windows 10 is to get an EV certificate.