// Activate Security // // CryptoMemory Library Include Files #include "CM_LIB.h" #include "CM_I2C.h" #include "CM_I2C_L.h" #include "CM_GPA.h" #include // Local function prototypes static uint8_t cm_AuthenEncrypt(uint8_t ucCmd1, uint8_t ucAddrCi, uint8_t * pucCi, uint8_t * pucG_Sk, uint8_t * pucRandom); // Global Data uint8_t ucCM_Ci[8], ucCM_G_Sk[8]; uint8_t ucCM_Q_Ch[16], ucCM_Ci2[8]; // Activate Security // // When called the function: // ?reads the current cryptogram (Ci) of the key set, // ?computes the next cryptogram (Ci+1) based on the secret key pucKey (GCi) and the random number selected, // ?sends the (Ci+1) and the random number to the CryptoMemory?device, // ?computes (Ci+2) and compares its computed value the new cryptogram of the key set. // ?If (Ci+2) matches the new cryptogram of the key set, authentication was successful. // In addition, if ucEncrypt is TRUE the function: // ?computes the new session key (Ci+3) and a challenge, // ?sends the new session key and the challenge to the CryptoMemory?device, // ?If the new session key and the challenge are correctly related, encryption is activated. // uint8_t cm_ActiveSecurity(uint8_t ucKeySet, uint8_t * pucKey, uint8_t * pucRandom, uint8_t ucEncrypt) { uint8_t i; uint8_t ucAddrCi; uint8_t ucReturn; // Read Ci for selected key set ucAddrCi = CM_Ci + (ucKeySet<<4); // Ci blocks on 16 byte boundries if ((ucReturn = cm_ReadConfigZone(ucAddrCi, ucCM_Ci, 8)) != SUCCESS) { printf("---> cm_ActiveSecurity log1 ucReturn %d\n", ucReturn); return ucReturn; } // Try to activate authentication for (i = 0; i < 8; ++i) ucCM_G_Sk[i] = pucKey[i]; if ((ucReturn = cm_AuthenEncrypt(ucKeySet, ucAddrCi, ucCM_Ci, ucCM_G_Sk, pucRandom)) != SUCCESS) { printf("---> cm_ActiveSecurity log2 ucReturn %d\n", ucReturn); return ucReturn; } ucCM_Authenticate = TRUE; // If Encryption required, try to activate that too if (ucEncrypt) { if (pucRandom) pucRandom += 8; if ((ucReturn = cm_AuthenEncrypt(ucKeySet+0x10, ucAddrCi, ucCM_Ci, ucCM_G_Sk, pucRandom)) != SUCCESS) { printf("---> cm_ActiveSecurity log3 ucReturn %d\n", ucReturn); return ucReturn; } ucCM_Encrypt = TRUE; } // Done return SUCCESS; } // Common code for both activating authentication and encryption static uint8_t cm_AuthenEncrypt(uint8_t ucCmd1, uint8_t ucAddrCi, uint8_t * pucCi, uint8_t * pucG_Sk, uint8_t * pucRandom) { uint8_t i; uint8_t ucReturn; // Generate chalange data if (pucRandom) for (i = 0; i < 8; ++i) ucCM_Q_Ch[i] = pucRandom[i]; else CM_LOW_LEVEL.RandomGen(ucCM_Q_Ch); for (i = 0; i < 8; ++i) ucCM_Q_Ch[i] = pucRandom[i]; cm_AuthenEncryptCal(pucCi, pucG_Sk, ucCM_Q_Ch, &ucCM_Q_Ch[8]); // Send chalange ucCM_InsBuff[0] = 0xb8; ucCM_InsBuff[1] = ucCmd1; ucCM_InsBuff[2] = 0x00; ucCM_InsBuff[3] = 0x10; if ((ucReturn = cm_WriteCommand(ucCM_InsBuff, ucCM_Q_Ch, 16)) != SUCCESS) { printf("cm_AuthenEncrypt log1 ucReturn %d\n", ucReturn); return ucReturn; } // Give chips some clocks to do calculations CM_LOW_LEVEL.WaitClock(30); //3 // Verify result if ((ucReturn = cm_ReadConfigZone(ucAddrCi, ucCM_Ci2, 8)) != SUCCESS) { printf("cm_AuthenEncrypt log2 ucReturn %d\n", ucReturn); return ucReturn; } // for(i=0;i<8;i++) // { // printf("i=%d, %#x : %#x\n", i, pucCi[i], ucCM_Ci2[i]); // } for(i=0; i<8; i++) { if (pucCi[i]!=ucCM_Ci2[i]) { return FAILED; } } // Done return SUCCESS; }