// 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 // ------------------------------------------------------------------------------------------------- // 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