1-Wire® library for mbed. Complete 1-Wire library that supports our silicon masters along with a bit-bang master on the MAX32600MBED platform with one common interface for mbed. Slave support has also been included and more slaves will be added as time permits.
Dependents: MAXREFDES131_Qt_Demo MAX32630FTHR_iButton_uSD_Logger MAX32630FTHR_DS18B20_uSD_Logger MAXREFDES130_131_Demo ... more
Superseded by MaximInterface.
Diff: OneWire_Memory/Authenticators/DS28E15_22_25/DS28E15_22_25.cpp
- Revision:
- 49:36954b62f503
- Parent:
- 34:11fffbe98ef9
- Child:
- 50:e967f9befbd0
--- a/OneWire_Memory/Authenticators/DS28E15_22_25/DS28E15_22_25.cpp Thu Apr 07 11:26:20 2016 -0500 +++ b/OneWire_Memory/Authenticators/DS28E15_22_25/DS28E15_22_25.cpp Fri Apr 08 16:11:16 2016 -0500 @@ -27,19 +27,20 @@ #include "OneWire_Masters/OneWireMaster.h" #include "mbed.h" -// 1-Wire commands -#define CMD_WRITE_MEMORY 0x55 -#define CMD_READ_MEMORY 0xF0 -#define CMD_LOAD_LOCK_SECRET 0x33 -#define CMD_COMPUTE_LOCK_SECRET 0x3C -#define CMD_SELECT_SECRET 0x0F -#define CMD_COMPUTE_PAGEMAC 0xA5 -#define CMD_READ_STATUS 0xAA -#define CMD_WRITE_BLOCK_PROTECT 0xC3 -#define CMD_WRITE_AUTH_MEMORY 0x5A -#define CMD_WRITE_AUTH_PROTECT 0xCC -#define CMD_PIO_READ 0xDD -#define CMD_PIO_WRITE 0x96 +/// 1-Wire device commands. +enum Command +{ + CMD_WRITE_MEMORY = 0x55, + CMD_READ_MEMORY = 0xF0, + CMD_LOAD_LOCK_SECRET = 0x33, + CMD_COMPUTE_LOCK_SECRET = 0x3C, + CMD_READ_WRITE_SCRATCHPAD = 0x0F, + CMD_COMPUTE_PAGEMAC = 0xA5, + CMD_READ_STATUS = 0xAA, + CMD_WRITE_BLOCK_PROTECT = 0xC3, + CMD_WRITE_AUTH_MEMORY = 0x5A, + CMD_WRITE_AUTH_PROTECT = 0xCC, +}; DS28E15_22_25::BlockProtection::BlockProtection(bool readProtection, bool writeProtection, bool eepromEmulation, bool authProtection, std::uint8_t blockNum) { @@ -151,19 +152,6 @@ return blocks; } -//-------------------------------------------------------------------------- -// Write page protection byte. -// -// Parameters -// block - block number (0 to 7) which covers two pages each -// new_value - new protection byte -// old_value - old protection byte -// manid - manufacturer ID -// contflag - Flag to indicate the write is continued from the last -// -// Returns: true - protection written -// false - Failed to set protection -// OneWireSlave::CmdResult DS28E15_22_25::writeAuthBlockProtection(const ISha256MacCoprocessor & MacCoproc, const BlockProtection & newProtection, const BlockProtection & oldProtection, bool contflag) { std::uint8_t buf[256], cs; @@ -171,7 +159,7 @@ Mac mac; buf[cnt++] = CMD_WRITE_AUTH_PROTECT; - buf[cnt++] = newProtection.status(); + buf[cnt++] = newProtection.statusByte(); // Send command m_OW_master.OWWriteBlock(&buf[0], 2); @@ -193,7 +181,7 @@ return CommunicationError; ISha256MacCoprocessor::CmdResult result; - result = calculateProtectionWriteMac(MacCoproc, newProtection, oldProtection, romId, manId, mac); + result = computeProtectionWriteMac(MacCoproc, newProtection, oldProtection, romId, manId, mac); if (result != ISha256MacCoprocessor::Success) return OperationFailure; cnt = 0; @@ -232,17 +220,6 @@ return OperationFailure; } -//-------------------------------------------------------------------------- -// Write page protection byte. -// -// Parameters -// block - block number (0 to 7) which covers two pages each -// prot - protection byte -// contflag - Flag to indicate the write is continued from the last -// -// Returns: true - protection written -// false - Failed to set protection -// OneWireSlave::CmdResult DS28E15_22_25::writeBlockProtection(const BlockProtection & protection, bool continuing) { std::uint8_t buf[256], cs; @@ -255,7 +232,7 @@ } // compute parameter byte - buf[cnt++] = protection.status(); + buf[cnt++] = protection.statusByte(); m_OW_master.OWWriteBlock(&buf[0], cnt); @@ -289,33 +266,15 @@ return OperationFailure; } - - - OneWireSlave::CmdResult DS28E15_22_25::readBlockProtection(unsigned int blockNum, BlockProtection & protection) { std::uint8_t buf; CmdResult result = readStatus(false, false, blockNum, &buf); if (result == Success) - protection.setStatus(buf); + protection.setStatusByte(buf); return result; } -//-------------------------------------------------------------------------- -// Read status bytes, either personality or page protection. -// -// Parameters -// personality - flag to indicate the read is the 4 personality bytes (true) -// or page page protection (false) -// allpages - flag to indicate if just one page (false) or all (true) page protection -// bytes. -// page_num - page number if reading protection 0 to 1 -// rdbuf - 16 byte buffer personality bytes (length 4) or page protection -// (length 1 or 16) -// -// Returns: true - status read -// false - Failed to read status -// OneWireSlave::CmdResult DS28E15_22_25::readStatus(bool personality, bool allpages, unsigned int pageNum, std::uint8_t * rdbuf) const { std::uint8_t buf[256]; @@ -378,44 +337,31 @@ return Success; } - - - -ISha256MacCoprocessor::CmdResult DS28E15_22_25::calculateAuthMac(const ISha256MacCoprocessor & MacCoproc, unsigned int pageNum, const Scratchpad & challenge, const Page & pageData, const RomId & romId, const ManId & manId, bool anon, Mac & mac) +ISha256MacCoprocessor::CmdResult DS28E15_22_25::computeAuthMac(const ISha256MacCoprocessor & MacCoproc, const Page & pageData, unsigned int pageNum, const Scratchpad & challenge, const RomId & romId, const ManId & manId, Mac & mac) { - ISha256MacCoprocessor::AuthMacData authMacData; - - // insert ROM number or FF - if (anon) - std::memset(authMacData, 0xFF, RomId::byteLen); - else - std::memcpy(authMacData, romId, RomId::byteLen); + ISha256MacCoprocessor::AuthMacData authMacData; + + // insert ROM number or FF + std::memcpy(authMacData, romId, RomId::byteLen); + + authMacData[10] = pageNum; - authMacData[10] = pageNum; + authMacData[9] = manId[0]; + authMacData[8] = manId[1]; - authMacData[9] = manId[0]; - authMacData[8] = manId[1]; - - authMacData[11] = 0x00; + authMacData[11] = 0x00; - return MacCoproc.computeAuthMac(pageData, challenge, authMacData, mac); + return MacCoproc.computeAuthMac(pageData, challenge, authMacData, mac); } -//-------------------------------------------------------------------------- -// Do Compute Page MAC command and return MAC. Optionally do -// annonymous mode (anon != 0). -// -// Parameters -// sn - secret number 0 or 1 -// page_num - page number to read 0 - 16 -// challange - 32 byte buffer containing the challenge -// mac - 32 byte buffer for page data read -// anon - Flag to indicate Annonymous mode -// -// Returns: true - page read has correct MAC -// false - Failed to read page or incorrect MAC -// -OneWireSlave::CmdResult DS28E15_22_25::computeReadPageMAC(unsigned int page_num, bool anon, Mac & mac) const +ISha256MacCoprocessor::CmdResult DS28E15_22_25::computeAuthMacAnon(const ISha256MacCoprocessor & MacCoproc, const Page & pageData, unsigned int pageNum, const Scratchpad & challenge, const ManId & manId, Mac & mac) +{ + RomId romId; + std::memset(romId, 0xFF, RomId::byteLen); + return computeAuthMac(MacCoproc, pageData, pageNum, challenge, romId, manId, mac); +} + +OneWireSlave::CmdResult DS28E15_22_25::computeReadPageMac(unsigned int page_num, bool anon, Mac & mac) const { std::uint8_t buf[256],cs; int cnt = 0; @@ -460,17 +406,6 @@ return Success; } -//---------------------------------------------------------------------- -// Compute secret operation on the DS28E25/DS28E22/DS28E15. -// -// 'sn' - secret number 0 or 1 -// 'partial' - partial secret to load (32 bytes) -// 'pagedata' - page data to compute (32 bytes) -// 'lock' - option to lock the secret after the load (lock = true) -// -// Return: true - load complete -// false - error during load, device not present -// OneWireSlave::CmdResult DS28E15_22_25::computeSecret(unsigned int page_num, bool lock) { std::uint8_t buf[256], cs; @@ -508,21 +443,12 @@ return OperationFailure; } -//---------------------------------------------------------------------- -// Write the scratchpad (challenge or secret) -// -// 'sn' - secret number 0 or 1 -// 'data' - data to write to the scratchpad (32 bytes) -// -// Return: true - select complete -// false - error during select, device not present -// OneWireSlave::CmdResult DS28E15_22_25::writeScratchpad(const Scratchpad & data) const { std::uint8_t buf[256]; int cnt = 0, offset; - buf[cnt++] = CMD_SELECT_SECRET; + buf[cnt++] = CMD_READ_WRITE_SCRATCHPAD; if ((romId.familyCode() == DS28E25_FAMILY) || (romId.familyCode() == DS28E22_FAMILY)) buf[cnt++] = 0x20; else @@ -559,16 +485,48 @@ return Success; } -//---------------------------------------------------------------------- -// Load first secret operation on the DS28E25/DS28E22/DS28E15. -// -// 'sn' - secret number 0 or 1 -// 'secret' - secret to load (32 bytes) -// 'lock' - option to lock the secret after the load (lock = true) -// -// Return: true - load complete -// false - error during load, device not present -// +OneWireSlave::CmdResult DS28E15_22_25::readScratchpad(Scratchpad & data) const +{ + std::uint8_t buf[256]; + int cnt = 0, offset; + + buf[cnt++] = CMD_READ_WRITE_SCRATCHPAD; + if ((romId.familyCode() == DS28E25_FAMILY) || (romId.familyCode() == DS28E22_FAMILY)) + buf[cnt++] = 0x2F; + else + buf[cnt++] = 0x0F; + + // Send command + m_OW_master.OWWriteBlock(&buf[0], 2); + + // Read CRC + m_OW_master.OWReadBlock(&buf[cnt], 2); + cnt += 2; + + offset = cnt; + + // Receive the data + m_OW_master.OWReadBlock(&buf[cnt], data.length); + cnt += data.length; + + // Read CRC + m_OW_master.OWReadBlock(&buf[cnt], 2); + cnt += 2; + + // check first CRC16 + if (OneWireMaster::calculateCRC16(buf, 0, offset) != 0xB001) + return CommunicationError; + + // check the second CRC16 + if (OneWireMaster::calculateCRC16(buf, offset, (cnt - offset)) != 0xB001) + return CommunicationError; + + // Copy to output + memcpy(data, &buf[offset], data.length); + + return Success; +} + OneWireSlave::CmdResult DS28E15_22_25::loadSecret(bool lock) { std::uint8_t buf[256], cs; @@ -606,18 +564,6 @@ return OperationFailure; } -//-------------------------------------------------------------------------- -// Read page and verify CRC. Multiple pages can -// be read without re-selecting the device using the continue flag. -// -// Parameters -// page - page number where the block to write is located (0 to 15) -// rdbuf - 32 byte buffer to contain the data to read -// contflag - Flag to indicate the write is continued from the last -// -// Returns: true - block read and verified CRC -// false - Failed to write block (no presence or invalid CRC16) -// OneWireSlave::CmdResult DS28E15_22_25::readPage(unsigned int page, Page & rdbuf, bool continuing) const { std::uint8_t buf[256]; @@ -663,20 +609,6 @@ return Success; } -//-------------------------------------------------------------------------- -// Write a 4 byte memory block using an authenticated write (with MAC). -// The MAC must be pre-calculated. -// -// Parameters -// page - page number where the block to write is located (0 to 15) -// block - block number in page (0 to 7) -// new_data - 4 byte buffer containing the data to write -// mac - mac to use for the write -// contflag - Flag to indicate the write is continued from the last -// -// Returns: true - block written -// false - Failed to write block (no presence or invalid CRC16) -// OneWireSlave::CmdResult DS28E15_22_25::writeAuthSegmentMac(unsigned int pageNum, unsigned int segmentNum, const Segment & newData, const Mac & mac, bool continuing) { std::uint8_t buf[256], cs; @@ -780,22 +712,7 @@ return OperationFailure; } -//-------------------------------------------------------------------------- -// Compute MAC to write a 4 byte memory block using an authenticated -// write. -// -// Parameters -// page - page number where the block to write is located (0 to 15) -// block - block number in page (0 to 7) -// new_data - 4 byte buffer containing the data to write -// old_data - 4 byte buffer containing the data to write -// manid - 2 byte buffer containing the manufacturer ID (general device: 00h,00h) -// mac - buffer to put the calculated mac into -// -// Returns: true - mac calculated -// false - Failed to calculate -// -ISha256MacCoprocessor::CmdResult DS28E15_22_25::calculateSegmentWriteMac(const ISha256MacCoprocessor & MacCoproc, unsigned int pageNum, unsigned int segmentNum, const Segment & newData, const Segment & oldData, const RomId & romId, const ManId & manId, Mac & mac) +ISha256MacCoprocessor::CmdResult DS28E15_22_25::computeSegmentWriteMac(const ISha256MacCoprocessor & MacCoproc, unsigned int pageNum, unsigned int segmentNum, const Segment & newData, const Segment & oldData, const RomId & romId, const ManId & manId, Mac & mac) { ISha256MacCoprocessor::WriteMacData MT; @@ -816,10 +733,7 @@ return MacCoproc.computeWriteMac(MT, mac); } - - - -ISha256MacCoprocessor::CmdResult DS28E15_22_25::calculateProtectionWriteMac(const ISha256MacCoprocessor & MacCoproc, const BlockProtection & newProtection, const BlockProtection & oldProtection, const RomId & romId, const ManId & manId, Mac & mac) +ISha256MacCoprocessor::CmdResult DS28E15_22_25::computeProtectionWriteMac(const ISha256MacCoprocessor & MacCoproc, const BlockProtection & newProtection, const BlockProtection & oldProtection, const RomId & romId, const ManId & manId, Mac & mac) { ISha256MacCoprocessor::WriteMacData MT; @@ -848,24 +762,6 @@ return MacCoproc.computeWriteMac(MT, mac); } -//-------------------------------------------------------------------------- -// Write a 4 byte memory block using an authenticated write (with MAC). -// The block location is selected by the -// page number and offset block within the page. Multiple blocks can -// be programmed without re-selecting the device using the continue flag. -// This function does not use the Authenticated Write operation. -// -// Parameters -// page - page number where the block to write is located (0 to 15) -// block - block number in page (0 to 7) -// new_data - 4 byte buffer containing the data to write -// old_data - 4 byte buffer containing the data to write -// manid - 2 byte buffer containing the manufacturer ID (general device: 00h,00h) -// contflag - Flag to indicate the write is continued from the last -// -// Returns: true - block written -// false - Failed to write block (no presence or invalid CRC16) -// OneWireSlave::CmdResult DS28E15_22_25::writeAuthSegment(const ISha256MacCoprocessor & MacCoproc, unsigned int pageNum, unsigned int segmentNum, const Segment & newData, const Segment & oldData, bool continuing) { std::uint8_t buf[256], cs; @@ -934,7 +830,7 @@ // compute the mac ISha256MacCoprocessor::CmdResult result; Mac mac; - result = calculateSegmentWriteMac(MacCoproc, pageNum, segmentNum, newData, oldData, romId, manId, mac); + result = computeSegmentWriteMac(MacCoproc, pageNum, segmentNum, newData, oldData, romId, manId, mac); if (result != ISha256MacCoprocessor::Success) return OperationFailure; @@ -976,9 +872,6 @@ return OperationFailure; } - - - OneWireSlave::CmdResult DS28E15_22_25::readSegment(unsigned int page, unsigned int segment, Segment & data) const { OneWireMaster::CmdResult result; @@ -1000,21 +893,6 @@ return (result == OneWireMaster::Success ? OneWireSlave::Success : OneWireSlave::CommunicationError); } -//-------------------------------------------------------------------------- -// Write a 4 byte memory block. The block location is selected by the -// page number and offset blcok within the page. Multiple blocks can -// be programmed without re-selecting the device using the continue flag. -// This function does not use the Authenticated Write operation. -// -// Parameters -// page - page number where the block to write is located (0 to 15) -// block - block number in page (0 to 7) -// data - 4 byte buffer containing the data to write -// contflag - Flag to indicate the write is continued from the last -// -// Returns: true - block written -// false - Failed to write block (no presence or invalid CRC16) -// OneWireSlave::CmdResult DS28E15_22_25::writeSegment(unsigned int page, unsigned int block, const Segment & data, bool continuing) { std::uint8_t buf[256], cs; @@ -1079,22 +957,7 @@ return OperationFailure; } -//---------------------------------------------------------------------- -// Performs a Compute Next SHA-256 calculation given the provided 32-bytes -// of binding data and 8 byte partial secret. The first 8 bytes of the -// resulting MAC is set as the new secret. -// -// 'binding' - 32 byte buffer containing the binding data -// 'partial' - 8 byte buffer with new partial secret -// 'page_num' - page number that the compute is calculated on -// 'manid' - manufacturer ID -// -// Globals used : SECRET used in calculation and set to new secret -// -// Returns: true if compute successful -// false failed to do compute -// -ISha256MacCoprocessor::CmdResult DS28E15_22_25::calculateNextSecret(ISha256MacCoprocessor & MacCoproc, const Page & binding, const Scratchpad & partial, const RomId & romId, const ManId & manId, unsigned int pageNum) +ISha256MacCoprocessor::CmdResult DS28E15_22_25::computeNextSecret(ISha256MacCoprocessor & MacCoproc, const Page & bindingPage, unsigned int bindingPageNum, const Scratchpad & partialSecret, const RomId & romId, const ManId & manId) { ISha256MacCoprocessor::SlaveSecretData slaveSecretData; @@ -1102,9 +965,9 @@ std::memcpy(slaveSecretData, romId, RomId::byteLen); slaveSecretData[11] = 0x00; - slaveSecretData[10] = pageNum; + slaveSecretData[10] = bindingPageNum; slaveSecretData[9] = manId[0]; slaveSecretData[8] = manId[1]; - return MacCoproc.computeSlaveSecret(binding, partial, slaveSecretData); + return MacCoproc.computeSlaveSecret(bindingPage, partialSecret, slaveSecretData); }