In order to prevent tampering with in-system communications, all communication flows have to be encrypted and/or authenticated. For example content sent to video devices has to be encrypted with AES-128. This requirement for cryptography extends beyond basic content encryption to encompass not just data flowing over various buses but also command and control data flowing between software components. For example communications between user-mode and kernel-mode components are authenticated with OMAC message authentication-code tags, at considerable cost to both ends of the connection. The initial crypto handshake is:
driver -> application: cert + nonce
application -> driver: RSA-OAEP-SHA512( nonce || key || seqNo1 || seqNo2 )
In this step the driver supplies its certificate to the calling application via DxgkDdiOPMGetCertificate() and a 128-bit nonce via DxgkDdiOPMGetRandomNumber(). This is either a COPP or an OPM certificate, with COPP being the older Windows XP content protection and OPM being the newer Windows Vista one. There's also a third type of fleur-de-lis certificate that the driver uses if it has a UAB (User-Accessible Bus). The certificates contain a 2048-bit RSA key which is used to encrypt a 40-byte payload containing the nonce provided by the driver, a 128-bit session key, and two 32-bit initial sequence numbers (they start at random values), the first number is for status messages via DxgkDdiOPMGetInformation() and the second for command messages via DxgkDdiOPMConfigureProtectedOutput().
Once the keys are set up, each function call is:
in = OMAC( nonce || seqNo || data )
out = OMAC( nonce || seqNo || data )
(I've used conventional bits-on-the-wire notation for this, the values are actually fields in a structure so for example the sequence number is provided in the ulSequenceNumber member). This is very similar to the protocol used in SSL or SSH (in practice some steps like cipher suite negotiation are omitted, since there's a hardcoded set of ciphers used). Finding SSL being run inside a PC from one software module to another is just weird.
Needless to say, this extremely CPU-intensive mechanism is a very painful way to provide protection for content, and this fact has been known for many years. Twenty years ago, in their work on the ABYSS security module, IBM researchers concluded that the use of encrypted buses as a protection mechanism was impractical.
In order to prevent active attacks, device drivers are required to poll the underlying hardware every 30ms for digital outputs and every 150 ms for analog ones to ensure that everything appears kosher. This means that even with nothing else happening in the system, a mass of assorted drivers has to wake up thirty times a second just to ensure that… nothing continues to happen (commenting on this mechanism, Leo Laporte in his Security Now podcast with Steve Gibson calls Vista “an operating system that is insanely paranoid”). In addition to this polling, further device-specific polling is also done, for example Vista polls video devices on each video frame displayed in order to check that all of the grenade pins (tilt bits) are still as they should be. We already have multiple reports from Vista reviewers of playback problems with video and audio content, with video frames dropped and audio stuttering even on high-end systems [Note I]. Time will tell whether this problem is due to immature drivers or has been caused by the overhead imposed by Vista's content protection mechanisms interfering with playback.
Bookmarks