Questions regarding D function computation

Hi Guys,


We just have a few things we need to clarify with the implementation of the D function for Fairplay. We are trying to implement our KSM using php and we used as a reference the c implementation that came with the FPS SDK and FPS deployment package. I hope you could shed some light on the following matter since we are a bit lost in the implementation.


1. In the reference implementation written in C (DeriviationFunction.c) on the part "Reunify into 2 32 bits value" there is this part of c code:


    for (i = 1 ; i < 7; i++) {
        MBlock[0] += MBlock[i];
    }
    MBlock[1] = 0;
    for (i = 0 ; i < 7; i++) {
        MBlock[1] += MBlock[i + 7];
    }


Now, from the sample SPC1.bin given an unpadded R2 value of :


11f7be612ca95ef5e007ce51896ae4502ca3d8801b


MBlock[0] will reach a point that the result will no longer fit in a 32 bit unsigned int. So it will be truncated to maintain a 32 bit unsigned int. Is this intentional? We ask since php will simply convert the variable to 64 bit and in order to maintain the 32 bit and have the same result as the c code we need to pack the result of the operation to 32 bit after the += operation, for example:


for ($ctr = 0; $ctr < 7; $ctr++) {
  $val = hexdec(bin2hex($this->mblock[$ctr])); //unpack("I", $this->mblock[$ctr]);
  //$this->debugMe("MBLOCK_A: " . $val);
  $this->mblock_a += $val;
  $temp = pack("N*", $this->mblock_a);
  $this->mblock_a = hexdec(bin2hex($temp));
  }


Is this operation correct? Is this how it really should be?


2. Could you clarify how to use the "Test Vectors" in the "D Function Computation Guide", in "Listing 2". It is not really clear where the values of "in" are coming from since it has a size of 20B while the padded R2 after the C_r function will result in 64 bytes. The result of SHA1 will be 20B (before encryption), but if the "in " is the result of SHA1 then should'nt the "out" be simply the value of it's first 16 bytes? As it says in the test vector, before the Listing 2:


"The out values specified in these sample vectors are the 16-byte values that are obtained before encrypting with ASk"


And in the "Hashing Operation" part it says:


"The output size of the SHA1 function is 20B. We are using the first 16 bytes as input for the next function."


And the next function in the documentation and the sample code is already the encryption.


3. Is there any "Test Vectors" that we can use that takes a real value for R2 (21 bytes) and outputs the 16 bytes before the encryption? This way we would be able to test if our process are correct. Or is it possible to get the ASK that we can use against the R2 of the sample spc from the FPS SDK to check whether we will get the correct DASK?


Regards,

anyone could clarify these question? or are the questions too stupid?

Accepted Answer

Hi,


1.

The overflow of uint32 is intentional. You should be able to achieve this by truncating uint64 to 32 bits.


2. 3.

As the document says, the padding function is generic, so regardless of the size of input (provided that below 56 bytes) it should be padded to 64 bytes and then SHA1 is to be calculated based on this 64 byte array.

It's possible to test the padding process using listed test vectors. Also, as you have noticed, there is no 21 byte example, which confused me a bit too.

Testing DASK computation goes down to verifying if the integrity bytes from within the encrypted SK..R1 match with integrity bytes given in a separate TLLV.


Hope this helps

Greg

Thank you, this was very helpful!

Questions regarding D function computation
 
 
Q