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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DS28E15_22_25.h Source File

DS28E15_22_25.h

00001 /******************************************************************//**
00002 * Copyright (C) 2016 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 OneWire_Authenticators_DS28E15_22_25
00034 #define OneWire_Authenticators_DS28E15_22_25
00035 
00036 #include "Utilities/array.h"
00037 #include "Slaves/Authenticators/ISha256MacCoproc.h"
00038 #include "Slaves/OneWireSlave.h"
00039 
00040 namespace OneWire
00041 {
00042     /// Interface to the DS28E15/22/25 series of authenticators including low power variants.
00043     class DS28E15_22_25 : public OneWireSlave
00044     {
00045     public:
00046         /// Holds the contents of a device memory segment.
00047         typedef array<uint8_t, 4>  Segment;
00048 
00049         /// Holds the contents of a device memory page.
00050         typedef array<uint8_t, 32> Page;
00051 
00052         /// Holds the contents of the device scratchpad.
00053         typedef array<uint8_t, 32> Scratchpad;
00054 
00055         /// Container for a SHA-256 MAC.
00056         typedef array<uint8_t, 32> Mac;
00057 
00058         /// Container for a manufacturer ID.
00059         typedef array<uint8_t, 2>  ManId;
00060 
00061         /// Container for the device personality.
00062         class Personality
00063         {
00064         public:
00065             typedef array<uint8_t, 4>  Buffer ;
00066             
00067         private:
00068             Buffer  m_data;
00069 
00070         public:
00071             Personality() { }
00072             explicit Personality(const Buffer  & dataBytes) : m_data(dataBytes) { }
00073            
00074             uint8_t PB1() const { return m_data[0]; }
00075             uint8_t PB2() const { return m_data[1]; }
00076             ManId  manId() const { ManId  manId = { m_data[2], m_data[3] }; return manId; }
00077             bool secretLocked() const { return (PB2() & 0x01); }
00078             
00079             bool operator==(const Personality & rhs) const { return (this->m_data == rhs.m_data); }
00080             bool operator!=(const Personality & rhs) const { return !operator==(rhs); }
00081         };
00082 
00083         /// Represents the status of a memory protection block.
00084         class BlockProtection
00085         {
00086         private:
00087             static const uint8_t readProtectionMask = 0x80, writeProtectionMask = 0x40, eepromEmulationMask = 0x20, authProtectionMask = 0x10, blockNumMask = 0x0F;
00088             uint8_t m_status;
00089 
00090         public:
00091             explicit BlockProtection(uint8_t status = 0x00) : m_status(status) { }
00092             BlockProtection(bool readProtection, bool writeProtection, bool eepromEmulation, bool authProtection, unsigned int blockNum);
00093 
00094             /// Get the byte representation used by the device.
00095             uint8_t statusByte() const { return m_status; }
00096             /// Set the byte representation used by the device.
00097             void setStatusByte(uint8_t status) { m_status = status; }
00098 
00099             /// Get the Block Number which is indexed from zero.
00100             unsigned int blockNum() const { return (m_status & blockNumMask); }
00101             /// Set the Block Number which is indexed from zero.
00102             void setBlockNum(unsigned int blockNum);
00103 
00104             /// Get the Read Protection status.
00105             /// @returns True if Read Protection is enabled.
00106             bool readProtection() const { return ((m_status & readProtectionMask) == readProtectionMask); }
00107             /// Set the Read Protection status.
00108             void setReadProtection(bool readProtection);
00109 
00110             /// Get the Write Protection status.
00111             /// @returns True if Write Protection is enabled.
00112             bool writeProtection() const { return ((m_status & writeProtectionMask) == writeProtectionMask); }
00113             /// Set the Write Protection status.
00114             void setWriteProtection(bool writeProtection);
00115 
00116             /// Get the EEPROM Emulation Mode status.
00117             /// @returns True if EEPROM Emulation Mode is enabled.
00118             bool eepromEmulation() const { return ((m_status & eepromEmulationMask) == eepromEmulationMask); }
00119             /// Set the EEPROM Emulation Mode status.
00120             void setEepromEmulation(bool eepromEmulation);
00121 
00122             /// Get the Authentication Protection status.
00123             /// @returns True if Authentication Protection is enabled.
00124             bool authProtection() const { return ((m_status & authProtectionMask) == authProtectionMask); }
00125             /// Set the Authentication Protection status.
00126             void setAuthProtection(bool authProtection);
00127 
00128             /// Check if no protection options are enabled.
00129             /// @returns True if no protection options are enabled.
00130             bool noProtection() const;
00131 
00132             bool operator==(const BlockProtection & rhs) const { return (this->m_status == rhs.m_status); }
00133             bool operator!=(const BlockProtection & rhs) const { return !operator==(rhs); }
00134         };
00135 
00136         /// Compute the MAC for an Authenticated Write to a memory segment.
00137         /// @param MacCoproc Coprocessor with Slave Secret to use for the computation.
00138         /// @param pageNum Page number for write operation.
00139         /// @param segmentNum Segment number within page for write operation.
00140         /// @param[in] newData New data to write to the segment.
00141         /// @param[in] oldData Existing data contained in the segment.
00142         /// @param[in] romId 1-Wire ROM ID of the device.
00143         /// @param[in] manId Manufacturer ID of the device.
00144         /// @param[out] mac The computed MAC.
00145         /// @returns The result code indicated by the coprocessor.
00146         static ISha256MacCoproc::CmdResult computeSegmentWriteMac(const ISha256MacCoproc & MacCoproc,
00147                                                                   unsigned int pageNum,
00148                                                                   unsigned int segmentNum,
00149                                                                   const Segment & newData,
00150                                                                   const Segment & oldData,
00151                                                                   const RomId & romId ,
00152                                                                   const ManId & manId ,
00153                                                                   Mac & mac);
00154 
00155         /// Compute the MAC for an Authenticated Write to a memory protection block.
00156         /// @param MacCoproc Coprocessor with Slave Secret to use for the operation.
00157         /// @param[in] newProtection New protection status to write.
00158         /// @param[in] oldProtection Existing protection status in device.
00159         /// @param[in] romId 1-Wire ROM ID of the device.
00160         /// @param[in] manId Manufacturer ID of the device.
00161         /// @param[out] mac The computed MAC.
00162         /// @returns The result code indicated by the coprocessor.
00163         static ISha256MacCoproc::CmdResult computeProtectionWriteMac(const ISha256MacCoproc & MacCoproc,
00164                                                                      const BlockProtection & newProtection,
00165                                                                      const BlockProtection & oldProtection,
00166                                                                      const RomId & romId ,
00167                                                                      const ManId & manId ,
00168                                                                      Mac & mac);
00169 
00170         /// Compute the next secret from the existing secret.
00171         /// @param MacCoproc Coprocessor with Master Secret to use for the operation.
00172         ///        Slave Secret will be updated with the computation result.
00173         /// @param[in] bindingPage Binding data from a device memory page.
00174         /// @param bindingPageNum Number of the page where the binding data is from.
00175         /// @param[in] partialSecret Partial secret data from the device scratchpad.
00176         /// @param[in] romId 1-Wire ROM ID of the device.
00177         /// @param[in] manId Manufacturer ID of the device.
00178         /// @returns The result code indicated by the coprocessor.
00179         static ISha256MacCoproc::CmdResult computeNextSecret(ISha256MacCoproc & MacCoproc,
00180                                                              const Page & bindingPage,
00181                                                              unsigned int bindingPageNum,
00182                                                              const Scratchpad & partialSecret,
00183                                                              const RomId & romId ,
00184                                                              const ManId & manId );
00185 
00186         /// Compute a Page MAC for authentication.
00187         /// @param MacCoproc Coprocessor with Slave Secret to use for the operation.
00188         /// @param[in] pageData Data from a device memory page.
00189         /// @param pageNum Number of the page to use data from.
00190         /// @param[in] challenge Random challenge to prevent replay attacks.
00191         /// @param[in] romId 1-Wire ROM ID of the device.
00192         /// @param[in] manId Manufacturer ID of the device.
00193         /// @param[out] mac The computed MAC.
00194         static ISha256MacCoproc::CmdResult computeAuthMac(const ISha256MacCoproc & MacCoproc,
00195                                                           const Page & pageData,
00196                                                           unsigned int pageNum,
00197                                                           const Scratchpad & challenge,
00198                                                           const RomId & romId ,
00199                                                           const ManId & manId ,
00200                                                           Mac & mac);
00201 
00202         /// Compute a Page MAC for authentication using anonymous mode.
00203         /// @param MacCoproc Coprocessor with Slave Secret to use for the operation.
00204         /// @param[in] pageData Data from a device memory page.
00205         /// @param pageNum Number of the page to use data from.
00206         /// @param[in] challenge Random challenge to prevent replay attacks.
00207         /// @param[in] manId Manufacturer ID of the device.
00208         /// @param[out] mac The computed MAC.
00209         static ISha256MacCoproc::CmdResult computeAuthMacAnon(const ISha256MacCoproc & MacCoproc,
00210                                                               const Page & pageData,
00211                                                               unsigned int pageNum,
00212                                                               const Scratchpad & challenge,
00213                                                               const ManId & manId ,
00214                                                               Mac & mac);
00215 
00216         /// Number of segments per page.
00217         static const unsigned int segmentsPerPage = (Page::csize / Segment::csize);
00218         
00219         /// Creates a segment representation from a subsection of the page data.
00220         /// @param segmentNum Segment number within page to copy from.
00221         /// @returns The copied segment data.
00222         static Segment  segmentFromPage(unsigned int segmentNum, const Page & page);
00223 
00224         /// Copies segment data to the page.
00225         /// @param segmentNum Segment number within the page to copy to.
00226         /// @param[in] segment Segment to copy from.
00227         static void segmentToPage(unsigned int segmentNum, const Segment  & segment, Page & page);
00228 
00229         /// @{
00230         /// Manufacturer ID
00231         ManId  manId () const { return m_manId; }
00232         void setManId(const ManId & manId ) { m_manId = manId ; }
00233         /// @}
00234 
00235         /// @{
00236         /// Enable low voltage timing
00237         bool lowVoltage () const { return m_lowVoltage; }
00238         void setLowVoltage(bool lowVoltage ) { m_lowVoltage = lowVoltage ; }
00239         /// @}
00240 
00241         // Const member functions should not affect the state of the memory, block protection, or secret on the DS28Exx.
00242         // Scratchpad on the DS28Exx is considered mutable.
00243 
00244         /// Perform Load and Lock Secret command on the device.
00245         /// @note The secret should already be stored in the scratchpad on the device.
00246         /// @param lock Prevent further changes to the secret on the device after loading.
00247         CmdResult loadSecret(bool lock);
00248 
00249         /// Read memory segment using the Read Memory command on the device.
00250         /// @note 1-Wire ROM selection should have already occurred.
00251         /// @param pageNum Page number for read operation.
00252         /// @param segmentNum Segment number within page for read operation.
00253         /// @param[out] data Buffer to read data from the segment into.
00254         /// @param continuing True if continuing a previous Read Memory command.
00255         ///                   False to begin a new command.
00256         CmdResult readSegment(unsigned int pageNum, unsigned int segmentNum, Segment & data, bool continuing = false) const;
00257 
00258         /// Write memory segment using the Write Memory command.
00259         /// @note 1-Wire ROM selection should have already occurred.
00260         /// @param pageNum Page number for write operation.
00261         /// @param segmentNum Segment number within page for write operation.
00262         /// @param[in] data Data to write to the memory segment.
00263         /// @param continuing True to continue writing with the next sequential segment.
00264         ///                   False to begin a new command.
00265         CmdResult writeSegment(unsigned int pageNum, unsigned int segmentNum, const Segment & data, bool continuing = false);
00266 
00267         /// Read memory page using the Read Memory command on the device.
00268         /// @note 1-Wire ROM selection should have already occurred.
00269         /// @param pageNum Page number for write operation.
00270         /// @param[out] rdbuf Buffer to read data from the page into.
00271         /// @param continuing True if continuing a previous Read Memory command.
00272         ///                   False to begin a new command.
00273         CmdResult readPage(unsigned int pageNum, Page & rdbuf, bool continuing = false) const;
00274 
00275         /// Perform a Compute and Lock Secret command on the device.
00276         /// @note 1-Wire ROM selection should have already occurred.
00277         /// @param pageNum Page number to use as the binding data.
00278         /// @param lock Prevent further changes to the secret on the device after computing.
00279         CmdResult computeSecret(unsigned int pageNum, bool lock);
00280 
00281         /// Perform a Compute Page MAC command on the device.
00282         /// Read back the MAC and verify the CRC16.
00283         /// @note 1-Wire ROM selection should have already occurred.
00284         /// @param pageNum Page number to use for the computation.
00285         /// @param anon True to compute in anonymous mode where ROM ID is not used.
00286         /// @param[out] mac The device computed MAC.
00287         CmdResult computeReadPageMac(unsigned int pageNum, bool anon, Mac & mac) const;
00288 
00289         /// Update the status of a memory protection block using the Write Page Protection command.
00290         /// @note 1-Wire ROM selection should have already occurred.
00291         /// @param[in] Desired protection status for the block.
00292         ///            It is not possible to disable existing protections.
00293         /// @param continuing True to continue a previous Write Page Protection command.
00294         ///                   False to begin a new command.
00295         CmdResult writeBlockProtection(const BlockProtection & protection);
00296 
00297         /// Update the status of a memory protection block using the Authenticated Write Page Protection command.
00298         /// @note 1-Wire ROM selection should have already occurred.
00299         /// @param MacCoproc Coprocessor with Slave Secret to use for the operation.
00300         /// @param[in] newProtection New protection status to write.
00301         /// @param[in] oldProtection Existing protection status in device.
00302         /// @param continuing True to continue a previous Authenticated Write Page Protection command.
00303         ///                   False to begin a new command.
00304         CmdResult writeAuthBlockProtection(const ISha256MacCoproc & MacCoproc,
00305                                            const BlockProtection & newProtection,
00306                                            const BlockProtection & oldProtection);
00307                                       
00308     protected:    
00309         /// @param owMaster 1-Wire Master to use for communication with DS28E15/22/25.
00310         /// @param lowVoltage Enable low voltage timing.
00311         DS28E15_22_25 (RandomAccessRomIterator & selector, bool lowVoltage );
00312         
00313         ~DS28E15_22_25 () { }
00314         
00315         template <class T>
00316         CmdResult doWriteScratchpad(const Scratchpad & data) const;
00317 
00318         template <class T>
00319         CmdResult doReadScratchpad(Scratchpad & data) const;
00320         
00321         template <class T>
00322         CmdResult doReadBlockProtection(unsigned int blockNum, BlockProtection & protection) const;
00323 
00324         template <class T>
00325         CmdResult doReadPersonality(Personality & personality) const;
00326         
00327         template <class T>
00328         CmdResult doWriteAuthSegment(const ISha256MacCoproc & MacCoproc,
00329                                      unsigned int pageNum,
00330                                      unsigned int segmentNum,
00331                                      const Segment & newData,
00332                                      const Segment & oldData,
00333                                      bool continuing);
00334 
00335         template <class T>
00336         CmdResult doWriteAuthSegmentMac(unsigned int pageNum,
00337                                         unsigned int segmentNum,
00338                                         const Segment & newData,
00339                                         const Mac & mac,
00340                                         bool continuing);
00341         
00342         template <class T, size_t N>
00343         CmdResult doReadAllBlockProtection(array<BlockProtection, N> & protection) const;
00344 
00345     private:
00346         /// Read status bytes which are either personality or block protection.
00347         /// @note 1-Wire ROM selection should have already occurred.
00348         /// @param personality True to read personality or false to read block protection.
00349         /// @param allpages True to read all pages or false to read one page.
00350         /// @param pageNum Page number if reading block protection.
00351         /// @param rdbuf Buffer to receive data read from device.
00352         template <class T>
00353         CmdResult readStatus(bool personality, bool allpages, unsigned int blockNum, uint8_t * rdbuf) const;
00354     
00355         ManId m_manId;
00356         bool m_lowVoltage;
00357     
00358         static const unsigned int shaComputationDelayMs = 3;
00359         static const unsigned int eepromWriteDelayMs = 10;
00360         unsigned int secretEepromWriteDelayMs() const { return (m_lowVoltage ? 200 : 100); }
00361     };
00362 }
00363 
00364 #endif