Aleksandrs Gumenuks / MaximInterface_Extended

Dependents:   mbed_DS28EC20_GPIO

Committer:
IanBenzMaxim
Date:
Thu Jan 11 13:50:39 2018 -0600
Revision:
3:f818ea5172ed
Parent:
0:f77ad7f72d04
Child:
6:a8c83a2e6fa4
Updated to version 1.1.

Who changed what in which revision?

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