In HDCP 2.3 (pdf) during the Session Key Exchange, the HDCP transmitter sends also the 256-bit HMAC of riv (HMAC-SHA256(riv, kd)).
Why is it required? Does it prevent any attack?
Let's first break down this
As described in RFC2104, an HMAC can be defined as follows:
H is the chosen hash function,
K is the secret key,
⊕ is the exclusive OR symbol,
|| is the concatenation symbol and
opad are constant values.
Based on this paper, building HMAC upon the backdoored Merkle-Damgård hash function yields a backdoored HMAC scheme, which is easily forgeable using the backdoor key.
Hence, it is easy to see that after the messages are prepended by
k⊕ipad, they still lead to a collision in the inner hash chain of HMAC~h. Since the outer chain is equal for all messages,
m∗ both have the same tag
t. Putting differently, HMAC is not backdoor-resilient just because it uses a secret key. In summary, since an adversary holding a backdoor can forge a tag for a new message, HMAC~h is forgeable and hence not pseudorandom.
Please, refer to paper, for more information.
A HMAC is a specific construction for calculating a message authentication code (MAC) involving a cryptographic hash function in combination with a secret key. Input is a message and a key, output is the HMAC value. It is used to verify data integrity and authenticity of a message. The accompanying hash function for the HDCP standard is the SHA256 function which works with input blocks of 512 bits.
In the HDCP standard, the HMAC-SHA256 function is used for the locality check and the calculation of H (HMAC of
km). The most demanding HMAC calculation concerning the timing is the one used in the locality check. As mentioned before, the NIOS processor has not enough computing power to complete a HMAC-SHA256 operation within 2 ms. That’s why this block has to be rewritten in VHDL. The HMAC for the locality check has a key size of 256 bits and a message size of 64 bits.
The locality check asks receiver and transmitter to calculate a HMAC value of a random number
rn(message) and the pre-shared key
kd. Before the calculation starts, the pre-shared key
kdhas to be xored with a pre-shared random number (
rrx). The random number
rnis sent in plaintext to the receiver, the receiver sends back the HMAC value. The transmitter checks now if its own HMAC is identical to the received HMAC. Only someone who is in possession of the pre-shared key can compute the correct HMAC value. Additionally, it is impossible to conclude the key from the HMAC value, because the HMAC-SHA256 algorithm is a one way function.
(Kindly provided by Lukas Itin's Master Thesis)
As shown below, the key is generated using p = ((riv XOR streamCtr) || inputCtr). It is required that "no two elementary streams contained in a given program or different programs can have the same streamCtr if those elementary streams share the same Ks or riv" in order that the streams will be encrypted with different keys (using different p).
If an attacker can modify the riv he can make the transmitter generate the key of another streamCtr by sending modified riv.
The purpose of sending the HMAC is to provide more authenticity to the message.
HDCP Receiver’s public key Certificate is verified by the HDCP transmitter then the devices share a master key Km. [...] Upon receiving the encrypted Km, receiver decrypt it using the receiver private key.
Then here is the purpose of the HMAC:
After the receiver successfully decrypts the km, it sends back the H_Prime, a HMAC-SHA-256, hash value of the master key Km to the transmitter. This is to provide an acknowledgement to the transmitter that the receiver has indeed successfully decrypt the master Key Km.
Check this link for details