Proxmark3 community

Research, development and trades concerning the powerful Proxmark3 device.

Remember; sharing is caring. Bring something back to the community.


"Learn the tools of the trade the hard way." +Fravia

You are not logged in.

Announcement

Time changes and with it the technology
Proxmark3 @ discord

Users of this forum, please be aware that information stored on this site is not private.

#1 2010-07-10 15:15:07

gene
Member
Registered: 2010-07-10
Posts: 2

Multi Sector authentication

Hi,

I am currently trying to understand the multi sector authentication process. Therefore I tried to verify these traces given by roel. Everything works fine for the first authentication round and after the second authencation command and resetting the Crypto1 state, I am able to correctly decrypt the new Nt. But afterwards my encrypted reader answer [Nr + Nt'] differs from the trace.

Testing multi sector authentication!

UID:    9C599B32
Key:    FFFFFFFFFFFF

First authentication: 

Nt:    82A4166C
[Nr + Nt']:  A1E458CE6EEA41E0
At:    9A427B20
command:  6000F57B
switching key
decrypted Nt:  A55D950B
Nt':    1491FBDB
[Nr + Nt']:  00F539F4473612FD   <- this result seems to be wrong

My current understanding is, that the nested authentication only differs in the first authentication step where Nt is send encrypted. I would highly appreciate any comments or hints!

#include "crapto1.h"
#include <stdio.h>

int main(void)
{
  uint16_t i;
  uint64_t key = 0xffffffffffffLLU;  
  uint8_t uid[] = {0x9c,0x59,0x9b,0x32};
  uint8_t nt[]  = {0x82,0xA4,0x16,0x6C};
  uint8_t nr[]  = {0xEF,0xEA,0x1C,0xDA};
  uint8_t ar[8];
  uint8_t at[]  = {0x5c,0xad,0xf4,0x39};

  printf("\nTesting multi sector authentication!\n\n");

  printf("UID:\t\t");
  for(i=0;i<4;i++)
    printf("%02X",uid[i]);
  printf("\n");

  printf("Key:\t\t%llX\n\n",key);

  printf("First authentication: \n\n");

  uint32_t nt32 = 0;
  for(i=0;i<4;i++)
    nt32 = (nt32 << 8) | nt[i];
  
  printf("Nt:\t\t%08X\n",nt32);

  struct Crypto1State * state;
  state = crypto1_create(key);

  // feed in uid^nt and drop keystream in the first round
  for(i=0;i<4;i++)
  {
    crypto1_byte(state,uid[i]^nt[i],0);
  }
  
  // encrypt reader nonce
  for(i=0;i<4;i++)
  {
    ar[i] = crypto1_byte(state,nr[i],0) ^ nr[i];
  }

  // generate answer to tag nonce and encrypt it
  nt32 = prng_successor(nt32,32);

  for(i=4;i<8;i++)
  {
    nt32 = prng_successor(nt32,8);
    ar[i] = crypto1_byte(state,0x00,0) ^ (nt32&0xff);
  }
  
  // output
  printf("[Nr + Nt']:\t");
  for(i=0;i<8;i++)
    printf("%02X",ar[i]);
  printf("\n");

  // decrypt tag answer at
  printf("At:\t\t");
  for(i=0;i<4;i++)
    printf("%02X",crypto1_byte(state,0x00,0)^at[i]);
  printf("\n");

  // encrypted 2nd authentication command
  uint8_t command[] = {0x8e,0x0e,0x5d,0xb9};

  // decrypt command
  printf("command:\t");
  for(i=0;i<4;i++)
    printf("%02X",crypto1_byte(state,0x00,0)^command[i]);
  printf("\n");


  // interesting part begins here:

  printf("switching key\n");
  crypto1_destroy(state);

  state = crypto1_create(key);

  uint8_t nt_enc[] = {0x5a,0x92,0x0d,0x85};
  
  // feed in uid^nt_enc and decrypt tagnonce
  printf("decrypted Nt:\t");
  
  // this time do not drop the first 32 keystream bits 
  // use them to decrypt [Nt]
  for(i=0;i<4;i++)
  {      
    printf("%02X",crypto1_byte(state,uid[i]^nt_enc[i],1)^nt_enc[i]);
  }
  printf("\n");
    
  uint8_t nt_new[] = {0xA5,0x5D,0x95,0x0B};
  uint8_t nr_new[] = {0xEF,0x60,0xE2,0x6F};  

  uint32_t nt32_new = 0;
  for(i=0;i<4;i++)
    nt32_new = (nt32_new << 8) | nt_new[i];
  
// From here on it seems to go wrong :(

  // encrypt reader nonce
  for(i=0;i<4;i++)
  {
    ar[i] = crypto1_byte(state,nr_new[i],0) ^ nr_new[i];
  }
  
  // generate answer to tag nonce and encrypt it
  nt32_new = prng_successor(nt32_new,32);
  printf("Nt':\t\t");
  for(i=4;i<8;i++)
  {
    nt32_new = prng_successor(nt32_new,8);
    printf("%02X",nt32_new&0xff);
    ar[i] = crypto1_byte(state,0x00,0) ^ (nt32_new&0xff);
  }
  printf("\n");
  // Output
  printf("[Nr + Nt']:\t");
  for(i=0;i<8;i++)
    printf("%02X",ar[i]);
  printf("\n");

            
  return 0;
}

Offline

#2 2010-07-12 01:59:18

hat
Contributor
Registered: 2009-04-12
Posts: 160

Re: Multi Sector authentication

so after a little while i figured it out

roel's flaw in the trace: what he calls Nr is actually just the keystream that Nr is xorred against
and uhm your flaw is writing horrible code smile

here's a clean version of what goes on:

#include "crapto1.h"
#include <stdio.h>


int main()
{
        struct Crypto1State * state;

        //shared informationn
        uint64_t key = 0xffffffffffffULL;
        uint32_t uid = 0x9c599b32;


        //information available to the tag
        uint32_t nonce = 0xA55D950B;
        uint32_t rn_enc = 0x98d76b77;
        uint32_t rr_enc = 0xd6c6e870;

        //information available to the reader
        uint32_t nonce_enc = 0x5a920d85;
        uint32_t rn = 0x77B78918;
        uint32_t tr_enc = 0xca7e0b63;

//TAG
        printf("from the TAG's point of view:\n");
        state = crypto1_create(key);
        printf("\tsending [tag nonce]   : %08X\n", nonce ^ crypto1_word(state, uid ^ nonce, 0));
        printf("\treceived reader nonce : %08X\n", rn_enc ^ crypto1_word(state, rn_enc , 1));
        printf("\treceived reader reply : %08X\n", rr_enc ^ crypto1_word(state, 0, 0));
        printf("\tsending [tag reply]   : %08X\n", prng_successor(nonce, 96) ^ crypto1_word(state, 0, 0));


//READER
        printf("\nfrom the READER's point of view:\n");
        state = crypto1_create(key);
        printf("\treceived tag nonce     : %08X\n", nonce = (nonce_enc ^ crypto1_word(state, uid ^ nonce_enc, 1)));
        printf("\tsending [reader nonce] : %08X\n", rn ^ crypto1_word(state, rn, 0)); 
        printf("\tsending [reader reply] : %08X\n", prng_successor(nonce, 64) ^ crypto1_word(state, 0, 0)); 
        printf("\treceived tag reply     : %08X\n", tr_enc ^ crypto1_word(state, 0, 0));
        return 0;
}

to get roel's output substitute in

        printf("\treceived reader nonce : %08X\n",  crypto1_word(state, rn_enc , 1));

cheers.

Offline

#3 2010-07-12 08:37:15

gene
Member
Registered: 2010-07-10
Posts: 2

Re: Multi Sector authentication

Thank you very much!

Offline

Board footer

Powered by FluxBB