In the last 2 years the process of signing drivers has changed significantly. At this point, almost everybody has had their original SHA1 certifcate expire and has migrated to a SHA256 Extended Validation (EV) certificate. The goal of this article is to summarize the steps necessary to produce a single installation package which will work on all OS versions from Windows 7 forward. Note that if your company has both a SHA1 and SHA256 certificate you may still be able to dual sign a driver in a way that it will work on the original, unpatched, Windows 7. However, given the push to deprecate SHA1 signatures, for the scope of this article we are going to assume Windows 7 has been patched to include the support for SHA256 signatures.
With that in mind, let’s first address the necessary update to add SHA256 signature support in Windows 7 and Server 2008 R2. KB3033929 is the designation for the required patch. As of this writing, it can be found here.
For the sake of simplicity, we will describe a simple driver package named “foo” which consists of foo.sys, foo.inf and foo.cat. At a high level the steps would be as follows:
- Locally sign foo.sys using signtool
- Locally generate foo.cat using inf2cat
- Locally sign foo.cat using signtool
- Package foo.sys, foo.inf and foo.cat into foo.cab using makecab
- Locally sign foo.cab using signtool
- Submit foo.cab to the Hardware Dev Center Dashboard
- Download the attestation-signed package from the Dashboard
- Generate a new foo.cat file using inf2cat and the remaining files downloaded from the Dashboard
- Locally sign foo.cat using signtool
At this point you will have a foo.sys file which is dual signed by your company’s cert and Microsoft’s. You will also have a foo.cat file which contains the hashes for the dual signed driver and the INF file. Note that this new foo.cat file will only have a single signature and it will be that of your company, not Microsoft. More on this in a minute…
Now we’ll go through the steps again in more detail. Note that we are only covering the x64 package, but the steps are nearly identical for the x86 variant.
Locally sign foo.sys using signtool
Note, we use DigiCert for our EV cert so a few of the parameters may need to change if you use another CA. The first command signs our driver with a SHA256 signature. We identify our EV cert’s fingerprint explicitly to avoid confusion in environments with multiple compatible certs.
signtool sign /sha1 [fingerprint_of_cert] /v /ac "C:\Certs\DigiCert High Assurance EV Root CA.crt" /a /tr http://timestamp.digicert.com /td sha256 /fd sha256 foo.sys
Locally generate foo.cat using inf2cat
Now we specify the OS versions which we support and generate the foo.cat file. Note that we have a subdirectory called “cat-files” which contains only foo.sys and foo.inf prior to invoking this command.
Inf2Cat /driver:cat-files /os:7_X64,Server2008R2_X64,8_X64,Server6_3_X64,Server8_X64,10_X64,Server10_X64
Locally sign foo.cat using signtool
signtool sign /sha1 [fingerprint_of_cert] /v /ac "C:\Certs\DigiCert High Assurance EV Root CA.crt" /a /tr http://timestamp.digicert.com /td sha256 /fd sha256 cat-files\foo.cat
Package foo.sys, foo.inf and foo.cat into foo.cab using makecab
We have another subdirectory called cab-files, which starts out empty. We invoke makecab from within this folder, referencing a cab description file (.ddf) located in the parent directory.
makecab /f ..\foo.ddf
The foo.ddf file contains the following:
.OPTION EXPLICIT ; Generate errors .Set CabinetFileCountThreshold=0 .Set FolderFileCountThreshold=0 .Set FolderSizeThreshold=0 .Set MaxCabinetSize=0 .Set MaxDiskFileCount=0 .Set MaxDiskSize=0 .Set CompressionType=MSZIP .Set Cabinet=on .Set Compress=on ; Specify file name for new cab file .Set CabinetNameTemplate=foo.cab ; Specify the subdirectory for the files. ; Your cab file should not have files at the root level, ; and each driver package must be in a separate subfolder. ; .Set DestinationDir=Foo-x64 ..\cat-files\foo.cat ..\cat-files\foo.sys ..\cat-files\foo.inf
Locally sign foo.cab using signtool
You must sign the foo.cab file prior to submission otherwise the submission will fail. To sign the cab file, you can use the following command.
signtool sign /sha1 [fingerprint_of_cert] /v /ac "C:\Certs\DigiCert High Assurance EV Root CA.crt" /a /tr http://timestamp.digicert.com /td sha256 /fd sha256 foo.cab
Submit foo.cab to the Hardware Dev Center Dashboard
After submitting the package wait until the state shows “Completed”.
Download the attestation-signed package from the Dashboard
Extract the files from within the .zip file. You will only need foo.sys and foo.inf. The foo.cat file is also included in the zip, but, a .cat file can only contain a single signature. The .sys file, being a PE file, can contain multiple signatures, but the .cat file does not have this ability. Therefore, the only signature present on the downloaded foo.cat is the Microsoft/Win10 signature. This signature will not be recognized by Windows 7. As a result, we need to generate a new .cat file. We cannot use the .cat file we previously generated (prior to creating foo.cab) because now foo.sys has a second signature (Microsoft’s) and therefore its hash would no longer match.
Generate a new foo.cat file using inf2cat and the remaining files downloaded from the Dashboard
We create another subdirectory called cat-final and put the downloaded foo.sys and foo.inf in it. Then we run the following:
Inf2Cat /driver:cat-final /os:7_X64,Server2008R2_X64,8_X64,Server6_3_X64,Server8_X64,10_X64,Server10_X64
Locally sign foo.cat using signtool
signtool sign /sha1 [fingerprint_of_cert] /v /ac "C:\Certs\DigiCert High Assurance EV Root CA.crt" /a /tr http://timestamp.digicert.com /td sha256 /fd sha256 cat-final\foo.cat
At this point, if you have followed all of the steps, you should have a foo.cat file which is signed by your cert only and a foo.sys file which is signed by your cert and Microsoft’s. foo.inf, being a plain text file, will not have any signatures of course. This package should now install on Windows 7 and newer operating systems without any issues. Because it has not been WHQL/HLK certified, there will still be a dialog confirming the publisher, but it will not block the installation and it will show up as a signed driver in Device Manager.