Device interface library for multiple platforms including Mbed.

Dependents:   DeepCover Embedded Security in IoT MaximInterface MAXREFDES155#

Maxim Interface is a library framework focused on providing flexible and expressive hardware interfaces. Both communication interfaces such as I2C and 1-Wire and device interfaces such as DS18B20 are supported. Modern C++ concepts are used extensively while keeping compatibility with C++98/C++03 and requiring no external dependencies. The embedded-friendly design does not depend on exceptions or RTTI.

The full version of the project is hosted on GitLab: https://gitlab.com/iabenz/MaximInterface

Revision:
8:5ea891c7d1a1
Parent:
7:9cd16581b578
--- a/MaximInterfaceDevices/DS28C36_DS2476.hpp	Mon Jul 22 11:44:07 2019 -0500
+++ b/MaximInterfaceDevices/DS28C36_DS2476.hpp	Mon Sep 16 11:13:37 2019 -0500
@@ -1,5 +1,5 @@
 /*******************************************************************************
-* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
+* Copyright (C) Maxim Integrated Products, Inc., All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
@@ -30,10 +30,11 @@
 * ownership rights.
 *******************************************************************************/
 
-#ifndef MaximInterfaceDevices_DS28C36_DS2476
-#define MaximInterfaceDevices_DS28C36_DS2476
+#ifndef MaximInterfaceDevices_DS28C36_DS2476_hpp
+#define MaximInterfaceDevices_DS28C36_DS2476_hpp
 
 #include <stdint.h>
+#include <utility>
 #include <vector>
 #include <MaximInterfaceCore/Algorithm.hpp>
 #include <MaximInterfaceCore/array_span.hpp>
@@ -154,77 +155,74 @@
   /// @brief Write memory with no protection.
   /// @param pageNum Number of page to write.
   /// @param page Data to write.
-  MaximInterfaceDevices_EXPORT Core::error_code
+  MaximInterfaceDevices_EXPORT Core::Result<void>
   writeMemory(int pageNum, Page::const_span page);
 
   /// @brief Read memory with no protection.
   /// @param pageNum Number of page to read.
-  /// @param[out] page Data that was read.
-  MaximInterfaceDevices_EXPORT Core::error_code readMemory(int pageNum,
-                                                           Page::span page);
+  /// @returns Data that was read.
+  MaximInterfaceDevices_EXPORT Core::Result<Page::array>
+  readMemory(int pageNum) const;
 
   /// @brief Write the temporary buffer.
   /// @param data Data to write.
-  MaximInterfaceDevices_EXPORT Core::error_code
+  MaximInterfaceDevices_EXPORT Core::Result<void>
   writeBuffer(Core::span<const uint_least8_t> data);
 
   /// @brief Read the temporary buffer.
-  /// @param[out] data Data that was read.
-  MaximInterfaceDevices_EXPORT Core::error_code
-  readBuffer(std::vector<uint_least8_t> & data);
+  /// @returns Data that was read.
+  MaximInterfaceDevices_EXPORT Core::Result<std::vector<uint_least8_t> >
+  readBuffer() const;
 
   /// @brief Read the protection settings of a page.
   /// @param pageNum Number of page to read.
-  /// @param[out] protection Protection that was read.
-  MaximInterfaceDevices_EXPORT Core::error_code
-  readPageProtection(int pageNum, PageProtection & protection);
+  /// @returns Protection that was read.
+  MaximInterfaceDevices_EXPORT Core::Result<PageProtection>
+  readPageProtection(int pageNum) const;
 
   /// @brief Set the protection settings of a page.
   /// @param pageNum Number of page to write.
   /// @param protection Protection to write.
-  MaximInterfaceDevices_EXPORT Core::error_code
+  MaximInterfaceDevices_EXPORT Core::Result<void>
   setPageProtection(int pageNum, const PageProtection & protection);
 
   /// Decrement the decrement-only counter.
-  MaximInterfaceDevices_EXPORT Core::error_code decrementCounter();
+  MaximInterfaceDevices_EXPORT Core::Result<void> decrementCounter();
 
   /// @brief Read a block of random data from the RNG.
   /// @param[out] data Random data from RNG with length from 1 to 64.
