123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- // Encryption Functions
- //
- // Note: the naming conventions in this module do not match those used in all other modules. This
- // is because the name used in this module are intended to be as close to those used in the
- // Atmel documentation to make verification of these functions simpler.
- #include "CM_GPA.h"
- #include <stdint.h>
- // -------------------------------------------------------------------------------------------------
- // Data
- // -------------------------------------------------------------------------------------------------
- uint8_t ucGpaRegisters[Gpa_Regs];
- // -------------------------------------------------------------------------------------------------
- // Functions
- // -------------------------------------------------------------------------------------------------
- // Reset the cryptographic state
- void cm_ResetCrypto(void)
- {
- uint8_t i;
-
- for (i = 0; i < Gpa_Regs; ++i) ucGpaRegisters[i] = 0;
- ucCM_Encrypt = ucCM_Authenticate = FALSE;
- }
- // Generate next value
- uint8_t cm_GPAGen(uint8_t Datain)
- {
- uint8_t Din_gpa;
- uint8_t Ri, Si, Ti;
- uint8_t R_sum, S_sum, T_sum;
-
- // Input Character
- Din_gpa = Datain^Gpa_byte;
- Ri = Din_gpa&0x1f; //Ri[4:0] = Din_gpa[4:0]
- Si = ((Din_gpa<<3)&0x78)|((Din_gpa>>5)&0x07); //Si[6:0] = {Din_gpa[3:0], Din_gpa[7:5]}
- Ti = (Din_gpa>>3)&0x1f; //Ti[4:0] = Din_gpa[7:3];
-
- //R polynomial
- R_sum = cm_Mod(RD, cm_RotR(RG), CM_MOD_R);
- RG = RF;
- RF = RE;
- RE = RD;
- RD = RC^Ri;
- RC = RB;
- RB = RA;
- RA = R_sum;
-
- //S ploynomial
- S_sum = cm_Mod(SF, cm_RotS(SG), CM_MOD_S);
- SG = SF;
- SF = SE^Si;
- SE = SD;
- SD = SC;
- SC = SB;
- SB = SA;
- SA = S_sum;
-
- //T polynomial
- T_sum = cm_Mod(TE,TC,CM_MOD_T);
- TE = TD;
- TD = TC;
- TC = TB^Ti;
- TB = TA;
- TA = T_sum;
- // Output Stage
- Gpa_byte =(Gpa_byte<<4)&0xF0; // shift gpa_byte left by 4
- Gpa_byte |= ((((RA^RE)&0x1F)&(~SA))|(((TA^TD)&0x1F)&SA))&0x0F; // concat 4 prev bits and 4 new bits
- return Gpa_byte;
- }
- // Do authenticate/encrypt chalange encryption
- void cm_AuthenEncryptCal(uint8_t *Ci, uint8_t *G_Sk, uint8_t *Q, uint8_t *Ch)
- {
- uint8_t i, j;
-
- // Reset all registers
- cm_ResetCrypto();//by jgw must attention this : its will infect ucCM_Authenticate and ucCM_Encrypt
-
- // Setup the cyptographic registers
- for(j = 0; j < 4; j++) {
- for(i = 0; i<3; i++) cm_GPAGen(Ci[2*j]);
- for(i = 0; i<3; i++) cm_GPAGen(Ci[2*j+1]);
- cm_GPAGen(Q[j]);
- }
-
- for(j = 0; j<4; j++ ) {
- for(i = 0; i<3; i++) cm_GPAGen(G_Sk[2*j]);
- for(i = 0; i<3; i++) cm_GPAGen(G_Sk[2*j+1]);
- cm_GPAGen(Q[j+4]);
- }
-
- // begin to generate Ch
- cm_GPAGenN(6); // 6 0x00s
- Ch[0] = Gpa_byte;
- for (j = 1; j<8; j++) {
- cm_GPAGenN(7); // 7 0x00s
- Ch[j] = Gpa_byte;
- }
-
- // then calculate new Ci and Sk, to compare with the new Ci and Sk read from eeprom
- Ci[0] = 0xff; // reset AAC
- for(j = 1; j<8; j++) {
- cm_GPAGenN(2); // 2 0x00s
- Ci[j] = Gpa_byte;
- }
- for(j = 0; j<8; j++) {
- cm_GPAGenN(2); // 2 0x00s
- G_Sk[j] = Gpa_byte;
- }
-
- cm_GPAGenN(3); // 3 0x00s
- }
- // Calaculate Checksum
- void cm_CalChecksum(uint8_t *Ck_sum)
- {
- cm_GPAGenN(15); // 15 0x00s
- Ck_sum[0] = Gpa_byte;
- cm_GPAGenN(5); // 5 0x00s
- Ck_sum[1] = Gpa_byte;
- }
- // The following functions are "macros" for commonly done actions
- // Clock some zeros into the state machine
- void cm_GPAGenN(uint8_t Count)
- {
- while(Count--) cm_GPAGen(0x00);
- }
- // Clock some zeros into the state machine, then clock in a byte of data
- void cm_GPAGenNF(uint8_t Count, uint8_t DataIn)
- {
- cm_GPAGenN(Count); // First ones are allways zeros
- cm_GPAGen(DataIn); // Final one is sometimes different
- }
- // Include 2 bytes of a command into a polynominal
- void cm_GPAcmd2(uint8_t * pucInsBuff)
- {
- cm_GPAGenNF(5, pucInsBuff[2]);
- cm_GPAGenNF(5, pucInsBuff[3]);
- }
-
- // Include 3 bytes of a command into a polynominal
- void cm_GPAcmd3(uint8_t * pucInsBuff)
- {
- cm_GPAGenNF(5, pucInsBuff[1]);
- cm_GPAcmd2(pucInsBuff);
- }
-
- // Include the data in the polynominals and decrypt it required
- void cm_GPAdecrypt(uint8_t ucEncrypt, uint8_t * pucBuffer, uint8_t ucCount)
- {
- uint8_t i;
-
- for (i = 0; i < ucCount; ++i) {
- if (ucEncrypt) pucBuffer[i] = pucBuffer[i]^Gpa_byte;
- cm_GPAGen(pucBuffer[i]);
- cm_GPAGenN(5); // 5 clocks with 0x00 data
- }
- }
- // Include the data in the polynominals and encrypt it required
- void cm_GPAencrypt(uint8_t ucEncrypt, uint8_t * pucBuffer, uint8_t ucCount)
- {
- uint8_t i, ucData;
- for (i = 0; i<ucCount; i++) {
- cm_GPAGenN(5); // 5 0x00s
- ucData = pucBuffer[i];
- if (ucEncrypt) pucBuffer[i] = pucBuffer[i]^Gpa_byte;
- cm_GPAGen(ucData);
- }
- }
|