Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: mbed_DS28EC20_GPIO
DS28E38.hpp
00001 /******************************************************************************* 00002 * Copyright (C) 2017 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 MaximInterface_DS28E38 00034 #define MaximInterface_DS28E38 00035 00036 #include <stdint.h> 00037 #include <MaximInterface/Links/RunCommand.hpp> 00038 #include <MaximInterface/Utilities/array_span.hpp> 00039 #include <MaximInterface/Utilities/Ecc256.hpp> 00040 #include <MaximInterface/Utilities/Export.h> 00041 #include <MaximInterface/Utilities/FlagSet.hpp> 00042 #include <MaximInterface/Utilities/ManId.hpp> 00043 #include <MaximInterface/Utilities/system_error.hpp> 00044 00045 namespace MaximInterface { 00046 00047 class DS28E38 { 00048 public: 00049 /// Device command results. 00050 enum ErrorValue { 00051 InvalidOperationError = 0x55, 00052 InvalidParameterError = 0x77, 00053 InvalidSequenceError = 0x33, 00054 InternalError = 0x22, 00055 DeviceDisabledError = 0x88, 00056 InvalidResponseError = 00057 0x100 ///< Command response does not match expected format. 00058 }; 00059 00060 /// @name Device memory pages 00061 /// @{ 00062 00063 static const int decrementCounterPage = 3; 00064 static const int publicKeyXPage = 4; 00065 static const int publicKeyYPage = 5; 00066 static const int privateKeyPage = 6; 00067 00068 /// @} 00069 00070 static const int memoryPages = 7; 00071 00072 /// Holds a device memory page. 00073 typedef array_span<uint_least8_t, 32> Page; 00074 00075 // Format page authentication input data. 00076 class PageAuthenticationData; 00077 00078 /// Page protection types. 00079 enum PageProtectionType { 00080 RP = 0x01, ///< Read protection. 00081 WP = 0x02, ///< Write protection. 00082 EM = 0x04, ///< EPROM emulation mode. 00083 DC = 0x08, ///< Decrement counter. 00084 PF = 0x10 ///< PUF used as private key. 00085 }; 00086 typedef FlagSet<PageProtectionType, 5> PageProtection; 00087 00088 struct Status { 00089 enum EntropyHealthTestStatus { 00090 TestNotPerformed = 0xFF, 00091 EntropyHealthy = 0xAA, 00092 EntropyNotHealthy = 0xDD 00093 }; 00094 00095 typedef array<PageProtection, memoryPages> PageProtectionList; 00096 typedef array<uint_least8_t, 2> RomVersion; 00097 00098 PageProtectionList pageProtection; 00099 ManId::array manId; 00100 RomVersion romVersion; 00101 EntropyHealthTestStatus entropyHealthTestStatus; 00102 }; 00103 00104 explicit DS28E38(const RunCommand & runCommand) : doRunCommand(runCommand) {} 00105 00106 void setRunCommand(const RunCommand & runCommand) { 00107 doRunCommand = runCommand; 00108 } 00109 00110 /// @brief Write memory with no protection. 00111 /// @param pageNum Number of page to write. 00112 /// @param page Data to write. 00113 MaximInterface_EXPORT error_code writeMemory(int pageNum, 00114 Page::const_span page); 00115 00116 /// @brief Read memory with no protection. 00117 /// @param pageNum Number of page to read. 00118 /// @param[out] page Data that was read. 00119 MaximInterface_EXPORT error_code readMemory(int pageNum, Page::span page); 00120 00121 /// @brief 00122 /// Reads the current status of the device and optionally performs an 00123 /// entropy health test. 00124 /// @param entropyHealthTest True to perform an entropy health test. 00125 /// @param[out] status Status that was read. 00126 MaximInterface_EXPORT error_code readStatus(bool entropyHealthTest, 00127 Status & status); 00128 00129 /// @brief Set the protection settings of a page. 00130 /// @param pageNum Number of page to write. 00131 /// @param protection Protection to write. 00132 MaximInterface_EXPORT error_code 00133 setPageProtection(int pageNum, const PageProtection & protection); 00134 00135 /// @brief Compute and read page authentication with ECDSA. 00136 /// @param pageNum Number of page to authenticate. 00137 /// @param anonymous True to disable use of ROM ID in computation. 00138 /// @param challenge Random challenge used to prevent replay attacks. 00139 /// @param[out] signature Computed page signature. 00140 MaximInterface_EXPORT error_code computeAndReadPageAuthentication( 00141 int pageNum, bool anonymous, Page::const_span challenge, 00142 Ecc256::Signature::span signature); 00143 00144 /// Decrement the decrement-only counter. 00145 MaximInterface_EXPORT error_code decrementCounter(); 00146 00147 /// Permanently disable the device. 00148 MaximInterface_EXPORT error_code disableDevice(); 00149 00150 /// @brief Generate a new ECDSA public key from an existing private key. 00151 /// @param privateKeyPuf True if PUF is used as the private key. 00152 /// @param writeProtectEnable True to lock the key against further writes. 00153 MaximInterface_EXPORT error_code 00154 generateEcc256KeyPair(bool privateKeyPuf, bool writeProtectEnable); 00155 00156 /// @brief Read a block of random data from the RNG. 00157 /// @param[out] data Random data from RNG with length from 1 to 64. 00158 MaximInterface_EXPORT error_code readRng(span<uint_least8_t> data); 00159 00160 MaximInterface_EXPORT static const error_category & errorCategory(); 00161 00162 protected: 00163 MaximInterface_EXPORT error_code runCommand(span<const uint_least8_t> command, 00164 int delayTime, 00165 span<uint_least8_t> & response); 00166 00167 MaximInterface_EXPORT error_code runCommand(span<const uint_least8_t> command, 00168 int delayTime); 00169 00170 private: 00171 RunCommand doRunCommand; 00172 }; 00173 00174 inline error_code make_error_code(DS28E38::ErrorValue e) { 00175 return error_code(e, DS28E38::errorCategory()); 00176 } 00177 00178 /// @brief Read the device MAN ID using the Read Status command. 00179 /// @param ds28e38 Device to read. 00180 /// @param[out] manId Read MAN ID valid when operation is successful. 00181 MaximInterface_EXPORT error_code readManId(DS28E38 & ds28e38, 00182 ManId::span manId); 00183 00184 /// Format page authentication input data. 00185 class DS28E38::PageAuthenticationData { 00186 public: 00187 typedef array_span<uint_least8_t, 00188 RomId::size + 2 * Page::size + 1 + ManId::size> 00189 Result; 00190 00191 PageAuthenticationData() : result_() {} 00192 00193 /// Formatted data result. 00194 Result::const_span result() const { return result_; } 00195 00196 /// @name ROM ID 00197 /// @brief 1-Wire ROM ID of the device. 00198 /// @{ 00199 00200 /// Get mutable ROM ID. 00201 RomId::span romId() { 00202 return make_span(result_).subspan<romIdIdx, RomId::size>(); 00203 } 00204 00205 /// Get immutable ROM ID. 00206 RomId::const_span romId() const { 00207 return const_cast<PageAuthenticationData &>(*this).romId(); 00208 } 00209 00210 /// Set ROM ID. 00211 PageAuthenticationData & setRomId(RomId::const_span romId) { 00212 copy(romId, this->romId()); 00213 return *this; 00214 } 00215 00216 /// Set ROM ID for use in anonymous mode. 00217 MaximInterface_EXPORT PageAuthenticationData & setAnonymousRomId(); 00218 00219 /// @} 00220 00221 /// @name Page 00222 /// @brief Data from a device memory page. 00223 /// @{ 00224 00225 /// Get mutable page. 00226 Page::span page() { 00227 return make_span(result_).subspan<pageIdx, Page::size>(); 00228 } 00229 00230 /// Get immutable page. 00231 Page::const_span page() const { 00232 return const_cast<PageAuthenticationData &>(*this).page(); 00233 } 00234 00235 /// Set page. 00236 PageAuthenticationData & setPage(Page::const_span page) { 00237 copy(page, this->page()); 00238 return *this; 00239 } 00240 00241 /// @} 00242 00243 /// @name Challenge 00244 /// @brief Random challenge used to prevent replay attacks. 00245 /// @{ 00246 00247 /// Get mutable Challenge. 00248 Page::span challenge() { 00249 return make_span(result_).subspan<challengeIdx, Page::size>(); 00250 } 00251 00252 /// Get immutable Challenge. 00253 Page::const_span challenge() const { 00254 return const_cast<PageAuthenticationData &>(*this).challenge(); 00255 } 00256 00257 /// Set Challenge. 00258 PageAuthenticationData & setChallenge(Page::const_span challenge) { 00259 copy(challenge, this->challenge()); 00260 return *this; 00261 } 00262 00263 /// @} 00264 00265 /// @name Page number 00266 /// @brief Number of the page to use data from. 00267 /// @{ 00268 00269 /// Get page number. 00270 int pageNum() const { return result_[pageNumIdx]; } 00271 00272 /// Set page number. 00273 PageAuthenticationData & setPageNum(int pageNum) { 00274 result_[pageNumIdx] = pageNum; 00275 return *this; 00276 } 00277 00278 /// @} 00279 00280 /// @name MAN ID 00281 /// @brief Manufacturer ID of the device. 00282 /// @{ 00283 00284 /// Get mutable MAN ID. 00285 ManId::span manId() { 00286 return make_span(result_).subspan<manIdIdx, ManId::size>(); 00287 } 00288 00289 /// Get immutable MAN ID. 00290 ManId::const_span manId() const { 00291 return const_cast<PageAuthenticationData &>(*this).manId(); 00292 } 00293 00294 /// Set MAN ID. 00295 PageAuthenticationData & setManId(ManId::const_span manId) { 00296 copy(manId, this->manId()); 00297 return *this; 00298 } 00299 00300 /// @} 00301 00302 private: 00303 typedef Result::span::index_type index; 00304 00305 static const index romIdIdx = 0; 00306 static const index pageIdx = romIdIdx + RomId::size; 00307 static const index challengeIdx = pageIdx + Page::size; 00308 static const index pageNumIdx = challengeIdx + Page::size; 00309 static const index manIdIdx = pageNumIdx + 1; 00310 00311 Result::array result_; 00312 }; 00313 00314 } // namespace MaximInterface 00315 00316 #endif
Generated on Tue Jul 12 2022 23:29:45 by
1.7.2