Extended MaximInterface

Dependents:   mbed_DS28EC20_GPIO

Committer:
IanBenzMaxim
Date:
Wed Jan 23 13:11:04 2019 -0600
Revision:
6:a8c83a2e6fa4
Parent:
3:f818ea5172ed
Child:
7:471901a04573
Updated to version 1.6 and removed platform files that are incompatible with mbed.

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 6:a8c83a2e6fa4 64 // Device memory pages.
IanBenzMaxim 6:a8c83a2e6fa4 65 static const int publicKeyAxPage = 16;
IanBenzMaxim 6:a8c83a2e6fa4 66 static const int publicKeyAyPage = 17;
IanBenzMaxim 6:a8c83a2e6fa4 67 static const int publicKeyBxPage = 18;
IanBenzMaxim 6:a8c83a2e6fa4 68 static const int publicKeyByPage = 19;
IanBenzMaxim 6:a8c83a2e6fa4 69 static const int publicKeyCxPage = 20;
IanBenzMaxim 6:a8c83a2e6fa4 70 static const int publicKeyCyPage = 21;
IanBenzMaxim 6:a8c83a2e6fa4 71 static const int privateKeyAPage = 22;
IanBenzMaxim 6:a8c83a2e6fa4 72 static const int privateKeyBPage = 23;
IanBenzMaxim 6:a8c83a2e6fa4 73 static const int privateKeyCPage = 24;
IanBenzMaxim 6:a8c83a2e6fa4 74 static const int secretAPage = 25;
IanBenzMaxim 6:a8c83a2e6fa4 75 static const int secretBPage = 26;
IanBenzMaxim 6:a8c83a2e6fa4 76 static const int decrementCounterPage = 27;
IanBenzMaxim 6:a8c83a2e6fa4 77 static const int romOptionsPage = 28;
IanBenzMaxim 6:a8c83a2e6fa4 78 static const int gpioControlPage = 29;
IanBenzMaxim 6:a8c83a2e6fa4 79 static const int publicKeySxPage = 30;
IanBenzMaxim 6:a8c83a2e6fa4 80 static const int publicKeySyPage = 31;
IanBenzMaxim 6:a8c83a2e6fa4 81
IanBenzMaxim 6:a8c83a2e6fa4 82 /// Number of memory pages on the device.
IanBenzMaxim 6:a8c83a2e6fa4 83 static const int memoryPages = 32;
IanBenzMaxim 6:a8c83a2e6fa4 84
IanBenzMaxim 6:a8c83a2e6fa4 85 /// Available keys for ECDSA operations.
IanBenzMaxim 6:a8c83a2e6fa4 86 enum KeyNum { KeyNumA = 0, KeyNumB = 1, KeyNumC = 2, KeyNumS = 3 };
IanBenzMaxim 6:a8c83a2e6fa4 87
IanBenzMaxim 6:a8c83a2e6fa4 88 /// Available secrets for HMAC operations.
IanBenzMaxim 6:a8c83a2e6fa4 89 enum SecretNum { SecretNumA = 0, SecretNumB = 1, SecretNumS = 2 };
IanBenzMaxim 6:a8c83a2e6fa4 90
IanBenzMaxim 6:a8c83a2e6fa4 91 /// Data hash type when verifying an ECDSA signature.
IanBenzMaxim 6:a8c83a2e6fa4 92 enum HashType {
IanBenzMaxim 6:a8c83a2e6fa4 93 HashInBuffer = 0, ///< Hash is loaded in the buffer.
IanBenzMaxim 6:a8c83a2e6fa4 94 DataInBuffer = 1, ///< Compute hash from data loaded in the buffer.
IanBenzMaxim 6:a8c83a2e6fa4 95 THASH = 2 ///< Use THASH from Compute Multiblock Hash command.
IanBenzMaxim 6:a8c83a2e6fa4 96 };
IanBenzMaxim 6:a8c83a2e6fa4 97
IanBenzMaxim 6:a8c83a2e6fa4 98 /// Available PIO states when verifying an ECDSA signature.
IanBenzMaxim 6:a8c83a2e6fa4 99 enum PioState { Unchanged, Conducting, HighImpedance };
IanBenzMaxim 6:a8c83a2e6fa4 100
IanBenzMaxim 6:a8c83a2e6fa4 101 /// Holds a device memory page.
IanBenzMaxim 6:a8c83a2e6fa4 102 typedef array_span<uint_least8_t, 32> Page;
IanBenzMaxim 6:a8c83a2e6fa4 103
IanBenzMaxim 6:a8c83a2e6fa4 104 /// Format page authentication input data.
IanBenzMaxim 6:a8c83a2e6fa4 105 class PageAuthenticationData;
IanBenzMaxim 6:a8c83a2e6fa4 106
IanBenzMaxim 6:a8c83a2e6fa4 107 /// Format authenticated write input data.
IanBenzMaxim 6:a8c83a2e6fa4 108 class WriteAuthenticationData;
IanBenzMaxim 6:a8c83a2e6fa4 109
IanBenzMaxim 6:a8c83a2e6fa4 110 /// Format compute secret input data.
IanBenzMaxim 6:a8c83a2e6fa4 111 class ComputeSecretData;
IanBenzMaxim 6:a8c83a2e6fa4 112
IanBenzMaxim 6:a8c83a2e6fa4 113 /// Format encryption or decryption HMAC input data.
IanBenzMaxim 6:a8c83a2e6fa4 114 class EncryptionHmacData;
IanBenzMaxim 6:a8c83a2e6fa4 115
IanBenzMaxim 6:a8c83a2e6fa4 116 /// Access fields in the ROM Options page. Can be used with writeMemory and
IanBenzMaxim 6:a8c83a2e6fa4 117 /// readMemory functions.
IanBenzMaxim 6:a8c83a2e6fa4 118 class RomOptions;
IanBenzMaxim 6:a8c83a2e6fa4 119
IanBenzMaxim 6:a8c83a2e6fa4 120 /// Access fields in the GPIO Control page. Can be used with writeMemory and
IanBenzMaxim 6:a8c83a2e6fa4 121 /// readMemory functions.
IanBenzMaxim 6:a8c83a2e6fa4 122 class GpioControl;
IanBenzMaxim 6:a8c83a2e6fa4 123
IanBenzMaxim 6:a8c83a2e6fa4 124 /// Page protection types.
IanBenzMaxim 6:a8c83a2e6fa4 125 enum PageProtectionType {
IanBenzMaxim 6:a8c83a2e6fa4 126 RP = 0x01, ///< Read protection.
IanBenzMaxim 6:a8c83a2e6fa4 127 WP = 0x02, ///< Write protection.
IanBenzMaxim 6:a8c83a2e6fa4 128 EM = 0x04, ///< EPROM emulation mode.
IanBenzMaxim 6:a8c83a2e6fa4 129 APH = 0x08, ///< Authentication write protection HMAC.
IanBenzMaxim 6:a8c83a2e6fa4 130 EPH = 0x10, ///< Encryption and authenticated write protection HMAC.
IanBenzMaxim 6:a8c83a2e6fa4 131 AUTH = 0x20, ///< Public Key C is set to authority public key.
IanBenzMaxim 6:a8c83a2e6fa4 132 ECH = 0x40, ///< Encrypted read and write using shared key from ECDH.
IanBenzMaxim 6:a8c83a2e6fa4 133 ECW = 0x80 ///< Authentication write protection ECDSA.
IanBenzMaxim 6:a8c83a2e6fa4 134 };
IanBenzMaxim 6:a8c83a2e6fa4 135 typedef FlagSet<PageProtectionType, 8> PageProtection;
IanBenzMaxim 6:a8c83a2e6fa4 136
IanBenzMaxim 6:a8c83a2e6fa4 137 /// Challenge for an encrypted device memory page.
IanBenzMaxim 6:a8c83a2e6fa4 138 typedef array_span<uint_least8_t, 8> EncryptionChallenge;
IanBenzMaxim 6:a8c83a2e6fa4 139
IanBenzMaxim 6:a8c83a2e6fa4 140 DS28C36(Sleep & sleep, I2CMaster & master, uint_least8_t address = 0x36)
IanBenzMaxim 6:a8c83a2e6fa4 141 : sleep_(&sleep), master(&master), address_(address & 0xFE) {}
IanBenzMaxim 6:a8c83a2e6fa4 142
IanBenzMaxim 6:a8c83a2e6fa4 143 void setSleep(Sleep & sleep) { sleep_ = &sleep; }
IanBenzMaxim 6:a8c83a2e6fa4 144
IanBenzMaxim 6:a8c83a2e6fa4 145 void setMaster(I2CMaster & master) { this->master = &master; }
IanBenzMaxim 6:a8c83a2e6fa4 146
IanBenzMaxim 6:a8c83a2e6fa4 147 uint_least8_t address() const { return address_; }
IanBenzMaxim 6:a8c83a2e6fa4 148
IanBenzMaxim 6:a8c83a2e6fa4 149 void setAddress(uint_least8_t address) { address_ = address & 0xFE; }
IanBenzMaxim 6:a8c83a2e6fa4 150
IanBenzMaxim 6:a8c83a2e6fa4 151 /// Write memory with no protection.
IanBenzMaxim 6:a8c83a2e6fa4 152 /// @param pageNum Number of page to write.
IanBenzMaxim 6:a8c83a2e6fa4 153 /// @param page Data to write.
IanBenzMaxim 6:a8c83a2e6fa4 154 MaximInterface_EXPORT error_code writeMemory(int pageNum,
IanBenzMaxim 6:a8c83a2e6fa4 155 Page::const_span page);
IanBenzMaxim 6:a8c83a2e6fa4 156
IanBenzMaxim 6:a8c83a2e6fa4 157 /// Read memory with no protection.
IanBenzMaxim 6:a8c83a2e6fa4 158 /// @param pageNum Number of page to read.
IanBenzMaxim 6:a8c83a2e6fa4 159 /// @param[out] page Data that was read.
IanBenzMaxim 6:a8c83a2e6fa4 160 MaximInterface_EXPORT error_code readMemory(int pageNum, Page::span page);
IanBenzMaxim 6:a8c83a2e6fa4 161
IanBenzMaxim 6:a8c83a2e6fa4 162 /// Write the temporary buffer.
IanBenzMaxim 6:a8c83a2e6fa4 163 /// @param data Data to write.
IanBenzMaxim 6:a8c83a2e6fa4 164 MaximInterface_EXPORT error_code writeBuffer(span<const uint_least8_t> data);
IanBenzMaxim 6:a8c83a2e6fa4 165
IanBenzMaxim 6:a8c83a2e6fa4 166 /// Read the temporary buffer.
IanBenzMaxim 6:a8c83a2e6fa4 167 /// @param[out] data Data that was read.
IanBenzMaxim 6:a8c83a2e6fa4 168 MaximInterface_EXPORT error_code
IanBenzMaxim 6:a8c83a2e6fa4 169 readBuffer(std::vector<uint_least8_t> & data);
IanBenzMaxim 6:a8c83a2e6fa4 170
IanBenzMaxim 6:a8c83a2e6fa4 171 /// Read the protection settings of a page.
IanBenzMaxim 6:a8c83a2e6fa4 172 /// @param pageNum Number of page to read.
IanBenzMaxim 6:a8c83a2e6fa4 173 /// @param[out] protection Protection that was read.
IanBenzMaxim 6:a8c83a2e6fa4 174 MaximInterface_EXPORT error_code
IanBenzMaxim 6:a8c83a2e6fa4 175 readPageProtection(int pageNum, PageProtection & protection);
IanBenzMaxim 6:a8c83a2e6fa4 176
IanBenzMaxim 6:a8c83a2e6fa4 177 /// Set the protection settings of a page.
IanBenzMaxim 6:a8c83a2e6fa4 178 /// @param pageNum Number of page to write.
IanBenzMaxim 6:a8c83a2e6fa4 179 /// @param protection Protection to write.
IanBenzMaxim 6:a8c83a2e6fa4 180 MaximInterface_EXPORT error_code
IanBenzMaxim 6:a8c83a2e6fa4 181 setPageProtection(int pageNum, const PageProtection & protection);
IanBenzMaxim 6:a8c83a2e6fa4 182
IanBenzMaxim 6:a8c83a2e6fa4 183 /// Decrement the decrement-only counter.
IanBenzMaxim 6:a8c83a2e6fa4 184 MaximInterface_EXPORT error_code decrementCounter();
IanBenzMaxim 6:a8c83a2e6fa4 185
IanBenzMaxim 6:a8c83a2e6fa4 186 /// Read a block of random data from the RNG.
IanBenzMaxim 6:a8c83a2e6fa4 187 /// @param[out] data Random data from RNG with length from 1 to 64.
IanBenzMaxim 6:a8c83a2e6fa4 188 MaximInterface_EXPORT error_code readRng(span<uint_least8_t> data);
IanBenzMaxim 6:a8c83a2e6fa4 189
IanBenzMaxim 6:a8c83a2e6fa4 190 /// Read memory with encryption.
IanBenzMaxim 6:a8c83a2e6fa4 191 /// @param pageNum Number of page to read from.
IanBenzMaxim 6:a8c83a2e6fa4 192 /// @param secretNum Secret to use for encryption.
IanBenzMaxim 6:a8c83a2e6fa4 193 /// @param[out] challenge Encryption challenge that was read.
IanBenzMaxim 6:a8c83a2e6fa4 194 /// @param[out] data Encrypted page data that was read.
IanBenzMaxim 6:a8c83a2e6fa4 195 MaximInterface_EXPORT error_code
IanBenzMaxim 6:a8c83a2e6fa4 196 encryptedReadMemory(int pageNum, SecretNum secretNum,
IanBenzMaxim 6:a8c83a2e6fa4 197 EncryptionChallenge::span challenge, Page::span data);
IanBenzMaxim 6:a8c83a2e6fa4 198
IanBenzMaxim 6:a8c83a2e6fa4 199 /// Compute and read page authentication with ECDSA.
IanBenzMaxim 6:a8c83a2e6fa4 200 /// @param pageNum Number of page to authenticate.
IanBenzMaxim 6:a8c83a2e6fa4 201 /// @param keyNum Private key to use for authentication.
IanBenzMaxim 6:a8c83a2e6fa4 202 /// Key S cannot be used with this command.
IanBenzMaxim 6:a8c83a2e6fa4 203 /// @param[out] signature Computed page signature.
IanBenzMaxim 6:a8c83a2e6fa4 204 MaximInterface_EXPORT error_code computeAndReadPageAuthentication(
IanBenzMaxim 6:a8c83a2e6fa4 205 int pageNum, KeyNum keyNum, Ecc256::Signature::span signature);
IanBenzMaxim 6:a8c83a2e6fa4 206
IanBenzMaxim 6:a8c83a2e6fa4 207 /// Compute and read page authentication with HMAC.
IanBenzMaxim 6:a8c83a2e6fa4 208 /// @param pageNum Number of page to authenticate.
IanBenzMaxim 6:a8c83a2e6fa4 209 /// @param secretNum Secret to use for authentication.
IanBenzMaxim 6:a8c83a2e6fa4 210 /// @param[out] hmac Computed page HMAC.
IanBenzMaxim 6:a8c83a2e6fa4 211 MaximInterface_EXPORT error_code computeAndReadPageAuthentication(
IanBenzMaxim 6:a8c83a2e6fa4 212 int pageNum, SecretNum secretNum, Sha256::Hash::span hmac);
IanBenzMaxim 6:a8c83a2e6fa4 213
IanBenzMaxim 6:a8c83a2e6fa4 214 /// Write with SHA2 authentication.
IanBenzMaxim 6:a8c83a2e6fa4 215 /// @param pageNum Number of page to write.
IanBenzMaxim 6:a8c83a2e6fa4 216 /// @param secretNum Secret to use for authentication.
IanBenzMaxim 6:a8c83a2e6fa4 217 /// @param page Data to write.
IanBenzMaxim 6:a8c83a2e6fa4 218 MaximInterface_EXPORT error_code authenticatedSha2WriteMemory(
IanBenzMaxim 6:a8c83a2e6fa4 219 int pageNum, SecretNum secretNum, Page::const_span page);
IanBenzMaxim 6:a8c83a2e6fa4 220
IanBenzMaxim 6:a8c83a2e6fa4 221 /// Compute SHA2 secret and optionally lock.
IanBenzMaxim 6:a8c83a2e6fa4 222 /// @param pageNum Number of page to use in computation.
IanBenzMaxim 6:a8c83a2e6fa4 223 /// @param msecretNum Master secret to use in computation.
IanBenzMaxim 6:a8c83a2e6fa4 224 /// @param dsecretNum Destination secret to receive the computation result.
IanBenzMaxim 6:a8c83a2e6fa4 225 /// @param writeProtectEnable
IanBenzMaxim 6:a8c83a2e6fa4 226 /// True to lock the destination secret against further writes.
IanBenzMaxim 6:a8c83a2e6fa4 227 MaximInterface_EXPORT error_code
IanBenzMaxim 6:a8c83a2e6fa4 228 computeAndLockSha2Secret(int pageNum, SecretNum msecretNum,
IanBenzMaxim 6:a8c83a2e6fa4 229 SecretNum dsecretNum, bool writeProtectEnable);
IanBenzMaxim 6:a8c83a2e6fa4 230
IanBenzMaxim 6:a8c83a2e6fa4 231 /// Generate a new ECDSA key pair.
IanBenzMaxim 6:a8c83a2e6fa4 232 /// @param keyNum Key to generate. Key S cannot be used with this command.
IanBenzMaxim 6:a8c83a2e6fa4 233 /// @param writeProtectEnable True to lock the key against further writes.
IanBenzMaxim 6:a8c83a2e6fa4 234 MaximInterface_EXPORT error_code
IanBenzMaxim 6:a8c83a2e6fa4 235 generateEcc256KeyPair(KeyNum keyNum, bool writeProtectEnable);
IanBenzMaxim 6:a8c83a2e6fa4 236
IanBenzMaxim 6:a8c83a2e6fa4 237 /// Compute a hash over multiple blocks.
IanBenzMaxim 6:a8c83a2e6fa4 238 /// @param firstBlock True if this is the first block being hashed.
IanBenzMaxim 6:a8c83a2e6fa4 239 /// @param lastBlock True if this is the last block being hashed.
IanBenzMaxim 6:a8c83a2e6fa4 240 /// @param data
IanBenzMaxim 6:a8c83a2e6fa4 241 /// Data block to hash. Should be 64 bytes unless this is the last block.
IanBenzMaxim 6:a8c83a2e6fa4 242 MaximInterface_EXPORT error_code computeMultiblockHash(
IanBenzMaxim 6:a8c83a2e6fa4 243 bool firstBlock, bool lastBlock, span<const uint_least8_t> data);
IanBenzMaxim 6:a8c83a2e6fa4 244
IanBenzMaxim 6:a8c83a2e6fa4 245 /// Verify ECDSA signature.
IanBenzMaxim 6:a8c83a2e6fa4 246 /// @param keyNum Public key to use for verification.
IanBenzMaxim 6:a8c83a2e6fa4 247 /// @param hashType Source of the data hash input.
IanBenzMaxim 6:a8c83a2e6fa4 248 /// @param signature Signature to verify.
IanBenzMaxim 6:a8c83a2e6fa4 249 /// @param pioa New state of PIOA if verification successful.
IanBenzMaxim 6:a8c83a2e6fa4 250 /// @param piob New state of PIOB if verification successful.
IanBenzMaxim 6:a8c83a2e6fa4 251 MaximInterface_EXPORT error_code verifyEcdsaSignature(
IanBenzMaxim 6:a8c83a2e6fa4 252 KeyNum keyNum, HashType hashType, Ecc256::Signature::const_span signature,
IanBenzMaxim 6:a8c83a2e6fa4 253 PioState pioa = Unchanged, PioState piob = Unchanged);
IanBenzMaxim 6:a8c83a2e6fa4 254
IanBenzMaxim 6:a8c83a2e6fa4 255 /// Authenticate a public key for authenticated writes or encrypted reads with ECDH.
IanBenzMaxim 6:a8c83a2e6fa4 256 /// @param authWrites True to select authentication for writes.
IanBenzMaxim 6:a8c83a2e6fa4 257 /// @param ecdh True to select ECDH key exchange.
IanBenzMaxim 6:a8c83a2e6fa4 258 /// @param keyNum Private key to use for ECDH key exchange.
IanBenzMaxim 6:a8c83a2e6fa4 259 /// Key A or B can be selected.
IanBenzMaxim 6:a8c83a2e6fa4 260 /// @param csOffset Certificate customization field ending offset in buffer.
IanBenzMaxim 6:a8c83a2e6fa4 261 /// @param signature Signature to use for authentication of public key S.
IanBenzMaxim 6:a8c83a2e6fa4 262 MaximInterface_EXPORT error_code authenticateEcdsaPublicKey(
IanBenzMaxim 6:a8c83a2e6fa4 263 bool authWrites, bool ecdh, KeyNum keyNum, int csOffset,
IanBenzMaxim 6:a8c83a2e6fa4 264 Ecc256::Signature::const_span signature);
IanBenzMaxim 6:a8c83a2e6fa4 265
IanBenzMaxim 6:a8c83a2e6fa4 266 /// Write with ECDSA authentication.
IanBenzMaxim 6:a8c83a2e6fa4 267 /// @param pageNum Number of page to write.
IanBenzMaxim 6:a8c83a2e6fa4 268 /// @param page Data to write.
IanBenzMaxim 6:a8c83a2e6fa4 269 MaximInterface_EXPORT error_code
IanBenzMaxim 6:a8c83a2e6fa4 270 authenticatedEcdsaWriteMemory(int pageNum, Page::const_span page);
IanBenzMaxim 6:a8c83a2e6fa4 271
IanBenzMaxim 6:a8c83a2e6fa4 272 MaximInterface_EXPORT static const error_category & errorCategory();
IanBenzMaxim 6:a8c83a2e6fa4 273
IanBenzMaxim 6:a8c83a2e6fa4 274 protected:
IanBenzMaxim 6:a8c83a2e6fa4 275 // Timing constants.
IanBenzMaxim 6:a8c83a2e6fa4 276 static const int generateEcdsaSignatureTimeMs = 50;
IanBenzMaxim 6:a8c83a2e6fa4 277 static const int generateEccKeyPairTimeMs = 100;
IanBenzMaxim 6:a8c83a2e6fa4 278 static const int verifyEsdsaSignatureOrComputeEcdhTimeMs = 150;
IanBenzMaxim 6:a8c83a2e6fa4 279 static const int sha256ComputationTimeMs = 3;
IanBenzMaxim 6:a8c83a2e6fa4 280 static const int readMemoryTimeMs = /*1*/ 2;
IanBenzMaxim 6:a8c83a2e6fa4 281 static const int writeMemoryTimeMs = 15;
IanBenzMaxim 6:a8c83a2e6fa4 282
IanBenzMaxim 6:a8c83a2e6fa4 283 error_code writeCommand(uint_least8_t command,
IanBenzMaxim 6:a8c83a2e6fa4 284 span<const uint_least8_t> parameters);
IanBenzMaxim 6:a8c83a2e6fa4 285
IanBenzMaxim 6:a8c83a2e6fa4 286 error_code writeCommand(uint_least8_t command) {
IanBenzMaxim 6:a8c83a2e6fa4 287 return writeCommand(command, span<const uint_least8_t>());
IanBenzMaxim 6:a8c83a2e6fa4 288 }
IanBenzMaxim 6:a8c83a2e6fa4 289
IanBenzMaxim 6:a8c83a2e6fa4 290 error_code readVariableLengthResponse(span<uint_least8_t> & response);
IanBenzMaxim 6:a8c83a2e6fa4 291
IanBenzMaxim 6:a8c83a2e6fa4 292 error_code readFixedLengthResponse(span<uint_least8_t> response);
IanBenzMaxim 6:a8c83a2e6fa4 293
IanBenzMaxim 6:a8c83a2e6fa4 294 void sleep(int ms) const { sleep_->invoke(ms); }
IanBenzMaxim 6:a8c83a2e6fa4 295
IanBenzMaxim 6:a8c83a2e6fa4 296 private:
IanBenzMaxim 6:a8c83a2e6fa4 297 enum AuthType {
IanBenzMaxim 6:a8c83a2e6fa4 298 HmacWithSecretA = 0,
IanBenzMaxim 6:a8c83a2e6fa4 299 HmacWithSecretB = 1,
IanBenzMaxim 6:a8c83a2e6fa4 300 HmacWithSecretS = 2,
IanBenzMaxim 6:a8c83a2e6fa4 301 EcdsaWithKeyA = 3,
IanBenzMaxim 6:a8c83a2e6fa4 302 EcdsaWithKeyB = 4,
IanBenzMaxim 6:a8c83a2e6fa4 303 EcdsaWithKeyC = 5
IanBenzMaxim 6:a8c83a2e6fa4 304 };
IanBenzMaxim 6:a8c83a2e6fa4 305
IanBenzMaxim 6:a8c83a2e6fa4 306 const Sleep * sleep_;
IanBenzMaxim 6:a8c83a2e6fa4 307 I2CMaster * master;
IanBenzMaxim 6:a8c83a2e6fa4 308 uint_least8_t address_;
IanBenzMaxim 6:a8c83a2e6fa4 309
IanBenzMaxim 6:a8c83a2e6fa4 310 error_code computeAndReadPageAuthentication(int pageNum, AuthType authType);
IanBenzMaxim 6:a8c83a2e6fa4 311 };
IanBenzMaxim 6:a8c83a2e6fa4 312
IanBenzMaxim 6:a8c83a2e6fa4 313 /// Interface to the DS2476 coprocessor.
IanBenzMaxim 6:a8c83a2e6fa4 314 class DS2476 : public DS28C36 {
IanBenzMaxim 6:a8c83a2e6fa4 315 public:
IanBenzMaxim 6:a8c83a2e6fa4 316 DS2476(Sleep & sleep, I2CMaster & master, uint_least8_t address = 0x76)
IanBenzMaxim 6:a8c83a2e6fa4 317 : DS28C36(sleep, master, address) {}
IanBenzMaxim 6:a8c83a2e6fa4 318
IanBenzMaxim 6:a8c83a2e6fa4 319 /// Generate ECDSA signature.
IanBenzMaxim 6:a8c83a2e6fa4 320 /// @param keyNum Private key to use to create signature.
IanBenzMaxim 6:a8c83a2e6fa4 321 /// Key S cannot be used with this command.
IanBenzMaxim 6:a8c83a2e6fa4 322 /// @param[out] signature Computed signature.
IanBenzMaxim 6:a8c83a2e6fa4 323 MaximInterface_EXPORT error_code
IanBenzMaxim 6:a8c83a2e6fa4 324 generateEcdsaSignature(KeyNum keyNum, Ecc256::Signature::span signature);
IanBenzMaxim 6:a8c83a2e6fa4 325
IanBenzMaxim 6:a8c83a2e6fa4 326 /// Compute unique SHA2 secret.
IanBenzMaxim 6:a8c83a2e6fa4 327 /// @param msecretNum Master secret to use in computation.
IanBenzMaxim 6:a8c83a2e6fa4 328 MaximInterface_EXPORT error_code
IanBenzMaxim 6:a8c83a2e6fa4 329 computeSha2UniqueSecret(SecretNum msecretNum);
IanBenzMaxim 6:a8c83a2e6fa4 330
IanBenzMaxim 6:a8c83a2e6fa4 331 /// Compute SHA2 HMAC.
IanBenzMaxim 6:a8c83a2e6fa4 332 /// @param[out] hmac Computed HMAC.
IanBenzMaxim 6:a8c83a2e6fa4 333 MaximInterface_EXPORT error_code computeSha2Hmac(Sha256::Hash::span hmac);
IanBenzMaxim 6:a8c83a2e6fa4 334 };
IanBenzMaxim 6:a8c83a2e6fa4 335
IanBenzMaxim 6:a8c83a2e6fa4 336 inline error_code make_error_code(DS28C36::ErrorValue e) {
IanBenzMaxim 6:a8c83a2e6fa4 337 return error_code(e, DS28C36::errorCategory());
IanBenzMaxim 6:a8c83a2e6fa4 338 }
IanBenzMaxim 6:a8c83a2e6fa4 339
IanBenzMaxim 6:a8c83a2e6fa4 340 /// Hash arbitrary length data with successive Compute Multiblock Hash commands.
IanBenzMaxim 6:a8c83a2e6fa4 341 /// @param data Data to hash.
IanBenzMaxim 6:a8c83a2e6fa4 342 MaximInterface_EXPORT error_code
IanBenzMaxim 6:a8c83a2e6fa4 343 computeMultiblockHash(DS28C36 & ds28c36, span<const uint_least8_t> data);
IanBenzMaxim 6:a8c83a2e6fa4 344
IanBenzMaxim 6:a8c83a2e6fa4 345 /// Verify ECDSA signature.
IanBenzMaxim 6:a8c83a2e6fa4 346 /// @param publicKey Public key to use for verification.
IanBenzMaxim 6:a8c83a2e6fa4 347 /// @param data Data to verify.
IanBenzMaxim 6:a8c83a2e6fa4 348 /// @param signature Signature to verify.
IanBenzMaxim 6:a8c83a2e6fa4 349 /// @param pioa New state of PIOA if verification successful.
IanBenzMaxim 6:a8c83a2e6fa4 350 /// @param piob New state of PIOB if verification successful.
IanBenzMaxim 6:a8c83a2e6fa4 351 MaximInterface_EXPORT error_code verifyEcdsaSignature(
IanBenzMaxim 6:a8c83a2e6fa4 352 DS28C36 & ds28c36, DS28C36::KeyNum publicKey,
IanBenzMaxim 6:a8c83a2e6fa4 353 span<const uint_least8_t> data, Ecc256::Signature::const_span signature,
IanBenzMaxim 6:a8c83a2e6fa4 354 DS28C36::PioState pioa = DS28C36::Unchanged,
IanBenzMaxim 6:a8c83a2e6fa4 355 DS28C36::PioState piob = DS28C36::Unchanged);
IanBenzMaxim 6:a8c83a2e6fa4 356
IanBenzMaxim 6:a8c83a2e6fa4 357 /// Verify ECDSA signature.
IanBenzMaxim 6:a8c83a2e6fa4 358 /// @param publicKey
IanBenzMaxim 6:a8c83a2e6fa4 359 /// Public key to use for verification which is loaded into Public Key S.
IanBenzMaxim 6:a8c83a2e6fa4 360 /// @param data Data to verify.
IanBenzMaxim 6:a8c83a2e6fa4 361 /// @param signature Signature to verify.
IanBenzMaxim 6:a8c83a2e6fa4 362 /// @param pioa New state of PIOA if verification successful.
IanBenzMaxim 6:a8c83a2e6fa4 363 /// @param piob New state of PIOB if verification successful.
IanBenzMaxim 6:a8c83a2e6fa4 364 MaximInterface_EXPORT error_code verifyEcdsaSignature(
IanBenzMaxim 6:a8c83a2e6fa4 365 DS28C36 & ds28c36, Ecc256::PublicKey::const_span publicKey,
IanBenzMaxim 6:a8c83a2e6fa4 366 span<const uint_least8_t> data, Ecc256::Signature::const_span signature,
IanBenzMaxim 6:a8c83a2e6fa4 367 DS28C36::PioState pioa = DS28C36::Unchanged,
IanBenzMaxim 6:a8c83a2e6fa4 368 DS28C36::PioState piob = DS28C36::Unchanged);
IanBenzMaxim 6:a8c83a2e6fa4 369
IanBenzMaxim 6:a8c83a2e6fa4 370 /// Read the device ROM ID and MAN ID using the Read Memory command on the
IanBenzMaxim 6:a8c83a2e6fa4 371 /// ROM Options page.
IanBenzMaxim 6:a8c83a2e6fa4 372 /// @param[out] romId Read ROM ID valid when operation is successful.
IanBenzMaxim 6:a8c83a2e6fa4 373 /// @param[out] manId Read MAN ID valid when operation is successful.
IanBenzMaxim 6:a8c83a2e6fa4 374 MaximInterface_EXPORT error_code readRomIdAndManId(DS28C36 & ds28c36,
IanBenzMaxim 6:a8c83a2e6fa4 375 RomId::span romId,
IanBenzMaxim 6:a8c83a2e6fa4 376 ManId::span manId);
IanBenzMaxim 6:a8c83a2e6fa4 377
IanBenzMaxim 6:a8c83a2e6fa4 378 /// Enable coprocessor functionality on the DS2476 by writing to the
IanBenzMaxim 6:a8c83a2e6fa4 379 /// ROM Options page.
IanBenzMaxim 6:a8c83a2e6fa4 380 MaximInterface_EXPORT error_code enableCoprocessor(DS2476 & ds2476);
IanBenzMaxim 6:a8c83a2e6fa4 381
IanBenzMaxim 6:a8c83a2e6fa4 382 class DS28C36::PageAuthenticationData {
IanBenzMaxim 6:a8c83a2e6fa4 383 public:
IanBenzMaxim 6:a8c83a2e6fa4 384 typedef array_span<uint_least8_t,
IanBenzMaxim 6:a8c83a2e6fa4 385 RomId::size + 2 * Page::size + 1 + ManId::size>
IanBenzMaxim 6:a8c83a2e6fa4 386 Result;
IanBenzMaxim 6:a8c83a2e6fa4 387
IanBenzMaxim 6:a8c83a2e6fa4 388 PageAuthenticationData() : result_() {}
IanBenzMaxim 6:a8c83a2e6fa4 389
IanBenzMaxim 6:a8c83a2e6fa4 390 /// Formatted data result.
IanBenzMaxim 6:a8c83a2e6fa4 391 Result::const_span result() const { return result_; }
IanBenzMaxim 6:a8c83a2e6fa4 392
IanBenzMaxim 6:a8c83a2e6fa4 393 /// @{
IanBenzMaxim 6:a8c83a2e6fa4 394 /// 1-Wire ROM ID of the device.
IanBenzMaxim 6:a8c83a2e6fa4 395 RomId::span romId() {
IanBenzMaxim 6:a8c83a2e6fa4 396 return make_span(result_).subspan<romIdIdx, RomId::size>();
IanBenzMaxim 6:a8c83a2e6fa4 397 }
IanBenzMaxim 6:a8c83a2e6fa4 398
IanBenzMaxim 6:a8c83a2e6fa4 399 RomId::const_span romId() const {
IanBenzMaxim 6:a8c83a2e6fa4 400 return const_cast<PageAuthenticationData &>(*this).romId();
IanBenzMaxim 6:a8c83a2e6fa4 401 }
IanBenzMaxim 6:a8c83a2e6fa4 402
IanBenzMaxim 6:a8c83a2e6fa4 403 PageAuthenticationData & setRomId(RomId::const_span romId) {
IanBenzMaxim 6:a8c83a2e6fa4 404 copy(romId, this->romId());
IanBenzMaxim 6:a8c83a2e6fa4 405 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 406 }
IanBenzMaxim 6:a8c83a2e6fa4 407
IanBenzMaxim 6:a8c83a2e6fa4 408 MaximInterface_EXPORT PageAuthenticationData & setAnonymousRomId();
IanBenzMaxim 6:a8c83a2e6fa4 409 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 410
IanBenzMaxim 6:a8c83a2e6fa4 411 /// @{
IanBenzMaxim 6:a8c83a2e6fa4 412 /// Data from a device memory page.
IanBenzMaxim 6:a8c83a2e6fa4 413 Page::span page() {
IanBenzMaxim 6:a8c83a2e6fa4 414 return make_span(result_).subspan<pageIdx, Page::size>();
IanBenzMaxim 6:a8c83a2e6fa4 415 }
IanBenzMaxim 6:a8c83a2e6fa4 416
IanBenzMaxim 6:a8c83a2e6fa4 417 Page::const_span page() const {
IanBenzMaxim 6:a8c83a2e6fa4 418 return const_cast<PageAuthenticationData &>(*this).page();
IanBenzMaxim 6:a8c83a2e6fa4 419 }
IanBenzMaxim 6:a8c83a2e6fa4 420
IanBenzMaxim 6:a8c83a2e6fa4 421 PageAuthenticationData & setPage(Page::const_span page) {
IanBenzMaxim 6:a8c83a2e6fa4 422 copy(page, this->page());
IanBenzMaxim 6:a8c83a2e6fa4 423 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 424 }
IanBenzMaxim 6:a8c83a2e6fa4 425 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 426
IanBenzMaxim 6:a8c83a2e6fa4 427 /// @{
IanBenzMaxim 6:a8c83a2e6fa4 428 /// Random challenge used to prevent replay attacks.
IanBenzMaxim 6:a8c83a2e6fa4 429 Page::span challenge() {
IanBenzMaxim 6:a8c83a2e6fa4 430 return make_span(result_).subspan<challengeIdx, Page::size>();
IanBenzMaxim 6:a8c83a2e6fa4 431 }
IanBenzMaxim 6:a8c83a2e6fa4 432
IanBenzMaxim 6:a8c83a2e6fa4 433 Page::const_span challenge() const {
IanBenzMaxim 6:a8c83a2e6fa4 434 return const_cast<PageAuthenticationData &>(*this).challenge();
IanBenzMaxim 6:a8c83a2e6fa4 435 }
IanBenzMaxim 6:a8c83a2e6fa4 436
IanBenzMaxim 6:a8c83a2e6fa4 437 PageAuthenticationData & setChallenge(Page::const_span challenge) {
IanBenzMaxim 6:a8c83a2e6fa4 438 copy(challenge, this->challenge());
IanBenzMaxim 6:a8c83a2e6fa4 439 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 440 }
IanBenzMaxim 6:a8c83a2e6fa4 441 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 442
IanBenzMaxim 6:a8c83a2e6fa4 443 /// @{
IanBenzMaxim 6:a8c83a2e6fa4 444 /// Number of the page to use data from.
IanBenzMaxim 6:a8c83a2e6fa4 445 int pageNum() const { return result_[pageNumIdx]; }
IanBenzMaxim 6:a8c83a2e6fa4 446
IanBenzMaxim 6:a8c83a2e6fa4 447 PageAuthenticationData & setPageNum(int pageNum) {
IanBenzMaxim 6:a8c83a2e6fa4 448 result_[pageNumIdx] = pageNum;
IanBenzMaxim 6:a8c83a2e6fa4 449 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 450 }
IanBenzMaxim 6:a8c83a2e6fa4 451 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 452
IanBenzMaxim 6:a8c83a2e6fa4 453 /// @{
IanBenzMaxim 6:a8c83a2e6fa4 454 /// Manufacturer ID of the device.
IanBenzMaxim 6:a8c83a2e6fa4 455 ManId::span manId() {
IanBenzMaxim 6:a8c83a2e6fa4 456 return make_span(result_).subspan<manIdIdx, ManId::size>();
IanBenzMaxim 6:a8c83a2e6fa4 457 }
IanBenzMaxim 6:a8c83a2e6fa4 458
IanBenzMaxim 6:a8c83a2e6fa4 459 ManId::const_span manId() const {
IanBenzMaxim 6:a8c83a2e6fa4 460 return const_cast<PageAuthenticationData &>(*this).manId();
IanBenzMaxim 6:a8c83a2e6fa4 461 }
IanBenzMaxim 6:a8c83a2e6fa4 462
IanBenzMaxim 6:a8c83a2e6fa4 463 PageAuthenticationData & setManId(ManId::const_span manId) {
IanBenzMaxim 6:a8c83a2e6fa4 464 copy(manId, this->manId());
IanBenzMaxim 6:a8c83a2e6fa4 465 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 466 }
IanBenzMaxim 6:a8c83a2e6fa4 467 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 468
IanBenzMaxim 6:a8c83a2e6fa4 469 private:
IanBenzMaxim 6:a8c83a2e6fa4 470 typedef Result::span::index_type index;
IanBenzMaxim 6:a8c83a2e6fa4 471
IanBenzMaxim 6:a8c83a2e6fa4 472 static const index romIdIdx = 0;
IanBenzMaxim 6:a8c83a2e6fa4 473 static const index pageIdx = romIdIdx + RomId::size;
IanBenzMaxim 6:a8c83a2e6fa4 474 static const index challengeIdx = pageIdx + Page::size;
IanBenzMaxim 6:a8c83a2e6fa4 475 static const index pageNumIdx = challengeIdx + Page::size;
IanBenzMaxim 6:a8c83a2e6fa4 476 static const index manIdIdx = pageNumIdx + 1;
IanBenzMaxim 6:a8c83a2e6fa4 477
IanBenzMaxim 6:a8c83a2e6fa4 478 Result::array result_;
IanBenzMaxim 6:a8c83a2e6fa4 479 };
IanBenzMaxim 6:a8c83a2e6fa4 480
IanBenzMaxim 6:a8c83a2e6fa4 481 class DS28C36::WriteAuthenticationData {
IanBenzMaxim 6:a8c83a2e6fa4 482 public:
IanBenzMaxim 6:a8c83a2e6fa4 483 typedef PageAuthenticationData::Result Result;
IanBenzMaxim 6:a8c83a2e6fa4 484
IanBenzMaxim 6:a8c83a2e6fa4 485 WriteAuthenticationData() : data() {}
IanBenzMaxim 6:a8c83a2e6fa4 486
IanBenzMaxim 6:a8c83a2e6fa4 487 /// Formatted data result.
IanBenzMaxim 6:a8c83a2e6fa4 488 Result::const_span result() const { return data.result(); }
IanBenzMaxim 6:a8c83a2e6fa4 489
IanBenzMaxim 6:a8c83a2e6fa4 490 /// @{
IanBenzMaxim 6:a8c83a2e6fa4 491 /// 1-Wire ROM ID of the device.
IanBenzMaxim 6:a8c83a2e6fa4 492 RomId::span romId() { return data.romId(); }
IanBenzMaxim 6:a8c83a2e6fa4 493
IanBenzMaxim 6:a8c83a2e6fa4 494 RomId::const_span romId() const { return data.romId(); }
IanBenzMaxim 6:a8c83a2e6fa4 495
IanBenzMaxim 6:a8c83a2e6fa4 496 WriteAuthenticationData & setRomId(RomId::const_span romId) {
IanBenzMaxim 6:a8c83a2e6fa4 497 data.setRomId(romId);
IanBenzMaxim 6:a8c83a2e6fa4 498 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 499 }
IanBenzMaxim 6:a8c83a2e6fa4 500
IanBenzMaxim 6:a8c83a2e6fa4 501 WriteAuthenticationData & setAnonymousRomId() {
IanBenzMaxim 6:a8c83a2e6fa4 502 data.setAnonymousRomId();
IanBenzMaxim 6:a8c83a2e6fa4 503 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 504 }
IanBenzMaxim 6:a8c83a2e6fa4 505 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 506
IanBenzMaxim 6:a8c83a2e6fa4 507 /// @{
IanBenzMaxim 6:a8c83a2e6fa4 508 /// Existing data contained in the page.
IanBenzMaxim 6:a8c83a2e6fa4 509 Page::span oldPage() { return data.page(); }
IanBenzMaxim 6:a8c83a2e6fa4 510
IanBenzMaxim 6:a8c83a2e6fa4 511 Page::const_span oldPage() const { return data.page(); }
IanBenzMaxim 6:a8c83a2e6fa4 512
IanBenzMaxim 6:a8c83a2e6fa4 513 WriteAuthenticationData & setOldPage(Page::const_span oldPage) {
IanBenzMaxim 6:a8c83a2e6fa4 514 data.setPage(oldPage);
IanBenzMaxim 6:a8c83a2e6fa4 515 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 516 }
IanBenzMaxim 6:a8c83a2e6fa4 517 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 518
IanBenzMaxim 6:a8c83a2e6fa4 519 /// @{
IanBenzMaxim 6:a8c83a2e6fa4 520 /// New data to write to the page.
IanBenzMaxim 6:a8c83a2e6fa4 521 Page::span newPage() { return data.challenge(); }
IanBenzMaxim 6:a8c83a2e6fa4 522
IanBenzMaxim 6:a8c83a2e6fa4 523 Page::const_span newPage() const { return data.challenge(); }
IanBenzMaxim 6:a8c83a2e6fa4 524
IanBenzMaxim 6:a8c83a2e6fa4 525 WriteAuthenticationData & setNewPage(Page::const_span newPage) {
IanBenzMaxim 6:a8c83a2e6fa4 526 data.setChallenge(newPage);
IanBenzMaxim 6:a8c83a2e6fa4 527 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 528 }
IanBenzMaxim 6:a8c83a2e6fa4 529 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 530
IanBenzMaxim 6:a8c83a2e6fa4 531 /// @{
IanBenzMaxim 6:a8c83a2e6fa4 532 /// Page number for write operation.
IanBenzMaxim 6:a8c83a2e6fa4 533 int pageNum() const { return data.pageNum(); }
IanBenzMaxim 6:a8c83a2e6fa4 534
IanBenzMaxim 6:a8c83a2e6fa4 535 WriteAuthenticationData & setPageNum(int pageNum) {
IanBenzMaxim 6:a8c83a2e6fa4 536 data.setPageNum(pageNum);
IanBenzMaxim 6:a8c83a2e6fa4 537 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 538 }
IanBenzMaxim 6:a8c83a2e6fa4 539 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 540
IanBenzMaxim 6:a8c83a2e6fa4 541 /// @{
IanBenzMaxim 6:a8c83a2e6fa4 542 /// Manufacturer ID of the device.
IanBenzMaxim 6:a8c83a2e6fa4 543 ManId::span manId() { return data.manId(); }
IanBenzMaxim 6:a8c83a2e6fa4 544
IanBenzMaxim 6:a8c83a2e6fa4 545 ManId::const_span manId() const { return data.manId(); }
IanBenzMaxim 6:a8c83a2e6fa4 546
IanBenzMaxim 6:a8c83a2e6fa4 547 WriteAuthenticationData & setManId(ManId::const_span manId) {
IanBenzMaxim 6:a8c83a2e6fa4 548 data.setManId(manId);
IanBenzMaxim 6:a8c83a2e6fa4 549 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 550 }
IanBenzMaxim 6:a8c83a2e6fa4 551 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 552
IanBenzMaxim 6:a8c83a2e6fa4 553 private:
IanBenzMaxim 6:a8c83a2e6fa4 554 PageAuthenticationData data;
IanBenzMaxim 6:a8c83a2e6fa4 555 };
IanBenzMaxim 6:a8c83a2e6fa4 556
IanBenzMaxim 6:a8c83a2e6fa4 557 class DS28C36::ComputeSecretData {
IanBenzMaxim 6:a8c83a2e6fa4 558 public:
IanBenzMaxim 6:a8c83a2e6fa4 559 typedef PageAuthenticationData::Result Result;
IanBenzMaxim 6:a8c83a2e6fa4 560
IanBenzMaxim 6:a8c83a2e6fa4 561 ComputeSecretData() : data() {}
IanBenzMaxim 6:a8c83a2e6fa4 562
IanBenzMaxim 6:a8c83a2e6fa4 563 /// Formatted data result.
IanBenzMaxim 6:a8c83a2e6fa4 564 Result::const_span result() const { return data.result(); }
IanBenzMaxim 6:a8c83a2e6fa4 565
IanBenzMaxim 6:a8c83a2e6fa4 566 /// @{
IanBenzMaxim 6:a8c83a2e6fa4 567 /// 1-Wire ROM ID of the device.
IanBenzMaxim 6:a8c83a2e6fa4 568 RomId::span romId() { return data.romId(); }
IanBenzMaxim 6:a8c83a2e6fa4 569
IanBenzMaxim 6:a8c83a2e6fa4 570 RomId::const_span romId() const { return data.romId(); }
IanBenzMaxim 6:a8c83a2e6fa4 571
IanBenzMaxim 6:a8c83a2e6fa4 572 ComputeSecretData & setRomId(RomId::const_span romId) {
IanBenzMaxim 6:a8c83a2e6fa4 573 data.setRomId(romId);
IanBenzMaxim 6:a8c83a2e6fa4 574 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 575 }
IanBenzMaxim 6:a8c83a2e6fa4 576 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 577
IanBenzMaxim 6:a8c83a2e6fa4 578 /// @{
IanBenzMaxim 6:a8c83a2e6fa4 579 /// Binding Data contained in the selected page.
IanBenzMaxim 6:a8c83a2e6fa4 580 Page::span bindingData() { return data.page(); }
IanBenzMaxim 6:a8c83a2e6fa4 581
IanBenzMaxim 6:a8c83a2e6fa4 582 Page::const_span bindingData() const { return data.page(); }
IanBenzMaxim 6:a8c83a2e6fa4 583
IanBenzMaxim 6:a8c83a2e6fa4 584 ComputeSecretData & setBindingData(Page::const_span bindingData) {
IanBenzMaxim 6:a8c83a2e6fa4 585 data.setPage(bindingData);
IanBenzMaxim 6:a8c83a2e6fa4 586 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 587 }
IanBenzMaxim 6:a8c83a2e6fa4 588 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 589
IanBenzMaxim 6:a8c83a2e6fa4 590 /// @{
IanBenzMaxim 6:a8c83a2e6fa4 591 /// Partial Secret used for customization.
IanBenzMaxim 6:a8c83a2e6fa4 592 Page::span partialSecret() { return data.challenge(); }
IanBenzMaxim 6:a8c83a2e6fa4 593
IanBenzMaxim 6:a8c83a2e6fa4 594 Page::const_span partialSecret() const { return data.challenge(); }
IanBenzMaxim 6:a8c83a2e6fa4 595
IanBenzMaxim 6:a8c83a2e6fa4 596 ComputeSecretData & setPartialSecret(Page::const_span partialSecret) {
IanBenzMaxim 6:a8c83a2e6fa4 597 data.setChallenge(partialSecret);
IanBenzMaxim 6:a8c83a2e6fa4 598 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 599 }
IanBenzMaxim 6:a8c83a2e6fa4 600 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 601
IanBenzMaxim 6:a8c83a2e6fa4 602 /// @{
IanBenzMaxim 6:a8c83a2e6fa4 603 /// Page number for Binding Data.
IanBenzMaxim 6:a8c83a2e6fa4 604 int pageNum() const { return data.pageNum(); }
IanBenzMaxim 6:a8c83a2e6fa4 605
IanBenzMaxim 6:a8c83a2e6fa4 606 ComputeSecretData & setPageNum(int pageNum) {
IanBenzMaxim 6:a8c83a2e6fa4 607 data.setPageNum(pageNum);
IanBenzMaxim 6:a8c83a2e6fa4 608 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 609 }
IanBenzMaxim 6:a8c83a2e6fa4 610 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 611
IanBenzMaxim 6:a8c83a2e6fa4 612 /// @{
IanBenzMaxim 6:a8c83a2e6fa4 613 /// Manufacturer ID of the device.
IanBenzMaxim 6:a8c83a2e6fa4 614 ManId::span manId() { return data.manId(); }
IanBenzMaxim 6:a8c83a2e6fa4 615
IanBenzMaxim 6:a8c83a2e6fa4 616 ManId::const_span manId() const { return data.manId(); }
IanBenzMaxim 6:a8c83a2e6fa4 617
IanBenzMaxim 6:a8c83a2e6fa4 618 ComputeSecretData & setManId(ManId::const_span manId) {
IanBenzMaxim 6:a8c83a2e6fa4 619 data.setManId(manId);
IanBenzMaxim 6:a8c83a2e6fa4 620 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 621 }
IanBenzMaxim 6:a8c83a2e6fa4 622 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 623
IanBenzMaxim 6:a8c83a2e6fa4 624 private:
IanBenzMaxim 6:a8c83a2e6fa4 625 PageAuthenticationData data;
IanBenzMaxim 6:a8c83a2e6fa4 626 };
IanBenzMaxim 6:a8c83a2e6fa4 627
IanBenzMaxim 6:a8c83a2e6fa4 628 class DS28C36::EncryptionHmacData {
IanBenzMaxim 6:a8c83a2e6fa4 629 public:
IanBenzMaxim 6:a8c83a2e6fa4 630 typedef array_span<uint_least8_t,
IanBenzMaxim 6:a8c83a2e6fa4 631 EncryptionChallenge::size + RomId::size + 1 + ManId::size>
IanBenzMaxim 6:a8c83a2e6fa4 632 Result;
IanBenzMaxim 6:a8c83a2e6fa4 633
IanBenzMaxim 6:a8c83a2e6fa4 634 EncryptionHmacData() : result_() {}
IanBenzMaxim 6:a8c83a2e6fa4 635
IanBenzMaxim 6:a8c83a2e6fa4 636 /// Formatted data result.
IanBenzMaxim 6:a8c83a2e6fa4 637 Result::const_span result() const { return result_; }
IanBenzMaxim 6:a8c83a2e6fa4 638
IanBenzMaxim 6:a8c83a2e6fa4 639 /// @{
IanBenzMaxim 6:a8c83a2e6fa4 640 /// Random challenge used to prevent replay attacks.
IanBenzMaxim 6:a8c83a2e6fa4 641 EncryptionChallenge::span encryptionChallenge() {
IanBenzMaxim 6:a8c83a2e6fa4 642 return make_span(result_)
IanBenzMaxim 6:a8c83a2e6fa4 643 .subspan<encryptionChallengeIdx, EncryptionChallenge::size>();
IanBenzMaxim 6:a8c83a2e6fa4 644 }
IanBenzMaxim 6:a8c83a2e6fa4 645
IanBenzMaxim 6:a8c83a2e6fa4 646 EncryptionChallenge::const_span encryptionChallenge() const {
IanBenzMaxim 6:a8c83a2e6fa4 647 return const_cast<EncryptionHmacData &>(*this).encryptionChallenge();
IanBenzMaxim 6:a8c83a2e6fa4 648 }
IanBenzMaxim 6:a8c83a2e6fa4 649
IanBenzMaxim 6:a8c83a2e6fa4 650 EncryptionHmacData &
IanBenzMaxim 6:a8c83a2e6fa4 651 setEncryptionChallenge(EncryptionChallenge::const_span encryptionChallenge) {
IanBenzMaxim 6:a8c83a2e6fa4 652 copy(encryptionChallenge, this->encryptionChallenge());
IanBenzMaxim 6:a8c83a2e6fa4 653 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 654 }
IanBenzMaxim 6:a8c83a2e6fa4 655 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 656
IanBenzMaxim 6:a8c83a2e6fa4 657 /// @{
IanBenzMaxim 6:a8c83a2e6fa4 658 /// 1-Wire ROM ID of the device.
IanBenzMaxim 6:a8c83a2e6fa4 659 RomId::span romId() {
IanBenzMaxim 6:a8c83a2e6fa4 660 return make_span(result_).subspan<romIdIdx, RomId::size>();
IanBenzMaxim 6:a8c83a2e6fa4 661 }
IanBenzMaxim 6:a8c83a2e6fa4 662
IanBenzMaxim 6:a8c83a2e6fa4 663 RomId::const_span romId() const {
IanBenzMaxim 6:a8c83a2e6fa4 664 return const_cast<EncryptionHmacData &>(*this).romId();
IanBenzMaxim 6:a8c83a2e6fa4 665 }
IanBenzMaxim 6:a8c83a2e6fa4 666
IanBenzMaxim 6:a8c83a2e6fa4 667 EncryptionHmacData & setRomId(RomId::const_span romId) {
IanBenzMaxim 6:a8c83a2e6fa4 668 copy(romId, this->romId());
IanBenzMaxim 6:a8c83a2e6fa4 669 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 670 }
IanBenzMaxim 6:a8c83a2e6fa4 671
IanBenzMaxim 6:a8c83a2e6fa4 672 MaximInterface_EXPORT EncryptionHmacData & setAnonymousRomId();
IanBenzMaxim 6:a8c83a2e6fa4 673 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 674
IanBenzMaxim 6:a8c83a2e6fa4 675 /// @{
IanBenzMaxim 6:a8c83a2e6fa4 676 /// Number of the page to use data from.
IanBenzMaxim 6:a8c83a2e6fa4 677 int pageNum() const { return result_[pageNumIdx]; }
IanBenzMaxim 6:a8c83a2e6fa4 678
IanBenzMaxim 6:a8c83a2e6fa4 679 EncryptionHmacData & setPageNum(int pageNum) {
IanBenzMaxim 6:a8c83a2e6fa4 680 result_[pageNumIdx] = pageNum;
IanBenzMaxim 6:a8c83a2e6fa4 681 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 682 }
IanBenzMaxim 6:a8c83a2e6fa4 683 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 684
IanBenzMaxim 6:a8c83a2e6fa4 685 /// @{
IanBenzMaxim 6:a8c83a2e6fa4 686 /// Manufacturer ID of the device.
IanBenzMaxim 6:a8c83a2e6fa4 687 ManId::span manId() {
IanBenzMaxim 6:a8c83a2e6fa4 688 return make_span(result_).subspan<manIdIdx, ManId::size>();
IanBenzMaxim 6:a8c83a2e6fa4 689 }
IanBenzMaxim 6:a8c83a2e6fa4 690
IanBenzMaxim 6:a8c83a2e6fa4 691 ManId::const_span manId() const {
IanBenzMaxim 6:a8c83a2e6fa4 692 return const_cast<EncryptionHmacData &>(*this).manId();
IanBenzMaxim 6:a8c83a2e6fa4 693 }
IanBenzMaxim 6:a8c83a2e6fa4 694
IanBenzMaxim 6:a8c83a2e6fa4 695 EncryptionHmacData & setManId(ManId::const_span manId) {
IanBenzMaxim 6:a8c83a2e6fa4 696 copy(manId, this->manId());
IanBenzMaxim 6:a8c83a2e6fa4 697 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 698 }
IanBenzMaxim 6:a8c83a2e6fa4 699 /// @}
IanBenzMaxim 6:a8c83a2e6fa4 700
IanBenzMaxim 6:a8c83a2e6fa4 701 private:
IanBenzMaxim 6:a8c83a2e6fa4 702 typedef Result::span::index_type index;
IanBenzMaxim 6:a8c83a2e6fa4 703
IanBenzMaxim 6:a8c83a2e6fa4 704 static const index encryptionChallengeIdx = 0;
IanBenzMaxim 6:a8c83a2e6fa4 705 static const index romIdIdx =
IanBenzMaxim 6:a8c83a2e6fa4 706 encryptionChallengeIdx + EncryptionChallenge::size;
IanBenzMaxim 6:a8c83a2e6fa4 707 static const index pageNumIdx = romIdIdx + RomId::size;
IanBenzMaxim 6:a8c83a2e6fa4 708 static const index manIdIdx = pageNumIdx + 1;
IanBenzMaxim 6:a8c83a2e6fa4 709
IanBenzMaxim 6:a8c83a2e6fa4 710 Result::array result_;
IanBenzMaxim 6:a8c83a2e6fa4 711 };
IanBenzMaxim 6:a8c83a2e6fa4 712
IanBenzMaxim 6:a8c83a2e6fa4 713 class DS28C36::RomOptions {
IanBenzMaxim 6:a8c83a2e6fa4 714 public:
IanBenzMaxim 6:a8c83a2e6fa4 715 operator Page::const_span() const { return page; }
IanBenzMaxim 6:a8c83a2e6fa4 716 operator Page::span() { return page; }
IanBenzMaxim 6:a8c83a2e6fa4 717
IanBenzMaxim 6:a8c83a2e6fa4 718 bool anonymous() const { return page[anonymousIdx] == anonymousValue; }
IanBenzMaxim 6:a8c83a2e6fa4 719
IanBenzMaxim 6:a8c83a2e6fa4 720 void setAnonymous(bool anonymous) {
IanBenzMaxim 6:a8c83a2e6fa4 721 page[anonymousIdx] = (anonymous ? anonymousValue : 0);
IanBenzMaxim 6:a8c83a2e6fa4 722 }
IanBenzMaxim 6:a8c83a2e6fa4 723
IanBenzMaxim 6:a8c83a2e6fa4 724 ManId::const_span manId() const {
IanBenzMaxim 6:a8c83a2e6fa4 725 return make_span(page).subspan<22, ManId::size>();
IanBenzMaxim 6:a8c83a2e6fa4 726 }
IanBenzMaxim 6:a8c83a2e6fa4 727
IanBenzMaxim 6:a8c83a2e6fa4 728 RomId::const_span romId() const {
IanBenzMaxim 6:a8c83a2e6fa4 729 return make_span(page).subspan<24, RomId::size>();
IanBenzMaxim 6:a8c83a2e6fa4 730 }
IanBenzMaxim 6:a8c83a2e6fa4 731
IanBenzMaxim 6:a8c83a2e6fa4 732 private:
IanBenzMaxim 6:a8c83a2e6fa4 733 static const Page::array::size_type anonymousIdx = 1;
IanBenzMaxim 6:a8c83a2e6fa4 734 static const Page::array::value_type anonymousValue = 0xAA;
IanBenzMaxim 6:a8c83a2e6fa4 735
IanBenzMaxim 6:a8c83a2e6fa4 736 Page::array page;
IanBenzMaxim 6:a8c83a2e6fa4 737 };
IanBenzMaxim 6:a8c83a2e6fa4 738
IanBenzMaxim 6:a8c83a2e6fa4 739 class DS28C36::GpioControl {
IanBenzMaxim 6:a8c83a2e6fa4 740 public:
IanBenzMaxim 6:a8c83a2e6fa4 741 operator Page::const_span() const { return page; }
IanBenzMaxim 6:a8c83a2e6fa4 742 operator Page::span() { return page; }
IanBenzMaxim 6:a8c83a2e6fa4 743
IanBenzMaxim 6:a8c83a2e6fa4 744 bool pioaConducting() const {
IanBenzMaxim 6:a8c83a2e6fa4 745 return page[pioaConductingIdx] == pioConductingValue;
IanBenzMaxim 6:a8c83a2e6fa4 746 }
IanBenzMaxim 6:a8c83a2e6fa4 747
IanBenzMaxim 6:a8c83a2e6fa4 748 void setPioaConducting(bool pioaConducting) {
IanBenzMaxim 6:a8c83a2e6fa4 749 page[pioaConductingIdx] = (pioaConducting ? pioConductingValue : 0x55);
IanBenzMaxim 6:a8c83a2e6fa4 750 }
IanBenzMaxim 6:a8c83a2e6fa4 751
IanBenzMaxim 6:a8c83a2e6fa4 752 bool piobConducting() const {
IanBenzMaxim 6:a8c83a2e6fa4 753 return page[piobConductingIdx] == pioConductingValue;
IanBenzMaxim 6:a8c83a2e6fa4 754 }
IanBenzMaxim 6:a8c83a2e6fa4 755
IanBenzMaxim 6:a8c83a2e6fa4 756 void setPiobConducting(bool piobConducting) {
IanBenzMaxim 6:a8c83a2e6fa4 757 page[piobConductingIdx] = (piobConducting ? pioConductingValue : 0x55);
IanBenzMaxim 6:a8c83a2e6fa4 758 }
IanBenzMaxim 6:a8c83a2e6fa4 759
IanBenzMaxim 6:a8c83a2e6fa4 760 bool pioaLevel() const { return page[2] == pioLevelValue; }
IanBenzMaxim 6:a8c83a2e6fa4 761
IanBenzMaxim 6:a8c83a2e6fa4 762 bool piobLevel() const { return page[3] == pioLevelValue; }
IanBenzMaxim 6:a8c83a2e6fa4 763
IanBenzMaxim 6:a8c83a2e6fa4 764 private:
IanBenzMaxim 6:a8c83a2e6fa4 765 static const Page::array::size_type pioaConductingIdx = 0;
IanBenzMaxim 6:a8c83a2e6fa4 766 static const Page::array::size_type piobConductingIdx = 1;
IanBenzMaxim 6:a8c83a2e6fa4 767 static const Page::array::value_type pioConductingValue = 0xAA;
IanBenzMaxim 6:a8c83a2e6fa4 768 static const Page::array::value_type pioLevelValue = 0x55;
IanBenzMaxim 6:a8c83a2e6fa4 769
IanBenzMaxim 6:a8c83a2e6fa4 770 Page::array page;
IanBenzMaxim 6:a8c83a2e6fa4 771 };
IanBenzMaxim 6:a8c83a2e6fa4 772
IanBenzMaxim 6:a8c83a2e6fa4 773 } // namespace MaximInterface
IanBenzMaxim 6:a8c83a2e6fa4 774
IanBenzMaxim 6:a8c83a2e6fa4 775 #endif