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
Devices/DS28C36_DS2476.hpp@3:f818ea5172ed, 2018-01-11 (annotated)
- Committer:
- IanBenzMaxim
- Date:
- Thu Jan 11 13:50:39 2018 -0600
- Revision:
- 3:f818ea5172ed
- Parent:
- 0:f77ad7f72d04
- Child:
- 6:a8c83a2e6fa4
Updated to version 1.1.
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| IanBenzMaxim | 0:f77ad7f72d04 | 1 | /******************************************************************************* |
| IanBenzMaxim | 0:f77ad7f72d04 | 2 | * Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. |
| IanBenzMaxim | 0:f77ad7f72d04 | 3 | * |
| IanBenzMaxim | 0:f77ad7f72d04 | 4 | * Permission is hereby granted, free of charge, to any person obtaining a |
| IanBenzMaxim | 0:f77ad7f72d04 | 5 | * copy of this software and associated documentation files (the "Software"), |
| IanBenzMaxim | 0:f77ad7f72d04 | 6 | * to deal in the Software without restriction, including without limitation |
| IanBenzMaxim | 0:f77ad7f72d04 | 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| IanBenzMaxim | 0:f77ad7f72d04 | 8 | * and/or sell copies of the Software, and to permit persons to whom the |
| IanBenzMaxim | 0:f77ad7f72d04 | 9 | * Software is furnished to do so, subject to the following conditions: |
| IanBenzMaxim | 0:f77ad7f72d04 | 10 | * |
| IanBenzMaxim | 0:f77ad7f72d04 | 11 | * The above copyright notice and this permission notice shall be included |
| IanBenzMaxim | 0:f77ad7f72d04 | 12 | * in all copies or substantial portions of the Software. |
| IanBenzMaxim | 0:f77ad7f72d04 | 13 | * |
| IanBenzMaxim | 0:f77ad7f72d04 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| IanBenzMaxim | 0:f77ad7f72d04 | 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| IanBenzMaxim | 0:f77ad7f72d04 | 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
| IanBenzMaxim | 0:f77ad7f72d04 | 17 | * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES |
| IanBenzMaxim | 0:f77ad7f72d04 | 18 | * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
| IanBenzMaxim | 0:f77ad7f72d04 | 19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| IanBenzMaxim | 0:f77ad7f72d04 | 20 | * OTHER DEALINGS IN THE SOFTWARE. |
| IanBenzMaxim | 0:f77ad7f72d04 | 21 | * |
| IanBenzMaxim | 0:f77ad7f72d04 | 22 | * Except as contained in this notice, the name of Maxim Integrated |
| IanBenzMaxim | 0:f77ad7f72d04 | 23 | * Products, Inc. shall not be used except as stated in the Maxim Integrated |
| IanBenzMaxim | 0:f77ad7f72d04 | 24 | * Products, Inc. Branding Policy. |
| IanBenzMaxim | 0:f77ad7f72d04 | 25 | * |
| IanBenzMaxim | 0:f77ad7f72d04 | 26 | * The mere transfer of this software does not imply any licenses |
| IanBenzMaxim | 0:f77ad7f72d04 | 27 | * of trade secrets, proprietary technology, copyrights, patents, |
| IanBenzMaxim | 0:f77ad7f72d04 | 28 | * trademarks, maskwork rights, or any other form of intellectual |
| IanBenzMaxim | 0:f77ad7f72d04 | 29 | * property whatsoever. Maxim Integrated Products, Inc. retains all |
| IanBenzMaxim | 0:f77ad7f72d04 | 30 | * ownership rights. |
| IanBenzMaxim | 0:f77ad7f72d04 | 31 | *******************************************************************************/ |
| IanBenzMaxim | 0:f77ad7f72d04 | 32 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 33 | #ifndef MaximInterface_DS28C36_DS2476 |
| IanBenzMaxim | 0:f77ad7f72d04 | 34 | #define MaximInterface_DS28C36_DS2476 |
| IanBenzMaxim | 0:f77ad7f72d04 | 35 | |
| IanBenzMaxim | 3:f818ea5172ed | 36 | #include <stddef.h> |
| IanBenzMaxim | 3:f818ea5172ed | 37 | #include <stdint.h> |
| IanBenzMaxim | 0:f77ad7f72d04 | 38 | #include <vector> |
| IanBenzMaxim | 0:f77ad7f72d04 | 39 | #include <MaximInterface/Links/I2CMaster.hpp> |
| IanBenzMaxim | 0:f77ad7f72d04 | 40 | #include <MaximInterface/Links/Sleep.hpp> |
| IanBenzMaxim | 0:f77ad7f72d04 | 41 | #include <MaximInterface/Utilities/array.hpp> |
| IanBenzMaxim | 0:f77ad7f72d04 | 42 | #include <MaximInterface/Utilities/Ecc256.hpp> |
| IanBenzMaxim | 0:f77ad7f72d04 | 43 | #include <MaximInterface/Utilities/Export.h> |
| IanBenzMaxim | 0:f77ad7f72d04 | 44 | #include <MaximInterface/Utilities/RomId.hpp> |
| IanBenzMaxim | 0:f77ad7f72d04 | 45 | #include <MaximInterface/Utilities/ManId.hpp> |
| IanBenzMaxim | 0:f77ad7f72d04 | 46 | #include <MaximInterface/Utilities/Sha256.hpp> |
| IanBenzMaxim | 0:f77ad7f72d04 | 47 | #include <MaximInterface/Utilities/system_error.hpp> |
| IanBenzMaxim | 0:f77ad7f72d04 | 48 | #include <MaximInterface/Utilities/FlagSet.hpp> |
| IanBenzMaxim | 0:f77ad7f72d04 | 49 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 50 | namespace MaximInterface { |
| IanBenzMaxim | 0:f77ad7f72d04 | 51 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 52 | /// Interface to the DS28C36 authenticator. |
| IanBenzMaxim | 0:f77ad7f72d04 | 53 | class DS28C36 { |
| IanBenzMaxim | 0:f77ad7f72d04 | 54 | public: |
| IanBenzMaxim | 0:f77ad7f72d04 | 55 | /// Device command results. |
| IanBenzMaxim | 0:f77ad7f72d04 | 56 | enum ErrorValue { |
| IanBenzMaxim | 0:f77ad7f72d04 | 57 | ProtectionError = 0x55, |
| IanBenzMaxim | 0:f77ad7f72d04 | 58 | InvalidParameterError = 0x77, |
| IanBenzMaxim | 0:f77ad7f72d04 | 59 | InvalidSequenceError = 0x33, |
| IanBenzMaxim | 0:f77ad7f72d04 | 60 | InvalidEcdsaInputOrResultError = 0x22, |
| IanBenzMaxim | 0:f77ad7f72d04 | 61 | AuthenticationError = 0x100, |
| IanBenzMaxim | 0:f77ad7f72d04 | 62 | InvalidResponseError = 0x101 ///< Response does not match expected format. |
| IanBenzMaxim | 0:f77ad7f72d04 | 63 | }; |
| IanBenzMaxim | 0:f77ad7f72d04 | 64 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 65 | /// Device memory pages. |
| IanBenzMaxim | 0:f77ad7f72d04 | 66 | enum PageNum { |
| IanBenzMaxim | 0:f77ad7f72d04 | 67 | UserData0 = 0, |
| IanBenzMaxim | 0:f77ad7f72d04 | 68 | UserData1, |
| IanBenzMaxim | 0:f77ad7f72d04 | 69 | UserData2, |
| IanBenzMaxim | 0:f77ad7f72d04 | 70 | UserData3, |
| IanBenzMaxim | 0:f77ad7f72d04 | 71 | UserData4, |
| IanBenzMaxim | 0:f77ad7f72d04 | 72 | UserData5, |
| IanBenzMaxim | 0:f77ad7f72d04 | 73 | UserData6, |
| IanBenzMaxim | 0:f77ad7f72d04 | 74 | UserData7, |
| IanBenzMaxim | 0:f77ad7f72d04 | 75 | UserData8, |
| IanBenzMaxim | 0:f77ad7f72d04 | 76 | UserData9, |
| IanBenzMaxim | 0:f77ad7f72d04 | 77 | UserData10, |
| IanBenzMaxim | 0:f77ad7f72d04 | 78 | UserData11, |
| IanBenzMaxim | 0:f77ad7f72d04 | 79 | UserData12, |
| IanBenzMaxim | 0:f77ad7f72d04 | 80 | UserData13, |
| IanBenzMaxim | 0:f77ad7f72d04 | 81 | UserData14, |
| IanBenzMaxim | 0:f77ad7f72d04 | 82 | UserData15, |
| IanBenzMaxim | 0:f77ad7f72d04 | 83 | PublicKeyAX, |
| IanBenzMaxim | 0:f77ad7f72d04 | 84 | PublicKeyAY, |
| IanBenzMaxim | 0:f77ad7f72d04 | 85 | PublicKeyBX, |
| IanBenzMaxim | 0:f77ad7f72d04 | 86 | PublicKeyBY, |
| IanBenzMaxim | 0:f77ad7f72d04 | 87 | PublicKeyCX, |
| IanBenzMaxim | 0:f77ad7f72d04 | 88 | PublicKeyCY, |
| IanBenzMaxim | 0:f77ad7f72d04 | 89 | PrivateKeyA, |
| IanBenzMaxim | 0:f77ad7f72d04 | 90 | PrivateKeyB, |
| IanBenzMaxim | 0:f77ad7f72d04 | 91 | PrivateKeyC, |
| IanBenzMaxim | 0:f77ad7f72d04 | 92 | SecretA, |
| IanBenzMaxim | 0:f77ad7f72d04 | 93 | SecretB, |
| IanBenzMaxim | 0:f77ad7f72d04 | 94 | DecrementCounter, |
| IanBenzMaxim | 0:f77ad7f72d04 | 95 | RomOptions, |
| IanBenzMaxim | 0:f77ad7f72d04 | 96 | GpioControl, |
| IanBenzMaxim | 0:f77ad7f72d04 | 97 | PublicKeySX, |
| IanBenzMaxim | 0:f77ad7f72d04 | 98 | PublicKeySY |
| IanBenzMaxim | 0:f77ad7f72d04 | 99 | }; |
| IanBenzMaxim | 0:f77ad7f72d04 | 100 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 101 | /// Available keys for ECDSA operations. |
| IanBenzMaxim | 0:f77ad7f72d04 | 102 | enum KeyNum { KeyNumA = 0, KeyNumB = 1, KeyNumC = 2, KeyNumS = 3 }; |
| IanBenzMaxim | 0:f77ad7f72d04 | 103 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 104 | /// Available secrets for HMAC operations. |
| IanBenzMaxim | 0:f77ad7f72d04 | 105 | enum SecretNum { SecretNumA = 0, SecretNumB = 1, SecretNumS = 2 }; |
| IanBenzMaxim | 0:f77ad7f72d04 | 106 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 107 | /// Data hash type when verifying an ECDSA signature. |
| IanBenzMaxim | 0:f77ad7f72d04 | 108 | enum HashType { |
| IanBenzMaxim | 0:f77ad7f72d04 | 109 | HashInBuffer = 0, ///< Hash is loaded in the buffer. |
| IanBenzMaxim | 0:f77ad7f72d04 | 110 | DataInBuffer = 1, ///< Compute hash from data loaded in the buffer. |
| IanBenzMaxim | 0:f77ad7f72d04 | 111 | THASH = 2 ///< Use THASH from Compute Multiblock Hash command. |
| IanBenzMaxim | 0:f77ad7f72d04 | 112 | }; |
| IanBenzMaxim | 0:f77ad7f72d04 | 113 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 114 | /// Available PIO states when verifying an ECDSA signature. |
| IanBenzMaxim | 0:f77ad7f72d04 | 115 | enum PioState { Unchanged, Conducting, HighImpedance }; |
| IanBenzMaxim | 0:f77ad7f72d04 | 116 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 117 | /// Holds a device memory page. |
| IanBenzMaxim | 0:f77ad7f72d04 | 118 | typedef array<uint_least8_t, 32> Page; |
| IanBenzMaxim | 0:f77ad7f72d04 | 119 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 120 | /// Holds page authentication input data. |
| IanBenzMaxim | 0:f77ad7f72d04 | 121 | typedef array<uint_least8_t, 75> PageAuthenticationData; |
| IanBenzMaxim | 0:f77ad7f72d04 | 122 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 123 | /// Page protection types. |
| IanBenzMaxim | 0:f77ad7f72d04 | 124 | enum PageProtectionType { |
| IanBenzMaxim | 0:f77ad7f72d04 | 125 | RP = 0x01, ///< Read protection. |
| IanBenzMaxim | 0:f77ad7f72d04 | 126 | WP = 0x02, ///< Write protection. |
| IanBenzMaxim | 0:f77ad7f72d04 | 127 | EM = 0x04, ///< EPROM emulation mode. |
| IanBenzMaxim | 0:f77ad7f72d04 | 128 | APH = 0x08, ///< Authentication write protection HMAC. |
| IanBenzMaxim | 0:f77ad7f72d04 | 129 | EPH = 0x10, ///< Encryption and authenticated write protection HMAC. |
| IanBenzMaxim | 0:f77ad7f72d04 | 130 | AUTH = 0x20, ///< Public Key C is set to authority public key. |
| IanBenzMaxim | 0:f77ad7f72d04 | 131 | ECH = 0x40, ///< Encrypted read and write using shared key from ECDH. |
| IanBenzMaxim | 0:f77ad7f72d04 | 132 | ECW = 0x80 ///< Authentication write protection ECDSA. |
| IanBenzMaxim | 0:f77ad7f72d04 | 133 | }; |
| IanBenzMaxim | 0:f77ad7f72d04 | 134 | typedef FlagSet<PageProtectionType, 8> PageProtection; |
| IanBenzMaxim | 0:f77ad7f72d04 | 135 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 136 | /// Holds an encrypted device memory page. |
| IanBenzMaxim | 0:f77ad7f72d04 | 137 | struct EncryptedPage { |
| IanBenzMaxim | 3:f818ea5172ed | 138 | typedef array<uint_least8_t, 8> Challenge; |
| IanBenzMaxim | 3:f818ea5172ed | 139 | |
| IanBenzMaxim | 3:f818ea5172ed | 140 | /// Total size of all elements in bytes. |
| IanBenzMaxim | 3:f818ea5172ed | 141 | static const size_t size = Challenge::csize + Page::csize; |
| IanBenzMaxim | 3:f818ea5172ed | 142 | |
| IanBenzMaxim | 3:f818ea5172ed | 143 | Challenge challenge; |
| IanBenzMaxim | 0:f77ad7f72d04 | 144 | Page data; |
| IanBenzMaxim | 0:f77ad7f72d04 | 145 | }; |
| IanBenzMaxim | 0:f77ad7f72d04 | 146 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 147 | /// Number of memory pages on the device. |
| IanBenzMaxim | 0:f77ad7f72d04 | 148 | static const int memoryPages = 32; |
| IanBenzMaxim | 0:f77ad7f72d04 | 149 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 150 | DS28C36(const Sleep & sleep, I2CMaster & master, uint_least8_t address = 0x36) |
| IanBenzMaxim | 0:f77ad7f72d04 | 151 | : sleep_(&sleep), master(&master), address_(address & 0xFE) {} |
| IanBenzMaxim | 0:f77ad7f72d04 | 152 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 153 | void setSleep(const Sleep & sleep) { this->sleep_ = &sleep; } |
| IanBenzMaxim | 0:f77ad7f72d04 | 154 | void setMaster(I2CMaster & master) { this->master = &master; } |
| IanBenzMaxim | 0:f77ad7f72d04 | 155 | uint_least8_t address() const { return address_; } |
| IanBenzMaxim | 0:f77ad7f72d04 | 156 | void setAddress(uint_least8_t address) { this->address_ = (address & 0xFE); } |
| IanBenzMaxim | 0:f77ad7f72d04 | 157 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 158 | /// Write memory with no protection. |
| IanBenzMaxim | 0:f77ad7f72d04 | 159 | /// @param pageNum Number of page to write. |
| IanBenzMaxim | 0:f77ad7f72d04 | 160 | /// @param page Data to write. |
| IanBenzMaxim | 0:f77ad7f72d04 | 161 | MaximInterface_EXPORT error_code writeMemory(int pageNum, const Page & page); |
| IanBenzMaxim | 0:f77ad7f72d04 | 162 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 163 | /// Read memory with no protection. |
| IanBenzMaxim | 0:f77ad7f72d04 | 164 | /// @param pageNum Number of page to read. |
| IanBenzMaxim | 0:f77ad7f72d04 | 165 | /// @param[out] page Data that was read. |
| IanBenzMaxim | 0:f77ad7f72d04 | 166 | MaximInterface_EXPORT error_code readMemory(int pageNum, Page & page); |
| IanBenzMaxim | 0:f77ad7f72d04 | 167 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 168 | /// Write the temporary buffer. |
| IanBenzMaxim | 0:f77ad7f72d04 | 169 | /// @param data Data to write. |
| IanBenzMaxim | 0:f77ad7f72d04 | 170 | /// @param dataSize Size of data to write. |
| IanBenzMaxim | 0:f77ad7f72d04 | 171 | MaximInterface_EXPORT error_code writeBuffer(const uint_least8_t * data, |
| IanBenzMaxim | 0:f77ad7f72d04 | 172 | size_t dataSize); |
| IanBenzMaxim | 0:f77ad7f72d04 | 173 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 174 | /// Read the temporary buffer. |
| IanBenzMaxim | 0:f77ad7f72d04 | 175 | /// @param[out] data Data that was read. |
| IanBenzMaxim | 0:f77ad7f72d04 | 176 | MaximInterface_EXPORT error_code |
| IanBenzMaxim | 0:f77ad7f72d04 | 177 | readBuffer(std::vector<uint_least8_t> & data); |
| IanBenzMaxim | 0:f77ad7f72d04 | 178 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 179 | /// Read the protection settings of a page. |
| IanBenzMaxim | 0:f77ad7f72d04 | 180 | /// @param pageNum Number of page to read. |
| IanBenzMaxim | 0:f77ad7f72d04 | 181 | /// @param[out] protection Protection that was read. |
| IanBenzMaxim | 0:f77ad7f72d04 | 182 | MaximInterface_EXPORT error_code |
| IanBenzMaxim | 0:f77ad7f72d04 | 183 | readPageProtection(int pageNum, PageProtection & protection); |
| IanBenzMaxim | 0:f77ad7f72d04 | 184 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 185 | /// Set the protection settings of a page. |
| IanBenzMaxim | 0:f77ad7f72d04 | 186 | /// @param pageNum Number of page to write. |
| IanBenzMaxim | 0:f77ad7f72d04 | 187 | /// @param protection Protection to write. |
| IanBenzMaxim | 0:f77ad7f72d04 | 188 | MaximInterface_EXPORT error_code |
| IanBenzMaxim | 0:f77ad7f72d04 | 189 | setPageProtection(int pageNum, const PageProtection & protection); |
| IanBenzMaxim | 0:f77ad7f72d04 | 190 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 191 | /// Decrement the decrement-only counter. |
| IanBenzMaxim | 0:f77ad7f72d04 | 192 | MaximInterface_EXPORT error_code decrementCounter(); |
| IanBenzMaxim | 0:f77ad7f72d04 | 193 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 194 | /// Read a block of random data from the RNG. |
| IanBenzMaxim | 3:f818ea5172ed | 195 | /// @param[out] data Buffer to hold random data from RNG. |
| IanBenzMaxim | 3:f818ea5172ed | 196 | /// @param dataSize Number of bytes to read from 1 to 64 and length of data. |
| IanBenzMaxim | 3:f818ea5172ed | 197 | MaximInterface_EXPORT error_code readRng(uint_least8_t * data, |
| IanBenzMaxim | 3:f818ea5172ed | 198 | size_t dataSize); |
| IanBenzMaxim | 0:f77ad7f72d04 | 199 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 200 | /// Read memory with encryption. |
| IanBenzMaxim | 0:f77ad7f72d04 | 201 | /// @param pageNum Number of page to read from. |
| IanBenzMaxim | 0:f77ad7f72d04 | 202 | /// @param secretNum Secret to use for encryption. |
| IanBenzMaxim | 0:f77ad7f72d04 | 203 | /// @param[out] page Data that was read. |
| IanBenzMaxim | 0:f77ad7f72d04 | 204 | MaximInterface_EXPORT error_code encryptedReadMemory(int pageNum, |
| IanBenzMaxim | 0:f77ad7f72d04 | 205 | SecretNum secretNum, |
| IanBenzMaxim | 0:f77ad7f72d04 | 206 | EncryptedPage & page); |
| IanBenzMaxim | 0:f77ad7f72d04 | 207 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 208 | /// Compute and read page authentication with ECDSA. |
| IanBenzMaxim | 0:f77ad7f72d04 | 209 | /// @param pageNum Number of page to authenticate. |
| IanBenzMaxim | 0:f77ad7f72d04 | 210 | /// @param keyNum Private key to use for authentication. |
| IanBenzMaxim | 0:f77ad7f72d04 | 211 | /// Key S cannot be used with this command. |
| IanBenzMaxim | 0:f77ad7f72d04 | 212 | /// @param[out] signature Computed page signature. |
| IanBenzMaxim | 0:f77ad7f72d04 | 213 | MaximInterface_EXPORT error_code computeAndReadEcdsaPageAuthentication( |
| IanBenzMaxim | 0:f77ad7f72d04 | 214 | int pageNum, KeyNum keyNum, Ecc256::Signature & signature); |
| IanBenzMaxim | 0:f77ad7f72d04 | 215 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 216 | /// Compute and read page authentication with HMAC. |
| IanBenzMaxim | 0:f77ad7f72d04 | 217 | /// @param pageNum Number of page to authenticate. |
| IanBenzMaxim | 0:f77ad7f72d04 | 218 | /// @param secretNum Secret to use for authentication. |
| IanBenzMaxim | 0:f77ad7f72d04 | 219 | /// @param[out] hmac Computed page HMAC. |
| IanBenzMaxim | 0:f77ad7f72d04 | 220 | MaximInterface_EXPORT error_code computeAndReadHmacPageAuthentication( |
| IanBenzMaxim | 0:f77ad7f72d04 | 221 | int pageNum, SecretNum secretNum, Sha256::Hash & hmac); |
| IanBenzMaxim | 0:f77ad7f72d04 | 222 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 223 | /// Write with SHA2 authentication. |
| IanBenzMaxim | 0:f77ad7f72d04 | 224 | /// @param pageNum Number of page to write. |
| IanBenzMaxim | 0:f77ad7f72d04 | 225 | /// @param secretNum Secret to use for authentication. |
| IanBenzMaxim | 0:f77ad7f72d04 | 226 | /// @param page Data to write. |
| IanBenzMaxim | 0:f77ad7f72d04 | 227 | MaximInterface_EXPORT error_code authenticatedSha2WriteMemory( |
| IanBenzMaxim | 0:f77ad7f72d04 | 228 | int pageNum, SecretNum secretNum, const Page & page); |
| IanBenzMaxim | 0:f77ad7f72d04 | 229 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 230 | /// Compute SHA2 secret and optionally lock. |
| IanBenzMaxim | 0:f77ad7f72d04 | 231 | /// @param pageNum Number of page to use in computation. |
| IanBenzMaxim | 0:f77ad7f72d04 | 232 | /// @param msecretNum Master secret to use in computation. |
| IanBenzMaxim | 0:f77ad7f72d04 | 233 | /// @param dsecretNum Destination secret to receive the computation result. |
| IanBenzMaxim | 0:f77ad7f72d04 | 234 | /// @param writeProtectEnable |
| IanBenzMaxim | 0:f77ad7f72d04 | 235 | /// True to lock the destination secret against further writes. |
| IanBenzMaxim | 0:f77ad7f72d04 | 236 | MaximInterface_EXPORT error_code |
| IanBenzMaxim | 0:f77ad7f72d04 | 237 | computeAndLockSha2Secret(int pageNum, SecretNum msecretNum, |
| IanBenzMaxim | 0:f77ad7f72d04 | 238 | SecretNum dsecretNum, bool writeProtectEnable); |
| IanBenzMaxim | 0:f77ad7f72d04 | 239 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 240 | /// Generate a new ECDSA key pair. |
| IanBenzMaxim | 0:f77ad7f72d04 | 241 | /// @param keyNum Key to generate. Key S cannot be used with this command. |
| IanBenzMaxim | 0:f77ad7f72d04 | 242 | /// @param writeProtectEnable True to lock the key against further writes. |
| IanBenzMaxim | 0:f77ad7f72d04 | 243 | MaximInterface_EXPORT error_code |
| IanBenzMaxim | 0:f77ad7f72d04 | 244 | generateEcc256KeyPair(KeyNum keyNum, bool writeProtectEnable); |
| IanBenzMaxim | 0:f77ad7f72d04 | 245 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 246 | /// Compute a hash over multiple blocks. |
| IanBenzMaxim | 0:f77ad7f72d04 | 247 | /// @param firstBlock True if this is the first block being hashed. |
| IanBenzMaxim | 0:f77ad7f72d04 | 248 | /// @param lastBlock True if this is the last block being hashed. |
| IanBenzMaxim | 0:f77ad7f72d04 | 249 | /// @param data Data block to hash. |
| IanBenzMaxim | 0:f77ad7f72d04 | 250 | /// @param dataSize Size of data to hash. |
| IanBenzMaxim | 0:f77ad7f72d04 | 251 | /// Should be 64 bytes unless this is the last block. |
| IanBenzMaxim | 0:f77ad7f72d04 | 252 | MaximInterface_EXPORT error_code |
| IanBenzMaxim | 0:f77ad7f72d04 | 253 | computeMultiblockHash(bool firstBlock, bool lastBlock, |
| IanBenzMaxim | 0:f77ad7f72d04 | 254 | const uint_least8_t * data, size_t dataSize); |
| IanBenzMaxim | 0:f77ad7f72d04 | 255 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 256 | /// Verify ECDSA signature. |
| IanBenzMaxim | 0:f77ad7f72d04 | 257 | /// @param keyNum Public key to use for verification. |
| IanBenzMaxim | 0:f77ad7f72d04 | 258 | /// @param hashType Source of the data hash input. |
| IanBenzMaxim | 0:f77ad7f72d04 | 259 | /// @param signature Signature to verify. |
| IanBenzMaxim | 0:f77ad7f72d04 | 260 | /// @param pioa New state of PIOA if verification successful. |
| IanBenzMaxim | 0:f77ad7f72d04 | 261 | /// @param piob New state of PIOB if verification successful. |
| IanBenzMaxim | 0:f77ad7f72d04 | 262 | MaximInterface_EXPORT error_code verifyEcdsaSignature( |
| IanBenzMaxim | 0:f77ad7f72d04 | 263 | KeyNum keyNum, HashType hashType, const Ecc256::Signature & signature, |
| IanBenzMaxim | 0:f77ad7f72d04 | 264 | PioState pioa = Unchanged, PioState piob = Unchanged); |
| IanBenzMaxim | 0:f77ad7f72d04 | 265 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 266 | /// Authenticate a public key for authenticated writes or encrypted reads with ECDH. |
| IanBenzMaxim | 0:f77ad7f72d04 | 267 | /// @param authWrites True to select authentication for writes. |
| IanBenzMaxim | 0:f77ad7f72d04 | 268 | /// @param ecdh True to select ECDH key exchange. |
| IanBenzMaxim | 0:f77ad7f72d04 | 269 | /// @param keyNum Private key to use for ECDH key exchange. |
| IanBenzMaxim | 0:f77ad7f72d04 | 270 | /// Key A or B can be selected. |
| IanBenzMaxim | 0:f77ad7f72d04 | 271 | /// @param csOffset Certificate customization field ending offset in buffer. |
| IanBenzMaxim | 0:f77ad7f72d04 | 272 | /// @param signature Signature to use for authentication of public key S. |
| IanBenzMaxim | 0:f77ad7f72d04 | 273 | MaximInterface_EXPORT error_code |
| IanBenzMaxim | 0:f77ad7f72d04 | 274 | authenticateEcdsaPublicKey(bool authWrites, bool ecdh, KeyNum keyNum, |
| IanBenzMaxim | 0:f77ad7f72d04 | 275 | int csOffset, const Ecc256::Signature & signature); |
| IanBenzMaxim | 0:f77ad7f72d04 | 276 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 277 | /// Write with ECDSA authentication. |
| IanBenzMaxim | 0:f77ad7f72d04 | 278 | /// @param pageNum Number of page to write. |
| IanBenzMaxim | 0:f77ad7f72d04 | 279 | /// @param page Data to write. |
| IanBenzMaxim | 0:f77ad7f72d04 | 280 | MaximInterface_EXPORT error_code |
| IanBenzMaxim | 0:f77ad7f72d04 | 281 | authenticatedEcdsaWriteMemory(int pageNum, const Page & page); |
| IanBenzMaxim | 0:f77ad7f72d04 | 282 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 283 | /// Create data used by the Compute and Read Page Authentication command to |
| IanBenzMaxim | 0:f77ad7f72d04 | 284 | /// generate a signature. |
| IanBenzMaxim | 0:f77ad7f72d04 | 285 | MaximInterface_EXPORT static PageAuthenticationData |
| IanBenzMaxim | 0:f77ad7f72d04 | 286 | createPageAuthenticationData(const RomId & romId, const Page & page, |
| IanBenzMaxim | 0:f77ad7f72d04 | 287 | const Page & challenge, int pageNum, |
| IanBenzMaxim | 0:f77ad7f72d04 | 288 | const ManId & manId); |
| IanBenzMaxim | 0:f77ad7f72d04 | 289 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 290 | MaximInterface_EXPORT static const error_category & errorCategory(); |
| IanBenzMaxim | 0:f77ad7f72d04 | 291 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 292 | protected: |
| IanBenzMaxim | 0:f77ad7f72d04 | 293 | // Timing constants. |
| IanBenzMaxim | 0:f77ad7f72d04 | 294 | static const int generateEcdsaSignatureTimeMs = 50; |
| IanBenzMaxim | 0:f77ad7f72d04 | 295 | static const int generateEccKeyPairTimeMs = 100; |
| IanBenzMaxim | 0:f77ad7f72d04 | 296 | static const int verifyEsdsaSignatureOrComputeEcdhTimeMs = 150; |
| IanBenzMaxim | 0:f77ad7f72d04 | 297 | static const int sha256ComputationTimeMs = 3; |
| IanBenzMaxim | 0:f77ad7f72d04 | 298 | static const int readMemoryTimeMs = /*1*/ 2; |
| IanBenzMaxim | 0:f77ad7f72d04 | 299 | static const int writeMemoryTimeMs = 15; |
| IanBenzMaxim | 0:f77ad7f72d04 | 300 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 301 | error_code writeCommand(uint_least8_t command, |
| IanBenzMaxim | 0:f77ad7f72d04 | 302 | const uint_least8_t * parameters, |
| IanBenzMaxim | 0:f77ad7f72d04 | 303 | size_t parametersSize); |
| IanBenzMaxim | 3:f818ea5172ed | 304 | |
| IanBenzMaxim | 3:f818ea5172ed | 305 | error_code writeCommand(uint_least8_t command) { |
| IanBenzMaxim | 3:f818ea5172ed | 306 | return writeCommand(command, NULL, 0); |
| IanBenzMaxim | 3:f818ea5172ed | 307 | } |
| IanBenzMaxim | 3:f818ea5172ed | 308 | |
| IanBenzMaxim | 3:f818ea5172ed | 309 | error_code readVariableLengthResponse(uint_least8_t * response, |
| IanBenzMaxim | 3:f818ea5172ed | 310 | size_t & responseSize); |
| IanBenzMaxim | 3:f818ea5172ed | 311 | |
| IanBenzMaxim | 3:f818ea5172ed | 312 | error_code readFixedLengthResponse(uint_least8_t * response, |
| IanBenzMaxim | 3:f818ea5172ed | 313 | size_t responseSize); |
| IanBenzMaxim | 0:f77ad7f72d04 | 314 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 315 | void sleep(int ms) const { (*sleep_)(ms); } |
| IanBenzMaxim | 0:f77ad7f72d04 | 316 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 317 | private: |
| IanBenzMaxim | 0:f77ad7f72d04 | 318 | enum AuthType { |
| IanBenzMaxim | 0:f77ad7f72d04 | 319 | HmacWithSecretA = 0, |
| IanBenzMaxim | 0:f77ad7f72d04 | 320 | HmacWithSecretB = 1, |
| IanBenzMaxim | 0:f77ad7f72d04 | 321 | HmacWithSecretS = 2, |
| IanBenzMaxim | 0:f77ad7f72d04 | 322 | EcdsaWithKeyA = 3, |
| IanBenzMaxim | 0:f77ad7f72d04 | 323 | EcdsaWithKeyB = 4, |
| IanBenzMaxim | 0:f77ad7f72d04 | 324 | EcdsaWithKeyC = 5 |
| IanBenzMaxim | 0:f77ad7f72d04 | 325 | }; |
| IanBenzMaxim | 0:f77ad7f72d04 | 326 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 327 | const Sleep * sleep_; |
| IanBenzMaxim | 0:f77ad7f72d04 | 328 | I2CMaster * master; |
| IanBenzMaxim | 0:f77ad7f72d04 | 329 | uint_least8_t address_; |
| IanBenzMaxim | 0:f77ad7f72d04 | 330 | |
| IanBenzMaxim | 3:f818ea5172ed | 331 | error_code computeAndReadPageAuthentication(int pageNum, AuthType authType); |
| IanBenzMaxim | 0:f77ad7f72d04 | 332 | }; |
| IanBenzMaxim | 0:f77ad7f72d04 | 333 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 334 | /// Read the device ROM ID and MAN ID using the Read Memory command on the |
| IanBenzMaxim | 0:f77ad7f72d04 | 335 | /// ROM Options page. |
| IanBenzMaxim | 0:f77ad7f72d04 | 336 | /// @param[out] romId |
| IanBenzMaxim | 0:f77ad7f72d04 | 337 | /// Read ROM ID valid when operation is successful. May be set to NULL. |
| IanBenzMaxim | 0:f77ad7f72d04 | 338 | /// @param[out] manId |
| IanBenzMaxim | 0:f77ad7f72d04 | 339 | /// Read MAN ID valid when operation is successful. May be set to NULL. |
| IanBenzMaxim | 0:f77ad7f72d04 | 340 | MaximInterface_EXPORT error_code readRomIdAndManId(DS28C36 & ds28c36, |
| IanBenzMaxim | 0:f77ad7f72d04 | 341 | RomId * romId, |
| IanBenzMaxim | 0:f77ad7f72d04 | 342 | ManId * manId); |
| IanBenzMaxim | 0:f77ad7f72d04 | 343 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 344 | /// Hash arbitrary length data with successive Compute Multiblock Hash commands. |
| IanBenzMaxim | 0:f77ad7f72d04 | 345 | /// @param data Data to hash. |
| IanBenzMaxim | 0:f77ad7f72d04 | 346 | /// @param dataSize Size of data to hash. |
| IanBenzMaxim | 0:f77ad7f72d04 | 347 | MaximInterface_EXPORT error_code computeMultiblockHash( |
| IanBenzMaxim | 0:f77ad7f72d04 | 348 | DS28C36 & ds28c36, const uint_least8_t * data, const size_t dataSize); |
| IanBenzMaxim | 0:f77ad7f72d04 | 349 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 350 | /// Verify ECDSA signature. |
| IanBenzMaxim | 0:f77ad7f72d04 | 351 | /// @param publicKey Public key to use for verification. |
| IanBenzMaxim | 0:f77ad7f72d04 | 352 | /// @param data Data to verify. |
| IanBenzMaxim | 0:f77ad7f72d04 | 353 | /// @param dataSize Size of data to verify. |
| IanBenzMaxim | 0:f77ad7f72d04 | 354 | /// @param signature Signature to verify. |
| IanBenzMaxim | 0:f77ad7f72d04 | 355 | /// @param pioa New state of PIOA if verification successful. |
| IanBenzMaxim | 0:f77ad7f72d04 | 356 | /// @param piob New state of PIOB if verification successful. |
| IanBenzMaxim | 0:f77ad7f72d04 | 357 | MaximInterface_EXPORT error_code verifyEcdsaSignature( |
| IanBenzMaxim | 0:f77ad7f72d04 | 358 | DS28C36 & ds28c36, DS28C36::KeyNum publicKey, const uint_least8_t * data, |
| IanBenzMaxim | 0:f77ad7f72d04 | 359 | size_t dataSize, const Ecc256::Signature & signature, |
| IanBenzMaxim | 0:f77ad7f72d04 | 360 | DS28C36::PioState pioa = DS28C36::Unchanged, |
| IanBenzMaxim | 0:f77ad7f72d04 | 361 | DS28C36::PioState piob = DS28C36::Unchanged); |
| IanBenzMaxim | 0:f77ad7f72d04 | 362 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 363 | /// Verify ECDSA signature. |
| IanBenzMaxim | 0:f77ad7f72d04 | 364 | /// @param publicKey |
| IanBenzMaxim | 0:f77ad7f72d04 | 365 | /// Public key to use for verification which is loaded into Public Key S. |
| IanBenzMaxim | 0:f77ad7f72d04 | 366 | /// @param data Data to verify. |
| IanBenzMaxim | 0:f77ad7f72d04 | 367 | /// @param dataSize Size of data to verify. |
| IanBenzMaxim | 0:f77ad7f72d04 | 368 | /// @param signature Signature to verify. |
| IanBenzMaxim | 0:f77ad7f72d04 | 369 | /// @param pioa New state of PIOA if verification successful. |
| IanBenzMaxim | 0:f77ad7f72d04 | 370 | /// @param piob New state of PIOB if verification successful. |
| IanBenzMaxim | 0:f77ad7f72d04 | 371 | MaximInterface_EXPORT error_code |
| IanBenzMaxim | 0:f77ad7f72d04 | 372 | verifyEcdsaSignature(DS28C36 & ds28c36, const Ecc256::PublicKey & publicKey, |
| IanBenzMaxim | 0:f77ad7f72d04 | 373 | const uint_least8_t * data, size_t dataSize, |
| IanBenzMaxim | 0:f77ad7f72d04 | 374 | const Ecc256::Signature & signature, |
| IanBenzMaxim | 0:f77ad7f72d04 | 375 | DS28C36::PioState pioa = DS28C36::Unchanged, |
| IanBenzMaxim | 0:f77ad7f72d04 | 376 | DS28C36::PioState piob = DS28C36::Unchanged); |
| IanBenzMaxim | 0:f77ad7f72d04 | 377 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 378 | inline error_code make_error_code(DS28C36::ErrorValue e) { |
| IanBenzMaxim | 0:f77ad7f72d04 | 379 | return error_code(e, DS28C36::errorCategory()); |
| IanBenzMaxim | 0:f77ad7f72d04 | 380 | } |
| IanBenzMaxim | 0:f77ad7f72d04 | 381 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 382 | /// Interface to the DS2476 coprocessor. |
| IanBenzMaxim | 0:f77ad7f72d04 | 383 | class DS2476 : public DS28C36 { |
| IanBenzMaxim | 0:f77ad7f72d04 | 384 | public: |
| IanBenzMaxim | 0:f77ad7f72d04 | 385 | DS2476(const Sleep & sleep, I2CMaster & master, uint_least8_t address = 0x76) |
| IanBenzMaxim | 0:f77ad7f72d04 | 386 | : DS28C36(sleep, master, address) {} |
| IanBenzMaxim | 0:f77ad7f72d04 | 387 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 388 | /// Generate ECDSA signature. |
| IanBenzMaxim | 0:f77ad7f72d04 | 389 | /// @param keyNum Private key to use to create signature. |
| IanBenzMaxim | 0:f77ad7f72d04 | 390 | /// Key S cannot be used with this command. |
| IanBenzMaxim | 0:f77ad7f72d04 | 391 | /// @param[out] signature Computed signature. |
| IanBenzMaxim | 0:f77ad7f72d04 | 392 | MaximInterface_EXPORT error_code |
| IanBenzMaxim | 0:f77ad7f72d04 | 393 | generateEcdsaSignature(KeyNum keyNum, Ecc256::Signature & signature); |
| IanBenzMaxim | 0:f77ad7f72d04 | 394 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 395 | /// Compute unique SHA2 secret. |
| IanBenzMaxim | 0:f77ad7f72d04 | 396 | /// @param msecretNum Master secret to use in computation. |
| IanBenzMaxim | 0:f77ad7f72d04 | 397 | MaximInterface_EXPORT error_code |
| IanBenzMaxim | 0:f77ad7f72d04 | 398 | computeSha2UniqueSecret(SecretNum msecretNum); |
| IanBenzMaxim | 0:f77ad7f72d04 | 399 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 400 | /// Compute SHA2 HMAC. |
| IanBenzMaxim | 0:f77ad7f72d04 | 401 | /// @param[out] hmac Computed HMAC. |
| IanBenzMaxim | 0:f77ad7f72d04 | 402 | MaximInterface_EXPORT error_code computeSha2Hmac(Sha256::Hash & hmac); |
| IanBenzMaxim | 0:f77ad7f72d04 | 403 | }; |
| IanBenzMaxim | 0:f77ad7f72d04 | 404 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 405 | /// Enable coprocessor functionality on the DS2476 by writing to the |
| IanBenzMaxim | 0:f77ad7f72d04 | 406 | /// ROM Options page. |
| IanBenzMaxim | 0:f77ad7f72d04 | 407 | MaximInterface_EXPORT error_code enableCoprocessor(DS2476 & ds2476); |
| IanBenzMaxim | 0:f77ad7f72d04 | 408 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 409 | } // namespace MaximInterface |
| IanBenzMaxim | 0:f77ad7f72d04 | 410 | |
| IanBenzMaxim | 0:f77ad7f72d04 | 411 | #endif |