Earlier posts considered the idea of using a smartphone as a smartcard replacement for security scenarios such as logical access and encryption. The upshot is that presence of an embedded secure element and support for NFC with card-emulation mode gets surprisingly close without installing any software on either side. A commodity OS such as Windows already recognizes the phone as a smart card when it is tapped against an NFC reader, and attempts to use it for traditional smart card scenarios such as login. This article takes a closer look at exactly what goes on inside Windows when interacting with the phone over NFC, a story best related through a historical perspective on cryptography in Windows.
The first systematic usage of cryptography in Windows dates back to the 1990s and Clinton administration, when crypto wars were still raging. On one side the US government lobbied for strong export restrictions, arguing that encryption made it easier for criminals to evade surveillance by law enforcement agencies. On the other side an alliance of industry, civil liberatarians, self-described cypherpunks and academics pushed for widespread commercial availability of strong cryptography. Meanwhile the sudden growth of the web and ecommerce gave rise to the first large scale use of crypto for consumers: the Secure Sockets Layer protocol or SSL was the ultimate kitchen sink, mixing all of the basic building blocks: public-key encryption, symmetric ciphers, hash functions, digital certificates. The dependence of ecommerce on SSL translated into a product requirement to have all of those moving pieces implemented.
Eventually the US would back down from its position and the restrictions largely lifted in 2000, but not before they took their toll on the design of Windows cryptography API or CAPI for short. CAPI tried to walk this fine lien of enabling the “permited” use cases such as online banking for good guys while making it difficult for bad guys to implement the “frowned upon” scenarios. Many of the inexplicable design choices reflect these constraints. Case in point: for the longest time it was not possible for users to generate their own keys and provide that to the API for use in an encryption operation. Because users could override export restrictions, and for example use 128-bit keys when they were supposed to be limited to weak ciphers only. (Even when the regulatory constraints went away, the API remained hobbled with the restrictions, with the bizarre exponent-of-one trick to import keys with a dummy RSA operation.)
Still CAPI tried to provide an extensibility mechanism, using the notion of cryptographic service providers or CSPs. Applications did not simply ask to encrypt a message or compute a hash. Instead they firsted pick a CSP, which provided the implementation for set of algorithm and invoked the functionality through a consistent interface. (A similar extensibility mechanism was adopted later by openssl in the notion of engines.) While this made life slightly more cumbersome for consumers of cryptography– even simple tasks such as “hash this message with SHA1” required dozens of lines of code– on paper the model had significant advantages:
- Support for new algorithms can be added by end users. In other words a third-party could author a CSP and install thiswithout waiting for MSFT to update the OS.
- Default implementation of existing algorithms could be replaced. If a customer was concerned about side-channel attacks in the built-in RSA implementation, they could in principle write an improved version.
- System-wide policies could be set on choice of algorithms. One could mandate that all applications that use hashing would pick SHA256 for example.
In reality it did not quite pan-out that way, for reasons beyond the scope of this post. But for our purposes the main feature is how smart cards were incorporated into the framework. Originally support for smart cards and custom cryptographic hardware such as HSMs were viewed as a special case of the second scenario. In this model each smartcard vendor writes a CSP tailored to the precise capabilities of their hardware. Customers would install that CSP on the machines where they planned to use that card. Magically CAPI ensures that requests from existing applications– web browser, email client, VPN app etc.– are be transparently routed to the new CSP without changing the application. This is what the initial architecture looked like: