CM_SECURE.c 3.9 KB

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