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
Diff: MaximInterfaceDevices/DS28C36_DS2476.hpp
- 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_; };