Smart-card logon for OS X (part II)

[continued from part I]

Local vs domain logon

In keeping with the Windows example from 2013, this post will also look at local smart-card logon, as opposed to directory based. That is, the credentials on the card correspond to a user account that is defined on the local machine, as opposed to a centralized identity management service such as Active Directory. A directory-based approach would allow similar authentication to any domain-joined machine using a smart-card, while the local case only works for a user account recognized by one machine. For example, it would not be possible to use these credentials to access a remote file-share afterwards, while that would be supported for the AD scenario because the logon in that case results in Kerberos credentials recognized by all other domain participants.

Interestingly that local logon case is natively supported by the remnants of smart-card infrastructure in OS X. By contrast Windows only ships with domain logon, using PKINIT extension to Kerberos. Third-party solutions such as eIDAuthenticate are required to get local scenario working on Windows. (In the same way that Apple can’t seem to grok enterprise requirements, MSFT errs in the other direction of enabling certain functionality only for enterprise. One can imagine a confused program manager in Redmond asking “why would an average user ever want to login with a smart-card?”)

Certificate mapping

At a high-level there are two pieces to smart-card logon, which is to say authenticating with a digital certificate where the private key happens to reside on a “smart card.” (Increasingly the card is not an actual card but could be a USB token or even virtual-card emulated by the TPM on the local machine.)

  • Target machine decides which user account that certificate represents
  • The card proves possession of the private-key corresponding to the public-key found in the certificate

The second part is a relatively straightforward cryptographic problem that has many precedents in the literature, including SSH public-key authentication and TLS client authentication. Typically both sides jointly generate a challenge, the card performs a private-key operation using that challenge and machine verifies the result using the public-key. Exact details vary based on key-type and allowed key-usage attributes in the certificate. For example if the certificate had an RSA key, the machine could encrypt some data and ask the card to respond with proof that it can recover the original plaintext. If the certificate instead had an ECDSA key which is only usable for signatures but not encryption (or it has an RSA key but the key-usage constraints on the certificate rule out encryption) the protocol may involve signing a jointly generated challenge.

Tangent: PKINIT in reality

Reality of PKINIT specification is a lot messier— not to mention the quirks of how Windows has implemented it historically. Authentication of user is achieved indirectly in two steps. First client sends the Kerberos domain-controller (KDC) a request signed with its own key-pair, then receives a Kerberos ticket-granting-ticket (TGT) from KDC encoded in one of two different ways:

  • Encrypted in the same RSA key used by the client when signing— this was the only option supported in early implementations of PKINIT in Windows
  • Using a Diffie-Hellman key exchange, with DH parameter and client input authenticated by the signature sent in the original request

Mapping from any CA

The good news is local logon does not involve a KDC, there is no reason for implementations to worry about idiosyncrasies of RFC4556 or interop with Kerberos. Instead they have a different problem in mapping a certificate to user accounts. This is relatively straightforward in the enterprise: user certificates are issued by an internal certificate authority that is either part of Active Directory domain controller using the certificate services role (in the common case of an all-Windows shop) or some stand-alone internal CA that has been configured for this purpose and marked as trusted by AD. The certificates are based on a fixed template with username encoded in specific  X509 fields such as email address or UPN, universal principal name. That takes the guesswork out of deciding which user is involved.  The UPN “” or that same value in email field unambiguously indicates this is user Alice logging into Acme enterprise domain.

By contrast local smart-card logon is typically designed to work with any existing certificates the user may have, including self-signed ones; this approach might be called “bring-your-own-certificate” or BYOC. No assumptions can be made about the template that certificate follows, other than conforming to X509. It may not have any fields that would allow obvious linking with the local account. For example there may be no UPN and email address might point to Alice’s corporate account, while the machine in question is a stand-alone home PC with personal account nicknamed “sunshine.” Main design challenge then is devising a flexible and secure way to choose which certificates are permitted to login to which account.



Smart-card logon for OS X (part I)

OS X in the enterprise

Apple is not exactly known for an enthusiastic enterprise scenarios, which is surprising considering the company’s steady rise in popularity as standard issue IT equipment at large companies. It was common for Mac-operations team at Google to frequently report bugs that made it difficult to manage the enterprise fleet— and Google has thousands of Macbooks company wide. These were routinely ignored and under-prioritized by a culture more focused on designing shiny objects than pedestrian tasks like enterprise controls. So one would expect that a decidedly enterprise-oriented security feature along the lines of smart-card logon could not possibly work on OS X. But the real surprise is it can be made to work using only open source software and in spite of Apple’s best attempts to deprecate all things smart-card related.

Market pressure: it works

Back-tracking  we have the first riddle: why did a consumer-oriented platform known more for flashy graphics than high-security scenarios even bother implementing smart-card support in the first place? The credit for that goes to the US government—indirectly. Presidential directive HSPD-12 called for a common identification standard for federal employees and contractors. In response, NIST developed FIPS 201 as a comprehensive standard encompassing hardware/software for employee badges, PKI-based credentials on those badges and framework for identity management built around those credentials. The vision was ambitious, encompassing both physical access- say getting into restricted areas inside an airport- and logical access such as authenticating to a server in the cloud. Lynchpin of this vision was the CAC (Common Access Card), later replaced by PIV or Personal Identity Verification card. Compliance with CAC and PIV became baseline requirement for certain product sales to the federal government.