-  MaximInterfaceDevices_EXPORT Core::error_code
-  readRng(Core::span<uint_least8_t> data);
+  MaximInterfaceDevices_EXPORT Core::Result<void>
+  readRng(Core::span<uint_least8_t> data) const;
 
   /// @brief Read memory with encryption.
   /// @param pageNum Number of page to read from.
   /// @param secretNum Secret to use for encryption.
-  /// @param[out] challenge Encryption challenge that was read.
-  /// @param[out] data Encrypted page data that was read.
-  MaximInterfaceDevices_EXPORT Core::error_code
-  encryptedReadMemory(int pageNum, SecretNum secretNum,
-                      EncryptionChallenge::span challenge, Page::span data);
+  /// @returns Encryption challenge and encrypted page data that was read.
+  MaximInterfaceDevices_EXPORT
+      Core::Result<std::pair<EncryptionChallenge::array, Page::array> >
+      encryptedReadMemory(int pageNum, SecretNum secretNum) const;
 
   /// @brief Compute and read page authentication with ECDSA.
   /// @param pageNum Number of page to authenticate.
   /// @param keyNum
   /// Private key to use for authentication.
   /// Key S cannot be used with this command.
-  /// @param[out] signature Computed page signature.
-  MaximInterfaceDevices_EXPORT Core::error_code
-  computeAndReadPageAuthentication(int pageNum, KeyNum keyNum,
-                                   Core::Ecc256::Signature::span signature);
+  /// @returns Computed page signature.
+  MaximInterfaceDevices_EXPORT Core::Result<Core::Ecc256::Signature::array>
+  computeAndReadPageAuthentication(int pageNum, KeyNum keyNum) const;
 
   /// @brief Compute and read page authentication with HMAC.
   /// @param pageNum Number of page to authenticate.
   /// @param secretNum Secret to use for authentication.
-  /// @param[out] hmac Computed page HMAC.
-  MaximInterfaceDevices_EXPORT Core::error_code
-  computeAndReadPageAuthentication(int pageNum, SecretNum secretNum,
-                                   Page::span hmac);
+  /// @returns Computed page HMAC.
+  MaximInterfaceDevices_EXPORT Core::Result<Page::array>
+  computeAndReadPageAuthentication(int pageNum, SecretNum secretNum) const;
 
   /// @brief Write with SHA2 authentication.
   /// @param pageNum Number of page to write.
   /// @param secretNum Secret to use for authentication.
   /// @param page Data to write.
-  MaximInterfaceDevices_EXPORT Core::error_code
+  MaximInterfaceDevices_EXPORT Core::Result<void>
   authenticatedSha2WriteMemory(int pageNum, SecretNum secretNum,
                                Page::const_span page);
 
@@ -234,14 +232,14 @@
   /// @param dsecretNum Destination secret to receive the computation result.
   /// @param writeProtectEnable
   /// True to lock the destination secret against further writes.
-  MaximInterfaceDevices_EXPORT Core::error_code
+  MaximInterfaceDevices_EXPORT Core::Result<void>
   computeAndLockSha2Secret(int pageNum, SecretNum msecretNum,
                            SecretNum dsecretNum, bool writeProtectEnable);
 
   /// @brief Generate a new ECDSA key pair.
   /// @param keyNum Key to generate. Key S cannot be used with this command.
   /// @param writeProtectEnable True to lock the key against further writes.
-  MaximInterfaceDevices_EXPORT Core::error_code
+  MaximInterfaceDevices_EXPORT Core::Result<void>
   generateEcc256KeyPair(KeyNum keyNum, bool writeProtectEnable);
 
   /// @brief Compute a hash over multiple blocks.
@@ -249,7 +247,7 @@
   /// @param lastBlock True if this is the last block being hashed.
   /// @param data
   /// Data block to hash. Should be 64 bytes unless this is the last block.
-  MaximInterfaceDevices_EXPORT Core::error_code
+  MaximInterfaceDevices_EXPORT Core::Result<void>
   computeMultiblockHash(bool firstBlock, bool lastBlock,
                         Core::span<const uint_least8_t> data);
 
@@ -259,7 +257,7 @@
   /// @param signature Signature to verify.
   /// @param pioa New state of PIOA if verification successful.
   /// @param piob New state of PIOB if verification successful.
-  MaximInterfaceDevices_EXPORT Core::error_code
+  MaximInterfaceDevices_EXPORT Core::Result<void>
   verifyEcdsaSignature(KeyNum keyNum, HashType hashType,
                        Core::Ecc256::Signature::const_span signature,
                        PioState pioa = Unchanged, PioState piob = Unchanged);
