123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- // Activate Security
- //
- // CryptoMemory Library Include Files
- #include "CM_LIB.h"
- #include "CM_I2C.h"
- #include "CM_I2C_L.h"
- #include "CM_GPA.h"
- #include <stdio.h>
- // 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;
- }
|