MTPZ: Handshake, Part 1 - Application Certificate Message

So, in the time between this post and the post detailing my initialization notes, I managed to fully emulate
the Zune software in its generation of its first message that is sent to the device. This is referred to as
the Application Certificate Message, which is sent with the MTP opcode of PTP_OC_MTP_WMDRMPD_SendWMDRMPDAppRequest.
It is the first of three messages that are sent back and forth between the software and the device.

To start off, here’s the hex dump of an actual communication between the Zune software and the device. This is
strictly the Application Certificate Message.

The first two bytes 02 01 seem to be marker bytes that simply indicate to the device that what follows
is most likely a valid message.

Certificate serialization

What the software does next is take its two certificates that it decrypted and deserialized during initialization, and then
reserialize them into binary format. It’s clear, from looking at the above sample, that the Application Certificate Message contains the
two certificates (Zune Software CA 1 and Zune Software Leaf 1), starting with the bytes 02 00 00 01 35 at offset 0x07.

The software indicates that what follows is certificate data by writing the marker byte 01, followed by the 32-bit length
of the certificate data (in this case, 0x275). Then, the software writes the certificate data itself. For the sake
of ease of implementation, this can be seen as the original block of certificate data that was decrypted during initialazation,
rather than the reserialization of the deserialized certificate data.

It’s worth noting that the certificate data is always constant, and does not change.

Random byte generation

After writing the certificate data, the software generates 16 random bytes. The software writes the 16-bit length of the random bytes
(therefore, always 00 10), followed by the random bytes themselves. This is seen in the above sample at offset 0x027C. In this sample,
the random bytes are B5 11 F7 8F 84 CE 60 2F 70 11 0C 98 02 54 B1 70.

These random bytes are necessary from a security standpoint because without them, the certificate message would always be constant and
therefore wouldn’t necessarily need to be generated by an impersonating software.

Message signature

This is where things get interesting. In a nutshell, the software takes the serialized certificate data (including the marker and length bytes),
appends the random bytes (including the length bytes) and calls that the message. It then signs the message using a typical RSA signing process.
The process involves computing a hash of the message (in this case, standard SHA-1 with some byte manipulations and other techniques), and then
using the RSA private key and modulus to create a signature of the message. The benefit of having a signature is that since the message is signed with
the private key, the recipient can use the corresponding public key to retrieve the sender’s hash of the message. Then, the recipient can perform the hash
procedure on the message and compare its own computed hash with the sender’s hash. If the two are the same, then the recipient can assume that whoever sent the
message is the owner of the private key and, therefore, the person they want to be communicating with.

Hash computation

The computation of the hash of the message involves using SHA-1 multiple times, in addition to other byte manipulation techniques. Specifically,
a SHA-1 hash is computed of the message (the certificate data and random bytes). Another hash is then computed of the message hash. These
20 bytes from the hash are placed into a 128-byte buffer, which we will call oview, at offset 107. Then, the byte at offset 106 is set to 01.
The 20 bytes from the hash are hashed (resulting in a new 20 byte hash), and XOR’d with oview at offset 0. The new 20 byte hash is
then hashed again, and XOR’d with oview at offset 20. This process repeats until the entire buffer has been XOR’d with a hash. Then,
the last byte is set to 188. Finally, oview is reversed. This is the final generated hash that is computed by both the
software and the device.

Signing

The RSA signing process involves raising the hash to the private key exponent, modulo the modulus (md mod n, where m is the hash,
d is the private key, and n is the modulus). The first matter of business is to actually compute the private key exponent, since we have every bit of information
about the private key (particularly, the two primes p and q) except for the private key exponent itself (see the notes post for the RSA private key information
that was decrypted during the initialization stage). Luckily, this is (relatively) easy to compute:

Once the private key is obtained, it’s a simple matter of raising the hash to the private key exponent, modulo the modulus. Since the modulus and private key exponent
are both 1024 bits long, the signature should also be 1024 bits long, or 128 bytes.

The big picture

So, in essence, the general format of the Application Certificate Message is the certificate data, followed by random bytes, followed by the digital signature. Outlined
below is the specific structure of the message.

And there’s the first handshake message sent between the two endpoints. After this Application Certificate Message is sent, the device’s handshake response is read
by the software and validated, the topic of the next blog post.