@@ -273,7 +271,7 @@
   /// Private key to use for ECDH key exchange. Key A or B can be selected.
   /// @param csOffset Certificate customization field ending offset in buffer.
   /// @param signature Signature to use for authentication of public key S.
-  MaximInterfaceDevices_EXPORT Core::error_code
+  MaximInterfaceDevices_EXPORT Core::Result<void>
   authenticateEcdsaPublicKey(bool authWrites, bool ecdh, KeyNum keyNum,
                              int csOffset,
                              Core::Ecc256::Signature::const_span signature);
@@ -281,7 +279,7 @@
   /// @brief Write with ECDSA authentication.
   /// @param pageNum Number of page to write.
   /// @param page Data to write.
-  MaximInterfaceDevices_EXPORT Core::error_code
+  MaximInterfaceDevices_EXPORT Core::Result<void>
   authenticatedEcdsaWriteMemory(int pageNum, Page::const_span page);
 
   MaximInterfaceDevices_EXPORT static const Core::error_category &
@@ -296,17 +294,19 @@
   static const int readMemoryTimeMs = /*1*/ 2;
   static const int writeMemoryTimeMs = 15;
 
-  Core::error_code writeCommand(uint_least8_t command,
-                                Core::span<const uint_least8_t> parameters);
+  Core::Result<void>
+  writeCommand(uint_least8_t command,
+               Core::span<const uint_least8_t> parameters) const;
 
-  Core::error_code writeCommand(uint_least8_t command) {
+  Core::Result<void> writeCommand(uint_least8_t command) const {
     return writeCommand(command, Core::span<const uint_least8_t>());
   }
 
-  Core::error_code
-  readVariableLengthResponse(Core::span<uint_least8_t> & response);
+  Core::Result<Core::span<uint_least8_t>::index_type>
+  readVariableLengthResponse(Core::span<uint_least8_t> response) const;
 
-  Core::error_code readFixedLengthResponse(Core::span<uint_least8_t> response);
+  Core::Result<void>
+  readFixedLengthResponse(Core::span<uint_least8_t> response) const;
 
   void sleep(int ms) const { sleep_->invoke(ms); }
 
@@ -320,12 +320,12 @@
     EcdsaWithKeyC = 5
   };
 
+  Core::Result<void> computeAndReadPageAuthentication(int pageNum,
+                                                      AuthType authType) const;
+
   const Core::Sleep * sleep_;
   Core::I2CMaster * master;
   uint_least8_t address_;
-
-  Core::error_code computeAndReadPageAuthentication(int pageNum,
-                                                    AuthType authType);
 };
 
 /// Interface to the DS2476 coprocessor.
@@ -339,22 +339,31 @@
   /// @param keyNum
   /// Private key to use to create signature.
   /// Key S cannot be used with this command.
-  /// @param[out] signature Computed signature.
-  MaximInterfaceDevices_EXPORT Core::error_code
-  generateEcdsaSignature(KeyNum keyNum,
-                         Core::Ecc256::Signature::span signature);
+  /// @returns Computed signature.
+  MaximInterfaceDevices_EXPORT Core::Result<Core::Ecc256::Signature::array>
+  generateEcdsaSignature(KeyNum keyNum) const;
 
   /// @brief Compute unique SHA2 secret.
   /// @param msecretNum Master secret to use in computation.
-  MaximInterfaceDevices_EXPORT Core::error_code
+  MaximInterfaceDevices_EXPORT Core::Result<void>
   computeSha2UniqueSecret(SecretNum msecretNum);
 
   /// @brief Compute SHA2 HMAC.
-  /// @param[out] hmac Computed HMAC.
-  MaximInterfaceDevices_EXPORT Core::error_code
-  computeSha2Hmac(Page::span hmac);
+  /// @returns Computed HMAC.
+  MaximInterfaceDevices_EXPORT Core::Result<Page::array>
+  computeSha2Hmac() const;
 };
 
