//---------------------------------------------------------------------- // Write Data Page for DS1963S. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'pagenum' - page number to write to // 'data' - buffer to write into page // 'resume' - if true, device access is resumed using the RESUME // ROM command (0xA5). Otherwise, a a MATCH ROM is // used along with the device's entire address number. // // Return: TRUE - Write successfull // FALSE - error occurred during write. // SMALLINT WriteDataPageSHA18(int portnum, SMALLINT pagenum, uchar* data, SMALLINT resume) { uchar buffer[32]; int addr = pagenum << 5, addr_buff; uchar es = 0; OWASSERT( EraseScratchpadSHA18(portnum, addr, resume), OWERROR_ERASE_SCRATCHPAD_FAILED, FALSE ); OWASSERT( WriteScratchpadSHA18(portnum, addr, data, 32, TRUE), OWERROR_WRITE_SCRATCHPAD_FAILED, FALSE ); OWASSERT( ReadScratchpadSHA18(portnum, &addr_buff, &es, buffer, TRUE), OWERROR_READ_SCRATCHPAD_FAILED, FALSE ); // verify that what we read is exactly what we wrote OWASSERT( (addr == addr_buff) && (es == 0x1F) && (memcmp(buffer, data, 32)==0), OWERROR_READ_SCRATCHPAD_FAILED, FALSE ); OWASSERT( CopyScratchpadSHA18(portnum, addr, 32, TRUE), OWERROR_COPY_SCRATCHPAD_FAILED, FALSE ); return TRUE; }
//------------------------------------------------------------------------- // Creates a random challenge using the SHA engine of the given // coprocessor. // // 'copr' - Structure for holding coprocessor information. // 'pagenum' - pagenumber to use for calculation. // 'chlg' - 3-byte return buffer for challenge. // 'offset' - offset into resulting MAC to pull challenge data from. // // Return: TRUE - create challenge succeeded. // FALSE - an error occurred. // SMALLINT CreateChallenge(SHACopr* copr, SMALLINT pageNum, uchar* chlg, SMALLINT offset) { uchar scratchpad[32]; int addr = pageNum << 5; uchar es = 0x1F; int start = 8; if(offset>0 && offset<17) start += offset; //set the serial number owSerialNum(copr->portnum, copr->devAN, FALSE); OWASSERT( EraseScratchpadSHA18(copr->portnum, addr, FALSE), OWERROR_ERASE_SCRATCHPAD_FAILED, FALSE ); OWASSERT( SHAFunction18(copr->portnum, SHA_COMPUTE_CHALLENGE, addr, TRUE), OWERROR_SHA_FUNCTION_FAILED, FALSE ); OWASSERT( ReadScratchpadSHA18(copr->portnum, &addr, &es, scratchpad, TRUE), OWERROR_READ_SCRATCHPAD_FAILED, FALSE ); memcpy(chlg,&scratchpad[start],3); return TRUE; }
//------------------------------------------------------------------------- // Creates a data signature for the given data buffer using the hardware // coprocessor. // // 'copr' - Structure for holding coprocessor information. // 'data' - data written to the data page to sign // 'scratchpad' - data written to the scratchpad to sign // 'signature' - data buffer which is either holding the signature that // must match exactly what is generated on the coprocessor // -or- will hold the resulting signature created by the // coprocessor. // 'readSignature' - implies whether or not the signature buffer // receives the contents of the scratchpad or is used to // match the contents of the scratchpad. If true, // scratchpad contents are read into the signature buffer. // // Return: If TRUE, the user's authentication response matched exactly the // signature generated by the coprocessor or the signature was // successfully copied into the return buffer. // If FALSE, an error occurred or the signature did not match. // SMALLINT CreateDataSignature(SHACopr* copr, uchar* data, uchar* scratchpad, uchar* signature, SMALLINT readSignature) { int addr = copr->signPageNumber << 5; // set the serial number to that of the coprocessor owSerialNum(copr->portnum, copr->devAN, FALSE); OWASSERT( WriteDataPageSHA18(copr->portnum, copr->signPageNumber, data, FALSE), OWERROR_WRITE_DATA_PAGE_FAILED, FALSE ); OWASSERT( WriteScratchpadSHA18(copr->portnum, addr, scratchpad, 32, TRUE), OWERROR_WRITE_SCRATCHPAD_FAILED, FALSE ); OWASSERT( SHAFunction18(copr->portnum, SHA_SIGN_DATA_PAGE, addr, TRUE), OWERROR_SHA_FUNCTION_FAILED, FALSE ); if(readSignature) { OWASSERT( ReadScratchpadSHA18(copr->portnum, 0, 0, scratchpad, TRUE), OWERROR_READ_SCRATCHPAD_FAILED, FALSE ); } else { OWASSERT( MatchScratchpadSHA18(copr->portnum, signature, TRUE), OWERROR_MATCH_SCRATCHPAD_FAILED, FALSE ); } memcpy(signature, &scratchpad[8], 20); return TRUE; }
//---------------------------------------------------------------------- // Read Authenticated Page for DS1963S. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'pagenum' - page number to do a read authenticate // 'data' - buffer to read into from page // 'sign' - buffer for storing sha computation // 'resume' - if true, device access is resumed using the RESUME // ROM command (0xA5). Otherwise, a a MATCH ROM is // used along with the device's entire address number. // // Return: Value of write cycle counter for the page // -1 for error // int ReadAuthPageSHA18(int portnum, SMALLINT pagenum, uchar* data, uchar* sign, SMALLINT resume) { short send_cnt=0; uchar send_block[56]; short num_verf; SMALLINT i; ushort lastcrc16; int address = pagenum*32, wcc = -1; if(!resume) { // access the device OWASSERT( SelectSHA(portnum), OWERROR_ACCESS_FAILED, -1 ); } else { // transmit RESUME command send_block[send_cnt++] = ROM_CMD_RESUME; } //seed the crc setcrc16(portnum,0); // change number of verification bytes if in overdrive num_verf = (in_overdrive[portnum&0x0FF]) ? 10 : 2; // create the send block // Read Authenticated Page command send_block[send_cnt] = CMD_READ_AUTH_PAGE; lastcrc16 = docrc16(portnum, send_block[send_cnt++]); // TA1 send_block[send_cnt] = (uchar)(address & 0xFF); lastcrc16 = docrc16(portnum,send_block[send_cnt++]); // TA2 send_block[send_cnt] = (uchar)((address >> 8) & 0xFF); lastcrc16 = docrc16(portnum,send_block[send_cnt++]); // now add the read bytes for data bytes, counter, and crc16, verification //for (i = 0; i < (42 + num_verf); i++) // send_block[send_cnt++] = 0xFF; memset(&send_block[send_cnt], 0x0FF, 42+num_verf); send_cnt += 42+num_verf; // now send the block OWASSERT( owBlock(portnum,resume,send_block,send_cnt), OWERROR_BLOCK_FAILED, -1 ); //\\//\\//\\//\\//\\//\\//\\//\\//\\// #ifdef DEBUG_DUMP debugout(send_block,send_cnt); #endif //\\//\\//\\//\\//\\//\\//\\//\\//\\// // check the CRC for (i = resume?4:3; i < (send_cnt - num_verf); i++) lastcrc16 = docrc16(portnum,send_block[i]); // verify CRC16 is correct OWASSERT( lastcrc16==0xB001, OWERROR_CRC_FAILED, -1); // check verification OWASSERT( ((send_block[send_cnt-1] & 0xF0) == 0x50) || ((send_block[send_cnt-1] & 0xF0) == 0xA0), OWERROR_NO_COMPLETION_BYTE, -1); // transfer results //cnt = 0; //for (i = send_cnt - 42 - num_verf; i < (send_cnt - 10 - num_verf); i++) // data[cnt++] = send_block[i]; memcpy(data, &send_block[send_cnt-42-num_verf], 32); wcc = BytesToInt(&send_block[send_cnt-10-num_verf], 4); if(sign!=NULL) { OWASSERT( ReadScratchpadSHA18(portnum, 0, 0, send_block, TRUE), OWERROR_READ_SCRATCHPAD_FAILED, FALSE ); //for(i=0; i<20; i++) // sign[i] = send_block[i+8]; memcpy(sign, &send_block[8], 20); } return wcc; }