CM_SECURE.c 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. // Activate Security
  2. //
  3. // CryptoMemory Library Include Files
  4. #include "CM_LIB.h"
  5. #include "CM_I2C.h"
  6. #include "CM_I2C_L.h"
  7. #include "CM_GPA.h"
  8. // Local function prototypes
  9. static uint8_t cm_AuthenEncrypt(uint8_t ucCmd1, uint8_t ucAddrCi, uint8_t * pucCi, uint8_t * pucG_Sk, uint8_t * pucRandom);
  10. // Global Data
  11. uint8_t ucCM_Ci[8], ucCM_G_Sk[8];
  12. uint8_t ucCM_Q_Ch[16], ucCM_Ci2[8];
  13. // Activate Security
  14. //
  15. // When called the function:
  16. // ?reads the current cryptogram (Ci) of the key set,
  17. // ?computes the next cryptogram (Ci+1) based on the secret key pucKey (GCi) and the random number selected,
  18. // ?sends the (Ci+1) and the random number to the CryptoMemory?device,
  19. // ?computes (Ci+2) and compares its computed value the new cryptogram of the key set.
  20. // ?If (Ci+2) matches the new cryptogram of the key set, authentication was successful.
  21. // In addition, if ucEncrypt is TRUE the function:
  22. // ?computes the new session key (Ci+3) and a challenge,
  23. // ?sends the new session key and the challenge to the CryptoMemory?device,
  24. // ?If the new session key and the challenge are correctly related, encryption is activated.
  25. //
  26. uint8_t cm_ActiveSecurity(uint8_t ucKeySet, uint8_t * pucKey, uint8_t * pucRandom, uint8_t ucEncrypt)
  27. {
  28. uint8_t i;
  29. uint8_t ucAddrCi;
  30. uint8_t ucReturn;
  31. // Read Ci for selected key set
  32. ucAddrCi = CM_Ci + (ucKeySet<<4); // Ci blocks on 16 byte boundries
  33. if ((ucReturn = cm_ReadConfigZone(ucAddrCi, ucCM_Ci, 8)) != SUCCESS)
  34. return ucReturn;
  35. // Try to activate authentication
  36. for (i = 0; i < 8; ++i) ucCM_G_Sk[i] = pucKey[i];
  37. { if ((ucReturn = cm_AuthenEncrypt(ucKeySet, ucAddrCi, ucCM_Ci, ucCM_G_Sk, pucRandom)) != SUCCESS)
  38. return ucReturn;
  39. }
  40. ucCM_Authenticate = TRUE;
  41. // If Encryption required, try to activate that too
  42. if (ucEncrypt) {
  43. if (pucRandom) pucRandom += 8;
  44. if ((ucReturn = cm_AuthenEncrypt(ucKeySet+0x10, ucAddrCi, ucCM_Ci, ucCM_G_Sk, pucRandom)) != SUCCESS)
  45. return ucReturn;
  46. ucCM_Encrypt = TRUE;
  47. }
  48. // Done
  49. return SUCCESS;
  50. }
  51. // Common code for both activating authentication and encryption
  52. static uint8_t cm_AuthenEncrypt(uint8_t ucCmd1, uint8_t ucAddrCi, uint8_t * pucCi, uint8_t * pucG_Sk, uint8_t * pucRandom)
  53. {
  54. uint8_t i;
  55. uint8_t ucReturn;
  56. // Generate chalange data
  57. if (pucRandom)
  58. for (i = 0; i < 8; ++i) ucCM_Q_Ch[i] = pucRandom[i];
  59. else
  60. CM_LOW_LEVEL.RandomGen(ucCM_Q_Ch);
  61. for (i = 0; i < 8; ++i)
  62. ucCM_Q_Ch[i] = pucRandom[i];
  63. cm_AuthenEncryptCal(pucCi, pucG_Sk, ucCM_Q_Ch, &ucCM_Q_Ch[8]);
  64. // Send chalange
  65. ucCM_InsBuff[0] = 0xb8;
  66. ucCM_InsBuff[1] = ucCmd1;
  67. ucCM_InsBuff[2] = 0x00;
  68. ucCM_InsBuff[3] = 0x10;
  69. if ((ucReturn = cm_WriteCommand(ucCM_InsBuff, ucCM_Q_Ch, 16)) != SUCCESS)
  70. return ucReturn;
  71. // Give chips some clocks to do calculations
  72. CM_LOW_LEVEL.WaitClock(3);
  73. // Verify result
  74. if ((ucReturn = cm_ReadConfigZone(ucAddrCi, ucCM_Ci2, 8)) != SUCCESS)
  75. return ucReturn;
  76. for(i=0; i<8; i++) if (pucCi[i]!=ucCM_Ci2[i])
  77. return FAILED;
  78. // Done
  79. return SUCCESS;
  80. }