+} // namespace MaximInterfaceDevices
+namespace MaximInterfaceCore {
+
+template <>
+struct is_error_code_enum<MaximInterfaceDevices::DS28C36::ErrorValue>
+    : true_type {};
+
+} // namespace MaximInterfaceCore
+namespace MaximInterfaceDevices {
+
 inline Core::error_code make_error_code(DS28C36::ErrorValue e) {
   return Core::error_code(e, DS28C36::errorCategory());
 }
@@ -363,7 +372,7 @@
 /// Hash arbitrary length data with successive Compute Multiblock Hash commands.
 /// @param ds28c36 Device for computation.
 /// @param data Data to hash.
-MaximInterfaceDevices_EXPORT Core::error_code
+MaximInterfaceDevices_EXPORT Core::Result<void>
 computeMultiblockHash(DS28C36 & ds28c36, Core::span<const uint_least8_t> data);
 
 /// @brief Verify ECDSA signature.
@@ -373,7 +382,7 @@
 /// @param signature Signature to verify.
 /// @param pioa New state of PIOA if verification successful.
 /// @param piob New state of PIOB if verification successful.
-MaximInterfaceDevices_EXPORT Core::error_code
+MaximInterfaceDevices_EXPORT Core::Result<void>
 verifyEcdsaSignature(DS28C36 & ds28c36, DS28C36::KeyNum publicKey,
                      Core::span<const uint_least8_t> data,
                      Core::Ecc256::Signature::const_span signature,
@@ -388,7 +397,7 @@
 /// @param signature Signature to verify.
 /// @param pioa New state of PIOA if verification successful.
 /// @param piob New state of PIOB if verification successful.
-MaximInterfaceDevices_EXPORT Core::error_code
+MaximInterfaceDevices_EXPORT Core::Result<void>
 verifyEcdsaSignature(DS28C36 & ds28c36,
                      Core::Ecc256::PublicKey::const_span publicKey,
                      Core::span<const uint_least8_t> data,
@@ -397,25 +406,15 @@
                      DS28C36::PioState piob = DS28C36::Unchanged);
 
 /// @brief
-/// Read the device ROM ID and MAN ID using the Read Memory command on the
-/// ROM Options page.
-/// @param ds28c36 Device to read.
-/// @param[out] romId Read ROM ID valid when operation is successful.
-/// @param[out] manId Read MAN ID valid when operation is successful.
-MaximInterfaceDevices_EXPORT Core::error_code
-readRomIdAndManId(DS28C36 & ds28c36, Core::RomId::span romId,
-                  Core::ManId::span manId);
-
-/// @brief
 /// Enable coprocessor functionality on the DS2476 by writing to the
 /// GPIO Control page.
-MaximInterfaceDevices_EXPORT Core::error_code
+MaximInterfaceDevices_EXPORT Core::Result<void>
 enableCoprocessor(DS2476 & ds2476);
 
 /// @brief
 /// Disable blocking of the ROM ID on the DS2476 by writing to the
 /// ROM Options page.
-MaximInterfaceDevices_EXPORT Core::error_code enableRomId(DS2476 & ds2476);
+MaximInterfaceDevices_EXPORT Core::Result<void> enableRomId(DS2476 & ds2476);
 
 /// Format page authentication input data.
 class DS28C36::PageAuthenticationData {
@@ -536,13 +535,11 @@
   /// @}
 
 private:
-  typedef Result::span::index_type index;
-
-  static const index romIdIdx = 0;
-  static const index pageIdx = romIdIdx + Core::RomId::size;
-  static const index challengeIdx = pageIdx + Page::size;
-  static const index pageNumIdx = challengeIdx + Page::size;
-  static const index manIdIdx = pageNumIdx + 1;
+  static const size_t romIdIdx = 0;
+  static const size_t pageIdx = romIdIdx + Core::RomId::size;
+  static const size_t challengeIdx = pageIdx + Page::size;
+  static const size_t pageNumIdx = challengeIdx + Page::size;
+  static const size_t manIdIdx = pageNumIdx + 1;
 
   Result::array result_;
 };
@@ -855,13 +852,11 @@
   /// @}
 
 private:
-  typedef Result::span::index_type index;
-
-  static const index encryptionChallengeIdx = 0;
-  static const index romIdIdx =
+  static const size_t encryptionChallengeIdx = 0;
+  static const size_t romIdIdx =
       encryptionChallengeIdx + EncryptionChallenge::size;
-  static const index pageNumIdx = romIdIdx + Core::RomId::size;
-  static const index manIdIdx = pageNumIdx + 1;
+  static const size_t pageNumIdx = romIdIdx + Core::RomId::size;
+  static const size_t manIdIdx = pageNumIdx + 1;
 
   Result::array result_;
 };