CM_GPA.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. // Encryption Functions
  2. //
  3. // Note: the naming conventions in this module do not match those used in all other modules. This
  4. // is because the name used in this module are intended to be as close to those used in the
  5. // Atmel documentation to make verification of these functions simpler.
  6. #include "CM_GPA.h"
  7. #include <stdint.h>
  8. // -------------------------------------------------------------------------------------------------
  9. // Data
  10. // -------------------------------------------------------------------------------------------------
  11. uint8_t ucGpaRegisters[Gpa_Regs];
  12. // -------------------------------------------------------------------------------------------------
  13. // Functions
  14. // -------------------------------------------------------------------------------------------------
  15. // Reset the cryptographic state
  16. void cm_ResetCrypto(void)
  17. {
  18. uint8_t i;
  19. for (i = 0; i < Gpa_Regs; ++i) ucGpaRegisters[i] = 0;
  20. ucCM_Encrypt = ucCM_Authenticate = FALSE;
  21. }
  22. // Generate next value
  23. uint8_t cm_GPAGen(uint8_t Datain)
  24. {
  25. uint8_t Din_gpa;
  26. uint8_t Ri, Si, Ti;
  27. uint8_t R_sum, S_sum, T_sum;
  28. // Input Character
  29. Din_gpa = Datain^Gpa_byte;
  30. Ri = Din_gpa&0x1f; //Ri[4:0] = Din_gpa[4:0]
  31. Si = ((Din_gpa<<3)&0x78)|((Din_gpa>>5)&0x07); //Si[6:0] = {Din_gpa[3:0], Din_gpa[7:5]}
  32. Ti = (Din_gpa>>3)&0x1f; //Ti[4:0] = Din_gpa[7:3];
  33. //R polynomial
  34. R_sum = cm_Mod(RD, cm_RotR(RG), CM_MOD_R);
  35. RG = RF;
  36. RF = RE;
  37. RE = RD;
  38. RD = RC^Ri;
  39. RC = RB;
  40. RB = RA;
  41. RA = R_sum;
  42. //S ploynomial
  43. S_sum = cm_Mod(SF, cm_RotS(SG), CM_MOD_S);
  44. SG = SF;
  45. SF = SE^Si;
  46. SE = SD;
  47. SD = SC;
  48. SC = SB;
  49. SB = SA;
  50. SA = S_sum;
  51. //T polynomial
  52. T_sum = cm_Mod(TE,TC,CM_MOD_T);
  53. TE = TD;
  54. TD = TC;
  55. TC = TB^Ti;
  56. TB = TA;
  57. TA = T_sum;
  58. // Output Stage
  59. Gpa_byte =(Gpa_byte<<4)&0xF0; // shift gpa_byte left by 4
  60. Gpa_byte |= ((((RA^RE)&0x1F)&(~SA))|(((TA^TD)&0x1F)&SA))&0x0F; // concat 4 prev bits and 4 new bits
  61. return Gpa_byte;
  62. }
  63. // Do authenticate/encrypt chalange encryption
  64. void cm_AuthenEncryptCal(uint8_t *Ci, uint8_t *G_Sk, uint8_t *Q, uint8_t *Ch)
  65. {
  66. uint8_t i, j;
  67. // Reset all registers
  68. cm_ResetCrypto();//by jgw must attention this : its will infect ucCM_Authenticate and ucCM_Encrypt
  69. // Setup the cyptographic registers
  70. for(j = 0; j < 4; j++) {
  71. for(i = 0; i<3; i++) cm_GPAGen(Ci[2*j]);
  72. for(i = 0; i<3; i++) cm_GPAGen(Ci[2*j+1]);
  73. cm_GPAGen(Q[j]);
  74. }
  75. for(j = 0; j<4; j++ ) {
  76. for(i = 0; i<3; i++) cm_GPAGen(G_Sk[2*j]);
  77. for(i = 0; i<3; i++) cm_GPAGen(G_Sk[2*j+1]);
  78. cm_GPAGen(Q[j+4]);
  79. }
  80. // begin to generate Ch
  81. cm_GPAGenN(6); // 6 0x00s
  82. Ch[0] = Gpa_byte;
  83. for (j = 1; j<8; j++) {
  84. cm_GPAGenN(7); // 7 0x00s
  85. Ch[j] = Gpa_byte;
  86. }
  87. // then calculate new Ci and Sk, to compare with the new Ci and Sk read from eeprom
  88. Ci[0] = 0xff; // reset AAC
  89. for(j = 1; j<8; j++) {
  90. cm_GPAGenN(2); // 2 0x00s
  91. Ci[j] = Gpa_byte;
  92. }
  93. for(j = 0; j<8; j++) {
  94. cm_GPAGenN(2); // 2 0x00s
  95. G_Sk[j] = Gpa_byte;
  96. }
  97. cm_GPAGenN(3); // 3 0x00s
  98. }
  99. // Calaculate Checksum
  100. void cm_CalChecksum(uint8_t *Ck_sum)
  101. {
  102. cm_GPAGenN(15); // 15 0x00s
  103. Ck_sum[0] = Gpa_byte;
  104. cm_GPAGenN(5); // 5 0x00s
  105. Ck_sum[1] = Gpa_byte;
  106. }
  107. // The following functions are "macros" for commonly done actions
  108. // Clock some zeros into the state machine
  109. void cm_GPAGenN(uint8_t Count)
  110. {
  111. while(Count--) cm_GPAGen(0x00);
  112. }
  113. // Clock some zeros into the state machine, then clock in a byte of data
  114. void cm_GPAGenNF(uint8_t Count, uint8_t DataIn)
  115. {
  116. cm_GPAGenN(Count); // First ones are allways zeros
  117. cm_GPAGen(DataIn); // Final one is sometimes different
  118. }
  119. // Include 2 bytes of a command into a polynominal
  120. void cm_GPAcmd2(uint8_t * pucInsBuff)
  121. {
  122. cm_GPAGenNF(5, pucInsBuff[2]);
  123. cm_GPAGenNF(5, pucInsBuff[3]);
  124. }
  125. // Include 3 bytes of a command into a polynominal
  126. void cm_GPAcmd3(uint8_t * pucInsBuff)
  127. {
  128. cm_GPAGenNF(5, pucInsBuff[1]);
  129. cm_GPAcmd2(pucInsBuff);
  130. }
  131. // Include the data in the polynominals and decrypt it required
  132. void cm_GPAdecrypt(uint8_t ucEncrypt, uint8_t * pucBuffer, uint8_t ucCount)
  133. {
  134. uint8_t i;
  135. for (i = 0; i < ucCount; ++i) {
  136. if (ucEncrypt) pucBuffer[i] = pucBuffer[i]^Gpa_byte;
  137. cm_GPAGen(pucBuffer[i]);
  138. cm_GPAGenN(5); // 5 clocks with 0x00 data
  139. }
  140. }
  141. // Include the data in the polynominals and encrypt it required
  142. void cm_GPAencrypt(uint8_t ucEncrypt, uint8_t * pucBuffer, uint8_t ucCount)
  143. {
  144. uint8_t i, ucData;
  145. for (i = 0; i<ucCount; i++) {
  146. cm_GPAGenN(5); // 5 0x00s
  147. ucData = pucBuffer[i];
  148. if (ucEncrypt) pucBuffer[i] = pucBuffer[i]^Gpa_byte;
  149. cm_GPAGen(ucData);
  150. }
  151. }