Extended MaximInterface

Dependents:   mbed_DS28EC20_GPIO

Committer:
reARMnimator
Date:
Wed Apr 03 12:33:10 2019 +0000
Revision:
8:211d1b8f730c
Parent:
7:471901a04573
Merge with version 1.7;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
IanBenzMaxim 6:a8c83a2e6fa4 1 /*******************************************************************************
IanBenzMaxim 6:a8c83a2e6fa4 2 * Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
IanBenzMaxim 6:a8c83a2e6fa4 3 *
IanBenzMaxim 6:a8c83a2e6fa4 4 * Permission is hereby granted, free of charge, to any person obtaining a
IanBenzMaxim 6:a8c83a2e6fa4 5 * copy of this software and associated documentation files (the "Software"),
IanBenzMaxim 6:a8c83a2e6fa4 6 * to deal in the Software without restriction, including without limitation
IanBenzMaxim 6:a8c83a2e6fa4 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
IanBenzMaxim 6:a8c83a2e6fa4 8 * and/or sell copies of the Software, and to permit persons to whom the
IanBenzMaxim 6:a8c83a2e6fa4 9 * Software is furnished to do so, subject to the following conditions:
IanBenzMaxim 6:a8c83a2e6fa4 10 *
IanBenzMaxim 6:a8c83a2e6fa4 11 * The above copyright notice and this permission notice shall be included
IanBenzMaxim 6:a8c83a2e6fa4 12 * in all copies or substantial portions of the Software.
IanBenzMaxim 6:a8c83a2e6fa4 13 *
IanBenzMaxim 6:a8c83a2e6fa4 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
IanBenzMaxim 6:a8c83a2e6fa4 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
IanBenzMaxim 6:a8c83a2e6fa4 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IanBenzMaxim 6:a8c83a2e6fa4 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
IanBenzMaxim 6:a8c83a2e6fa4 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
IanBenzMaxim 6:a8c83a2e6fa4 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
IanBenzMaxim 6:a8c83a2e6fa4 20 * OTHER DEALINGS IN THE SOFTWARE.
IanBenzMaxim 6:a8c83a2e6fa4 21 *
IanBenzMaxim 6:a8c83a2e6fa4 22 * Except as contained in this notice, the name of Maxim Integrated
IanBenzMaxim 6:a8c83a2e6fa4 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
IanBenzMaxim 6:a8c83a2e6fa4 24 * Products, Inc. Branding Policy.
IanBenzMaxim 6:a8c83a2e6fa4 25 *
IanBenzMaxim 6:a8c83a2e6fa4 26 * The mere transfer of this software does not imply any licenses
IanBenzMaxim 6:a8c83a2e6fa4 27 * of trade secrets, proprietary technology, copyrights, patents,
IanBenzMaxim 6:a8c83a2e6fa4 28 * trademarks, maskwork rights, or any other form of intellectual
IanBenzMaxim 6:a8c83a2e6fa4 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
IanBenzMaxim 6:a8c83a2e6fa4 30 * ownership rights.
IanBenzMaxim 6:a8c83a2e6fa4 31 *******************************************************************************/
IanBenzMaxim 6:a8c83a2e6fa4 32
IanBenzMaxim 6:a8c83a2e6fa4 33 #ifndef MaximInterface_DS28C36_DS2476
IanBenzMaxim 6:a8c83a2e6fa4 34 #define MaximInterface_DS28C36_DS2476
IanBenzMaxim 6:a8c83a2e6fa4 35
IanBenzMaxim 6:a8c83a2e6fa4 36 #include <stdint.h>
IanBenzMaxim 6:a8c83a2e6fa4 37 #include <vector>
IanBenzMaxim 6:a8c83a2e6fa4 38 #include <MaximInterface/Links/I2CMaster.hpp>
IanBenzMaxim 6:a8c83a2e6fa4 39 #include <MaximInterface/Links/Sleep.hpp>
IanBenzMaxim 6:a8c83a2e6fa4 40 #include <MaximInterface/Utilities/array_span.hpp>
IanBenzMaxim 6:a8c83a2e6fa4 41 #include <MaximInterface/Utilities/Ecc256.hpp>
IanBenzMaxim 6:a8c83a2e6fa4 42 #include <MaximInterface/Utilities/Export.h>
IanBenzMaxim 6:a8c83a2e6fa4 43 #include <MaximInterface/Utilities/RomId.hpp>
IanBenzMaxim 6:a8c83a2e6fa4 44 #include <MaximInterface/Utilities/ManId.hpp>
IanBenzMaxim 6:a8c83a2e6fa4 45 #include <MaximInterface/Utilities/Sha256.hpp>
IanBenzMaxim 6:a8c83a2e6fa4 46 #include <MaximInterface/Utilities/system_error.hpp>
IanBenzMaxim 6:a8c83a2e6fa4 47 #include <MaximInterface/Utilities/FlagSet.hpp>
IanBenzMaxim 6:a8c83a2e6fa4 48
IanBenzMaxim 6:a8c83a2e6fa4 49 namespace MaximInterface {
IanBenzMaxim 6:a8c83a2e6fa4 50
IanBenzMaxim 6:a8c83a2e6fa4 51 /// Interface to the DS28C36 authenticator.
IanBenzMaxim 6:a8c83a2e6fa4 52 class DS28C36 {
IanBenzMaxim 6:a8c83a2e6fa4 53 public:
IanBenzMaxim 6:a8c83a2e6fa4 54 /// Device command results.
IanBenzMaxim 6:a8c83a2e6fa4 55 enum ErrorValue {
IanBenzMaxim 6:a8c83a2e6fa4 56 ProtectionError = 0x55,
IanBenzMaxim 6:a8c83a2e6fa4 57 InvalidParameterError = 0x77,
IanBenzMaxim 6:a8c83a2e6fa4 58 InvalidSequenceError = 0x33,
IanBenzMaxim 6:a8c83a2e6fa4 59 InvalidEcdsaInputOrResultError = 0x22,
IanBenzMaxim 6:a8c83a2e6fa4 60 AuthenticationError = 0x100,
IanBenzMaxim 6:a8c83a2e6fa4 61 InvalidResponseError = 0x101 ///< Response does not match expected format.
IanBenzMaxim 6:a8c83a2e6fa4 62 };
IanBenzMaxim 6:a8c83a2e6fa4 63
IanBenzMaxim 7:471901a04573 64 /// @name Device memory pages
IanBenzMaxim 7:471901a04573 65 /// @{
IanBenzMaxim 7:471901a04573 66
IanBenzMaxim 6:a8c83a2e6fa4 67 static const int publicKeyAxPage = 16;
IanBenzMaxim 6:a8c83a2e6fa4 68 static const int publicKeyAyPage = 17;
IanBenzMaxim 6:a8c83a2e6fa4 69 static const int publicKeyBxPage = 18;
IanBenzMaxim 6:a8c83a2e6fa4 70 static const int publicKeyByPage = 19;
IanBenzMaxim 6:a8c83a2e6fa4 71 static const int publicKeyCxPage = 20;
IanBenzMaxim 6:a8c83a2e6fa4 72 static const int publicKeyCyPage = 21;
IanBenzMaxim 6:a8c83a2e6fa4 73 static const int privateKeyAPage = 22;
IanBenzMaxim 6:a8c83a2e6fa4 74 static const int privateKeyBPage = 23;
IanBenzMaxim 6:a8c83a2e6fa4 75 static const int privateKeyCPage = 24;
IanBenzMaxim 6:a8c83a2e6fa4 76 static const int secretAPage = 25;
IanBenzMaxim 6:a8c83a2e6fa4 77 static const int secretBPage = 26;
IanBenzMaxim 6:a8c83a2e6fa4 78 static const int decrementCounterPage = 27;
IanBenzMaxim 6:a8c83a2e6fa4 79 static const int romOptionsPage = 28;
IanBenzMaxim 6:a8c83a2e6fa4 80 static const int gpioControlPage = 29;
IanBenzMaxim 6:a8c83a2e6fa4 81 static const int publicKeySxPage = 30;
IanBenzMaxim 6:a8c83a2e6fa4 82 static const int publicKeySyPage = 31;
IanBenzMaxim 7:471901a04573 83
IanBenzMaxim 7:471901a04573 84 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 85
IanBenzMaxim 6:a8c83a2e6fa4 86 /// Number of memory pages on the device.
IanBenzMaxim 6:a8c83a2e6fa4 87 static const int memoryPages = 32;
IanBenzMaxim 6:a8c83a2e6fa4 88
IanBenzMaxim 6:a8c83a2e6fa4 89 /// Available keys for ECDSA operations.
IanBenzMaxim 6:a8c83a2e6fa4 90 enum KeyNum { KeyNumA = 0, KeyNumB = 1, KeyNumC = 2, KeyNumS = 3 };
IanBenzMaxim 6:a8c83a2e6fa4 91
IanBenzMaxim 6:a8c83a2e6fa4 92 /// Available secrets for HMAC operations.
IanBenzMaxim 6:a8c83a2e6fa4 93 enum SecretNum { SecretNumA = 0, SecretNumB = 1, SecretNumS = 2 };
IanBenzMaxim 6:a8c83a2e6fa4 94
IanBenzMaxim 6:a8c83a2e6fa4 95 /// Data hash type when verifying an ECDSA signature.
IanBenzMaxim 6:a8c83a2e6fa4 96 enum HashType {
IanBenzMaxim 6:a8c83a2e6fa4 97 HashInBuffer = 0, ///< Hash is loaded in the buffer.
IanBenzMaxim 6:a8c83a2e6fa4 98 DataInBuffer = 1, ///< Compute hash from data loaded in the buffer.
IanBenzMaxim 6:a8c83a2e6fa4 99 THASH = 2 ///< Use THASH from Compute Multiblock Hash command.
IanBenzMaxim 6:a8c83a2e6fa4 100 };
IanBenzMaxim 6:a8c83a2e6fa4 101
IanBenzMaxim 6:a8c83a2e6fa4 102 /// Available PIO states when verifying an ECDSA signature.
IanBenzMaxim 6:a8c83a2e6fa4 103 enum PioState { Unchanged, Conducting, HighImpedance };
IanBenzMaxim 6:a8c83a2e6fa4 104
IanBenzMaxim 6:a8c83a2e6fa4 105 /// Holds a device memory page.
IanBenzMaxim 6:a8c83a2e6fa4 106 typedef array_span<uint_least8_t, 32> Page;
IanBenzMaxim 6:a8c83a2e6fa4 107
IanBenzMaxim 7:471901a04573 108 // Format page authentication input data.
IanBenzMaxim 6:a8c83a2e6fa4 109 class PageAuthenticationData;
IanBenzMaxim 6:a8c83a2e6fa4 110
IanBenzMaxim 7:471901a04573 111 // Format authenticated write input data.
IanBenzMaxim 6:a8c83a2e6fa4 112 class WriteAuthenticationData;
IanBenzMaxim 6:a8c83a2e6fa4 113
IanBenzMaxim 7:471901a04573 114 // Format compute secret input data.
IanBenzMaxim 6:a8c83a2e6fa4 115 class ComputeSecretData;
IanBenzMaxim 6:a8c83a2e6fa4 116
IanBenzMaxim 7:471901a04573 117 // Format encryption or decryption HMAC input data.
IanBenzMaxim 6:a8c83a2e6fa4 118 class EncryptionHmacData;
IanBenzMaxim 6:a8c83a2e6fa4 119
IanBenzMaxim 7:471901a04573 120 // Access fields in the ROM Options page.
IanBenzMaxim 6:a8c83a2e6fa4 121 class RomOptions;
IanBenzMaxim 6:a8c83a2e6fa4 122
IanBenzMaxim 7:471901a04573 123 // Access fields in the GPIO Control page.
IanBenzMaxim 6:a8c83a2e6fa4 124 class GpioControl;
IanBenzMaxim 6:a8c83a2e6fa4 125
IanBenzMaxim 6:a8c83a2e6fa4 126 /// Page protection types.
IanBenzMaxim 6:a8c83a2e6fa4 127 enum PageProtectionType {
IanBenzMaxim 6:a8c83a2e6fa4 128 RP = 0x01, ///< Read protection.
IanBenzMaxim 6:a8c83a2e6fa4 129 WP = 0x02, ///< Write protection.
IanBenzMaxim 6:a8c83a2e6fa4 130 EM = 0x04, ///< EPROM emulation mode.
IanBenzMaxim 6:a8c83a2e6fa4 131 APH = 0x08, ///< Authentication write protection HMAC.
IanBenzMaxim 6:a8c83a2e6fa4 132 EPH = 0x10, ///< Encryption and authenticated write protection HMAC.
IanBenzMaxim 6:a8c83a2e6fa4 133 AUTH = 0x20, ///< Public Key C is set to authority public key.
IanBenzMaxim 6:a8c83a2e6fa4 134 ECH = 0x40, ///< Encrypted read and write using shared key from ECDH.
IanBenzMaxim 6:a8c83a2e6fa4 135 ECW = 0x80 ///< Authentication write protection ECDSA.
IanBenzMaxim 6:a8c83a2e6fa4 136 };
IanBenzMaxim 6:a8c83a2e6fa4 137 typedef FlagSet<PageProtectionType, 8> PageProtection;
IanBenzMaxim 6:a8c83a2e6fa4 138
IanBenzMaxim 6:a8c83a2e6fa4 139 /// Challenge for an encrypted device memory page.
IanBenzMaxim 6:a8c83a2e6fa4 140 typedef array_span<uint_least8_t, 8> EncryptionChallenge;
IanBenzMaxim 6:a8c83a2e6fa4 141
IanBenzMaxim 6:a8c83a2e6fa4 142 DS28C36(Sleep & sleep, I2CMaster & master, uint_least8_t address = 0x36)
IanBenzMaxim 6:a8c83a2e6fa4 143 : sleep_(&sleep), master(&master), address_(address & 0xFE) {}
IanBenzMaxim 6:a8c83a2e6fa4 144
IanBenzMaxim 6:a8c83a2e6fa4 145 void setSleep(Sleep & sleep) { sleep_ = &sleep; }
IanBenzMaxim 6:a8c83a2e6fa4 146
IanBenzMaxim 6:a8c83a2e6fa4 147 void setMaster(I2CMaster & master) { this->master = &master; }
IanBenzMaxim 6:a8c83a2e6fa4 148
IanBenzMaxim 6:a8c83a2e6fa4 149 uint_least8_t address() const { return address_; }
IanBenzMaxim 6:a8c83a2e6fa4 150
IanBenzMaxim 6:a8c83a2e6fa4 151 void setAddress(uint_least8_t address) { address_ = address & 0xFE; }
IanBenzMaxim 6:a8c83a2e6fa4 152
IanBenzMaxim 7:471901a04573 153 /// @brief Write memory with no protection.
IanBenzMaxim 6:a8c83a2e6fa4 154 /// @param pageNum Number of page to write.
IanBenzMaxim 6:a8c83a2e6fa4 155 /// @param page Data to write.
IanBenzMaxim 6:a8c83a2e6fa4 156 MaximInterface_EXPORT error_code writeMemory(int pageNum,
IanBenzMaxim 6:a8c83a2e6fa4 157 Page::const_span page);
IanBenzMaxim 6:a8c83a2e6fa4 158
IanBenzMaxim 7:471901a04573 159 /// @brief Read memory with no protection.
IanBenzMaxim 6:a8c83a2e6fa4 160 /// @param pageNum Number of page to read.
IanBenzMaxim 6:a8c83a2e6fa4 161 /// @param[out] page Data that was read.
IanBenzMaxim 6:a8c83a2e6fa4 162 MaximInterface_EXPORT error_code readMemory(int pageNum, Page::span page);
IanBenzMaxim 6:a8c83a2e6fa4 163
IanBenzMaxim 7:471901a04573 164 /// @brief Write the temporary buffer.
IanBenzMaxim 6:a8c83a2e6fa4 165 /// @param data Data to write.
IanBenzMaxim 6:a8c83a2e6fa4 166 MaximInterface_EXPORT error_code writeBuffer(span<const uint_least8_t> data);
IanBenzMaxim 6:a8c83a2e6fa4 167
IanBenzMaxim 7:471901a04573 168 /// @brief Read the temporary buffer.
IanBenzMaxim 6:a8c83a2e6fa4 169 /// @param[out] data Data that was read.
IanBenzMaxim 6:a8c83a2e6fa4 170 MaximInterface_EXPORT error_code
IanBenzMaxim 6:a8c83a2e6fa4 171 readBuffer(std::vector<uint_least8_t> & data);
IanBenzMaxim 6:a8c83a2e6fa4 172
IanBenzMaxim 7:471901a04573 173 /// @brief Read the protection settings of a page.
IanBenzMaxim 6:a8c83a2e6fa4 174 /// @param pageNum Number of page to read.
IanBenzMaxim 6:a8c83a2e6fa4 175 /// @param[out] protection Protection that was read.
IanBenzMaxim 6:a8c83a2e6fa4 176 MaximInterface_EXPORT error_code
IanBenzMaxim 6:a8c83a2e6fa4 177 readPageProtection(int pageNum, PageProtection & protection);
IanBenzMaxim 6:a8c83a2e6fa4 178
IanBenzMaxim 7:471901a04573 179 /// @brief Set the protection settings of a page.
IanBenzMaxim 6:a8c83a2e6fa4 180 /// @param pageNum Number of page to write.
IanBenzMaxim 6:a8c83a2e6fa4 181 /// @param protection Protection to write.
IanBenzMaxim 6:a8c83a2e6fa4 182 MaximInterface_EXPORT error_code
IanBenzMaxim 6:a8c83a2e6fa4 183 setPageProtection(int pageNum, const PageProtection & protection);
IanBenzMaxim 6:a8c83a2e6fa4 184
IanBenzMaxim 6:a8c83a2e6fa4 185 /// Decrement the decrement-only counter.
IanBenzMaxim 6:a8c83a2e6fa4 186 MaximInterface_EXPORT error_code decrementCounter();
IanBenzMaxim 6:a8c83a2e6fa4 187
IanBenzMaxim 7:471901a04573 188 /// @brief Read a block of random data from the RNG.
IanBenzMaxim 6:a8c83a2e6fa4 189 /// @param[out] data Random data from RNG with length from 1 to 64.
IanBenzMaxim 6:a8c83a2e6fa4 190 MaximInterface_EXPORT error_code readRng(span<uint_least8_t> data);
IanBenzMaxim 6:a8c83a2e6fa4 191
IanBenzMaxim 7:471901a04573 192 /// @brief Read memory with encryption.
IanBenzMaxim 6:a8c83a2e6fa4 193 /// @param pageNum Number of page to read from.
IanBenzMaxim 6:a8c83a2e6fa4 194 /// @param secretNum Secret to use for encryption.
IanBenzMaxim 6:a8c83a2e6fa4 195 /// @param[out] challenge Encryption challenge that was read.
IanBenzMaxim 6:a8c83a2e6fa4 196 /// @param[out] data Encrypted page data that was read.
IanBenzMaxim 6:a8c83a2e6fa4 197 MaximInterface_EXPORT error_code
IanBenzMaxim 6:a8c83a2e6fa4 198 encryptedReadMemory(int pageNum, SecretNum secretNum,
IanBenzMaxim 6:a8c83a2e6fa4 199 EncryptionChallenge::span challenge, Page::span data);
IanBenzMaxim 6:a8c83a2e6fa4 200
IanBenzMaxim 7:471901a04573 201 /// @brief Compute and read page authentication with ECDSA.
IanBenzMaxim 6:a8c83a2e6fa4 202 /// @param pageNum Number of page to authenticate.
IanBenzMaxim 7:471901a04573 203 /// @param keyNum
IanBenzMaxim 7:471901a04573 204 /// Private key to use for authentication.
IanBenzMaxim 6:a8c83a2e6fa4 205 /// Key S cannot be used with this command.
IanBenzMaxim 6:a8c83a2e6fa4 206 /// @param[out] signature Computed page signature.
IanBenzMaxim 6:a8c83a2e6fa4 207 MaximInterface_EXPORT error_code computeAndReadPageAuthentication(
IanBenzMaxim 6:a8c83a2e6fa4 208 int pageNum, KeyNum keyNum, Ecc256::Signature::span signature);
IanBenzMaxim 6:a8c83a2e6fa4 209
IanBenzMaxim 7:471901a04573 210 /// @brief Compute and read page authentication with HMAC.
IanBenzMaxim 6:a8c83a2e6fa4 211 /// @param pageNum Number of page to authenticate.
IanBenzMaxim 6:a8c83a2e6fa4 212 /// @param secretNum Secret to use for authentication.
IanBenzMaxim 6:a8c83a2e6fa4 213 /// @param[out] hmac Computed page HMAC.
IanBenzMaxim 6:a8c83a2e6fa4 214 MaximInterface_EXPORT error_code computeAndReadPageAuthentication(
IanBenzMaxim 6:a8c83a2e6fa4 215 int pageNum, SecretNum secretNum, Sha256::Hash::span hmac);
IanBenzMaxim 6:a8c83a2e6fa4 216
IanBenzMaxim 7:471901a04573 217 /// @brief Write with SHA2 authentication.
IanBenzMaxim 6:a8c83a2e6fa4 218 /// @param pageNum Number of page to write.
IanBenzMaxim 6:a8c83a2e6fa4 219 /// @param secretNum Secret to use for authentication.
IanBenzMaxim 6:a8c83a2e6fa4 220 /// @param page Data to write.
IanBenzMaxim 6:a8c83a2e6fa4 221 MaximInterface_EXPORT error_code authenticatedSha2WriteMemory(
IanBenzMaxim 6:a8c83a2e6fa4 222 int pageNum, SecretNum secretNum, Page::const_span page);
IanBenzMaxim 6:a8c83a2e6fa4 223
IanBenzMaxim 7:471901a04573 224 /// @brief Compute SHA2 secret and optionally lock.
IanBenzMaxim 6:a8c83a2e6fa4 225 /// @param pageNum Number of page to use in computation.
IanBenzMaxim 6:a8c83a2e6fa4 226 /// @param msecretNum Master secret to use in computation.
IanBenzMaxim 6:a8c83a2e6fa4 227 /// @param dsecretNum Destination secret to receive the computation result.
IanBenzMaxim 6:a8c83a2e6fa4 228 /// @param writeProtectEnable
IanBenzMaxim 6:a8c83a2e6fa4 229 /// True to lock the destination secret against further writes.
IanBenzMaxim 6:a8c83a2e6fa4 230 MaximInterface_EXPORT error_code
IanBenzMaxim 6:a8c83a2e6fa4 231 computeAndLockSha2Secret(int pageNum, SecretNum msecretNum,
IanBenzMaxim 6:a8c83a2e6fa4 232 SecretNum dsecretNum, bool writeProtectEnable);
IanBenzMaxim 6:a8c83a2e6fa4 233
IanBenzMaxim 7:471901a04573 234 /// @brief Generate a new ECDSA key pair.
IanBenzMaxim 6:a8c83a2e6fa4 235 /// @param keyNum Key to generate. Key S cannot be used with this command.
IanBenzMaxim 6:a8c83a2e6fa4 236 /// @param writeProtectEnable True to lock the key against further writes.
IanBenzMaxim 6:a8c83a2e6fa4 237 MaximInterface_EXPORT error_code
IanBenzMaxim 6:a8c83a2e6fa4 238 generateEcc256KeyPair(KeyNum keyNum, bool writeProtectEnable);
IanBenzMaxim 6:a8c83a2e6fa4 239
IanBenzMaxim 7:471901a04573 240 /// @brief Compute a hash over multiple blocks.
IanBenzMaxim 6:a8c83a2e6fa4 241 /// @param firstBlock True if this is the first block being hashed.
IanBenzMaxim 6:a8c83a2e6fa4 242 /// @param lastBlock True if this is the last block being hashed.
IanBenzMaxim 6:a8c83a2e6fa4 243 /// @param data
IanBenzMaxim 6:a8c83a2e6fa4 244 /// Data block to hash. Should be 64 bytes unless this is the last block.
IanBenzMaxim 6:a8c83a2e6fa4 245 MaximInterface_EXPORT error_code computeMultiblockHash(
IanBenzMaxim 6:a8c83a2e6fa4 246 bool firstBlock, bool lastBlock, span<const uint_least8_t> data);
IanBenzMaxim 6:a8c83a2e6fa4 247
IanBenzMaxim 7:471901a04573 248 /// @brief Verify ECDSA signature.
IanBenzMaxim 6:a8c83a2e6fa4 249 /// @param keyNum Public key to use for verification.
IanBenzMaxim 6:a8c83a2e6fa4 250 /// @param hashType Source of the data hash input.
IanBenzMaxim 6:a8c83a2e6fa4 251 /// @param signature Signature to verify.
IanBenzMaxim 6:a8c83a2e6fa4 252 /// @param pioa New state of PIOA if verification successful.
IanBenzMaxim 6:a8c83a2e6fa4 253 /// @param piob New state of PIOB if verification successful.
IanBenzMaxim 6:a8c83a2e6fa4 254 MaximInterface_EXPORT error_code verifyEcdsaSignature(
IanBenzMaxim 6:a8c83a2e6fa4 255 KeyNum keyNum, HashType hashType, Ecc256::Signature::const_span signature,
IanBenzMaxim 6:a8c83a2e6fa4 256 PioState pioa = Unchanged, PioState piob = Unchanged);
IanBenzMaxim 6:a8c83a2e6fa4 257
IanBenzMaxim 7:471901a04573 258 /// @brief
IanBenzMaxim 7:471901a04573 259 /// Authenticate a public key for authenticated writes or encrypted reads
IanBenzMaxim 7:471901a04573 260 /// with ECDH.
IanBenzMaxim 6:a8c83a2e6fa4 261 /// @param authWrites True to select authentication for writes.
IanBenzMaxim 6:a8c83a2e6fa4 262 /// @param ecdh True to select ECDH key exchange.
IanBenzMaxim 7:471901a04573 263 /// @param keyNum
IanBenzMaxim 7:471901a04573 264 /// Private key to use for ECDH key exchange. Key A or B can be selected.
IanBenzMaxim 6:a8c83a2e6fa4 265 /// @param csOffset Certificate customization field ending offset in buffer.
IanBenzMaxim 6:a8c83a2e6fa4 266 /// @param signature Signature to use for authentication of public key S.
IanBenzMaxim 6:a8c83a2e6fa4 267 MaximInterface_EXPORT error_code authenticateEcdsaPublicKey(
IanBenzMaxim 6:a8c83a2e6fa4 268 bool authWrites, bool ecdh, KeyNum keyNum, int csOffset,
IanBenzMaxim 6:a8c83a2e6fa4 269 Ecc256::Signature::const_span signature);
IanBenzMaxim 6:a8c83a2e6fa4 270
IanBenzMaxim 7:471901a04573 271 /// @brief Write with ECDSA authentication.
IanBenzMaxim 6:a8c83a2e6fa4 272 /// @param pageNum Number of page to write.
IanBenzMaxim 6:a8c83a2e6fa4 273 /// @param page Data to write.
IanBenzMaxim 6:a8c83a2e6fa4 274 MaximInterface_EXPORT error_code
IanBenzMaxim 6:a8c83a2e6fa4 275 authenticatedEcdsaWriteMemory(int pageNum, Page::const_span page);
IanBenzMaxim 6:a8c83a2e6fa4 276
IanBenzMaxim 6:a8c83a2e6fa4 277 MaximInterface_EXPORT static const error_category & errorCategory();
IanBenzMaxim 6:a8c83a2e6fa4 278
IanBenzMaxim 6:a8c83a2e6fa4 279 protected:
IanBenzMaxim 6:a8c83a2e6fa4 280 // Timing constants.
IanBenzMaxim 6:a8c83a2e6fa4 281 static const int generateEcdsaSignatureTimeMs = 50;
IanBenzMaxim 6:a8c83a2e6fa4 282 static const int generateEccKeyPairTimeMs = 100;
IanBenzMaxim 6:a8c83a2e6fa4 283 static const int verifyEsdsaSignatureOrComputeEcdhTimeMs = 150;
IanBenzMaxim 6:a8c83a2e6fa4 284 static const int sha256ComputationTimeMs = 3;
IanBenzMaxim 6:a8c83a2e6fa4 285 static const int readMemoryTimeMs = /*1*/ 2;
IanBenzMaxim 6:a8c83a2e6fa4 286 static const int writeMemoryTimeMs = 15;
IanBenzMaxim 6:a8c83a2e6fa4 287
IanBenzMaxim 6:a8c83a2e6fa4 288 error_code writeCommand(uint_least8_t command,
IanBenzMaxim 6:a8c83a2e6fa4 289 span<const uint_least8_t> parameters);
IanBenzMaxim 6:a8c83a2e6fa4 290
IanBenzMaxim 6:a8c83a2e6fa4 291 error_code writeCommand(uint_least8_t command) {
IanBenzMaxim 6:a8c83a2e6fa4 292 return writeCommand(command, span<const uint_least8_t>());
IanBenzMaxim 6:a8c83a2e6fa4 293 }
IanBenzMaxim 6:a8c83a2e6fa4 294
IanBenzMaxim 6:a8c83a2e6fa4 295 error_code readVariableLengthResponse(span<uint_least8_t> & response);
IanBenzMaxim 6:a8c83a2e6fa4 296
IanBenzMaxim 6:a8c83a2e6fa4 297 error_code readFixedLengthResponse(span<uint_least8_t> response);
IanBenzMaxim 6:a8c83a2e6fa4 298
IanBenzMaxim 6:a8c83a2e6fa4 299 void sleep(int ms) const { sleep_->invoke(ms); }
IanBenzMaxim 6:a8c83a2e6fa4 300
IanBenzMaxim 6:a8c83a2e6fa4 301 private:
IanBenzMaxim 6:a8c83a2e6fa4 302 enum AuthType {
IanBenzMaxim 6:a8c83a2e6fa4 303 HmacWithSecretA = 0,
IanBenzMaxim 6:a8c83a2e6fa4 304 HmacWithSecretB = 1,
IanBenzMaxim 6:a8c83a2e6fa4 305 HmacWithSecretS = 2,
IanBenzMaxim 6:a8c83a2e6fa4 306 EcdsaWithKeyA = 3,
IanBenzMaxim 6:a8c83a2e6fa4 307 EcdsaWithKeyB = 4,
IanBenzMaxim 6:a8c83a2e6fa4 308 EcdsaWithKeyC = 5
IanBenzMaxim 6:a8c83a2e6fa4 309 };
IanBenzMaxim 6:a8c83a2e6fa4 310
IanBenzMaxim 6:a8c83a2e6fa4 311 const Sleep * sleep_;
IanBenzMaxim 6:a8c83a2e6fa4 312 I2CMaster * master;
IanBenzMaxim 6:a8c83a2e6fa4 313 uint_least8_t address_;
IanBenzMaxim 6:a8c83a2e6fa4 314
IanBenzMaxim 6:a8c83a2e6fa4 315 error_code computeAndReadPageAuthentication(int pageNum, AuthType authType);
IanBenzMaxim 6:a8c83a2e6fa4 316 };
IanBenzMaxim 6:a8c83a2e6fa4 317
IanBenzMaxim 6:a8c83a2e6fa4 318 /// Interface to the DS2476 coprocessor.
IanBenzMaxim 6:a8c83a2e6fa4 319 class DS2476 : public DS28C36 {
IanBenzMaxim 6:a8c83a2e6fa4 320 public:
IanBenzMaxim 6:a8c83a2e6fa4 321 DS2476(Sleep & sleep, I2CMaster & master, uint_least8_t address = 0x76)
IanBenzMaxim 6:a8c83a2e6fa4 322 : DS28C36(sleep, master, address) {}
IanBenzMaxim 6:a8c83a2e6fa4 323
IanBenzMaxim 7:471901a04573 324 /// @brief Generate ECDSA signature.
IanBenzMaxim 7:471901a04573 325 /// @param keyNum
IanBenzMaxim 7:471901a04573 326 /// Private key to use to create signature.
IanBenzMaxim 6:a8c83a2e6fa4 327 /// Key S cannot be used with this command.
IanBenzMaxim 6:a8c83a2e6fa4 328 /// @param[out] signature Computed signature.
IanBenzMaxim 6:a8c83a2e6fa4 329 MaximInterface_EXPORT error_code
IanBenzMaxim 6:a8c83a2e6fa4 330 generateEcdsaSignature(KeyNum keyNum, Ecc256::Signature::span signature);
IanBenzMaxim 6:a8c83a2e6fa4 331
IanBenzMaxim 7:471901a04573 332 /// @brief Compute unique SHA2 secret.
IanBenzMaxim 6:a8c83a2e6fa4 333 /// @param msecretNum Master secret to use in computation.
IanBenzMaxim 6:a8c83a2e6fa4 334 MaximInterface_EXPORT error_code
IanBenzMaxim 6:a8c83a2e6fa4 335 computeSha2UniqueSecret(SecretNum msecretNum);
IanBenzMaxim 6:a8c83a2e6fa4 336
IanBenzMaxim 7:471901a04573 337 /// @brief Compute SHA2 HMAC.
IanBenzMaxim 6:a8c83a2e6fa4 338 /// @param[out] hmac Computed HMAC.
IanBenzMaxim 6:a8c83a2e6fa4 339 MaximInterface_EXPORT error_code computeSha2Hmac(Sha256::Hash::span hmac);
IanBenzMaxim 6:a8c83a2e6fa4 340 };
IanBenzMaxim 6:a8c83a2e6fa4 341
IanBenzMaxim 6:a8c83a2e6fa4 342 inline error_code make_error_code(DS28C36::ErrorValue e) {
IanBenzMaxim 6:a8c83a2e6fa4 343 return error_code(e, DS28C36::errorCategory());
IanBenzMaxim 6:a8c83a2e6fa4 344 }
IanBenzMaxim 6:a8c83a2e6fa4 345
IanBenzMaxim 7:471901a04573 346 /// @brief
IanBenzMaxim 6:a8c83a2e6fa4 347 /// Hash arbitrary length data with successive Compute Multiblock Hash commands.
IanBenzMaxim 7:471901a04573 348 /// @param ds28c36 Device for computation.
IanBenzMaxim 6:a8c83a2e6fa4 349 /// @param data Data to hash.
IanBenzMaxim 6:a8c83a2e6fa4 350 MaximInterface_EXPORT error_code
IanBenzMaxim 6:a8c83a2e6fa4 351 computeMultiblockHash(DS28C36 & ds28c36, span<const uint_least8_t> data);
IanBenzMaxim 6:a8c83a2e6fa4 352
IanBenzMaxim 7:471901a04573 353 /// @brief Verify ECDSA signature.
IanBenzMaxim 7:471901a04573 354 /// @param ds28c36 Device for computation.
IanBenzMaxim 6:a8c83a2e6fa4 355 /// @param publicKey Public key to use for verification.
IanBenzMaxim 6:a8c83a2e6fa4 356 /// @param data Data to verify.
IanBenzMaxim 6:a8c83a2e6fa4 357 /// @param signature Signature to verify.
IanBenzMaxim 6:a8c83a2e6fa4 358 /// @param pioa New state of PIOA if verification successful.
IanBenzMaxim 6:a8c83a2e6fa4 359 /// @param piob New state of PIOB if verification successful.
IanBenzMaxim 6:a8c83a2e6fa4 360 MaximInterface_EXPORT error_code verifyEcdsaSignature(
IanBenzMaxim 6:a8c83a2e6fa4 361 DS28C36 & ds28c36, DS28C36::KeyNum publicKey,
IanBenzMaxim 6:a8c83a2e6fa4 362 span<const uint_least8_t> data, Ecc256::Signature::const_span signature,
IanBenzMaxim 6:a8c83a2e6fa4 363 DS28C36::PioState pioa = DS28C36::Unchanged,
IanBenzMaxim 6:a8c83a2e6fa4 364 DS28C36::PioState piob = DS28C36::Unchanged);
IanBenzMaxim 6:a8c83a2e6fa4 365
IanBenzMaxim 7:471901a04573 366 /// @brief Verify ECDSA signature.
IanBenzMaxim 7:471901a04573 367 /// @param ds28c36 Device for computation.
IanBenzMaxim 6:a8c83a2e6fa4 368 /// @param publicKey
IanBenzMaxim 6:a8c83a2e6fa4 369 /// Public key to use for verification which is loaded into Public Key S.
IanBenzMaxim 6:a8c83a2e6fa4 370 /// @param data Data to verify.
IanBenzMaxim 6:a8c83a2e6fa4 371 /// @param signature Signature to verify.
IanBenzMaxim 6:a8c83a2e6fa4 372 /// @param pioa New state of PIOA if verification successful.
IanBenzMaxim 6:a8c83a2e6fa4 373 /// @param piob New state of PIOB if verification successful.
IanBenzMaxim 6:a8c83a2e6fa4 374 MaximInterface_EXPORT error_code verifyEcdsaSignature(
IanBenzMaxim 6:a8c83a2e6fa4 375 DS28C36 & ds28c36, Ecc256::PublicKey::const_span publicKey,
IanBenzMaxim 6:a8c83a2e6fa4 376 span<const uint_least8_t> data, Ecc256::Signature::const_span signature,
IanBenzMaxim 6:a8c83a2e6fa4 377 DS28C36::PioState pioa = DS28C36::Unchanged,
IanBenzMaxim 6:a8c83a2e6fa4 378 DS28C36::PioState piob = DS28C36::Unchanged);
IanBenzMaxim 6:a8c83a2e6fa4 379
IanBenzMaxim 7:471901a04573 380 /// @brief
IanBenzMaxim 6:a8c83a2e6fa4 381 /// Read the device ROM ID and MAN ID using the Read Memory command on the
IanBenzMaxim 6:a8c83a2e6fa4 382 /// ROM Options page.
IanBenzMaxim 7:471901a04573 383 /// @param ds28c36 Device to read.
IanBenzMaxim 6:a8c83a2e6fa4 384 /// @param[out] romId Read ROM ID valid when operation is successful.
IanBenzMaxim 6:a8c83a2e6fa4 385 /// @param[out] manId Read MAN ID valid when operation is successful.
IanBenzMaxim 6:a8c83a2e6fa4 386 MaximInterface_EXPORT error_code readRomIdAndManId(DS28C36 & ds28c36,
IanBenzMaxim 6:a8c83a2e6fa4 387 RomId::span romId,
IanBenzMaxim 6:a8c83a2e6fa4 388 ManId::span manId);
IanBenzMaxim 6:a8c83a2e6fa4 389
IanBenzMaxim 7:471901a04573 390 /// @brief
IanBenzMaxim 6:a8c83a2e6fa4 391 /// Enable coprocessor functionality on the DS2476 by writing to the
IanBenzMaxim 7:471901a04573 392 /// GPIO Control page.
IanBenzMaxim 6:a8c83a2e6fa4 393 MaximInterface_EXPORT error_code enableCoprocessor(DS2476 & ds2476);
IanBenzMaxim 6:a8c83a2e6fa4 394
IanBenzMaxim 7:471901a04573 395 /// @brief
IanBenzMaxim 7:471901a04573 396 /// Disable blocking of the ROM ID on the DS2476 by writing to the
IanBenzMaxim 7:471901a04573 397 /// ROM Options page.
IanBenzMaxim 7:471901a04573 398 MaximInterface_EXPORT error_code enableRomId(DS2476 & ds2476);
IanBenzMaxim 7:471901a04573 399
IanBenzMaxim 7:471901a04573 400 /// Format page authentication input data.
IanBenzMaxim 6:a8c83a2e6fa4 401 class DS28C36::PageAuthenticationData {
IanBenzMaxim 6:a8c83a2e6fa4 402 public:
IanBenzMaxim 6:a8c83a2e6fa4 403 typedef array_span<uint_least8_t,
IanBenzMaxim 6:a8c83a2e6fa4 404 RomId::size + 2 * Page::size + 1 + ManId::size>
IanBenzMaxim 6:a8c83a2e6fa4 405 Result;
IanBenzMaxim 6:a8c83a2e6fa4 406
IanBenzMaxim 6:a8c83a2e6fa4 407 PageAuthenticationData() : result_() {}
IanBenzMaxim 6:a8c83a2e6fa4 408
IanBenzMaxim 6:a8c83a2e6fa4 409 /// Formatted data result.
IanBenzMaxim 6:a8c83a2e6fa4 410 Result::const_span result() const { return result_; }
IanBenzMaxim 6:a8c83a2e6fa4 411
IanBenzMaxim 7:471901a04573 412 /// @name ROM ID
IanBenzMaxim 7:471901a04573 413 /// @brief 1-Wire ROM ID of the device.
IanBenzMaxim 6:a8c83a2e6fa4 414 /// @{
IanBenzMaxim 7:471901a04573 415
IanBenzMaxim 7:471901a04573 416 /// Get mutable ROM ID.
IanBenzMaxim 6:a8c83a2e6fa4 417 RomId::span romId() {
IanBenzMaxim 6:a8c83a2e6fa4 418 return make_span(result_).subspan<romIdIdx, RomId::size>();
IanBenzMaxim 6:a8c83a2e6fa4 419 }
IanBenzMaxim 6:a8c83a2e6fa4 420
IanBenzMaxim 7:471901a04573 421 /// Get immutable ROM ID.
IanBenzMaxim 6:a8c83a2e6fa4 422 RomId::const_span romId() const {
IanBenzMaxim 6:a8c83a2e6fa4 423 return const_cast<PageAuthenticationData &>(*this).romId();
IanBenzMaxim 6:a8c83a2e6fa4 424 }
IanBenzMaxim 6:a8c83a2e6fa4 425
IanBenzMaxim 7:471901a04573 426 /// Set ROM ID.
IanBenzMaxim 6:a8c83a2e6fa4 427 PageAuthenticationData & setRomId(RomId::const_span romId) {
IanBenzMaxim 6:a8c83a2e6fa4 428 copy(romId, this->romId());
IanBenzMaxim 6:a8c83a2e6fa4 429 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 430 }
IanBenzMaxim 6:a8c83a2e6fa4 431
IanBenzMaxim 7:471901a04573 432 /// Set ROM ID for use in anonymous mode.
IanBenzMaxim 6:a8c83a2e6fa4 433 MaximInterface_EXPORT PageAuthenticationData & setAnonymousRomId();
IanBenzMaxim 7:471901a04573 434
IanBenzMaxim 6:a8c83a2e6fa4 435 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 436
IanBenzMaxim 7:471901a04573 437 /// @name Page
IanBenzMaxim 7:471901a04573 438 /// @brief Data from a device memory page.
IanBenzMaxim 6:a8c83a2e6fa4 439 /// @{
IanBenzMaxim 7:471901a04573 440
IanBenzMaxim 7:471901a04573 441 /// Get mutable page.
IanBenzMaxim 6:a8c83a2e6fa4 442 Page::span page() {
IanBenzMaxim 6:a8c83a2e6fa4 443 return make_span(result_).subspan<pageIdx, Page::size>();
IanBenzMaxim 6:a8c83a2e6fa4 444 }
IanBenzMaxim 6:a8c83a2e6fa4 445
IanBenzMaxim 7:471901a04573 446 /// Get immutable page.
IanBenzMaxim 6:a8c83a2e6fa4 447 Page::const_span page() const {
IanBenzMaxim 6:a8c83a2e6fa4 448 return const_cast<PageAuthenticationData &>(*this).page();
IanBenzMaxim 6:a8c83a2e6fa4 449 }
IanBenzMaxim 6:a8c83a2e6fa4 450
IanBenzMaxim 7:471901a04573 451 /// Set page.
IanBenzMaxim 6:a8c83a2e6fa4 452 PageAuthenticationData & setPage(Page::const_span page) {
IanBenzMaxim 6:a8c83a2e6fa4 453 copy(page, this->page());
IanBenzMaxim 6:a8c83a2e6fa4 454 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 455 }
IanBenzMaxim 7:471901a04573 456
IanBenzMaxim 6:a8c83a2e6fa4 457 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 458
IanBenzMaxim 7:471901a04573 459 /// @name Challenge
IanBenzMaxim 7:471901a04573 460 /// @brief Random challenge used to prevent replay attacks.
IanBenzMaxim 6:a8c83a2e6fa4 461 /// @{
IanBenzMaxim 7:471901a04573 462
IanBenzMaxim 7:471901a04573 463 /// Get mutable Challenge.
IanBenzMaxim 6:a8c83a2e6fa4 464 Page::span challenge() {
IanBenzMaxim 6:a8c83a2e6fa4 465 return make_span(result_).subspan<challengeIdx, Page::size>();
IanBenzMaxim 6:a8c83a2e6fa4 466 }
IanBenzMaxim 6:a8c83a2e6fa4 467
IanBenzMaxim 7:471901a04573 468 /// Get immutable Challenge.
IanBenzMaxim 6:a8c83a2e6fa4 469 Page::const_span challenge() const {
IanBenzMaxim 6:a8c83a2e6fa4 470 return const_cast<PageAuthenticationData &>(*this).challenge();
IanBenzMaxim 6:a8c83a2e6fa4 471 }
IanBenzMaxim 6:a8c83a2e6fa4 472
IanBenzMaxim 7:471901a04573 473 /// Set Challenge.
IanBenzMaxim 6:a8c83a2e6fa4 474 PageAuthenticationData & setChallenge(Page::const_span challenge) {
IanBenzMaxim 6:a8c83a2e6fa4 475 copy(challenge, this->challenge());
IanBenzMaxim 6:a8c83a2e6fa4 476 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 477 }
IanBenzMaxim 7:471901a04573 478
IanBenzMaxim 6:a8c83a2e6fa4 479 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 480
IanBenzMaxim 7:471901a04573 481 /// @name Page number
IanBenzMaxim 7:471901a04573 482 /// @brief Number of the page to use data from.
IanBenzMaxim 6:a8c83a2e6fa4 483 /// @{
IanBenzMaxim 7:471901a04573 484
IanBenzMaxim 7:471901a04573 485 /// Get page number.
IanBenzMaxim 6:a8c83a2e6fa4 486 int pageNum() const { return result_[pageNumIdx]; }
IanBenzMaxim 6:a8c83a2e6fa4 487
IanBenzMaxim 7:471901a04573 488 /// Set page number.
IanBenzMaxim 6:a8c83a2e6fa4 489 PageAuthenticationData & setPageNum(int pageNum) {
IanBenzMaxim 6:a8c83a2e6fa4 490 result_[pageNumIdx] = pageNum;
IanBenzMaxim 6:a8c83a2e6fa4 491 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 492 }
IanBenzMaxim 7:471901a04573 493
IanBenzMaxim 6:a8c83a2e6fa4 494 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 495
IanBenzMaxim 7:471901a04573 496 /// @name MAN ID
IanBenzMaxim 7:471901a04573 497 /// @brief Manufacturer ID of the device.
IanBenzMaxim 6:a8c83a2e6fa4 498 /// @{
IanBenzMaxim 7:471901a04573 499
IanBenzMaxim 7:471901a04573 500 /// Get mutable MAN ID.
IanBenzMaxim 6:a8c83a2e6fa4 501 ManId::span manId() {
IanBenzMaxim 6:a8c83a2e6fa4 502 return make_span(result_).subspan<manIdIdx, ManId::size>();
IanBenzMaxim 6:a8c83a2e6fa4 503 }
IanBenzMaxim 6:a8c83a2e6fa4 504
IanBenzMaxim 7:471901a04573 505 /// Get immutable MAN ID.
IanBenzMaxim 6:a8c83a2e6fa4 506 ManId::const_span manId() const {
IanBenzMaxim 6:a8c83a2e6fa4 507 return const_cast<PageAuthenticationData &>(*this).manId();
IanBenzMaxim 6:a8c83a2e6fa4 508 }
IanBenzMaxim 6:a8c83a2e6fa4 509
IanBenzMaxim 7:471901a04573 510 /// Set MAN ID.
IanBenzMaxim 6:a8c83a2e6fa4 511 PageAuthenticationData & setManId(ManId::const_span manId) {
IanBenzMaxim 6:a8c83a2e6fa4 512 copy(manId, this->manId());
IanBenzMaxim 6:a8c83a2e6fa4 513 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 514 }
IanBenzMaxim 7:471901a04573 515
IanBenzMaxim 6:a8c83a2e6fa4 516 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 517
IanBenzMaxim 6:a8c83a2e6fa4 518 private:
IanBenzMaxim 6:a8c83a2e6fa4 519 typedef Result::span::index_type index;
IanBenzMaxim 6:a8c83a2e6fa4 520
IanBenzMaxim 6:a8c83a2e6fa4 521 static const index romIdIdx = 0;
IanBenzMaxim 6:a8c83a2e6fa4 522 static const index pageIdx = romIdIdx + RomId::size;
IanBenzMaxim 6:a8c83a2e6fa4 523 static const index challengeIdx = pageIdx + Page::size;
IanBenzMaxim 6:a8c83a2e6fa4 524 static const index pageNumIdx = challengeIdx + Page::size;
IanBenzMaxim 6:a8c83a2e6fa4 525 static const index manIdIdx = pageNumIdx + 1;
IanBenzMaxim 6:a8c83a2e6fa4 526
IanBenzMaxim 6:a8c83a2e6fa4 527 Result::array result_;
IanBenzMaxim 6:a8c83a2e6fa4 528 };
IanBenzMaxim 6:a8c83a2e6fa4 529
IanBenzMaxim 7:471901a04573 530 /// Format authenticated write input data.
IanBenzMaxim 6:a8c83a2e6fa4 531 class DS28C36::WriteAuthenticationData {
IanBenzMaxim 6:a8c83a2e6fa4 532 public:
IanBenzMaxim 6:a8c83a2e6fa4 533 typedef PageAuthenticationData::Result Result;
IanBenzMaxim 6:a8c83a2e6fa4 534
IanBenzMaxim 6:a8c83a2e6fa4 535 WriteAuthenticationData() : data() {}
IanBenzMaxim 6:a8c83a2e6fa4 536
IanBenzMaxim 6:a8c83a2e6fa4 537 /// Formatted data result.
IanBenzMaxim 6:a8c83a2e6fa4 538 Result::const_span result() const { return data.result(); }
IanBenzMaxim 6:a8c83a2e6fa4 539
IanBenzMaxim 7:471901a04573 540 /// @name ROM ID
IanBenzMaxim 7:471901a04573 541 /// @brief 1-Wire ROM ID of the device.
IanBenzMaxim 6:a8c83a2e6fa4 542 /// @{
IanBenzMaxim 7:471901a04573 543
IanBenzMaxim 7:471901a04573 544 /// Get mutable ROM ID.
IanBenzMaxim 6:a8c83a2e6fa4 545 RomId::span romId() { return data.romId(); }
IanBenzMaxim 6:a8c83a2e6fa4 546
IanBenzMaxim 7:471901a04573 547 /// Get immutable ROM ID.
IanBenzMaxim 6:a8c83a2e6fa4 548 RomId::const_span romId() const { return data.romId(); }
IanBenzMaxim 6:a8c83a2e6fa4 549
IanBenzMaxim 7:471901a04573 550 /// Set ROM ID.
IanBenzMaxim 6:a8c83a2e6fa4 551 WriteAuthenticationData & setRomId(RomId::const_span romId) {
IanBenzMaxim 6:a8c83a2e6fa4 552 data.setRomId(romId);
IanBenzMaxim 6:a8c83a2e6fa4 553 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 554 }
IanBenzMaxim 6:a8c83a2e6fa4 555
IanBenzMaxim 7:471901a04573 556 /// Set ROM ID for use in anonymous mode.
IanBenzMaxim 6:a8c83a2e6fa4 557 WriteAuthenticationData & setAnonymousRomId() {
IanBenzMaxim 6:a8c83a2e6fa4 558 data.setAnonymousRomId();
IanBenzMaxim 6:a8c83a2e6fa4 559 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 560 }
IanBenzMaxim 7:471901a04573 561
IanBenzMaxim 6:a8c83a2e6fa4 562 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 563
IanBenzMaxim 7:471901a04573 564 /// @name Old page
IanBenzMaxim 7:471901a04573 565 /// @brief Existing data contained in the page.
IanBenzMaxim 6:a8c83a2e6fa4 566 /// @{
IanBenzMaxim 7:471901a04573 567
IanBenzMaxim 7:471901a04573 568 /// Get mutable old page.
IanBenzMaxim 6:a8c83a2e6fa4 569 Page::span oldPage() { return data.page(); }
IanBenzMaxim 6:a8c83a2e6fa4 570
IanBenzMaxim 7:471901a04573 571 /// Get immutable old page.
IanBenzMaxim 6:a8c83a2e6fa4 572 Page::const_span oldPage() const { return data.page(); }
IanBenzMaxim 6:a8c83a2e6fa4 573
IanBenzMaxim 7:471901a04573 574 /// Set old page.
IanBenzMaxim 6:a8c83a2e6fa4 575 WriteAuthenticationData & setOldPage(Page::const_span oldPage) {
IanBenzMaxim 6:a8c83a2e6fa4 576 data.setPage(oldPage);
IanBenzMaxim 6:a8c83a2e6fa4 577 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 578 }
IanBenzMaxim 7:471901a04573 579
IanBenzMaxim 6:a8c83a2e6fa4 580 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 581
IanBenzMaxim 7:471901a04573 582 /// @name New page
IanBenzMaxim 7:471901a04573 583 /// @brief New data to write to the page.
IanBenzMaxim 6:a8c83a2e6fa4 584 /// @{
IanBenzMaxim 7:471901a04573 585
IanBenzMaxim 7:471901a04573 586 /// Get mutable new page.
IanBenzMaxim 6:a8c83a2e6fa4 587 Page::span newPage() { return data.challenge(); }
IanBenzMaxim 6:a8c83a2e6fa4 588
IanBenzMaxim 7:471901a04573 589 /// Get immutable new page.
IanBenzMaxim 6:a8c83a2e6fa4 590 Page::const_span newPage() const { return data.challenge(); }
IanBenzMaxim 6:a8c83a2e6fa4 591
IanBenzMaxim 7:471901a04573 592 /// Set new page.
IanBenzMaxim 6:a8c83a2e6fa4 593 WriteAuthenticationData & setNewPage(Page::const_span newPage) {
IanBenzMaxim 6:a8c83a2e6fa4 594 data.setChallenge(newPage);
IanBenzMaxim 6:a8c83a2e6fa4 595 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 596 }
IanBenzMaxim 7:471901a04573 597
IanBenzMaxim 6:a8c83a2e6fa4 598 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 599
IanBenzMaxim 7:471901a04573 600 /// @name Page number
IanBenzMaxim 7:471901a04573 601 /// @brief Page number for write operation.
IanBenzMaxim 6:a8c83a2e6fa4 602 /// @{
IanBenzMaxim 7:471901a04573 603
IanBenzMaxim 7:471901a04573 604 /// Get page number.
IanBenzMaxim 6:a8c83a2e6fa4 605 int pageNum() const { return data.pageNum(); }
IanBenzMaxim 6:a8c83a2e6fa4 606
IanBenzMaxim 7:471901a04573 607 /// Set page number.
IanBenzMaxim 6:a8c83a2e6fa4 608 WriteAuthenticationData & setPageNum(int pageNum) {
IanBenzMaxim 6:a8c83a2e6fa4 609 data.setPageNum(pageNum);
IanBenzMaxim 6:a8c83a2e6fa4 610 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 611 }
IanBenzMaxim 7:471901a04573 612
IanBenzMaxim 6:a8c83a2e6fa4 613 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 614
IanBenzMaxim 7:471901a04573 615 /// @name MAN ID
IanBenzMaxim 7:471901a04573 616 /// @brief Manufacturer ID of the device.
IanBenzMaxim 6:a8c83a2e6fa4 617 /// @{
IanBenzMaxim 7:471901a04573 618
IanBenzMaxim 7:471901a04573 619 /// Get mutable MAN ID.
IanBenzMaxim 6:a8c83a2e6fa4 620 ManId::span manId() { return data.manId(); }
IanBenzMaxim 6:a8c83a2e6fa4 621
IanBenzMaxim 7:471901a04573 622 /// Get immutable MAN ID.
IanBenzMaxim 6:a8c83a2e6fa4 623 ManId::const_span manId() const { return data.manId(); }
IanBenzMaxim 6:a8c83a2e6fa4 624
IanBenzMaxim 7:471901a04573 625 /// Set MAN ID.
IanBenzMaxim 6:a8c83a2e6fa4 626 WriteAuthenticationData & setManId(ManId::const_span manId) {
IanBenzMaxim 6:a8c83a2e6fa4 627 data.setManId(manId);
IanBenzMaxim 6:a8c83a2e6fa4 628 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 629 }
IanBenzMaxim 7:471901a04573 630
IanBenzMaxim 6:a8c83a2e6fa4 631 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 632
IanBenzMaxim 6:a8c83a2e6fa4 633 private:
IanBenzMaxim 6:a8c83a2e6fa4 634 PageAuthenticationData data;
IanBenzMaxim 6:a8c83a2e6fa4 635 };
IanBenzMaxim 6:a8c83a2e6fa4 636
IanBenzMaxim 7:471901a04573 637 /// Format compute secret input data.
IanBenzMaxim 6:a8c83a2e6fa4 638 class DS28C36::ComputeSecretData {
IanBenzMaxim 6:a8c83a2e6fa4 639 public:
IanBenzMaxim 6:a8c83a2e6fa4 640 typedef PageAuthenticationData::Result Result;
IanBenzMaxim 6:a8c83a2e6fa4 641
IanBenzMaxim 6:a8c83a2e6fa4 642 ComputeSecretData() : data() {}
IanBenzMaxim 6:a8c83a2e6fa4 643
IanBenzMaxim 6:a8c83a2e6fa4 644 /// Formatted data result.
IanBenzMaxim 6:a8c83a2e6fa4 645 Result::const_span result() const { return data.result(); }
IanBenzMaxim 6:a8c83a2e6fa4 646
IanBenzMaxim 7:471901a04573 647 /// @name ROM ID
IanBenzMaxim 7:471901a04573 648 /// @brief 1-Wire ROM ID of the device.
IanBenzMaxim 6:a8c83a2e6fa4 649 /// @{
IanBenzMaxim 7:471901a04573 650
IanBenzMaxim 7:471901a04573 651 /// Get mutable ROM ID.
IanBenzMaxim 6:a8c83a2e6fa4 652 RomId::span romId() { return data.romId(); }
IanBenzMaxim 6:a8c83a2e6fa4 653
IanBenzMaxim 7:471901a04573 654 /// Get immutable ROM ID.
IanBenzMaxim 6:a8c83a2e6fa4 655 RomId::const_span romId() const { return data.romId(); }
IanBenzMaxim 6:a8c83a2e6fa4 656
IanBenzMaxim 7:471901a04573 657 /// Set ROM ID.
IanBenzMaxim 6:a8c83a2e6fa4 658 ComputeSecretData & setRomId(RomId::const_span romId) {
IanBenzMaxim 6:a8c83a2e6fa4 659 data.setRomId(romId);
IanBenzMaxim 6:a8c83a2e6fa4 660 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 661 }
IanBenzMaxim 7:471901a04573 662
IanBenzMaxim 6:a8c83a2e6fa4 663 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 664
IanBenzMaxim 7:471901a04573 665 /// @name Binding Data
IanBenzMaxim 7:471901a04573 666 /// @brief Binding Data contained in the selected page.
IanBenzMaxim 6:a8c83a2e6fa4 667 /// @{
IanBenzMaxim 7:471901a04573 668
IanBenzMaxim 7:471901a04573 669 /// Get mutable Binding Data.
IanBenzMaxim 6:a8c83a2e6fa4 670 Page::span bindingData() { return data.page(); }
IanBenzMaxim 6:a8c83a2e6fa4 671
IanBenzMaxim 7:471901a04573 672 /// Get immutable Binding Data.
IanBenzMaxim 6:a8c83a2e6fa4 673 Page::const_span bindingData() const { return data.page(); }
IanBenzMaxim 6:a8c83a2e6fa4 674
IanBenzMaxim 7:471901a04573 675 /// Set Binding Data.
IanBenzMaxim 6:a8c83a2e6fa4 676 ComputeSecretData & setBindingData(Page::const_span bindingData) {
IanBenzMaxim 6:a8c83a2e6fa4 677 data.setPage(bindingData);
IanBenzMaxim 6:a8c83a2e6fa4 678 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 679 }
IanBenzMaxim 7:471901a04573 680
IanBenzMaxim 6:a8c83a2e6fa4 681 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 682
IanBenzMaxim 7:471901a04573 683 /// @name Partial Secret
IanBenzMaxim 7:471901a04573 684 /// @brief Partial Secret used for customization.
IanBenzMaxim 6:a8c83a2e6fa4 685 /// @{
IanBenzMaxim 7:471901a04573 686
IanBenzMaxim 7:471901a04573 687 /// Get mutable Partial Secret.
IanBenzMaxim 6:a8c83a2e6fa4 688 Page::span partialSecret() { return data.challenge(); }
IanBenzMaxim 6:a8c83a2e6fa4 689
IanBenzMaxim 7:471901a04573 690 /// Get immutable Partial Secret.
IanBenzMaxim 6:a8c83a2e6fa4 691 Page::const_span partialSecret() const { return data.challenge(); }
IanBenzMaxim 6:a8c83a2e6fa4 692
IanBenzMaxim 7:471901a04573 693 /// Set Partial Secret.
IanBenzMaxim 6:a8c83a2e6fa4 694 ComputeSecretData & setPartialSecret(Page::const_span partialSecret) {
IanBenzMaxim 6:a8c83a2e6fa4 695 data.setChallenge(partialSecret);
IanBenzMaxim 6:a8c83a2e6fa4 696 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 697 }
IanBenzMaxim 7:471901a04573 698
IanBenzMaxim 6:a8c83a2e6fa4 699 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 700
IanBenzMaxim 7:471901a04573 701 /// @name Page number
IanBenzMaxim 7:471901a04573 702 /// @brief Page number for Binding Data.
IanBenzMaxim 6:a8c83a2e6fa4 703 /// @{
IanBenzMaxim 7:471901a04573 704
IanBenzMaxim 7:471901a04573 705 /// Get page number.
IanBenzMaxim 6:a8c83a2e6fa4 706 int pageNum() const { return data.pageNum(); }
IanBenzMaxim 6:a8c83a2e6fa4 707
IanBenzMaxim 7:471901a04573 708 /// Set page number.
IanBenzMaxim 6:a8c83a2e6fa4 709 ComputeSecretData & setPageNum(int pageNum) {
IanBenzMaxim 6:a8c83a2e6fa4 710 data.setPageNum(pageNum);
IanBenzMaxim 6:a8c83a2e6fa4 711 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 712 }
IanBenzMaxim 7:471901a04573 713
IanBenzMaxim 6:a8c83a2e6fa4 714 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 715
IanBenzMaxim 7:471901a04573 716 /// @name MAN ID
IanBenzMaxim 7:471901a04573 717 /// @brief Manufacturer ID of the device.
IanBenzMaxim 6:a8c83a2e6fa4 718 /// @{
IanBenzMaxim 7:471901a04573 719
IanBenzMaxim 7:471901a04573 720 /// Get mutable MAN ID.
IanBenzMaxim 6:a8c83a2e6fa4 721 ManId::span manId() { return data.manId(); }
IanBenzMaxim 6:a8c83a2e6fa4 722
IanBenzMaxim 7:471901a04573 723 /// Get immutable MAN ID.
IanBenzMaxim 6:a8c83a2e6fa4 724 ManId::const_span manId() const { return data.manId(); }
IanBenzMaxim 6:a8c83a2e6fa4 725
IanBenzMaxim 7:471901a04573 726 /// Set MAN ID.
IanBenzMaxim 6:a8c83a2e6fa4 727 ComputeSecretData & setManId(ManId::const_span manId) {
IanBenzMaxim 6:a8c83a2e6fa4 728 data.setManId(manId);
IanBenzMaxim 6:a8c83a2e6fa4 729 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 730 }
IanBenzMaxim 7:471901a04573 731
IanBenzMaxim 6:a8c83a2e6fa4 732 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 733
IanBenzMaxim 6:a8c83a2e6fa4 734 private:
IanBenzMaxim 6:a8c83a2e6fa4 735 PageAuthenticationData data;
IanBenzMaxim 6:a8c83a2e6fa4 736 };
IanBenzMaxim 6:a8c83a2e6fa4 737
IanBenzMaxim 7:471901a04573 738 /// Format encryption or decryption HMAC input data.
IanBenzMaxim 6:a8c83a2e6fa4 739 class DS28C36::EncryptionHmacData {
IanBenzMaxim 6:a8c83a2e6fa4 740 public:
IanBenzMaxim 6:a8c83a2e6fa4 741 typedef array_span<uint_least8_t,
IanBenzMaxim 6:a8c83a2e6fa4 742 EncryptionChallenge::size + RomId::size + 1 + ManId::size>
IanBenzMaxim 6:a8c83a2e6fa4 743 Result;
IanBenzMaxim 6:a8c83a2e6fa4 744
IanBenzMaxim 6:a8c83a2e6fa4 745 EncryptionHmacData() : result_() {}
IanBenzMaxim 6:a8c83a2e6fa4 746
IanBenzMaxim 6:a8c83a2e6fa4 747 /// Formatted data result.
IanBenzMaxim 6:a8c83a2e6fa4 748 Result::const_span result() const { return result_; }
IanBenzMaxim 6:a8c83a2e6fa4 749
IanBenzMaxim 7:471901a04573 750 /// @name Encryption Challenge
IanBenzMaxim 7:471901a04573 751 /// @brief Random challenge used to prevent replay attacks.
IanBenzMaxim 6:a8c83a2e6fa4 752 /// @{
IanBenzMaxim 7:471901a04573 753
IanBenzMaxim 7:471901a04573 754 /// Get mutable Encryption Challenge.
IanBenzMaxim 6:a8c83a2e6fa4 755 EncryptionChallenge::span encryptionChallenge() {
IanBenzMaxim 6:a8c83a2e6fa4 756 return make_span(result_)
IanBenzMaxim 6:a8c83a2e6fa4 757 .subspan<encryptionChallengeIdx, EncryptionChallenge::size>();
IanBenzMaxim 6:a8c83a2e6fa4 758 }
IanBenzMaxim 6:a8c83a2e6fa4 759
IanBenzMaxim 7:471901a04573 760 /// Get immutable Encryption Challenge.
IanBenzMaxim 6:a8c83a2e6fa4 761 EncryptionChallenge::const_span encryptionChallenge() const {
IanBenzMaxim 6:a8c83a2e6fa4 762 return const_cast<EncryptionHmacData &>(*this).encryptionChallenge();
IanBenzMaxim 6:a8c83a2e6fa4 763 }
IanBenzMaxim 6:a8c83a2e6fa4 764
IanBenzMaxim 7:471901a04573 765 /// Set Encryption Challenge.
IanBenzMaxim 6:a8c83a2e6fa4 766 EncryptionHmacData &
IanBenzMaxim 6:a8c83a2e6fa4 767 setEncryptionChallenge(EncryptionChallenge::const_span encryptionChallenge) {
IanBenzMaxim 6:a8c83a2e6fa4 768 copy(encryptionChallenge, this->encryptionChallenge());
IanBenzMaxim 6:a8c83a2e6fa4 769 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 770 }
IanBenzMaxim 7:471901a04573 771
IanBenzMaxim 6:a8c83a2e6fa4 772 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 773
IanBenzMaxim 7:471901a04573 774 /// @name ROM ID
IanBenzMaxim 7:471901a04573 775 /// @brief 1-Wire ROM ID of the device.
IanBenzMaxim 6:a8c83a2e6fa4 776 /// @{
IanBenzMaxim 7:471901a04573 777
IanBenzMaxim 7:471901a04573 778 /// Get mutable ROM ID.
IanBenzMaxim 6:a8c83a2e6fa4 779 RomId::span romId() {
IanBenzMaxim 6:a8c83a2e6fa4 780 return make_span(result_).subspan<romIdIdx, RomId::size>();
IanBenzMaxim 6:a8c83a2e6fa4 781 }
IanBenzMaxim 6:a8c83a2e6fa4 782
IanBenzMaxim 7:471901a04573 783 /// Get immutable ROM ID.
IanBenzMaxim 6:a8c83a2e6fa4 784 RomId::const_span romId() const {
IanBenzMaxim 6:a8c83a2e6fa4 785 return const_cast<EncryptionHmacData &>(*this).romId();
IanBenzMaxim 6:a8c83a2e6fa4 786 }
IanBenzMaxim 6:a8c83a2e6fa4 787
IanBenzMaxim 7:471901a04573 788 /// Set ROM ID.
IanBenzMaxim 6:a8c83a2e6fa4 789 EncryptionHmacData & setRomId(RomId::const_span romId) {
IanBenzMaxim 6:a8c83a2e6fa4 790 copy(romId, this->romId());
IanBenzMaxim 6:a8c83a2e6fa4 791 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 792 }
IanBenzMaxim 6:a8c83a2e6fa4 793
IanBenzMaxim 7:471901a04573 794 /// Set ROM ID for use in anonymous mode.
IanBenzMaxim 6:a8c83a2e6fa4 795 MaximInterface_EXPORT EncryptionHmacData & setAnonymousRomId();
IanBenzMaxim 7:471901a04573 796
IanBenzMaxim 6:a8c83a2e6fa4 797 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 798
IanBenzMaxim 7:471901a04573 799 /// @name Page number
IanBenzMaxim 7:471901a04573 800 /// @brief Number of the page to use data from.
IanBenzMaxim 6:a8c83a2e6fa4 801 /// @{
IanBenzMaxim 7:471901a04573 802
IanBenzMaxim 7:471901a04573 803 /// Get page number.
IanBenzMaxim 6:a8c83a2e6fa4 804 int pageNum() const { return result_[pageNumIdx]; }
IanBenzMaxim 6:a8c83a2e6fa4 805
IanBenzMaxim 7:471901a04573 806 /// Set page number.
IanBenzMaxim 6:a8c83a2e6fa4 807 EncryptionHmacData & setPageNum(int pageNum) {
IanBenzMaxim 6:a8c83a2e6fa4 808 result_[pageNumIdx] = pageNum;
IanBenzMaxim 6:a8c83a2e6fa4 809 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 810 }
IanBenzMaxim 7:471901a04573 811
IanBenzMaxim 6:a8c83a2e6fa4 812 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 813
IanBenzMaxim 7:471901a04573 814 /// @name MAN ID
IanBenzMaxim 7:471901a04573 815 /// @brief Manufacturer ID of the device.
IanBenzMaxim 6:a8c83a2e6fa4 816 /// @{
IanBenzMaxim 7:471901a04573 817
IanBenzMaxim 7:471901a04573 818 /// Get mutable MAN ID.
IanBenzMaxim 6:a8c83a2e6fa4 819 ManId::span manId() {
IanBenzMaxim 6:a8c83a2e6fa4 820 return make_span(result_).subspan<manIdIdx, ManId::size>();
IanBenzMaxim 6:a8c83a2e6fa4 821 }
IanBenzMaxim 6:a8c83a2e6fa4 822
IanBenzMaxim 7:471901a04573 823 /// Get immutable MAN ID.
IanBenzMaxim 6:a8c83a2e6fa4 824 ManId::const_span manId() const {
IanBenzMaxim 6:a8c83a2e6fa4 825 return const_cast<EncryptionHmacData &>(*this).manId();
IanBenzMaxim 6:a8c83a2e6fa4 826 }
IanBenzMaxim 6:a8c83a2e6fa4 827
IanBenzMaxim 7:471901a04573 828 /// Set MAN ID.
IanBenzMaxim 6:a8c83a2e6fa4 829 EncryptionHmacData & setManId(ManId::const_span manId) {
IanBenzMaxim 6:a8c83a2e6fa4 830 copy(manId, this->manId());
IanBenzMaxim 6:a8c83a2e6fa4 831 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 832 }
IanBenzMaxim 7:471901a04573 833
IanBenzMaxim 6:a8c83a2e6fa4 834 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 835
IanBenzMaxim 6:a8c83a2e6fa4 836 private:
IanBenzMaxim 6:a8c83a2e6fa4 837 typedef Result::span::index_type index;
IanBenzMaxim 6:a8c83a2e6fa4 838
IanBenzMaxim 6:a8c83a2e6fa4 839 static const index encryptionChallengeIdx = 0;
IanBenzMaxim 6:a8c83a2e6fa4 840 static const index romIdIdx =
IanBenzMaxim 6:a8c83a2e6fa4 841 encryptionChallengeIdx + EncryptionChallenge::size;
IanBenzMaxim 6:a8c83a2e6fa4 842 static const index pageNumIdx = romIdIdx + RomId::size;
IanBenzMaxim 6:a8c83a2e6fa4 843 static const index manIdIdx = pageNumIdx + 1;
IanBenzMaxim 6:a8c83a2e6fa4 844
IanBenzMaxim 6:a8c83a2e6fa4 845 Result::array result_;
IanBenzMaxim 6:a8c83a2e6fa4 846 };
IanBenzMaxim 6:a8c83a2e6fa4 847
IanBenzMaxim 7:471901a04573 848 /// Access fields in the ROM Options page.
IanBenzMaxim 6:a8c83a2e6fa4 849 class DS28C36::RomOptions {
IanBenzMaxim 6:a8c83a2e6fa4 850 public:
IanBenzMaxim 7:471901a04573 851 explicit RomOptions(Page::span page) : page(page) {}
IanBenzMaxim 6:a8c83a2e6fa4 852
IanBenzMaxim 7:471901a04573 853 bool romBlockDisable() const {
IanBenzMaxim 7:471901a04573 854 return page[romBlockDisableIdx] == enabledValue;
IanBenzMaxim 7:471901a04573 855 }
IanBenzMaxim 7:471901a04573 856
IanBenzMaxim 7:471901a04573 857 RomOptions & setRomBlockDisable(bool romBlockDisable) {
IanBenzMaxim 7:471901a04573 858 page[romBlockDisableIdx] = (romBlockDisable ? enabledValue : 0);
IanBenzMaxim 7:471901a04573 859 return *this;
IanBenzMaxim 7:471901a04573 860 }
IanBenzMaxim 7:471901a04573 861
IanBenzMaxim 7:471901a04573 862 bool anonymous() const { return page[anonymousIdx] == enabledValue; }
IanBenzMaxim 6:a8c83a2e6fa4 863
IanBenzMaxim 7:471901a04573 864 RomOptions & setAnonymous(bool anonymous) {
IanBenzMaxim 7:471901a04573 865 page[anonymousIdx] = (anonymous ? enabledValue : 0);
IanBenzMaxim 7:471901a04573 866 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 867 }
IanBenzMaxim 6:a8c83a2e6fa4 868
IanBenzMaxim 6:a8c83a2e6fa4 869 ManId::const_span manId() const {
IanBenzMaxim 7:471901a04573 870 return page.subspan<22, ManId::size>();
IanBenzMaxim 6:a8c83a2e6fa4 871 }
IanBenzMaxim 6:a8c83a2e6fa4 872
IanBenzMaxim 6:a8c83a2e6fa4 873 RomId::const_span romId() const {
IanBenzMaxim 7:471901a04573 874 return page.subspan<24, RomId::size>();
IanBenzMaxim 6:a8c83a2e6fa4 875 }
IanBenzMaxim 6:a8c83a2e6fa4 876
IanBenzMaxim 6:a8c83a2e6fa4 877 private:
IanBenzMaxim 7:471901a04573 878 static const Page::span::index_type romBlockDisableIdx = 0;
IanBenzMaxim 7:471901a04573 879 static const Page::span::index_type anonymousIdx = 1;
IanBenzMaxim 7:471901a04573 880 static const Page::span::value_type enabledValue = 0xAA;
IanBenzMaxim 6:a8c83a2e6fa4 881
IanBenzMaxim 7:471901a04573 882 Page::span page;
IanBenzMaxim 6:a8c83a2e6fa4 883 };
IanBenzMaxim 6:a8c83a2e6fa4 884
IanBenzMaxim 7:471901a04573 885 /// Access fields in the GPIO Control page.
IanBenzMaxim 6:a8c83a2e6fa4 886 class DS28C36::GpioControl {
IanBenzMaxim 6:a8c83a2e6fa4 887 public:
IanBenzMaxim 7:471901a04573 888 explicit GpioControl(Page::span page) : page(page) {}
IanBenzMaxim 6:a8c83a2e6fa4 889
IanBenzMaxim 6:a8c83a2e6fa4 890 bool pioaConducting() const {
IanBenzMaxim 6:a8c83a2e6fa4 891 return page[pioaConductingIdx] == pioConductingValue;
IanBenzMaxim 6:a8c83a2e6fa4 892 }
IanBenzMaxim 6:a8c83a2e6fa4 893
IanBenzMaxim 7:471901a04573 894 GpioControl & setPioaConducting(bool pioaConducting) {
IanBenzMaxim 6:a8c83a2e6fa4 895 page[pioaConductingIdx] = (pioaConducting ? pioConductingValue : 0x55);
IanBenzMaxim 7:471901a04573 896 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 897 }
IanBenzMaxim 6:a8c83a2e6fa4 898
IanBenzMaxim 6:a8c83a2e6fa4 899 bool piobConducting() const {
IanBenzMaxim 6:a8c83a2e6fa4 900 return page[piobConductingIdx] == pioConductingValue;
IanBenzMaxim 6:a8c83a2e6fa4 901 }
IanBenzMaxim 6:a8c83a2e6fa4 902
IanBenzMaxim 7:471901a04573 903 GpioControl & setPiobConducting(bool piobConducting) {
IanBenzMaxim 6:a8c83a2e6fa4 904 page[piobConductingIdx] = (piobConducting ? pioConductingValue : 0x55);
IanBenzMaxim 7:471901a04573 905 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 906 }
IanBenzMaxim 6:a8c83a2e6fa4 907
IanBenzMaxim 6:a8c83a2e6fa4 908 bool pioaLevel() const { return page[2] == pioLevelValue; }
IanBenzMaxim 6:a8c83a2e6fa4 909
IanBenzMaxim 6:a8c83a2e6fa4 910 bool piobLevel() const { return page[3] == pioLevelValue; }
IanBenzMaxim 6:a8c83a2e6fa4 911
IanBenzMaxim 6:a8c83a2e6fa4 912 private:
IanBenzMaxim 7:471901a04573 913 static const Page::span::index_type pioaConductingIdx = 0;
IanBenzMaxim 7:471901a04573 914 static const Page::span::index_type piobConductingIdx = 1;
IanBenzMaxim 7:471901a04573 915 static const Page::span::value_type pioConductingValue = 0xAA;
IanBenzMaxim 7:471901a04573 916 static const Page::span::value_type pioLevelValue = 0x55;
IanBenzMaxim 6:a8c83a2e6fa4 917
IanBenzMaxim 7:471901a04573 918 Page::span page;
IanBenzMaxim 6:a8c83a2e6fa4 919 };
IanBenzMaxim 6:a8c83a2e6fa4 920
IanBenzMaxim 6:a8c83a2e6fa4 921 } // namespace MaximInterface
IanBenzMaxim 6:a8c83a2e6fa4 922
IanBenzMaxim 6:a8c83a2e6fa4 923 #endif