Device interface library for multiple platforms including Mbed.

Dependents:   DeepCover Embedded Security in IoT MaximInterface MAXREFDES155#

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DS28E15_22_25.hpp Source File

DS28E15_22_25.hpp

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 #ifndef MaximInterfaceDevices_DS28E15_22_25_hpp
00034 #define MaximInterfaceDevices_DS28E15_22_25_hpp
00035 
00036 #include <stdint.h>
00037 #include <MaximInterfaceCore/Algorithm.hpp>
00038 #include <MaximInterfaceCore/array_span.hpp>
00039 #include <MaximInterfaceCore/ManId.hpp>
00040 #include <MaximInterfaceCore/OneWireMaster.hpp>
00041 #include <MaximInterfaceCore/RomId.hpp>
00042 #include <MaximInterfaceCore/SelectRom.hpp>
00043 #include <MaximInterfaceCore/Sleep.hpp>
00044 #include "Config.hpp"
00045 
00046 namespace MaximInterfaceDevices {
00047 
00048 /// @brief
00049 /// Interface to the DS28E15/22/25 series of authenticators
00050 /// including low power variants.
00051 /// @details
00052 /// Const member functions should not affect the state of the memory,
00053 /// block protection, or secret on the device.
00054 class DS28E15_22_25 {
00055 public:
00056   enum ErrorValue { CrcError = 1, OperationFailure };
00057 
00058   /// Holds the contents of a device memory segment.
00059   typedef Core::array_span<uint_least8_t, 4> Segment;
00060 
00061   /// Holds the contents of a device memory page.
00062   typedef Core::array_span<uint_least8_t, 32> Page;
00063 
00064   /// Number of segments per page.
00065   static const int segmentsPerPage = Page::size / Segment::size;
00066 
00067   /// Container for the device personality.
00068   struct Personality {
00069     uint_least8_t PB1;
00070     uint_least8_t PB2;
00071     Core::ManId::array manId;
00072 
00073     bool secretLocked() const { return PB2 & 0x01; }
00074   };
00075 
00076   // Represents the status of a memory protection block.
00077   class BlockProtection;
00078 
00079   // Format data to hash for an Authenticated Write to a memory segment.
00080   class SegmentWriteMacData;
00081 
00082   // Format data to hash for an Authenticated Write to a memory protection block.
00083   class ProtectionWriteMacData;
00084 
00085   // Format data to hash for device authentication or computing the next secret
00086   // from the existing secret.
00087   class AuthenticationData;
00088 
00089   void setSleep(Core::Sleep & sleep) { this->sleep = &sleep; }
00090 
00091   void setMaster(Core::OneWireMaster & master) { this->master = &master; }
00092 
00093   void setSelectRom(const Core::SelectRom & selectRom) {
00094     this->selectRom = selectRom;
00095   }
00096 
00097   /// @brief Read memory segment using the Read Memory command on the device.
00098   /// @param pageNum Page number for read operation.
00099   /// @param segmentNum Segment number within page for read operation.
00100   /// @returns Buffer to read data from the segment into.
00101   MaximInterfaceDevices_EXPORT Core::Result<Segment::array>
00102   readSegment(int pageNum, int segmentNum) const;
00103 
00104   /// @brief Continue an in-progress readSegment operation.
00105   /// @note A CRC16 will encountered after reading the last segment of a page.
00106   /// @returns Buffer to read data from the segment into.
00107   MaximInterfaceDevices_EXPORT Core::Result<Segment::array>
00108   continueReadSegment() const;
00109 
00110   /// @brief Write memory segment using the Write Memory command.
00111   /// @note 1-Wire ROM selection should have already occurred.
00112   /// @param pageNum Page number for write operation.
00113   /// @param segmentNum Segment number within page for write operation.
00114   /// @param[in] data Data to write to the memory segment.
00115   MaximInterfaceDevices_EXPORT Core::Result<void>
00116   writeSegment(int pageNum, int segmentNum, Segment::const_span data);
00117 
00118   /// @brief Continue an in-progress Write Memory command.
00119   /// @param[in] data Data to write to the memory segment.
00120   MaximInterfaceDevices_EXPORT Core::Result<void>
00121   continueWriteSegment(Segment::const_span data);
00122 
00123   /// @brief Read memory page using the Read Memory command on the device.
00124   /// @param pageNum Page number for write operation.
00125   /// @returns Buffer to read data from the page into.
00126   MaximInterfaceDevices_EXPORT Core::Result<Page::array>
00127   readPage(int pageNum) const;
00128 
00129   /// @brief Continue an in-progress readPageOperation.
00130   /// @returns Buffer to read data from the page into.
00131   MaximInterfaceDevices_EXPORT Core::Result<Page::array>
00132   continueReadPage() const;
00133 
00134   /// @brief
00135   /// Perform a Compute Page MAC command on the device.
00136   /// Read back the MAC and verify the CRC16.
00137   /// @param pageNum Page number to use for the computation.
00138   /// @param anon True to compute in anonymous mode where ROM ID is not used.
00139   /// @returns The device computed MAC.
00140   MaximInterfaceDevices_EXPORT Core::Result<Page::array>
00141   computeReadPageMac(int pageNum, bool anon) const;
00142 
00143   /// @brief
00144   /// Update the status of a memory protection block using the
00145   /// Write Page Protection command.
00146   /// @param protection
00147   /// Desired protection status for the block.
00148   /// It is not possible to disable existing protections.
00149   MaximInterfaceDevices_EXPORT Core::Result<void>
00150   writeBlockProtection(BlockProtection protection);
00151 
00152   /// @brief
00153   /// Update the status of a memory protection block using the
00154   /// Authenticated Write Page Protection command.
00155   /// @param newProtection New protection status to write.
00156   /// @param[in] mac Write MAC computed for this operation.
00157   MaximInterfaceDevices_EXPORT Core::Result<void>
00158   writeAuthBlockProtection(BlockProtection newProtection, Page::const_span mac);
00159 
00160   /// @brief Perform Load and Lock Secret command on the device.
00161   /// @note The secret should already be stored in the scratchpad on the device.
00162   /// @param lock
00163   /// Prevent further changes to the secret on the device after loading.
00164   MaximInterfaceDevices_EXPORT Core::Result<void> loadSecret(bool lock);
00165 
00166   /// @brief Perform a Compute and Lock Secret command on the device.
00167   /// @param pageNum Page number to use as the binding data.
00168   /// @param lock
00169   /// Prevent further changes to the secret on the device after computing.
00170   MaximInterfaceDevices_EXPORT Core::Result<void> computeSecret(int pageNum,
00171                                                                 bool lock);
00172 
00173   /// @brief Read the personality bytes using the Read Status command.
00174   /// @returns Receives personality read from device.
00175   MaximInterfaceDevices_EXPORT Core::Result<Personality>
00176   readPersonality() const;
00177 
00178   MaximInterfaceDevices_EXPORT static const Core::error_category &
00179   errorCategory();
00180 
00181 protected:
00182   enum Variant { DS28E15, DS28E22, DS28E25 };
00183 
00184   DS28E15_22_25(Core::Sleep & sleep, Core::OneWireMaster & master,
00185                 const Core::SelectRom & selectRom)
00186       : selectRom(selectRom), master(&master), sleep(&sleep) {}
00187 
00188   ~DS28E15_22_25() {}
00189 
00190   Core::Result<void> doWriteScratchpad(Page::const_span data, Variant variant);
00191 
00192   Core::Result<Page::array> doReadScratchpad(Variant variant) const;
00193 
00194   Core::Result<BlockProtection> doReadBlockProtection(int blockNum,
00195                                                       Variant variant) const;
00196 
00197   Core::Result<void> doWriteAuthSegment(int pageNum, int segmentNum,
00198                                         Segment::const_span newData,
00199                                         Page::const_span mac, Variant variant);
00200 
00201   Core::Result<void> doContinueWriteAuthSegment(Segment::const_span newData,
00202                                                 Page::const_span mac,
00203                                                 Variant variant);
00204 
00205   Core::Result<void>
00206   doReadAllBlockProtection(Core::span<BlockProtection> protection,
00207                            Variant variant) const;
00208 
00209   Core::Result<void> doLoadSecret(bool lock, bool lowPower);
00210 
00211   Core::Result<void> doComputeSecret(int pageNum, bool lock, bool lowPower);
00212 
00213 private:
00214   enum Command {
00215     WriteMemory = 0x55,
00216     ReadMemory = 0xF0,
00217     LoadAndLockSecret = 0x33,
00218     ComputeAndLockSecret = 0x3C,
00219     ReadWriteScratchpad = 0x0F,
00220     ComputePageMac = 0xA5,
00221     ReadStatus = 0xAA,
00222     WriteBlockProtection = 0xC3,
00223     AuthWriteMemory = 0x5A,
00224     AuthWriteBlockProtection = 0xCC,
00225   };
00226 
00227   Core::Result<void> doWriteAuthSegment(Segment::const_span newData,
00228                                         Page::const_span mac, Variant variant,
00229                                         bool continuing);
00230 
00231   Core::Result<void>
00232   writeCommandWithCrc(Command command, uint_least8_t parameter,
00233                       Core::OneWireMaster::Level level =
00234                           Core::OneWireMaster::NormalLevel) const;
00235 
00236   Core::SelectRom selectRom;
00237   Core::OneWireMaster * master;
00238   Core::Sleep * sleep;
00239 };
00240 
00241 } // namespace MaximInterfaceDevices
00242 namespace MaximInterfaceCore {
00243 
00244 template <>
00245 struct is_error_code_enum<MaximInterfaceDevices::DS28E15_22_25::ErrorValue>
00246     : true_type {};
00247 
00248 } // namespace MaximInterfaceCore
00249 namespace MaximInterfaceDevices {
00250 
00251 inline Core::error_code make_error_code(DS28E15_22_25::ErrorValue e) {
00252   return Core::error_code(e, DS28E15_22_25::errorCategory());
00253 }
00254 
00255 /// Interface to the DS28EL15 (low power) authenticator.
00256 class DS28EL15 : public DS28E15_22_25 {
00257 public:
00258   // DS28E15_22_25 traits
00259   static const int memoryPages = 2;
00260   static const int protectionBlocks = 4;
00261 
00262   DS28EL15(Core::Sleep & sleep, Core::OneWireMaster & master,
00263            const Core::SelectRom & selectRom)
00264       : DS28E15_22_25(sleep, master, selectRom) {}
00265 
00266   /// @brief Perform Write Scratchpad operation on the device.
00267   /// @param[in] data Data to write to the scratchpad.
00268   MaximInterfaceDevices_EXPORT Core::Result<void>
00269   writeScratchpad(Page::const_span data);
00270 
00271   /// @brief Perform a Read Scratchpad operation on the device.
00272   /// @returns Buffer to read data from the scratchpad into.
00273   MaximInterfaceDevices_EXPORT Core::Result<Page::array> readScratchpad() const;
00274 
00275   /// @brief
00276   /// Read the status of a memory protection block using the Read Status command.
00277   /// @param blockNum Block number to to read status of.
00278   /// @returns Receives protection status read from device.
00279   MaximInterfaceDevices_EXPORT Core::Result<BlockProtection>
00280   readBlockProtection(int blockNum) const;
00281 
00282   /// @brief Write memory segment using the Authenticated Write Memory command.
00283   /// @param pageNum Page number for write operation.
00284   /// @param segmentNum Segment number within page for write operation.
00285   /// @param[in] newData New data to write to the segment.
00286   /// @param[in] mac Write MAC computed for this operation.
00287   MaximInterfaceDevices_EXPORT Core::Result<void>
00288   writeAuthSegment(int pageNum, int segmentNum, Segment::const_span newData,
00289                    Page::const_span mac);
00290 
00291   /// @brief Continue an in-progress Authenticated Write Memory command.
00292   /// @param[in] newData New data to write to the segment.
00293   /// @param[in] mac Write MAC computed for this operation.
00294   MaximInterfaceDevices_EXPORT Core::Result<void>
00295   continueWriteAuthSegment(Segment::const_span newData, Page::const_span mac);
00296 
00297   /// @brief
00298   /// Read the status of all memory protection blocks using the Read Status command.
00299   /// @returns Receives protection statuses read from device.
00300   MaximInterfaceDevices_EXPORT
00301       Core::Result<Core::array<BlockProtection, protectionBlocks> >
00302       readAllBlockProtection() const;
00303 };
00304 
00305 /// Interface to the DS28E15 authenticator.
00306 class DS28E15 : public DS28EL15 {
00307 public:
00308   DS28E15(Core::Sleep & sleep, Core::OneWireMaster & master,
00309           const Core::SelectRom & selectRom)
00310       : DS28EL15(sleep, master, selectRom) {}
00311 
00312   /// @brief Perform Load and Lock Secret command on the device.
00313   /// @note The secret should already be stored in the scratchpad on the device.
00314   /// @param lock
00315   /// Prevent further changes to the secret on the device after loading.
00316   MaximInterfaceDevices_EXPORT Core::Result<void> loadSecret(bool lock);
00317 
00318   /// @brief Perform a Compute and Lock Secret command on the device.
00319   /// @param pageNum Page number to use as the binding data.
00320   /// @param lock
00321   /// Prevent further changes to the secret on the device after computing.
00322   MaximInterfaceDevices_EXPORT Core::Result<void> computeSecret(int pageNum,
00323                                                                 bool lock);
00324 };
00325 
00326 /// Interface to the DS28EL22 (low power) authenticator.
00327 class DS28EL22 : public DS28E15_22_25 {
00328 public:
00329   // DS28E15_22_25 traits
00330   static const int memoryPages = 8;
00331   static const int protectionBlocks = 4;
00332 
00333   DS28EL22(Core::Sleep & sleep, Core::OneWireMaster & master,
00334            const Core::SelectRom & selectRom)
00335       : DS28E15_22_25(sleep, master, selectRom) {}
00336 
00337   /// @brief Perform Write Scratchpad operation on the device.
00338   /// @param[in] data Data to write to the scratchpad.
00339   MaximInterfaceDevices_EXPORT Core::Result<void>
00340   writeScratchpad(Page::const_span data);
00341 
00342   /// @brief Perform a Read Scratchpad operation on the device.
00343   /// @returns Buffer to read data from the scratchpad into.
00344   MaximInterfaceDevices_EXPORT Core::Result<Page::array> readScratchpad() const;
00345 
00346   /// @brief
00347   /// Read the status of a memory protection block using the Read Status command.
00348   /// @param blockNum Block number to to read status of.
00349   /// @returns Receives protection status read from device.
00350   MaximInterfaceDevices_EXPORT Core::Result<BlockProtection>
00351   readBlockProtection(int blockNum) const;
00352 
00353   /// @brief Write memory segment using the Authenticated Write Memory command.
00354   /// @param pageNum Page number for write operation.
00355   /// @param segmentNum Segment number within page for write operation.
00356   /// @param[in] newData New data to write to the segment.
00357   /// @param[in] mac Write MAC computed for this operation.
00358   MaximInterfaceDevices_EXPORT Core::Result<void>
00359   writeAuthSegment(int pageNum, int segmentNum, Segment::const_span newData,
00360                    Page::const_span mac);
00361 
00362   /// @brief Continue an in-progress Authenticated Write Memory command.
00363   /// @param[in] newData New data to write to the segment.
00364   /// @param[in] mac Write MAC computed for this operation.
00365   MaximInterfaceDevices_EXPORT Core::Result<void>
00366   continueWriteAuthSegment(Segment::const_span newData, Page::const_span mac);
00367 
00368   /// @brief
00369   /// Read the status of all memory protection blocks using the Read Status command.
00370   /// @returns Receives protection statuses read from device.
00371   MaximInterfaceDevices_EXPORT
00372       Core::Result<Core::array<BlockProtection, protectionBlocks> >
00373       readAllBlockProtection() const;
00374 };
00375 
00376 /// Interface to the DS28E22 authenticator.
00377 class DS28E22 : public DS28EL22 {
00378 public:
00379   DS28E22(Core::Sleep & sleep, Core::OneWireMaster & master,
00380           const Core::SelectRom & selectRom)
00381       : DS28EL22(sleep, master, selectRom) {}
00382 
00383   /// @brief Perform Load and Lock Secret command on the device.
00384   /// @note The secret should already be stored in the scratchpad on the device.
00385   /// @param lock
00386   /// Prevent further changes to the secret on the device after loading.
00387   MaximInterfaceDevices_EXPORT Core::Result<void> loadSecret(bool lock);
00388 
00389   /// @brief Perform a Compute and Lock Secret command on the device.
00390   /// @param pageNum Page number to use as the binding data.
00391   /// @param lock
00392   /// Prevent further changes to the secret on the device after computing.
00393   MaximInterfaceDevices_EXPORT Core::Result<void> computeSecret(int pageNum,
00394                                                                 bool lock);
00395 };
00396 
00397 /// Interface to the DS28EL25 (low power) authenticator.
00398 class DS28EL25 : public DS28E15_22_25 {
00399 public:
00400   // DS28E15_22_25 traits
00401   static const int memoryPages = 16;
00402   static const int protectionBlocks = 8;
00403 
00404   DS28EL25(Core::Sleep & sleep, Core::OneWireMaster & master,
00405            const Core::SelectRom & selectRom)
00406       : DS28E15_22_25(sleep, master, selectRom) {}
00407 
00408   /// @brief Perform Write Scratchpad operation on the device.
00409   /// @param[in] data Data to write to the scratchpad.
00410   MaximInterfaceDevices_EXPORT Core::Result<void>
00411   writeScratchpad(Page::const_span data);
00412 
00413   /// @brief Perform a Read Scratchpad operation on the device.
00414   /// @returns Buffer to read data from the scratchpad into.
00415   MaximInterfaceDevices_EXPORT Core::Result<Page::array> readScratchpad() const;
00416 
00417   /// @brief
00418   /// Read the status of a memory protection block using the Read Status command.
00419   /// @param blockNum Block number to to read status of.
00420   /// @returns Receives protection status read from device.
00421   MaximInterfaceDevices_EXPORT Core::Result<BlockProtection>
00422   readBlockProtection(int blockNum) const;
00423 
00424   /// Write memory segment using the Authenticated Write Memory command.
00425   /// @param pageNum Page number for write operation.
00426   /// @param segmentNum Segment number within page for write operation.
00427   /// @param[in] newData New data to write to the segment.
00428   /// @param[in] mac Write MAC computed for this operation.
00429   MaximInterfaceDevices_EXPORT Core::Result<void>
00430   writeAuthSegment(int pageNum, int segmentNum, Segment::const_span newData,
00431                    Page::const_span mac);
00432 
00433   /// @brief Continue an in-progress Authenticated Write Memory command.
00434   /// @param[in] newData New data to write to the segment.
00435   /// @param[in] mac Write MAC computed for this operation.
00436   MaximInterfaceDevices_EXPORT Core::Result<void>
00437   continueWriteAuthSegment(Segment::const_span newData, Page::const_span mac);
00438 
00439   /// @brief
00440   /// Read the status of all memory protection blocks using the Read Status command.
00441   /// @returns Receives protection statuses read from device.
00442   MaximInterfaceDevices_EXPORT
00443       Core::Result<Core::array<BlockProtection, protectionBlocks> >
00444       readAllBlockProtection() const;
00445 };
00446 
00447 /// Interface to the DS28E25 authenticator.
00448 class DS28E25 : public DS28EL25 {
00449 public:
00450   DS28E25(Core::Sleep & sleep, Core::OneWireMaster & master,
00451           const Core::SelectRom & selectRom)
00452       : DS28EL25(sleep, master, selectRom) {}
00453 
00454   /// @brief Perform Load and Lock Secret command on the device.
00455   /// @note The secret should already be stored in the scratchpad on the device.
00456   /// @param lock Prevent further changes to the secret on the device after loading.
00457   MaximInterfaceDevices_EXPORT Core::Result<void> loadSecret(bool lock);
00458 
00459   /// @brief Perform a Compute and Lock Secret command on the device.
00460   /// @param pageNum Page number to use as the binding data.
00461   /// @param lock
00462   /// Prevent further changes to the secret on the device after computing.
00463   MaximInterfaceDevices_EXPORT Core::Result<void> computeSecret(int pageNum,
00464                                                                 bool lock);
00465 };
00466 
00467 /// Represents the status of a memory protection block.
00468 class DS28E15_22_25::BlockProtection {
00469 public:
00470   explicit BlockProtection(uint_least8_t status = 0x00) : status(status) {}
00471 
00472   /// Get the byte representation used by the device.
00473   uint_least8_t statusByte() const { return status; }
00474 
00475   /// Set the byte representation used by the device.
00476   BlockProtection & setStatusByte(uint_least8_t status) {
00477     this->status = status;
00478     return *this;
00479   }
00480 
00481   /// Get the Block Number which is indexed from zero.
00482   int blockNum() const { return (status & blockNumMask); }
00483 
00484   /// Set the Block Number which is indexed from zero.
00485   MaximInterfaceDevices_EXPORT BlockProtection & setBlockNum(int blockNum);
00486 
00487   /// @brief Get the Read Protection status.
00488   /// @returns True if Read Protection is enabled.
00489   bool readProtection() const {
00490     return ((status & readProtectionMask) == readProtectionMask);
00491   }
00492 
00493   /// Set the Read Protection status.
00494   MaximInterfaceDevices_EXPORT BlockProtection &
00495   setReadProtection(bool readProtection);
00496 
00497   /// @brief Get the Write Protection status.
00498   /// @returns True if Write Protection is enabled.
00499   bool writeProtection() const {
00500     return ((status & writeProtectionMask) == writeProtectionMask);
00501   }
00502 
00503   /// Set the Write Protection status.
00504   MaximInterfaceDevices_EXPORT BlockProtection &
00505   setWriteProtection(bool writeProtection);
00506 
00507   /// @brief Get the EEPROM Emulation Mode status.
00508   /// @returns True if EEPROM Emulation Mode is enabled.
00509   bool eepromEmulation() const {
00510     return ((status & eepromEmulationMask) == eepromEmulationMask);
00511   }
00512 
00513   /// Set the EEPROM Emulation Mode status.
00514   MaximInterfaceDevices_EXPORT BlockProtection &
00515   setEepromEmulation(bool eepromEmulation);
00516 
00517   /// @brief Get the Authentication Protection status.
00518   /// @returns True if Authentication Protection is enabled.
00519   bool authProtection() const {
00520     return ((status & authProtectionMask) == authProtectionMask);
00521   }
00522 
00523   /// Set the Authentication Protection status.
00524   MaximInterfaceDevices_EXPORT BlockProtection &
00525   setAuthProtection(bool authProtection);
00526 
00527   /// @brief Check if no protection options are enabled.
00528   /// @returns True if no protection options are enabled.
00529   MaximInterfaceDevices_EXPORT bool noProtection() const;
00530 
00531 private:
00532   static const unsigned int readProtectionMask = 0x80,
00533                             writeProtectionMask = 0x40,
00534                             eepromEmulationMask = 0x20,
00535                             authProtectionMask = 0x10,
00536                             blockNumMask = 0x0F;
00537   uint_least8_t status;
00538 };
00539 
00540 /// Format data to hash for an Authenticated Write to a memory segment.
00541 class DS28E15_22_25::SegmentWriteMacData {
00542 public:
00543   typedef Core::array_span<uint_least8_t, 20> Result;
00544 
00545   SegmentWriteMacData() : result_() {}
00546 
00547   /// Formatted data result.
00548   Result::const_span result() const { return result_; }
00549 
00550   /// @name ROM ID
00551   /// @brief 1-Wire ROM ID of the device.
00552   /// @{
00553 
00554   /// Get mutable ROM ID.
00555   Core::RomId::span romId() {
00556     return make_span(result_).subspan<romIdIdx, Core::RomId::size>();
00557   }
00558 
00559   /// Get immutable ROM ID.
00560   Core::RomId::const_span romId() const {
00561     return const_cast<SegmentWriteMacData &>(*this).romId();
00562   }
00563 
00564   /// Set ROM ID.
00565   SegmentWriteMacData & setRomId(Core::RomId::const_span romId) {
00566     copy(romId, this->romId());
00567     return *this;
00568   }
00569 
00570   /// @}
00571 
00572   /// @name MAN ID
00573   /// @brief Manufacturer ID of the device.
00574   /// @{
00575 
00576   /// Get mutable MAN ID.
00577   Core::ManId::span manId() {
00578     return make_span(result_).subspan<manIdIdx, Core::ManId::size>();
00579   }
00580 
00581   /// Get immutable MAN ID.
00582   Core::ManId::const_span manId() const {
00583     return const_cast<SegmentWriteMacData &>(*this).manId();
00584   }
00585 
00586   /// Set MAN ID.
00587   SegmentWriteMacData & setManId(Core::ManId::const_span manId) {
00588     copy(manId, this->manId());
00589     return *this;
00590   }
00591 
00592   /// @}
00593 
00594   /// @name Page number
00595   /// @brief Page number for write operation.
00596   /// @{
00597 
00598   /// Get page number.
00599   int pageNum() const { return result_[pageNumIdx]; }
00600 
00601   /// Set page number.
00602   SegmentWriteMacData & setPageNum(int pageNum) {
00603     result_[pageNumIdx] = pageNum;
00604     return *this;
00605   }
00606 
00607   /// @}
00608 
00609   /// @name Segment number
00610   /// @brief Segment number within page for write operation.
00611   /// @{
00612 
00613   /// Get segment number.
00614   int segmentNum() const { return result_[segmentNumIdx]; }
00615 
00616   /// Set segment number.
00617   SegmentWriteMacData & setSegmentNum(int segmentNum) {
00618     result_[segmentNumIdx] = segmentNum;
00619     return *this;
00620   }
00621 
00622   /// @}
00623 
00624   /// @name Old data
00625   /// @brief Existing data contained in the segment.
00626   /// @{
00627 
00628   /// Get mutable old data.
00629   Segment::span oldData() {
00630     return make_span(result_).subspan<oldDataIdx, Segment::size>();
00631   }
00632 
00633   /// Get immutable old data.
00634   Segment::const_span oldData() const {
00635     return const_cast<SegmentWriteMacData &>(*this).oldData();
00636   }
00637 
00638   /// Set old data.
00639   SegmentWriteMacData & setOldData(Segment::const_span oldData) {
00640     copy(oldData, this->oldData());
00641     return *this;
00642   }
00643 
00644   /// @}
00645 
00646   /// @name New data
00647   /// @brief New data to write to the segment.
00648   /// @{
00649 
00650   /// Get mutable new data.
00651   Segment::span newData() {
00652     return make_span(result_).subspan<newDataIdx, Segment::size>();
00653   }
00654 
00655   /// Get immutable new data.
00656   Segment::const_span newData() const {
00657     return const_cast<SegmentWriteMacData &>(*this).newData();
00658   }
00659 
00660   /// Set new data.
00661   SegmentWriteMacData & setNewData(Segment::const_span newData) {
00662     copy(newData, this->newData());
00663     return *this;
00664   }
00665 
00666   /// @}
00667 
00668 private:
00669   static const size_t romIdIdx = 0;
00670   static const size_t manIdIdx = romIdIdx + Core::RomId::size;
00671   static const size_t pageNumIdx = manIdIdx + Core::ManId::size;
00672   static const size_t segmentNumIdx = pageNumIdx + 1;
00673   static const size_t oldDataIdx = segmentNumIdx + 1;
00674   static const size_t newDataIdx = oldDataIdx + Segment::size;
00675 
00676   Result::array result_;
00677 };
00678 
00679 /// Format data to hash for an Authenticated Write to a memory protection block.
00680 class DS28E15_22_25::ProtectionWriteMacData {
00681 public:
00682   typedef Core::array_span<uint_least8_t, 20> Result;
00683 
00684   MaximInterfaceDevices_EXPORT ProtectionWriteMacData();
00685 
00686   /// Formatted data result.
00687   Result::const_span result() const { return result_; }
00688 
00689   /// @name ROM ID
00690   /// @brief 1-Wire ROM ID of the device.
00691   /// @{
00692 
00693   /// Get mutable ROM ID.
00694   Core::RomId::span romId() {
00695     return make_span(result_).subspan<romIdIdx, Core::RomId::size>();
00696   }
00697 
00698   /// Get immutable ROM ID.
00699   Core::RomId::const_span romId() const {
00700     return const_cast<ProtectionWriteMacData &>(*this).romId();
00701   }
00702 
00703   /// Set ROM ID.
00704   ProtectionWriteMacData & setRomId(Core::RomId::const_span romId) {
00705     copy(romId, this->romId());
00706     return *this;
00707   }
00708 
00709   /// @}
00710 
00711   /// @name MAN ID
00712   /// @brief Manufacturer ID of the device.
00713   /// @{
00714 
00715   /// Get mutable MAN ID.
00716   Core::ManId::span manId() {
00717     return make_span(result_).subspan<manIdIdx, Core::ManId::size>();
00718   }
00719 
00720   /// Get immutable MAN ID.
00721   Core::ManId::const_span manId() const {
00722     return const_cast<ProtectionWriteMacData &>(*this).manId();
00723   }
00724 
00725   /// Set MAN ID.
00726   ProtectionWriteMacData & setManId(Core::ManId::const_span manId) {
00727     copy(manId, this->manId());
00728     return *this;
00729   }
00730 
00731   /// @}
00732 
00733   /// @name Old protection
00734   /// @brief Existing protection status in device.
00735   /// @{
00736 
00737   /// Get old protection.
00738   BlockProtection oldProtection() const { return oldProtection_; }
00739 
00740   /// Set old protection.
00741   MaximInterfaceDevices_EXPORT ProtectionWriteMacData &
00742   setOldProtection(BlockProtection oldProtection);
00743 
00744   /// @}
00745 
00746   /// @name New protection
00747   /// @brief New protection status to write.
00748   /// @{
00749 
00750   /// Get new protection.
00751   BlockProtection newProtection() const { return newProtection_; }
00752 
00753   /// Set new protection.
00754   MaximInterfaceDevices_EXPORT ProtectionWriteMacData &
00755   setNewProtection(BlockProtection newProtection);
00756 
00757   /// @}
00758 
00759 private:
00760   static const size_t romIdIdx = 0;
00761   static const size_t manIdIdx = romIdIdx + Core::RomId::size;
00762   static const size_t blockNumIdx = manIdIdx + Core::ManId::size;
00763   static const size_t oldProtectionIdx = blockNumIdx + 2;
00764   static const size_t newProtectionIdx = oldProtectionIdx + 4;
00765 
00766   Result::array result_;
00767   BlockProtection oldProtection_;
00768   BlockProtection newProtection_;
00769 };
00770 
00771 /// @brief
00772 /// Format data to hash for device authentication or computing the next secret
00773 /// from the existing secret.
00774 class DS28E15_22_25::AuthenticationData {
00775 public:
00776   typedef Core::array_span<uint_least8_t, 76> Result;
00777 
00778   AuthenticationData() : result_() {}
00779 
00780   /// Formatted data result.
00781   Result::const_span result() const { return result_; }
00782 
00783   /// @name Page
00784   /// @brief Data from a device memory page.
00785   /// @{
00786 
00787   /// Get mutable page.
00788   Page::span page() {
00789     return make_span(result_).subspan<pageIdx, Page::size>();
00790   }
00791 
00792   /// Get immutable page.
00793   Page::const_span page() const {
00794     return const_cast<AuthenticationData &>(*this).page();
00795   }
00796 
00797   /// Set page.
00798   AuthenticationData & setPage(Page::const_span page) {
00799     copy(page, this->page());
00800     return *this;
00801   }
00802 
00803   /// @}
00804 
00805   /// @name Scratchpad
00806   /// @brief
00807   /// Data from device scratchpad used as a random challenge in device
00808   /// authentication and a partial secret in secret computation.
00809   /// @{
00810 
00811   /// Get mutable scratchpad.
00812   Page::span scratchpad() {
00813     return make_span(result_).subspan<scratchpadIdx, Page::size>();
00814   }
00815 
00816   /// Get immutable scratchpad.
00817   Page::const_span scratchpad() const {
00818     return const_cast<AuthenticationData &>(*this).scratchpad();
00819   }
00820 
00821   /// Set scratchpad.
00822   AuthenticationData & setScratchpad(Page::const_span scratchpad) {
00823     copy(scratchpad, this->scratchpad());
00824     return *this;
00825   }
00826 
00827   /// @}
00828 
00829   /// @name ROM ID
00830   /// @brief 1-Wire ROM ID of the device.
00831   /// @{
00832 
00833   /// Get mutable ROM ID.
00834   Core::RomId::span romId() {
00835     return make_span(result_).subspan<romIdIdx, Core::RomId::size>();
00836   }
00837 
00838   /// Get immutable ROM ID.
00839   Core::RomId::const_span romId() const {
00840     return const_cast<AuthenticationData &>(*this).romId();
00841   }
00842 
00843   /// Set ROM ID.
00844   AuthenticationData & setRomId(Core::RomId::const_span romId) {
00845     copy(romId, this->romId());
00846     return *this;
00847   }
00848 
00849   /// Set ROM ID for use in anonymous mode.
00850   MaximInterfaceDevices_EXPORT AuthenticationData & setAnonymousRomId();
00851 
00852   /// @}
00853 
00854   /// @name MAN ID
00855   /// @brief Manufacturer ID of the device.
00856   /// @{
00857 
00858   /// Get mutable MAN ID.
00859   Core::ManId::span manId() {
00860     return make_span(result_).subspan<manIdIdx, Core::ManId::size>();
00861   }
00862 
00863   /// Get immutable MAN ID.
00864   Core::ManId::const_span manId() const {
00865     return const_cast<AuthenticationData &>(*this).manId();
00866   }
00867 
00868   /// Set MAN ID.
00869   AuthenticationData & setManId(Core::ManId::const_span manId) {
00870     copy(manId, this->manId());
00871     return *this;
00872   }
00873 
00874   /// @}
00875 
00876   /// @name Page number
00877   /// @brief Number of the page to use data from.
00878   /// @{
00879 
00880   /// Get page number.
00881   int pageNum() const { return result_[pageNumIdx]; }
00882 
00883   /// Set page number.
00884   AuthenticationData & setPageNum(int pageNum) {
00885     result_[pageNumIdx] = pageNum;
00886     return *this;
00887   }
00888 
00889   /// @}
00890 
00891 private:
00892   static const size_t pageIdx = 0;
00893   static const size_t scratchpadIdx = pageIdx + Page::size;
00894   static const size_t romIdIdx = scratchpadIdx + Page::size;
00895   static const size_t manIdIdx = romIdIdx + Core::RomId::size;
00896   static const size_t pageNumIdx = manIdIdx + Core::ManId::size;
00897 
00898   Result::array result_;
00899 };
00900 
00901 } // namespace MaximInterfaceDevices
00902 
00903 #endif