That same demand got Windows Vista playing well with CAC and PIV. (Not that it mattered, as Vista never succeeded in the marketplace.) Much better out-of-the-box support carried over into Windows 7. Apple was not immune to that pressure either. OS X had its own proprietary tokend stack for interacting with smart-cards, comparable to the Windows smart-card mini driver architecture. A tokend module for PIV was provide starting with 10.5 to enable standard PIV scenarios such as email encryption or authenticating to websites in a browser.

Deprecated in favor of?

“There are 2 ways to do anything at Google: the deprecated one and the one that does not yet work.” — inside joke at Google

This is where the paths between Apple and MSFT diverged. MSFT continued to invest in improving the smart-card stack, introducing new mini-driver models and better PIV integration. OS X Lion removed support for tokend, no longer shipping the modules in the core OS image. This was the culminating act of Apple washing its hands clean off this pesky security technology, which had started earlier by open-sourcing the smart-card services component earlier and handing off development to a group of volunteers clustered around an open-source project.

In principle punting all development work to an open-source community does not sound too bad. Building blocks are freely available, if anyone cares to compile from sources and install the components manually. In practice most companies do not want to deal with the complexity of maintaining their own packages or watching updates from the upstream open-source project. Third-party vendors [this, that, others] stepped into the void to provide complete solutions going beyond tokend modules, offering additional utilities for administering the card that missing from OS X.

Apple may eventually define a new cryptography architecture with feature parity to CDSA. At the moment nothing ships in the box for enabling smart-card support, not even for PIV. But relics of the supposedly deprecated architecture still survive even in Mavericks. That foundation combined with tokend modules shipping in OpenSC installer- derived from that original open-source release- allow implementing smart-card logon using only free software.



Cloud storage and encryption revisited: Bitlocker attacks (part II)


Instead of adopting one of the standardized narrow block cipher modes for Bitlocker, Windows 8 removed the diffuser and reverted to plain CBC mode. This bizarre change greatly simplifies crafting controlled changes to binaries to obtain arbitrary code execution. Suppose we know the sectors on disk where a particular application resides and we know exactly which version of that application it is. Now the PE format for Windows executables contains many sections- some of them meta-data/headers, others resources such as strings and icons. More interestingly, there are the portions which are truly “executable;” they contain the stream of instructions that will run when this application is invoked. Being able to manipulate even a small number of instructions in that stream achieves code execution.

There are several practical difficulties along the way. As pointed out, CBC mode does not permit changes with surgical precision- we can control one full block of 16 bytes but only at the expense of having no say over the preceding one. But one can repeat the same trick with the next two adjacent blocks, getting to control  one out of two blocks in each sector. That calls for an unusual way to organize shell code: divide it into small fragments of 14 bytes or less, with 2-byte relative forward jumps at the end to skip over the next block that is outside our control. (As the analog of return-oriented programming, this could be jump-oriented programming.) We also need to locate a candidate block that can be used as entry point into the shell code. Recall that controlling block N requires that we modify block N-1; that means code linearly executing through block N-1 may crash or do strange things before reaching block N. Instead we need to find a point in the binary where a branch or call target lands at the beginning of a nicely aligned 16-byte block. Considering that most functions will be aligned at 8 or 16 byte addresses, this is not a significant hurdle.

Exploiting this against a local Bitlocker-protected boot volume is straightforward, as demonstrated in the iSEC research: choose a binary that is guaranteed to be executed automatically on boot without user action- such as winlogon– along with a code path in that binary that is guaranteed to be hit. For removable drives and cloud storage, it is less clear whether these conditions will arise in practice. Such volumes typically contain “data”- documents, presentations, music, photography etc. instead of executable files that can be readily infected with shellcode. (Exception being whole-system images meant for recovering from an OS corruption.) But one can not rule out more sophisticated attacks; the definition of what counts as “executable” is itself encoded in the filesystem metadata, which can be modified with the same technique for modifying file contents. For example the user may have uploaded a Word document with “doc” extension to the cloud. But if we change the extension to “bat” and modify the contents appropriately to create a valid batch file, we get code execution.

There is another challenge that makes exploitation harder for the cloud case: knowing exactly where on disk the file targeted for modifications resides. This is easier to determine for local attacks where disk layout is based on a fixed template. If we know the victim is using a particular Dell laptop with factory-installed Windows image, we can order an identical laptop with same size disk and examine which sectors the target binary occupies on that Window installation. (This will not work for files that are replaced. For example if an OS update brings in a new version of some system binary, chances are it will not be updated in place. Instead it will be recreated by assigning new sectors from unused space— sectors whose locations are unpredictable because they are based on the pattern disk usage up until that point.) By contrast volumes synced to the cloud do not have a fixed structure, directory pattern or naming convention that can be used to estimate where interesting data may have ended up.

Still, none of these problems qualify as a systemic mitigation. If anything the remote storage scenario illustrates why it is necessary to move beyond the core assumption in FDE, namely that each sector must encrypt to exactly one sector, with no room for expansion to accommodate integrity checks. That is a reasonable assumption for local disk encryption for reasons articulated in the Elephant diffuser whitepaper: compatibility when encrypting existing volumes, performance overhead from having to read/write multiple sectors if integrity checks were stored separately and resulting requirement for transactional updates. None of these constraints apply to cloud storage. It may be possible to retrofit required data expansion into protocols such as iSCSI to salvage full-disk encryption. A more pessimistic conclusion is that FDE is not the right framework for creating private storage in the cloud, and different file-system level approaches may be necessary.