Advertisement
Amrin12

authenticateEV2First

May 16th, 2024 (edited)
390
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2.      *
  3.      * @param {Number} keyNo
  4.      * @param {String} key
  5.      * @returns
  6.      */
  7.     authenticateEV2First = async (keyNo, key) => {
  8.         let cmd = DESFIRE_INS.AUTH_EV2_FIRST;
  9.         let _keyNo = DesfireUtils.intToHexArray(keyNo, 1);
  10.         let auth_key = key;
  11.         let _lenCap = [0x02];
  12.         let _pcdCap = [0xC0, 0x00];
  13.  
  14.         cmd = cmd.concat(_keyNo).concat(_lenCap).concat(_pcdCap);
  15.         let response = await this.sendCommand(cmd);
  16.        
  17.         let randB_enc = response.data;
  18.         console.log("Auth EV2 First RandB Enc: ", randB_enc);
  19.  
  20.         let randB = DesfireUtils.aesDecryptor(randB_enc, auth_key);
  21.         console.log("Auth EV2 First RandB: ", randB);
  22.  
  23.         let randB_rotate = await DesfireUtils.rotateLeft(randB);
  24.         console.log("Auth EV2 First RandB Rotate: ", randB_rotate);
  25.  
  26.         // Generate random 16-byte RndA
  27.         const randA = CryptoJS.lib.WordArray.random(16).toString(CryptoJS.enc.Hex);
  28.         console.log("Auth EV2 First RandA: ", randA);
  29.  
  30.         let randAB = randA.concat(randB_rotate);
  31.  
  32.         let iv = CryptoJS.enc.Hex.parse(randB_enc);
  33.         let randAB_enc = DesfireUtils.aesEncryptor(randAB, auth_key, iv);
  34.  
  35.         dataToSend = randAB_enc;
  36.  
  37.         let instructionByte = "AF";
  38.         let cmdString = instructionByte.concat(dataToSend).toUpperCase();
  39.  
  40.         let byteArray = cmdString.match(/.{1,2}/g).map(hex => parseInt(hex, 16));
  41.         cmd = byteArray;
  42.  
  43.         response = await this.sendCommand(cmd);
  44.         console.log("First part response: ", response);
  45.  
  46.         const status = response.status;
  47.  
  48.         if (status != DESFIRE_STATUS.SUCCESS) {
  49.             console.log(status);
  50.             console.log("RandB' is wrong!\n");
  51.             return false;
  52.         }
  53.  
  54.         let data_enc = response.data;
  55.        
  56.         iv = CryptoJS.enc.Hex.parse(dataToSend.slice(-32));
  57.  
  58.         // decrypt response
  59.         // response contains TI (4 bytes) + randA' (16 bytes) + PDcap related (12 bytes)
  60.         let data = DesfireUtils.aesDecryptor(data_enc, auth_key, iv);
  61.         console.log("Data received: ", data);
  62.  
  63.         let ti = data.slice(0, 8);
  64.         let newRandA = data.slice(8, 40);
  65.         let pcdcap_returned = data.slice(40);
  66.  
  67.         console.log("TI: ", ti);
  68.         console.log("RandA: ", newRandA);
  69.         console.log("PCDcap: ", pcdcap_returned);
  70.  
  71.         // rotate right
  72.         let newRandA_rotate = DesfireUtils.rotateRight(newRandA);
  73.  
  74.         if (newRandA_rotate.toUpperCase() !== randA.toUpperCase()) {
  75.             console.log("RandA' is not identical to original RandA. Authentication failed!\n");
  76.             return false;
  77.         }
  78.  
  79.         console.log("Auth successful!");
  80.  
  81.         // generate AuthSessionKeys
  82.         const session_label_enc = [0xA5, 0x5A];
  83.         const session_label_mac = [0x5A, 0xA5];
  84.         const session_counter = [0x00, 0x01];
  85.         const session_length = [0x00, 0x80];
  86.         const session_context = new Uint8Array(26);
  87.  
  88.         // xor some values in randA and randB
  89.         // create SessionKey
  90.         const randABytes = DesfireUtils.hexStringToByteArray(randA);
  91.         const randBBytes = DesfireUtils.hexStringToByteArray(randB);
  92.  
  93.         console.log("RandA Bytes: ", randABytes);
  94.         console.log("RandB Bytes: ", randBBytes);
  95.  
  96.         const randA_15_14 = randABytes.slice(0, 2);
  97.         const randA_13_8 = randABytes.slice(2, 8);
  98.         const randB_15_10 = randBBytes.slice(0, 6);
  99.         const randB_9_0 = randBBytes.slice(6, 16);
  100.         const randA_7_0 = randABytes.slice(8, 16);
  101.  
  102.         console.log("RandA_15_14:", randA_15_14);
  103.         console.log("RandA_13_8:", randA_13_8);
  104.         console.log("RandB_15_10:", randB_15_10);
  105.         console.log("RandB_9_0:", randB_9_0);
  106.         console.log("RandA_7_0:", randA_7_0);
  107.  
  108.         const randA_13_8_string = DesfireUtils.getHexFromDecArray(Array.from(randA_13_8));
  109.         const randB_15_10_string = DesfireUtils.getHexFromDecArray(Array.from(randB_15_10));
  110.         const xoredValues = DesfireUtils.xorHexStrings(randA_13_8_string, randB_15_10_string);
  111.        
  112.         const xored_bytes = DesfireUtils.hexStringToByte(xoredValues);
  113.  
  114.         console.log("XORed Value: ", xoredValues);
  115.         console.log("XORed Bytes: ", xored_bytes);
  116.  
  117.         session_context.set(randA_15_14, 0);
  118.         session_context.set(xored_bytes, 2);
  119.         session_context.set(randB_9_0, 8);
  120.         session_context.set(randA_7_0, 18);
  121.  
  122.         const session_context_array = Array.from(session_context);
  123.  
  124.         const sv1 = session_label_enc.concat(session_counter).concat(session_length).concat(session_context_array);
  125.         const sv2 = session_label_mac.concat(session_counter).concat(session_length).concat(session_context_array);
  126.  
  127.         const session_key_enc_string = Array.from(sv1).map(byte => {
  128.             // Convert each byte to its hexadecimal representation
  129.             return ('0' + byte.toString(16)).slice(-2); // Ensure two characters for each byte
  130.         }).join('');
  131.  
  132.         const session_key_mac_string = Array.from(sv2).map(byte => {
  133.             // Convert each byte to its hexadecimal representation
  134.             return ('0' + byte.toString(16)).slice(-2); // Ensure two characters for each byte
  135.         }).join('');
  136.  
  137.         console.log("SV1: ", sv1);
  138.         console.log("SV2: ", sv2);
  139.  
  140.         console.log("session_key_enc_string: ", session_key_enc_string)
  141.         console.log("session_key_mac_string: ", session_key_mac_string)
  142.  
  143.         const sessionAuthMac = CMAC.calculateCmac(key, session_key_mac_string);
  144.         const sessionAuthEnc = CMAC.calculateCmac(key, session_key_enc_string);
  145.  
  146.         this.sessionAuthMac = sessionAuthMac;
  147.         this.sessionAuthEnc = sessionAuthEnc;
  148.         this.CmdCounter = 0;
  149.         this.TransactionIdentifier = ti;
  150.         this.authenticateEV2FirstSucess = true;
  151.  
  152.         console.log("\n");
  153.         return true;
  154.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement