#include #define CM_LIB_GLOBALES #define EXTERNMACRO 2 #include "CM_LIB.h" #include "CM_I2C.h" #include "CM_I2C_L.h" #include #include uint8_t ucData[16], ucCi[8], ucSk[8]; // Zone Data uint8_t ucCM_UserZone; uint8_t ucCM_AntiTearing; // Chip state uint8_t ucCM_Encrypt; uint8_t ucCM_Authenticate; // Global data uint8_t ucCM_InsBuff[4]; uint8_t authenticationModeFlag = 0; uint8_t passwordModeFlag = 0; uint8_t encryptModeFlag = 0; uint8_t errorGlobalFlag = 0; //default : four user zone use Secret Seed G1 and password write/read 1(all use set 1) //Secret Seed : it's used by cm_ActiveSecurity uint8_t ucG[8] = {0x22,0x23,0x34,0x45,0x56,0x67,0x78,0x89}; //passworkd for write : it's used by cm_VerifyPassword uint8_t psword_w[3] = {0x22,0x34,0x56}; //passworkd for read : it's used by cm_VerifyPassword uint8_t psword_r[3] = {0x88,0x9a,0xbc}; uint8_t psword_7[3] = {0xDD, 0x77, 0x99}; uint8_t cm_Auth_Encrp_Personal(uint8_t pswMode,uint8_t authMode) { uint8_t ucReturn; uint8_t pwData[8] = {0}; uint8_t seedData[8] = {0}; uint8_t fab_id = 0x06; uint8_t cma_id = 0x04; uint8_t per_id = 0x00; uint8_t fuseData; int i; uint8_t configAll[240] = {0}; printf("---> cm_Auth_Encrp_Personal start...\n"); //read fuse cm_ReadFuse(&fuseData); if (ucReturn != SUCCESS) { printf("cm_ReadFuse is error\n"); errorGlobalFlag = 12; } if(fuseData == 0x00) { printf("FAB,CMA,PER------three fuse has burnned! Exit cm_Auth_Encrp_Personal!\n"); return 0; } printf("---> fuseData %#x\n", fuseData); uint8_t pwwr7[3] = {0xDD, 0x42, 0x97}; ucReturn = cm_VerifySecureCode(pwwr7); if (ucReturn != SUCCESS) { ucReturn = cm_VerifySecureCode(psword_7); if (ucReturn != SUCCESS) { printf("cm_VerifySecureCode 1 is error\n"); errorGlobalFlag = 15; /************ Read all configs *******************/ memset(configAll, 0, 240); ucReturn = cm_ReadConfigZone(0x00,configAll,240); if (ucReturn != SUCCESS) { printf("cm_ReadConfigZone all is error\n"); errorGlobalFlag = 13; } else { printf("======== Configure Memory ========="); for(i=0;i<240;i++) { if(i%8 == 0) printf("\n%04x: ", i); printf("%02X ", configAll[i]); } printf("\n"); } return -1; } printf("---> used psword_7: %#x %#x %#x\n", psword_7[0], psword_7[1], psword_7[2]); } // ----------------------------------------------write card mfg code 0x50 30 30 31 usleep(100); uint8_t cmc[4] = {0x50,0x30,0x30,0x31}; ucReturn = cm_WriteConfigZone(0x0C, cmc, 4, FALSE); if (ucReturn != SUCCESS) { printf("cm_WriteConfigZone 0x0C is error\n"); errorGlobalFlag = 2; return -1; } // ----------------------------------------------Write Identification Number = 00000000012345 usleep(100); uint8_t idnum[7] = {0x00,0x00,0x00,0x00,0x01,0x23,0x45}; ucReturn = cm_WriteConfigZone(0x19, idnum, 7, FALSE); if (ucReturn != SUCCESS) { printf("cm_WriteConfigZone 0x19 is error\n"); errorGlobalFlag = 3; return -1; } // ----------------------------------------------Write Issuer Code = STATION 035 usleep(100); uint8_t issue[16] = {0x53,0x54,0x41,0x54,0x49,0x4F,0x4E,0x20,0x30,0x33,0x35,0x00,0x00,0x00,0x00,0x00}; ucReturn = cm_WriteConfigZone(0x40, issue, 16, FALSE); if (ucReturn != SUCCESS) { printf("cm_WriteConfigZone 0x40 is error\n"); errorGlobalFlag = 4; return -1; } //---------------------------------------------config all user zone use the same password/seed of the set 1 // ---------------------------------------------Write Control for user zone 0 usleep(100); ucData[0] = ((pswMode & 0x03) << 6) | ((authMode & 0x3) << 4) | 0x07; // AR[0-3] = 0101 0111 ----> //01 ----> after Authentication successful ,then write correct password //01 ----> the read and write need to Authentication //1 ----> the host access(read/write) user zone use encryption mode(set 0 lead to unlock config zone error,i dont know why?) //111----> the default data ucData[1] = 0x51;//Authentication set 1, POM set 1, Key 1 //PR[0-3] = 0101 0001 //01 ----> the secret seed select set 1(secret seed zone) //01 ----> the POK select set 1(secret seed zone) //0001 ----> the password select set 1(password zone) ucReturn = cm_WriteConfigZone(0x20, ucData, 2, FALSE); if (ucReturn != SUCCESS) { printf("cm_WriteConfigZone 0x20 is error\n"); errorGlobalFlag = 5; return -1; } // ---------------------------------------------Write Control for user zone 1 usleep(100); ucReturn = cm_WriteConfigZone(0x22, ucData, 2, FALSE); if (ucReturn != SUCCESS) { printf("cm_WriteConfigZone 0x22 is error\n"); errorGlobalFlag = 6; return -1; } // ---------------------------------------------Write Control for user zone 2 usleep(100); ucReturn = cm_WriteConfigZone(0x24, ucData, 2, FALSE); if (ucReturn != SUCCESS) { printf("cm_WriteConfigZone 0x24 is error\n"); errorGlobalFlag = 7; return -1; } // ---------------------------------------------Write Control for user zone 3 usleep(100); ucReturn = cm_WriteConfigZone(0x26, ucData, 2, FALSE); if (ucReturn != SUCCESS) { printf("cm_WriteConfigZone 0x26 is error\n"); errorGlobalFlag = 8; return -1; } //----------------------------------------------Set DCR to allow unlimited checksum reads usleep(100); ucData[0] = 0xff;//after finish personal chip , must recover to the default // ucData[0] = 0xbf;//set unlimited checksum reads, Unlimited Authentication Trials,Eight Trials Allowed during debug for avoid the chip lock dead (why config 0x8f is error) ucReturn = cm_WriteConfigZone(0x18, ucData, 1, FALSE); if (ucReturn != SUCCESS) { printf("cm_WriteConfigZone 0x18 is error\n"); errorGlobalFlag = 9; return -1; } //---------------------------------------------- Write Ci1 usleep(100); ucCi[0] = 0xFF; ucCi[1] = 0x01; ucCi[2] = 0x02; ucCi[3] = 0x03; ucCi[4] = 0x04; ucCi[5] = 0x05; ucCi[6] = 0x06; ucCi[7] = 0x07; ucReturn = cm_WriteConfigZone(0x60, ucCi, 8, FALSE); if (ucReturn != SUCCESS) { printf("cm_WriteConfigZone 0x60 is error\n"); errorGlobalFlag = 10; return -1; } // ------------------------------------------------Write G1 usleep(100); // user must set and remember this secret for Secret Seed,then must be same whih cm_Auth_Encrp_rw before access to user zone for write or read . seedData[0] = ucG[0]; seedData[1] = ucG[1]; seedData[2] = ucG[2]; seedData[3] = ucG[3]; seedData[4] = ucG[4]; seedData[5] = ucG[5]; seedData[6] = ucG[6]; seedData[7] = ucG[7]; ucReturn = cm_WriteConfigZone(0x98, seedData, 8, FALSE); if (ucReturn != SUCCESS) { printf("cm_WriteConfigZone 0x98 is error\n"); errorGlobalFlag = 11; return -1; } //--------------------------------------------- Write PSW1 (both Write and Read) usleep(100); // user must set and remember this secret for password for write/read.then must be same whih cm_Auth_Encrp_rw before access to user zone for write or read . pwData[0] = 0xFF; pwData[1] = psword_w[0]; pwData[2] = psword_w[1]; pwData[3] = psword_w[2]; pwData[4] = 0xFF; pwData[5] = psword_r[0]; pwData[6] = psword_r[1]; pwData[7] = psword_r[2]; ucReturn = cm_WriteConfigZone(0xB8, pwData, 8, FALSE); if (ucReturn != SUCCESS) { printf("cm_WriteConfigZone 0xB8 is error\n"); errorGlobalFlag = 12; return -1; } //--------------------------------------------- Write PSW7 (only Write) usleep(100); pwData[0] = 0xFF; pwData[1] = psword_7[0]; pwData[2] = psword_7[1]; pwData[3] = psword_7[2]; ucReturn = cm_WriteConfigZone(0xE8, pwData, 4, FALSE); if (ucReturn != SUCCESS) { printf("cm_WriteConfigZone 0xE8 is error\n"); errorGlobalFlag = 13; return -1; } #if 1 usleep(1000); ucReturn = cm_BurnFuse(fab_id); if (ucReturn != SUCCESS) { printf("cm_BurnFuse fab_id is error\n"); errorGlobalFlag = 12; } usleep(1000); ucReturn = cm_BurnFuse(cma_id); if (ucReturn != SUCCESS) { printf("cm_BurnFuse cma_id is error\n"); errorGlobalFlag = 12; } usleep(1000); ucReturn = cm_BurnFuse(per_id); if (ucReturn != SUCCESS) { printf("cm_BurnFuse per_id is error\n"); errorGlobalFlag = 12; } #endif usleep(1000); //read fuse cm_ReadFuse(&fuseData); if (ucReturn != SUCCESS) { printf("cm_ReadFuse is error\n"); errorGlobalFlag = 12; } if(fuseData == 0x00) { printf("FAB,CMA,PER------three fuse are burnned successful\n"); } /************ Read all configs *******************/ memset(configAll, 0, 240); ucReturn = cm_ReadConfigZone(0x00,configAll,240); if (ucReturn != SUCCESS) { printf("cm_ReadConfigZone all is error\n"); errorGlobalFlag = 13; } else { printf("======== Configure Memory ========="); for(i=0;i<240;i++) { if(i%8 == 0) printf("\n%04x: ", i); printf("%02X ", configAll[i]); } printf("\n"); } if(errorGlobalFlag != 0) return FAILED; printf("---> cm_Auth_Encrp_Personal successful!\n"); return SUCCESS; } /* *FUNC: To init the chip of AT88SCxxx * *PARAM: * authMode : * 3 : close Authentication mode; * 2 : write Authentication mode; * 1 : normal Authentication mode; * 0 : dual access mode; * * pswMode : * 3 : close password mode; * 2 : write password mode; * 0/1 : read and write password mode; * * encryptFlag : * TRUE : enable encrypt mode * FALSE : disable encrypt mode * */ uint8_t cm_Auth_Encrp_Init(uint8_t authMode,uint8_t pswMode,uint8_t encryptFlag) { uint8_t ucReturn; uint8_t fuseData; int i; uint8_t ucData[4] = {0}; uint8_t configAll[240] = {0}; #if 0 //init I2C pin GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; stm32_gpio_init(GPIOE, &GPIO_InitStruct); #endif if(pswMode == 0x0 || pswMode == 0x1) passwordModeFlag = 1; else if(pswMode == 0x2) passwordModeFlag = 2; else passwordModeFlag = 0; if(authMode == 0) authenticationModeFlag = 0; else if(authMode == 1) authenticationModeFlag = 1; else if(authMode == 2) authenticationModeFlag = 2; else if(authMode == 3) authenticationModeFlag = 3; if(encryptFlag == TRUE) encryptModeFlag = 1; else encryptModeFlag = 0; cm_PowerOn(); /**************** Check AT88SC0104C Present******************/ ucData[0] = 0x5A; ucData[1] = 0xA5; ucReturn = cm_WriteConfigZone(0x0A, ucData, 2, FALSE); if (ucReturn != SUCCESS) { printf("cm_WriteConfigZone 0x0a is error\n"); errorGlobalFlag = 1; } usleep(100); //这个延时很重要,AT88SC0104C处理数据相当的慢。 // Read back data ucData[0] = 0x00; ucData[1] = 0x00; ucReturn = cm_ReadConfigZone(0x0A, ucData, 2); if (ucReturn != SUCCESS) { printf("cm_ReadConfigZone 0x0a is error\n"); errorGlobalFlag = 1; } if ((ucData[0]!= 0x5A) || (ucData[1]!= 0xA5) ) { printf("read back data is not same\n"); errorGlobalFlag = 1; } if(errorGlobalFlag != 0) { printf("there is a error and the flag = %d,the poweroff\n",errorGlobalFlag); cm_PowerOff(); return FAILED; } return ucReturn; } /* *cm_WR: * 0 : read * 1 : write *userZone: * select need to access the index of user zone in range of 0-3 *startInZone: * the start location in user zone for user operation of write/read,and the default data is 0 *pData: * the data buffer for store the write/read data *dataLen: * the byte number of write/read * */ uint8_t cm_Auth_Encrp_rw(uint8_t cm_WR,uint8_t userZone,uint8_t startInZone,uint8_t *pData,uint8_t dataLen) { uint8_t ucReturn; int i; uint8_t userZoneTemp = userZone & 0x03; uint8_t seedSet = 1;//which set of Secret Seed uint8_t pwset = 1;//which set of password for write/read //if(authenticationModeFlag == 0 || authenticationModeFlag == 1 || authenticationModeFlag == 2 || authenticationModeFlag == 3)//all to authenticate { if(encryptModeFlag == 1) { ucReturn = cm_ActiveSecurity(seedSet, ucG, NULL, TRUE); } else { ucReturn = cm_ActiveSecurity(seedSet, ucG, NULL, FALSE); } } if (ucReturn != SUCCESS) { printf("cm_ActiveSecurity is error\n"); return FAILED; } ucReturn = cm_SetUserZone(userZoneTemp, FALSE); if (ucReturn != SUCCESS) { printf("cm_SetUserZone is error\n"); return FAILED; } if(passwordModeFlag == 3) { if(cm_WR==0) { // Read back data for (i = 0; i < dataLen; ++i) pData[i] = 0x00; //clear pData ucReturn = cm_ReadSmallZone(startInZone, pData, dataLen); if (ucReturn != SUCCESS) { printf("cm_ReadSmallZone is error\n"); return FAILED; } } else { // Write data to user zone ucReturn = cm_WriteSmallZone(startInZone, pData, dataLen); if (ucReturn != SUCCESS) { printf("cm_WriteSmallZone is error\n"); return FAILED; } // Send checksum ucReturn = cm_SendChecksum(NULL); if (ucReturn != SUCCESS) { printf("cm_SendChecksum is error\n"); return FAILED; } } } else //(passwordModeFlag == 1 || passwordModeFlag == 2) { ucCM_Authenticate = TRUE; if(cm_WR==0) { // Read back data, firstly verify the read password ucReturn=cm_VerifyPassword(psword_r,pwset,CM_PWREAD); if (ucReturn != SUCCESS) { printf("cm_VerifyPassword is error\n"); return FAILED; } for (i = 0; i < dataLen; ++i) pData[i] = 0x00; //clear pData ucReturn = cm_ReadSmallZone(startInZone, pData, dataLen); if (ucReturn != SUCCESS) { printf("cm_ReadSmallZone is error\n"); return FAILED; } ucReturn =cm_ReadChecksum(NULL); if (ucReturn != SUCCESS) { printf("cm_ReadChecksum is error\n"); return FAILED; } } else { // Write data to user zone,firstly verify the write password ucReturn=cm_VerifyPassword(psword_w,pwset,CM_PWWRITE); if (ucReturn != SUCCESS) { printf("cm_VerifyPassword is error\n"); return FAILED; } ucReturn = cm_WriteSmallZone(startInZone, pData, dataLen); if (ucReturn != SUCCESS) { printf("cm_WriteSmallZone is error\n"); return FAILED; } // Send checksum ucReturn = cm_SendChecksum(NULL); if (ucReturn != SUCCESS) { printf("cm_SendChecksum is error\n"); return FAILED; } } } ucReturn = cm_DeactiveSecurity(); if (ucReturn != SUCCESS) { printf("cm_DeactiveSecurity is error\n"); return FAILED; } return SUCCESS; } uint8_t cm_Auth_Encrp_Read(uint8_t userZone,uint8_t startInZone,uint8_t* readData,uint8_t readLen) { uint8_t returnData = 0; returnData = cm_Auth_Encrp_rw(0,userZone,startInZone,readData,readLen); if(returnData != SUCCESS) return FAILED; else return SUCCESS; } uint8_t cm_Auth_Encrp_Write(uint8_t userZone,uint8_t startInZone,uint8_t* writeData,uint8_t writeLen) { uint8_t returnData = 0; returnData = cm_Auth_Encrp_rw(1,userZone,startInZone,writeData,writeLen); if(returnData != SUCCESS) return FAILED; else return SUCCESS; } uint8_t test_cryptomem(void) { uint8_t readData[16] = {0}; uint8_t readLen = 16; uint8_t writeData[16] = {0}; uint8_t writeLen = 16; uint8_t i; uint8_t returnData; uint8_t userZone = 1;//user need to access the index of user zone uint8_t startInZone = 0;//the start location of x user zone for write/read // returnData = cm_Auth_Encrp_Init(1,1,TRUE); // if(returnData != SUCCESS) // { // printf("cm_Auth_Encrp_Init is error\n"); // return FAILED; // } // printf("Write: \n"); for(i=0;i