'PN532 MiFare Ultralight C Mutual Authentication

Has anyone managed to get Mutual Authentication with an ultralight C card working using this chip? I understand the Authentication procedure but looking at the command set in the chips manual and trying a few things I don't think it is actually possible but thought I would post here before abanding the chip-set and moving back to using a CJS encoder for verification

Thanks in advance



Solution 1:[1]

Sample C source code:

typedef unsigned char byte;

int mutual_authentication( const byte *diversifiedKey )
{
    byte cmd[256], response[256];
    int cmdLen, responseLen;

    //Send 1A00
    cmd[0] = 0x1A;
    cmd[1] = 0x00;
    cmdLen = 2;
    int ret = send_command( cmd, cmdLen, response, &responseLen );

    //Get ekRndB
    byte ekRndB[8], rndB[8];

    memcpy(ekRndB, response, 8);
    //Decrypt ekRndB with diversifiedKey
    des_ISO_decrypt( diversifiedKey, ekRndB, rndB, 8 );

    //PCD Generates RndA
    byte randA[8] = "\x33,\x54,\x2A,\x87,\x21,\x00,\x77,\x98";//random numbers
    byte rndARndBComplement[16], ekRndARndBComplement[16];

    // Append RndA and RndB' ( RndB' is generated by rotating RndB one byte to the left )
    // after the status byte.
    memcpy(&rndARndBComplement[0],rndA,8);
    memcpy(&rndARndBComplement[8],&rndB[1],7);  // bytes 1 to 7
    rndARndBComplement[15] = rndB[0];           // byte 0

    // Apply the DES send operation to the 16 argument bytes before sending the second frame to the PICC
    des_ISO_encrypt(diversifiedKey, rndARndBComplement, ekRndARndBComplement, 16);

    cmd[0] = 0xAF;
    memcpy(&cmd[1], ekRndARndBComplement, 16);
    cmdLen = 17;

    ret = send_command( cmd, cmdLen, response, &responseLen );

    byte ekRndAComplement[8], rndAComplement[8], finalOutput[8];

    memcpy(&ekRndAComplement[0], &response[1], 8);
    des_ISO_decrypt(diversifiedKey, ekRndAComplement, rndAComplement, 8);

    memcpy(&finalOutput[1], &RndAComplement[0], 7);
    finalOutput[0] = rndAComplement[7];

    //compare the received RndA with the one we originally had
    return memcmp(&finalOutput[0], &rndA[0], 8);
}

Note: You should have your own implementation of send_command() (depending on your card reader), des_ISO_decrypt() and des_ISO_encrypt() (depending on your DES library).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Lewis Munene