Device interface library for multiple platforms including Mbed.
Dependents: DeepCover Embedded Security in IoT MaximInterface MAXREFDES155#
DS2465.cpp
00001 /******************************************************************************* 00002 * Copyright (C) Maxim Integrated Products, Inc., All Rights Reserved. 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a 00005 * copy of this software and associated documentation files (the "Software"), 00006 * to deal in the Software without restriction, including without limitation 00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00008 * and/or sell copies of the Software, and to permit persons to whom the 00009 * Software is furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included 00012 * in all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00017 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES 00018 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00019 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00020 * OTHER DEALINGS IN THE SOFTWARE. 00021 * 00022 * Except as contained in this notice, the name of Maxim Integrated 00023 * Products, Inc. shall not be used except as stated in the Maxim Integrated 00024 * Products, Inc. Branding Policy. 00025 * 00026 * The mere transfer of this software does not imply any licenses 00027 * of trade secrets, proprietary technology, copyrights, patents, 00028 * trademarks, maskwork rights, or any other form of intellectual 00029 * property whatsoever. Maxim Integrated Products, Inc. retains all 00030 * ownership rights. 00031 *******************************************************************************/ 00032 00033 #include <MaximInterfaceCore/Error.hpp> 00034 #include "DS2465.hpp" 00035 00036 #define TRY MaximInterfaceCore_TRY 00037 #define TRY_VALUE MaximInterfaceCore_TRY_VALUE 00038 00039 namespace MaximInterfaceDevices { 00040 00041 using namespace Core; 00042 00043 // Delay required after writing an EEPROM segment. 00044 static const int eepromSegmentWriteDelayMs = 10; 00045 00046 // Delay required after writing an EEPROM page such as the secret memory. 00047 static const int eepromPageWriteDelayMs = 8 * eepromSegmentWriteDelayMs; 00048 00049 // Delay required for a SHA computation to complete. 00050 static const int shaComputationDelayMs = 2; 00051 00052 static const uint_least8_t scratchpad = 0x00; 00053 static const uint_least8_t commandReg = 0x60; 00054 00055 static const uint_least8_t owTransmitBlockCmd = 0x69; 00056 00057 // DS2465 status bits. 00058 static const uint_least8_t status_1WB = 0x01; 00059 static const uint_least8_t status_PPD = 0x02; 00060 static const uint_least8_t status_SD = 0x04; 00061 static const uint_least8_t status_SBR = 0x20; 00062 static const uint_least8_t status_TSB = 0x40; 00063 static const uint_least8_t status_DIR = 0x80; 00064 00065 static const int maxBlockSize = 63; 00066 00067 const int DS2465::memoryPages; 00068 const int DS2465::segmentsPerPage; 00069 00070 Result<void> DS2465::initialize(Config config) { 00071 // reset DS2465 00072 Result<void> result = resetDevice(); 00073 if (result) { 00074 // write the default configuration setup 00075 result = writeConfig(config); 00076 } 00077 return result; 00078 } 00079 00080 Result<void> DS2465::computeNextMasterSecret(bool swap, int pageNum, 00081 PageRegion region) { 00082 Result<void> result = ArgumentOutOfRangeError; 00083 if (pageNum >= 0) { 00084 const uint_least8_t command[] = { 00085 0x1E, static_cast<uint_least8_t>(swap ? (0xC8 | (pageNum << 4) | region) 00086 : 0xBF)}; 00087 result = writeMemory(commandReg, command); 00088 } 00089 return result; 00090 } 00091 00092 Result<void> DS2465::computeWriteMac(bool regwrite, bool swap, int pageNum, 00093 int segmentNum) const { 00094 Result<void> result = ArgumentOutOfRangeError; 00095 if (pageNum >= 0 && segmentNum >= 0) { 00096 const uint_least8_t command[] = { 00097 0x2D, static_cast<uint_least8_t>((regwrite << 7) | (swap << 6) | 00098 (pageNum << 4) | segmentNum)}; 00099 result = writeMemory(commandReg, command); 00100 if (result) { 00101 sleep->invoke(shaComputationDelayMs); 00102 } 00103 } 00104 return result; 00105 } 00106 00107 Result<void> DS2465::computeAuthMac(bool swap, int pageNum, 00108 PageRegion region) const { 00109 Result<void> result = ArgumentOutOfRangeError; 00110 if (pageNum >= 0) { 00111 const uint_least8_t command[] = { 00112 0x3C, static_cast<uint_least8_t>(swap ? (0xC8 | (pageNum << 4) | region) 00113 : 0xBF)}; 00114 result = writeMemory(commandReg, command); 00115 if (result) { 00116 sleep->invoke(shaComputationDelayMs * 2); 00117 } 00118 } 00119 return result; 00120 } 00121 00122 Result<void> DS2465::computeSlaveSecret(bool swap, int pageNum, 00123 PageRegion region) { 00124 Result<void> result = ArgumentOutOfRangeError; 00125 if (pageNum >= 0) { 00126 const uint_least8_t command[] = { 00127 0x4B, static_cast<uint_least8_t>(swap ? (0xC8 | (pageNum << 4) | region) 00128 : 0xBF)}; 00129 result = writeMemory(commandReg, command); 00130 if (result) { 00131 sleep->invoke(shaComputationDelayMs * 2); 00132 } 00133 } 00134 return result; 00135 } 00136 00137 Result<DS2465::Page::array> DS2465::readPage(int pageNum) const { 00138 uint_least8_t addr; 00139 switch (pageNum) { 00140 case 0: 00141 addr = 0x80; 00142 break; 00143 case 1: 00144 addr = 0xA0; 00145 break; 00146 default: 00147 return ArgumentOutOfRangeError; 00148 } 00149 Page::array data; 00150 TRY(readMemory(addr, data)); 00151 return data; 00152 } 00153 00154 Result<void> DS2465::writePage(int pageNum, Page::const_span data) { 00155 Result<void> result = writeMemory(scratchpad, data); 00156 if (result) { 00157 result = copyScratchpad(false, pageNum, false, 0); 00158 } 00159 if (result) { 00160 sleep->invoke(eepromPageWriteDelayMs); 00161 } 00162 return result; 00163 } 00164 00165 Result<void> DS2465::writeSegment(int pageNum, int segmentNum, 00166 Segment::const_span data) { 00167 Result<void> result = writeMemory(scratchpad, data); 00168 if (result) { 00169 result = copyScratchpad(false, pageNum, true, segmentNum); 00170 } 00171 if (result) { 00172 sleep->invoke(eepromSegmentWriteDelayMs); 00173 } 00174 return result; 00175 } 00176 00177 Result<void> DS2465::writeMasterSecret(Page::const_span masterSecret) { 00178 Result<void> result = writeMemory(scratchpad, masterSecret); 00179 if (result) { 00180 result = copyScratchpad(true, 0, false, 0); 00181 } 00182 if (result) { 00183 sleep->invoke(eepromPageWriteDelayMs); 00184 } 00185 return result; 00186 } 00187 00188 Result<void> DS2465::copyScratchpad(bool destSecret, int pageNum, bool notFull, 00189 int segmentNum) { 00190 Result<void> result = ArgumentOutOfRangeError; 00191 if (pageNum >= 0 && segmentNum >= 0) { 00192 const uint_least8_t command[] = { 00193 0x5A, 00194 static_cast<uint_least8_t>(destSecret ? 0 00195 : (0x80 | (pageNum << 4) | 00196 (notFull << 3) | segmentNum))}; 00197 result = writeMemory(commandReg, command); 00198 } 00199 return result; 00200 } 00201 00202 Result<void> DS2465::configureLevel(Level level) { 00203 // Check if supported level 00204 if (!((level == NormalLevel) || (level == StrongLevel))) { 00205 return InvalidLevelError; 00206 } 00207 // Check if requested level already set 00208 if (curConfig.getSPU() == (level == StrongLevel)) { 00209 return none; 00210 } 00211 // Set the level 00212 return writeConfig(Config(curConfig).setSPU(level == StrongLevel)); 00213 } 00214 00215 Result<void> DS2465::setLevel (Level newLevel) { 00216 if (newLevel == StrongLevel) { 00217 return InvalidLevelError; 00218 } 00219 00220 return configureLevel(newLevel); 00221 } 00222 00223 Result<void> DS2465::setSpeed(Speed newSpeed) { 00224 // Check if supported speed 00225 if (!((newSpeed == OverdriveSpeed) || (newSpeed == StandardSpeed))) { 00226 return InvalidSpeedError; 00227 } 00228 // Check if requested speed is already set 00229 if (curConfig.get1WS() == (newSpeed == OverdriveSpeed)) { 00230 return none; 00231 } 00232 // Set the speed 00233 return writeConfig(Config(curConfig).set1WS(newSpeed == OverdriveSpeed)); 00234 } 00235 00236 Result<OneWireMaster::TripletData> DS2465::triplet(bool sendBit) { 00237 // 1-Wire Triplet (Case B) 00238 // S AD,0 [A] 1WT [A] SS [A] Sr AD,1 [A] [Status] A [Status] A\ P 00239 // \--------/ 00240 // Repeat until 1WB bit has changed to 0 00241 // [] indicates from slave 00242 // SS indicates byte containing search direction bit value in msbit 00243 00244 const uint_least8_t command[] = { 00245 0x78, static_cast<uint_least8_t>(sendBit ? 0x80 : 0x00)}; 00246 TRY(writeMemory(commandReg, command)); 00247 00248 uint_least8_t status; 00249 TRY_VALUE(status, pollBusy()); 00250 00251 TripletData data; 00252 data.readBit = ((status & status_SBR) == status_SBR); 00253 data.readBitComplement = ((status & status_TSB) == status_TSB); 00254 data.writeBit = ((status & status_DIR) == status_DIR); 00255 return data; 00256 } 00257 00258 Result<void> DS2465::readBlock(span<uint_least8_t> recvBuf) { 00259 // 1-Wire Receive Block (Case A) 00260 // S AD,0 [A] CommandReg [A] 1WRF [A] PR [A] P 00261 // [] indicates from slave 00262 // PR indicates byte containing parameter 00263 00264 span<uint_least8_t>::index_type recvIdx = 0; 00265 while (recvIdx < recvBuf.size()) { 00266 const uint_least8_t command[] = { 00267 0xE1, 00268 static_cast<uint_least8_t>(std::min<span<uint_least8_t>::index_type>( 00269 recvBuf.size() - recvIdx, maxBlockSize))}; 00270 TRY(writeMemory(commandReg, command)); 00271 TRY(pollBusy()); 00272 TRY(readMemory(scratchpad, recvBuf.subspan(recvIdx, command[1]))); 00273 recvIdx += command[1]; 00274 } 00275 return none; 00276 } 00277 00278 Result<void> DS2465::writeBlock(span<const uint_least8_t> sendBuf) { 00279 span<const uint_least8_t>::index_type sendIdx = 0; 00280 while (sendIdx < sendBuf.size()) { 00281 const uint_least8_t command[] = { 00282 owTransmitBlockCmd, static_cast<uint_least8_t>( 00283 std::min<span<const uint_least8_t>::index_type>( 00284 sendBuf.size() - sendIdx, maxBlockSize))}; 00285 00286 // prefill scratchpad with required data 00287 TRY(writeMemory(scratchpad, sendBuf.subspan(sendIdx, command[1]))); 00288 00289 // 1-Wire Transmit Block (Case A) 00290 // S AD,0 [A] CommandReg [A] 1WTB [A] PR [A] P 00291 // [] indicates from slave 00292 // PR indicates byte containing parameter 00293 TRY(writeMemory(commandReg, command)); 00294 TRY(pollBusy()); 00295 sendIdx += command[1]; 00296 } 00297 return none; 00298 } 00299 00300 Result<void> DS2465::writeMacBlock() { 00301 // 1-Wire Transmit Block (Case A) 00302 // S AD,0 [A] CommandReg [A] 1WTB [A] PR [A] P 00303 // [] indicates from slave 00304 // PR indicates byte containing parameter 00305 00306 const uint_least8_t command[] = {owTransmitBlockCmd, 0xFF}; 00307 TRY(writeMemory(commandReg, command)); 00308 TRY(pollBusy()); 00309 return none; 00310 } 00311 00312 Result<uint_least8_t> DS2465::readByteSetLevel(Level afterLevel) { 00313 // 1-Wire Read Bytes (Case C) 00314 // S AD,0 [A] CommandReg [A] 1WRB [A] Sr AD,1 [A] [Status] A [Status] A 00315 // \--------/ 00316 // Repeat until 1WB bit has changed to 0 00317 // Sr AD,0 [A] SRP [A] E1 [A] Sr AD,1 [A] DD A\ P 00318 // 00319 // [] indicates from slave 00320 // DD data read 00321 00322 TRY(configureLevel(afterLevel)); 00323 00324 uint_least8_t buf = 0x96; 00325 TRY(writeMemory(commandReg, make_span(&buf, 1))); 00326 TRY(pollBusy()); 00327 TRY(readMemory(0x62, make_span(&buf, 1))); 00328 return buf; 00329 } 00330 00331 Result<void> DS2465::writeByteSetLevel(uint_least8_t sendByte, 00332 Level afterLevel) { 00333 // 1-Wire Write Byte (Case B) 00334 // S AD,0 [A] CommandReg [A] 1WWB [A] DD [A] Sr AD,1 [A] [Status] A [Status] 00335 // A\ P 00336 // \--------/ 00337 // Repeat until 1WB bit has changed to 0 00338 // [] indicates from slave 00339 // DD data to write 00340 00341 TRY(configureLevel(afterLevel)); 00342 00343 const uint_least8_t command[] = {0xA5, sendByte}; 00344 TRY(writeMemory(commandReg, command)); 00345 TRY(pollBusy()); 00346 return none; 00347 } 00348 00349 Result<bool> DS2465::touchBitSetLevel(bool sendBit, Level afterLevel) { 00350 // 1-Wire bit (Case B) 00351 // S AD,0 [A] CommandReg [A] 1WSB [A] BB [A] Sr AD,1 [A] [Status] A [Status] 00352 // A\ P 00353 // \--------/ 00354 // Repeat until 1WB bit has changed to 0 00355 // [] indicates from slave 00356 // BB indicates byte containing bit value in msbit 00357 00358 TRY(configureLevel(afterLevel)); 00359 00360 const uint_least8_t command[] = { 00361 0x87, static_cast<uint_least8_t>(sendBit ? 0x80 : 0x00)}; 00362 TRY(writeMemory(commandReg, command)); 00363 00364 uint_least8_t status; 00365 TRY_VALUE(status, pollBusy()); 00366 00367 return (status & status_SBR) == status_SBR; 00368 } 00369 00370 Result<void> DS2465::writeMemory(uint_least8_t addr, 00371 span<const uint_least8_t> buf) const { 00372 // Write SRAM (Case A) 00373 // S AD,0 [A] VSA [A] DD [A] P 00374 // \-----/ 00375 // Repeat for each data byte 00376 // [] indicates from slave 00377 // VSA valid SRAM memory address 00378 // DD memory data to write 00379 00380 Result<void> result = master->start(address_); 00381 if (!result) { 00382 master->stop(); 00383 return result; 00384 } 00385 result = master->writeByte(addr); 00386 if (!result) { 00387 master->stop(); 00388 return result; 00389 } 00390 result = master->writeBlock(buf); 00391 if (!result) { 00392 master->stop(); 00393 return result; 00394 } 00395 result = master->stop(); 00396 return result; 00397 } 00398 00399 Result<void> DS2465::readMemory(uint_least8_t addr, 00400 span<uint_least8_t> buf) const { 00401 // Read (Case A) 00402 // S AD,0 [A] MA [A] Sr AD,1 [A] [DD] A [DD] A\ P 00403 // \-----/ 00404 // Repeat for each data byte, NAK last byte 00405 // [] indicates from slave 00406 // MA memory address 00407 // DD memory data read 00408 00409 Result<void> result = master->start(address_); 00410 if (!result) { 00411 master->stop(); 00412 return result; 00413 } 00414 result = master->writeByte(addr); 00415 if (!result) { 00416 master->stop(); 00417 return result; 00418 } 00419 result = readMemory(buf); 00420 return result; 00421 } 00422 00423 Result<void> DS2465::readMemory(span<uint_least8_t> buf) const { 00424 Result<void> result = master->start(address_ | 1); 00425 if (!result) { 00426 master->stop(); 00427 return result; 00428 } 00429 result = master->readBlock(buf, I2CMaster::Nack); 00430 if (!result) { 00431 master->stop(); 00432 return result; 00433 } 00434 result = master->stop(); 00435 return result; 00436 } 00437 00438 Result<void> DS2465::writeConfig(Config config) { 00439 const uint_least8_t configReg = 0x67; 00440 uint_least8_t configBuf = 00441 ((config.readByte() ^ 0xF) << 4) | config.readByte(); 00442 Result<void> result = writeMemory(configReg, make_span(&configBuf, 1)); 00443 if (result) { 00444 result = readMemory(configReg, make_span(&configBuf, 1)); 00445 } 00446 if (result && configBuf != config.readByte()) { 00447 result = HardwareError; 00448 } 00449 if (result) { 00450 curConfig = config; 00451 } 00452 return result; 00453 } 00454 00455 Result<void> DS2465::writePortParameter(PortParameter param, int val) { 00456 if (val < 0 || val > 15) { 00457 return ArgumentOutOfRangeError; 00458 } 00459 00460 uint_least8_t addr = 0; 00461 switch (param) { 00462 case tRSTL_STD: 00463 case tRSTL_OD: 00464 addr = 0x68; 00465 break; 00466 case tMSP_STD: 00467 case tMSP_OD: 00468 addr = 0x69; 00469 break; 00470 case tW0L_STD: 00471 case tW0L_OD: 00472 addr = 0x6A; 00473 break; 00474 case tREC0: 00475 addr = 0x6B; 00476 break; 00477 case RWPU: 00478 addr = 0x6C; 00479 break; 00480 case tW1L_OD: 00481 addr = 0x6D; 00482 break; 00483 } 00484 00485 uint_least8_t data; 00486 Result<void> result = readMemory(addr, make_span(&data, 1)); 00487 if (!result) { 00488 return result; 00489 } 00490 00491 uint_least8_t newData; 00492 if (param == tRSTL_OD || param == tMSP_OD || param == tW0L_OD) { 00493 newData = (data & 0x0F) | (val << 4); 00494 } else { 00495 newData = (data & 0xF0) | val; 00496 } 00497 00498 if (newData != data) { 00499 result = writeMemory(addr, make_span(&newData, 1)); 00500 } 00501 return result; 00502 } 00503 00504 Result<uint_least8_t> DS2465::pollBusy() const { 00505 const int pollLimit = 200; 00506 00507 int pollCount = 0; 00508 uint_least8_t status; 00509 do { 00510 const Result<void> result = readMemory(make_span(&status, 1)); 00511 if (!result) { 00512 return result.error(); 00513 } 00514 if (pollCount++ >= pollLimit) { 00515 return HardwareError; 00516 } 00517 } while ((status & status_1WB) == status_1WB); 00518 return status; 00519 } 00520 00521 Result<void> DS2465::reset() { 00522 // 1-Wire reset (Case B) 00523 // S AD,0 [A] CommandReg [A] 1WRS [A] Sr AD,1 [A] [Status] A [Status] A\ P 00524 // \--------/ 00525 // Repeat until 1WB bit has changed to 0 00526 // [] indicates from slave 00527 00528 uint_least8_t buf = 0xB4; 00529 TRY(writeMemory(commandReg, make_span(&buf, 1))); 00530 00531 TRY_VALUE(buf, pollBusy()); 00532 00533 if ((buf & status_SD) == status_SD) { 00534 return ShortDetectedError; 00535 } 00536 if ((buf & status_PPD) != status_PPD) { 00537 return NoSlaveError; 00538 } 00539 00540 return none; 00541 } 00542 00543 Result<void> DS2465::resetDevice() { 00544 // Device Reset 00545 // S AD,0 [A] CommandReg [A] 1WMR [A] Sr AD,1 [A] [SS] A\ P 00546 // [] indicates from slave 00547 // SS status byte to read to verify state 00548 00549 uint_least8_t buf = 0xF0; 00550 Result<void> result = writeMemory(commandReg, make_span(&buf, 1)); 00551 00552 if (result) { 00553 result = readMemory(make_span(&buf, 1)); 00554 } 00555 00556 if (result) { 00557 if ((buf & 0xF7) != 0x10) { 00558 result = HardwareError; 00559 } 00560 } 00561 00562 if (result) { 00563 reset(); // do a command to get 1-Wire master reset out of holding state 00564 } 00565 00566 return result; 00567 } 00568 00569 Result<void> 00570 DS2465::computeNextMasterSecret(AuthenticationData::const_span data) { 00571 Result<void> result = writeMemory(scratchpad, data); 00572 if (result) { 00573 result = computeNextMasterSecret(false, 0, FullPage); 00574 } 00575 return result; 00576 } 00577 00578 Result<void> 00579 DS2465::computeNextMasterSecretWithSwap(AuthenticationData::const_span data, 00580 int pageNum, PageRegion region) { 00581 Result<void> result = writeMemory(scratchpad, data); 00582 if (result) { 00583 result = computeNextMasterSecret(true, pageNum, region); 00584 } 00585 return result; 00586 } 00587 00588 Result<void> DS2465::doComputeWriteMac(WriteMacData::const_span data) const { 00589 Result<void> result = writeMemory(scratchpad, data); 00590 if (result) { 00591 result = computeWriteMac(false, false, 0, 0); 00592 } 00593 return result; 00594 } 00595 00596 Result<DS2465::Page::array> 00597 DS2465::computeWriteMac(WriteMacData::const_span data) const { 00598 Result<void> result = doComputeWriteMac(data); 00599 if (!result) { 00600 return result.error(); 00601 } 00602 Page::array mac; 00603 result = readMemory(mac); 00604 if (!result) { 00605 return result.error(); 00606 } 00607 return mac; 00608 } 00609 00610 Result<void> DS2465::computeAndTransmitWriteMac(WriteMacData::const_span data) { 00611 Result<void> result = doComputeWriteMac(data); 00612 if (result) { 00613 result = writeMacBlock(); 00614 } 00615 return result; 00616 } 00617 00618 Result<void> DS2465::doComputeWriteMacWithSwap(WriteMacData::const_span data, 00619 int pageNum, 00620 int segmentNum) const { 00621 Result<void> result = writeMemory(scratchpad, data); 00622 if (result) { 00623 result = computeWriteMac(false, true, pageNum, segmentNum); 00624 } 00625 return result; 00626 } 00627 00628 Result<DS2465::Page::array> 00629 DS2465::computeWriteMacWithSwap(WriteMacData::const_span data, int pageNum, 00630 int segmentNum) const { 00631 Result<void> result = doComputeWriteMacWithSwap(data, pageNum, segmentNum); 00632 if (!result) { 00633 return result.error(); 00634 } 00635 Page::array mac; 00636 result = readMemory(mac); 00637 if (!result) { 00638 return result.error(); 00639 } 00640 return mac; 00641 } 00642 00643 Result<void> 00644 DS2465::computeAndTransmitWriteMacWithSwap(WriteMacData::const_span data, 00645 int pageNum, int segmentNum) { 00646 Result<void> result = doComputeWriteMacWithSwap(data, pageNum, segmentNum); 00647 if (result) { 00648 result = writeMacBlock(); 00649 } 00650 return result; 00651 } 00652 00653 Result<void> DS2465::computeSlaveSecret(AuthenticationData::const_span data) { 00654 Result<void> result = writeMemory(scratchpad, data); 00655 if (result) { 00656 result = computeSlaveSecret(false, 0, FullPage); 00657 } 00658 return result; 00659 } 00660 00661 Result<void> 00662 DS2465::computeSlaveSecretWithSwap(AuthenticationData::const_span data, 00663 int pageNum, PageRegion region) { 00664 Result<void> result = writeMemory(scratchpad, data); 00665 if (result) { 00666 result = computeSlaveSecret(true, pageNum, region); 00667 } 00668 return result; 00669 } 00670 00671 Result<void> 00672 DS2465::doComputeAuthMac(AuthenticationData::const_span data) const { 00673 Result<void> result = writeMemory(scratchpad, data); 00674 if (result) { 00675 result = computeAuthMac(false, 0, FullPage); 00676 } 00677 return result; 00678 } 00679 00680 Result<DS2465::Page::array> 00681 DS2465::computeAuthMac(AuthenticationData::const_span data) const { 00682 Result<void> result = doComputeAuthMac(data); 00683 if (!result) { 00684 return result.error(); 00685 } 00686 Page::array mac; 00687 result = readMemory(mac); 00688 if (!result) { 00689 return result.error(); 00690 } 00691 return mac; 00692 } 00693 00694 Result<void> 00695 DS2465::computeAndTransmitAuthMac(AuthenticationData::const_span data) { 00696 Result<void> result = doComputeAuthMac(data); 00697 if (result) { 00698 result = writeMacBlock(); 00699 } 00700 return result; 00701 } 00702 00703 Result<void> 00704 DS2465::doComputeAuthMacWithSwap(AuthenticationData::const_span data, 00705 int pageNum, PageRegion region) const { 00706 Result<void> result = writeMemory(scratchpad, data); 00707 if (result) { 00708 result = computeAuthMac(true, pageNum, region); 00709 } 00710 return result; 00711 } 00712 00713 Result<DS2465::Page::array> 00714 DS2465::computeAuthMacWithSwap(AuthenticationData::const_span data, int pageNum, 00715 PageRegion region) const { 00716 Result<void> result = doComputeAuthMacWithSwap(data, pageNum, region); 00717 if (!result) { 00718 return result.error(); 00719 } 00720 Page::array mac; 00721 result = readMemory(mac); 00722 if (!result) { 00723 return result.error(); 00724 } 00725 return mac; 00726 } 00727 00728 Result<void> 00729 DS2465::computeAndTransmitAuthMacWithSwap(AuthenticationData::const_span data, 00730 int pageNum, PageRegion region) { 00731 Result<void> result = doComputeAuthMacWithSwap(data, pageNum, region); 00732 if (result) { 00733 result = writeMacBlock(); 00734 } 00735 return result; 00736 } 00737 00738 const error_category & DS2465::errorCategory() { 00739 static class : public error_category { 00740 public: 00741 virtual const char * name() const { return "MaximInterfaceDevices.DS2465"; } 00742 00743 virtual std::string message(int condition) const { 00744 switch (condition) { 00745 case HardwareError: 00746 return "Hardware Error"; 00747 00748 case ArgumentOutOfRangeError: 00749 return "Argument Out of Range Error"; 00750 } 00751 return defaultErrorMessage(condition); 00752 } 00753 } instance; 00754 return instance; 00755 } 00756 00757 } // namespace MaximInterfaceDevices
Generated on Tue Jul 12 2022 11:13:05 by 1.7.2