CSP Signatures

Background

Each Cryptographic Service Provider (CSP) that can be recognised for loading into the CryptoAPI system is represented by a registry key, with three required values. Details are given in relevant documentation from Microsoft. Of interest here are the string value Image Path, which locates the CSP file, and the binary data value Signature, which supplies data for validating the CSP file. The CryptoAPI system checks that the CSP file, as actually installed at the given location, matches the given signature. Without a match, the CryptoAPI system simply will not load the CSP file for execution.

Two assurances follow from this scheme of validating a CSP file:

Integrity

For an example of assuring the user, consider an attack that seeks to replace the expected CSP by one that would secretly save copies of every key generated, perhaps to send those keys surreptitiously to someone who has other means of intercepting the user’s communications (and needs the keys in order to decypher those communications). For this attack to succeed, it does not suffice to have found a way to get the compromised CSP installed on the user’s machine: the attacker must also know how to compute a signature that will be accepted as valid for the compromised CSP. The user is protected as long as the scheme for generating a correct digital signature is cryptographically secure.

Of course, validation by signature does not protect against this attack if the compromised CSP has been given a valid signature, whether indirectly or even unwittingly, by whatever entity has the job of signing CSPs! For instance, the attacker may be a law enforcement agency with lawful wire-tapping authority. It must be expected (though not necessarily agreed with) that such an agency can get its CSPs signed.

Export Control

For an example in which the U.S. Government protects its interests, consider that the Microsoft Base Cryptographic Provider, as supplied in the RSABASE.DLL file from the Windows 95 OSR2 package, implements the RSA public-key algorithm with all the coding required for generating keys of essentially arbitrary size but is constrained to execute that code only to generate key pairs with a 512-bit modulus. To get stronger encryption would be just a matter of patching the executable, except that without a correctly updated signature, the patched executable will not load into the CryptoAPI system.

Of course, validation by signature does not protect the U.S. Government’s interests from a foreign user who has the means and will to patch ADVAPI32, either in advance as a file on disk or at run-time as an image in memory, so that signature-checking succeeds without actually checking the signature!

Implementation Details

A CSP file’s Signature is essentially a 128-bit MD5 hash of the file’s contents that has been encrypted with some signing authority’s 1024-bit private key, using the RSA public-key algorithm.

Verification

When ADVAPI32 is to load a CSP file, it computes the MD5 hash of the file’s contents. By file here it is meant the file as actually present. This file might not be the same one that the given Signature was prepared for by some signing authority. To check, ADVAPI32 decrypts the Signature with the signing authority’s public key and requires the decrypted signature to have the form:

Offset Size Description
00h 10h bytes MD5 hash of file contents
10h byte 00h
11h 6Dh bytes irrelevant
7Eh byte 01h
7Fh byte 00h

Signing Authorities

As supplied with Windows 95 OSR2 and with NT 4.0, ADVAPI32 knows of two signing authorities in the sense that the verification described above is attempted with each of two public keys. In effect, ADVAPI32 recognises a CSP file as valid if the file’s hash matches a plausible Signature from either of two signing authorities.

The term “signing authority” is meant here just as a convenience of program logic and is not intended to suggest a one-to-one correspondence with persons or legal entities. It may be that one public key corresponds to any number of distinct legal entities, all of whom know the one matching private key. It may be that for both public keys, the matching private keys are held by just one person who has committed them to memory, destroyed all written and electronic records, and would rather die than reveal the keys to another living soul. There are surely any number of possibilities in between.

The two public keys for CSP validation do not have immediate visibility in the ADVAPI32 executable but are disguised with RC4 encryption using different 40-bit keys (that are related by a bitwise XOR). Inspection of the ADVAPI32.DBG symbol file from the retail NT 4.0 package shows readily that the two public keys have C-language labels KEY and NSAKEY.