Refactor to standard layout.
This commit is contained in:
198
include/emsha/emsha.h
Normal file
198
include/emsha/emsha.h
Normal file
@@ -0,0 +1,198 @@
|
||||
///
|
||||
/// \file emsha/emsha.h
|
||||
/// \author K. Isom <kyle@imap.cc>
|
||||
/// \date 2015-12-17
|
||||
/// \brief Declares an interface for an EMbedded Secure HAshing interface.
|
||||
///
|
||||
/// The MIT License (MIT)
|
||||
///
|
||||
/// Copyright (c) 2015 K. Isom <coder@kyleisom.net>
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// copy of this software and associated documentation files (the "Software"),
|
||||
/// to deal in the Software without restriction, including without limitation
|
||||
/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
/// and/or sell copies of the Software, and to permit persons to whom the
|
||||
/// Software is furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
///
|
||||
|
||||
|
||||
#ifndef EMSHA_EMSHA_H
|
||||
#define EMSHA_EMSHA_H
|
||||
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
// emsha is an EMbedded Secure HAshing interface.
|
||||
namespace emsha {
|
||||
|
||||
|
||||
#ifdef NDEBUG
|
||||
/// EMSHA_CHECK is used for sanity checks in certain parts of
|
||||
/// the code. If asserts are turned off, expand the check to an
|
||||
/// if statement that will return with retval if the condition
|
||||
/// isn't met.
|
||||
#define EMSHA_CHECK(condition, retval) if (!(condition)) { return (retval); }
|
||||
#else
|
||||
/// EMSHA_CHECK is used for sanity checks in certain parts of
|
||||
/// the code. If asserts are turned on, the check is expanded to
|
||||
/// an assertion that the condition holds. In this case, retval
|
||||
/// is not used.
|
||||
#define EMSHA_CHECK(condition, retval) (assert((condition)))
|
||||
#endif
|
||||
|
||||
/// SHA256_HASH_SIZE is the output length of SHA-256 in bytes.
|
||||
const std::uint32_t SHA256_HASH_SIZE = 32U;
|
||||
|
||||
|
||||
/// \brief Describe the result of an EMSHA operation.
|
||||
///
|
||||
/// The EMSHAResult type is used to indicate whether an operation
|
||||
/// succeeded, and if not, what the general fault type was.
|
||||
enum class EMSHAResult : std::uint8_t {
|
||||
/// An unknown fault occurred. This is a serious bug in the
|
||||
/// program.
|
||||
Unknown = 0U,
|
||||
|
||||
/// All operations have completed successfully so far.
|
||||
OK = 1U,
|
||||
|
||||
/// The self-test failed.
|
||||
TestFailure = 2U,
|
||||
|
||||
/// A null pointer was passed in as a buffer where it shouldn't
|
||||
/// have been.
|
||||
NullPointer = 3U,
|
||||
|
||||
/// The Hash is in an invalid state.
|
||||
InvalidState = 4U,
|
||||
|
||||
/// The input to SHA256::update is too large.
|
||||
InputTooLong = 5U,
|
||||
|
||||
/// The self tests have been disabled, but a self-test function
|
||||
/// was called.
|
||||
SelfTestDisabled = 6U
|
||||
} ;
|
||||
|
||||
|
||||
/// A Hash is an abstract base class supporting concrete classes
|
||||
/// that produce digests of data.
|
||||
class Hash {
|
||||
public:
|
||||
virtual ~Hash() = default;
|
||||
|
||||
/// \brief Bring the Hash back to its initial state.
|
||||
///
|
||||
/// That is, the idea is that
|
||||
///
|
||||
/// ```
|
||||
/// hash->reset();
|
||||
/// hash->update(...);
|
||||
/// hash->result(...);
|
||||
/// ```
|
||||
///
|
||||
/// is idempotent, assuming the inputs to update
|
||||
/// and result are constant. The implications of
|
||||
/// this for a given concrete class should be
|
||||
/// described in that class's documentation, but
|
||||
/// in general, it has the effect of preserving
|
||||
/// any initial state while removing any data
|
||||
/// written to the Hash via the update method.
|
||||
///
|
||||
/// \return An ::EMSHAResult describing the status of the
|
||||
/// operation.
|
||||
virtual EMSHAResult Reset() = 0;
|
||||
|
||||
/// \brief Write message data into the Hash.
|
||||
///
|
||||
/// \param message The message data to write into the Hash.
|
||||
/// \param messageLength The length of the message data.
|
||||
/// \return An ::EMSHAResult describing the status of the
|
||||
/// operation.
|
||||
virtual EMSHAResult Update(const std::uint8_t *message,
|
||||
std::uint32_t messageLength) = 0;
|
||||
|
||||
/// \brief Carry out any final operations on the Hash.
|
||||
///
|
||||
/// After a call to finalize, no more data can be written.
|
||||
/// Additionally, it transfers out the resulting hash into its
|
||||
/// argument.
|
||||
///
|
||||
/// \param digest The buffer to store the hash in.
|
||||
/// \return An ::EMSHAResult describing the status of the
|
||||
/// operation.
|
||||
virtual EMSHAResult Finalise(std::uint8_t *digest) = 0;
|
||||
|
||||
/// \brief Result transfers out the hash to the argument.
|
||||
///
|
||||
/// The Hash must keep enough state for repeated calls to
|
||||
/// result to work.
|
||||
///
|
||||
/// \param digest The buffer to store the hash in.
|
||||
/// \return An ::EMSHAResult describing the status of the
|
||||
/// operation.
|
||||
virtual EMSHAResult Result(std::uint8_t *digest) = 0;
|
||||
|
||||
/// \brief Return the output size of the Hash.
|
||||
///
|
||||
/// This is how large the buffers written to by result should
|
||||
/// be.
|
||||
virtual std::uint32_t Size() = 0;
|
||||
};
|
||||
|
||||
/// \brief Constant-time function for comparing two digests.
|
||||
///
|
||||
/// HashEqual provides a constant time function for comparing two
|
||||
/// digests. The caller *must* ensure that both a and b are the same
|
||||
/// size. The recommended approach is to use fixed-size buffers of
|
||||
/// emsha::SHA256_HASH_SIZE length:
|
||||
///
|
||||
/// ```c++
|
||||
/// uint8_t expected[emsha::SHA256_HASH_SIZE];
|
||||
/// uint8_t actual[emsha::SHA256_HASH_SIZE];
|
||||
///
|
||||
/// // Fill in expected and actual using the Hash operations.
|
||||
///
|
||||
/// if (hash_equal(expected, actual)) {
|
||||
/// proceed();
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// \param a A byte buffer of size Hash::Size().
|
||||
/// \param b A byte buffer of size Hash::Size().
|
||||
/// \return True if both byte arrays match.
|
||||
bool HashEqual(const std::uint8_t *a, const std::uint8_t *b);
|
||||
|
||||
|
||||
#ifndef EMSHA_NO_HEXSTRING
|
||||
/// \brief Write a hex-encoded version of a byte string.
|
||||
///
|
||||
/// HexString writes a hex-encoded version of the src byte array into
|
||||
/// dest. The caller **must** ensure that dest is `srclen * 2` bytes
|
||||
/// or longer.
|
||||
///
|
||||
/// \param dest The destination byte array at least (`2*srclen`)
|
||||
/// bytes in length.
|
||||
/// \param src A byte array containing the data to hexify.
|
||||
/// \param srclen The size in bytes of src.
|
||||
void HexString(std::uint8_t *dest, std::uint8_t *src, std::uint32_t srclen);
|
||||
#endif // EMSHA_NO_HEXSTRING
|
||||
|
||||
|
||||
} // end of namespace emsha
|
||||
|
||||
|
||||
#endif // EMSHA_EMSHA_H
|
||||
180
include/emsha/hmac.h
Normal file
180
include/emsha/hmac.h
Normal file
@@ -0,0 +1,180 @@
|
||||
///
|
||||
/// \file emsha/hmac.h
|
||||
/// \author K. Isom <kyle@imap.cc>
|
||||
/// \date 2015-12-17
|
||||
/// \brief Declares an interface for HMAC tagging.
|
||||
///
|
||||
/// The MIT License (MIT)
|
||||
///
|
||||
/// Copyright (c) 2015 K. Isom <coder@kyleisom.net>
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// copy of this software and associated documentation files (the "Software"),
|
||||
/// to deal in the Software without restriction, including without limitation
|
||||
/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
/// and/or sell copies of the Software, and to permit persons to whom the
|
||||
/// Software is furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
///
|
||||
|
||||
#ifndef EMSHA_HMAC_H
|
||||
#define EMSHA_HMAC_H
|
||||
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "emsha.h"
|
||||
#include "sha256.h"
|
||||
|
||||
|
||||
namespace emsha {
|
||||
|
||||
const uint32_t HMAC_KEY_LENGTH = SHA256_MB_SIZE;
|
||||
|
||||
/// HMAC is a keyed hash that can be used to produce an
|
||||
/// authenticated hash of some data. The HMAC is built on
|
||||
/// (and uses internally) the SHA256 class; it's helpful to
|
||||
/// note that faults that occur in the SHA-256 code will be
|
||||
/// propagated up as the return value from many of the HMAC
|
||||
/// functions.
|
||||
class HMAC : Hash {
|
||||
public:
|
||||
/// \brief Construct an HMAC with its initial key.
|
||||
///
|
||||
/// An HMAC is constructed with a key and the length of the
|
||||
/// key. This key is stored in the HMAC context, and is wiped
|
||||
/// by the HMAC destructor.
|
||||
///
|
||||
/// \param k The HMAC key.
|
||||
/// \param kl THe length of the HMAC key.
|
||||
HMAC(const uint8_t *k, uint32_t kl);
|
||||
|
||||
/// \brief Clear any data written to the HMAC.
|
||||
///
|
||||
/// This is equivalent to constructing a new HMAC, but it
|
||||
/// preserves the keys.
|
||||
///
|
||||
/// \return EMSHAResult::OK is returned if the reset occurred
|
||||
/// without (detected) fault. If a fault occurs with
|
||||
/// the underlying SHA256 context, the error code is
|
||||
/// returned.
|
||||
EMSHAResult Reset() override;
|
||||
|
||||
/// \brief Write data into the context.
|
||||
///
|
||||
/// While there is an upper limit on the size of data that the
|
||||
/// underlying hash can operate on, this package is designed
|
||||
/// for small systems that will not approach that level of data
|
||||
/// (which is on the order of 2 exabytes), so it is not a
|
||||
/// concern for this library.
|
||||
///
|
||||
/// \param message A byte array containing the message
|
||||
/// to be written.
|
||||
/// \param messageLength The message length, in bytes.
|
||||
/// \return An ::EMSHAResult describing the result of the
|
||||
/// operation.
|
||||
///
|
||||
/// - EMSHAResult::NullPointer is returned if m is NULL
|
||||
/// and ml is nonzero.
|
||||
/// - EMSHAResult::InvalidState is returned if the
|
||||
/// update is called after a call to finalize.
|
||||
/// - EMSHAResult::InputTooLong is returned if too much
|
||||
/// data has been written to the context.
|
||||
/// - EMSHAResult::OK is returned if the data was
|
||||
/// successfully written into the HMAC context.
|
||||
EMSHAResult Update(const std::uint8_t *message, std::uint32_t messageLength) override;
|
||||
|
||||
/// \brief Complete the HMAC computation.
|
||||
///
|
||||
/// \note Once #Finalise is called, the context cannot be
|
||||
/// updated unless the context is reset.
|
||||
///
|
||||
/// \param digest A byte buffer that must be at least #HMAC.Size()
|
||||
/// in length.
|
||||
/// \return An EMSHAResult describing the result of this
|
||||
/// method:
|
||||
///
|
||||
/// - EMSHAResult::NullPointer is returned if d is a
|
||||
/// null pointer.
|
||||
/// - EMSHAResult::InvalidState is returned if the HMAC
|
||||
/// context is in an invalid state, such as if there
|
||||
/// were errors in previous updates.
|
||||
/// - EMSHAResult::OK is returned if the context was
|
||||
/// successfully finalised and the digest copied to d.
|
||||
///
|
||||
EMSHAResult Finalise(std::uint8_t *digest) override;
|
||||
|
||||
/// \brief Copy the current digest into a destination buffer.
|
||||
///
|
||||
/// Copy the current digest from the HMAC context into
|
||||
/// `digest`, running #Finalise if needed. Once called, the
|
||||
/// context cannot be updated until the context is reset.
|
||||
///
|
||||
/// \param digest A byte buffer that must be at least #HMAC.size()
|
||||
/// in length.
|
||||
/// \return An ::EMSHAResult describing the result of this
|
||||
/// method:
|
||||
///
|
||||
/// - EMSHAResult::NullPointer is returned if d is a
|
||||
/// null pointer.
|
||||
/// - EMSHAResult::InvalidState is returned if the HMAC
|
||||
/// context is in an invalid state, such as if there
|
||||
/// were errors in previous updates.
|
||||
/// - EMSHAResult::OK is returned if the context was
|
||||
/// successfully finalised and the digest copied to d.
|
||||
EMSHAResult Result(std::uint8_t *digest) override;
|
||||
|
||||
|
||||
/// \brief Returns the output size of HMAC-SHA-256.
|
||||
///
|
||||
/// The buffers passed to #Update and #Finalise should be at
|
||||
/// least this size.
|
||||
///
|
||||
/// \return The expected size of buffers passed to result and
|
||||
/// finalize.
|
||||
std::uint32_t Size() override;
|
||||
|
||||
/// When an HMAC context is destroyed, it is reset and
|
||||
/// the key material is zeroised using the STL `fill`
|
||||
/// function.
|
||||
~HMAC();
|
||||
private:
|
||||
uint8_t hstate;
|
||||
SHA256 ctx;
|
||||
uint8_t k[HMAC_KEY_LENGTH];
|
||||
uint8_t buf[SHA256_HASH_SIZE];
|
||||
|
||||
EMSHAResult reset();
|
||||
inline EMSHAResult finalResult(uint8_t *d);
|
||||
};
|
||||
|
||||
|
||||
/// \brief Perform a single-pass HMAC computation over a message.
|
||||
///
|
||||
/// \param k A byte buffer containing the HMAC key.
|
||||
/// \param kl The length of the HMAC key.
|
||||
/// \param m The message data over which the HMAC is to be computed.
|
||||
/// \param ml The length of the message.
|
||||
/// \param d Byte buffer that will be used to store the resulting
|
||||
/// HMAC. It should be emsha::SHA256_HASH_SIZE bytes in size.
|
||||
/// \return An ::EMSHAResult describing the result of the HMAC operation.
|
||||
EMSHAResult
|
||||
ComputeHMAC(const uint8_t *k, const uint32_t kl,
|
||||
const uint8_t *m, const uint32_t ml,
|
||||
uint8_t *d);
|
||||
|
||||
|
||||
} // end of namespace emsha
|
||||
|
||||
|
||||
#endif // EMSHA_HMAC_H
|
||||
96
include/emsha/internal.h
Normal file
96
include/emsha/internal.h
Normal file
@@ -0,0 +1,96 @@
|
||||
///
|
||||
/// \file emsha/internal.h
|
||||
/// \author K. Isom <kyle@imap.cc>
|
||||
/// \date 2015-12-17
|
||||
/// \brief Declares internal interfaces for the emsha library.
|
||||
///
|
||||
/// The MIT License (MIT)
|
||||
///
|
||||
/// Copyright (c) 2015 K. Isom <coder@kyleisom.net>
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// copy of this software and associated documentation files (the "Software"),
|
||||
/// to deal in the Software without restriction, including without limitation
|
||||
/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
/// and/or sell copies of the Software, and to permit persons to whom the
|
||||
/// Software is furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
///
|
||||
|
||||
#ifndef EMSHA_INTERNAL_H
|
||||
#define EMSHA_INTERNAL_H
|
||||
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
using std::uint8_t;
|
||||
using std::uint32_t;
|
||||
|
||||
|
||||
namespace emsha {
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
rotr32(uint32_t x, uint8_t n)
|
||||
{
|
||||
return ((x >> n) | (x << (32 - n)));
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
sha_ch(uint32_t x, uint32_t y, uint32_t z)
|
||||
{
|
||||
return ((x & y) ^ ((~x) & z));
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
sha_maj(uint32_t x, uint32_t y, uint32_t z)
|
||||
{
|
||||
return (x & y) ^ (x & z) ^ (y & z);
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
sha_Sigma0(uint32_t x)
|
||||
{
|
||||
return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22);
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
sha_Sigma1(uint32_t x)
|
||||
{
|
||||
return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25);
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
sha_sigma0(uint32_t x)
|
||||
{
|
||||
return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >> 3);
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
sha_sigma1(uint32_t x)
|
||||
{
|
||||
return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >> 10);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // end of namespace emsha
|
||||
|
||||
|
||||
#endif // EMSHA_INTERNAL_H
|
||||
194
include/emsha/sha256.h
Normal file
194
include/emsha/sha256.h
Normal file
@@ -0,0 +1,194 @@
|
||||
///
|
||||
/// \file emsha/sha256.h
|
||||
/// \author K. Isom <kyle@imap.cc>
|
||||
/// \date 2015-12-17
|
||||
/// \brief Declares an interface for producing SHA-256 hashes.
|
||||
///
|
||||
/// The MIT License (MIT)
|
||||
///
|
||||
/// Copyright (c) 2015 K. Isom <coder@kyleisom.net>
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// copy of this software and associated documentation files (the "Software"),
|
||||
/// to deal in the Software without restriction, including without limitation
|
||||
/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
/// and/or sell copies of the Software, and to permit persons to whom the
|
||||
/// Software is furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
///
|
||||
|
||||
#ifndef EMSHA_SHA256_H
|
||||
#define EMSHA_SHA256_H
|
||||
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <array>
|
||||
#include <emsha/emsha.h>
|
||||
|
||||
|
||||
namespace emsha {
|
||||
|
||||
|
||||
/// SHA256_MB_SIZE is the size of a message block.
|
||||
const uint32_t SHA256_MB_SIZE = 64;
|
||||
|
||||
class SHA256 : Hash {
|
||||
public:
|
||||
/// \brief A SHA256 context does not need any special
|
||||
/// construction.
|
||||
///
|
||||
/// It can be declared and immediately start being used.
|
||||
SHA256();
|
||||
|
||||
/// The SHA256 destructor will clear out its internal
|
||||
/// message buffer; all the members are local and
|
||||
/// not resource handles, so cleanup is minimal.
|
||||
~SHA256();
|
||||
|
||||
/// \brief Clear the internal state of the SHA256 context,
|
||||
/// returning it to its initial state.
|
||||
///
|
||||
/// \return This should always return EMSHAResult::OK.
|
||||
EMSHAResult Reset() override;
|
||||
|
||||
/// \brief Writes data into the SHA256.
|
||||
///
|
||||
/// While there is an upper limit on the size of data that
|
||||
/// SHA-256 can operate on, this package is designed for small
|
||||
/// systems that will not approach that level of data (which is
|
||||
/// on the order of 2 exabytes), so it is not thought to be a
|
||||
/// concern.
|
||||
///
|
||||
/// \param message A byte array containing the message to be
|
||||
/// written. It must not be NULL (unless the
|
||||
/// message length is zero).
|
||||
/// \param messageLength The message length, in bytes.
|
||||
/// \return An ::EMSHAResult describing the result of the
|
||||
/// operation.
|
||||
///
|
||||
/// - EMSHAResult::NullPointer is returned if m is a
|
||||
/// nullptr and ml is nonzero.
|
||||
/// - EMSHAResult::InvalidState is returned if the
|
||||
/// update is called after a call to finalize.
|
||||
/// - EMSHAResult::InputTooLong is returned if too much
|
||||
/// data has been written to the context.
|
||||
/// - EMSHAResult::OK is returned if the data was
|
||||
/// successfully added to the SHA-256 context.
|
||||
EMSHAResult Update(const std::uint8_t *message, std::uint32_t messageLength) override;
|
||||
|
||||
/// \brief Complete the digest.
|
||||
///
|
||||
/// Once this method is called, the context cannot be updated
|
||||
/// unless the context is reset.
|
||||
///
|
||||
/// \param digest byte buffer that must be at least
|
||||
/// SHA256.size() in length.
|
||||
/// \return An ::EMSHAResult describing the result of the
|
||||
/// operation.
|
||||
///
|
||||
/// - EMSHAResult::NullPointer is returned if a nullptr
|
||||
/// is passed in.
|
||||
/// - EMSHAResult::InvalidState is returned if the
|
||||
/// SHA-256 context is in an invalid state, such as
|
||||
/// if there were errors in previous updates.
|
||||
/// - EMSHAResult::OK is returned if the context was
|
||||
/// successfully finalised and the digest copied to
|
||||
/// digest.
|
||||
EMSHAResult Finalise(std::uint8_t *digest) override;
|
||||
|
||||
/// \brief Copy the result from the SHA-256
|
||||
/// context into the buffer pointed to by d,
|
||||
/// running #Finalise if needed. Once called,
|
||||
/// the context cannot be updated until the
|
||||
/// context is reset.
|
||||
///
|
||||
/// \param digest A byte buffer that must be at least
|
||||
/// SHA256.size() in length.
|
||||
/// \return An ::EMSHAResult describing the result of the
|
||||
/// operation.
|
||||
///
|
||||
/// - EMSHAResult::NullPointer is returned if a nullptr
|
||||
/// is passed in.
|
||||
/// - EMSHAResult::InvalidState is returned if the
|
||||
/// SHA-256 context is in an invalid state, such as
|
||||
/// if there were errors in previous updates.
|
||||
/// - EMSHAResult::OK is returned if the context was
|
||||
/// successfully finalised and the digest copied to
|
||||
/// digest.
|
||||
EMSHAResult Result(std::uint8_t *digest) override;
|
||||
|
||||
/// \brief Returns the output size of SHA-256.
|
||||
///
|
||||
/// The buffers passed to #Update and #Finalise should be at
|
||||
/// least this size.
|
||||
///
|
||||
/// \return The expected size of buffers passed to result and
|
||||
/// finalize.
|
||||
std::uint32_t Size() override;
|
||||
|
||||
private:
|
||||
uint64_t mlen; // Current message length.
|
||||
uint32_t i_hash[8]; // The intermediate hash is 8x 32-bit blocks.
|
||||
|
||||
// hStatus is the hash status, and hComplete indicates
|
||||
// whether the hash has been finalised.
|
||||
EMSHAResult hStatus;
|
||||
uint8_t hComplete;
|
||||
|
||||
// mb is the message block, and mbi is the message
|
||||
// block index.
|
||||
uint8_t mbi;
|
||||
std::array<uint8_t, SHA256_MB_SIZE> mb;
|
||||
|
||||
inline EMSHAResult addLength(const uint32_t);
|
||||
inline void updateMessageBlock(void);
|
||||
inline void padMessage(uint8_t pc);
|
||||
uint32_t chunkToUint32(uint32_t offset);
|
||||
uint32_t uint32ToChunk(uint32_t offset);
|
||||
EMSHAResult reset();
|
||||
}; // end class SHA256
|
||||
|
||||
|
||||
/// \brief SHA256Digest performs a single pass hashing of the message
|
||||
/// passed in.
|
||||
///
|
||||
/// \param m Byte buffer containing the message to hash.
|
||||
/// \param ml The length of m.
|
||||
/// \param d Byte buffer that will be used to store the resulting hash;
|
||||
/// it should have at least emsha::SHA256_HASH_SIZE bytes
|
||||
/// available.
|
||||
/// \return An ::EMSHAResult describing the result of the operation.
|
||||
EMSHAResult SHA256Digest(const uint8_t *m, uint32_t ml, uint8_t *d);
|
||||
|
||||
/// \brief SHA256SelfTest runs through two test cases to ensure that the
|
||||
/// SHA-256 functions are working correctly.
|
||||
///
|
||||
/// \return The result of the self-test.
|
||||
///
|
||||
/// - EMSHAResult::OK is returned if the self tests pass.
|
||||
/// - EMSHAResult::SelfTestDisabled is returned if the self
|
||||
/// tests have been disabled (e.g., libemsha was compiled
|
||||
/// with the EMSHA_NO_SELFTEST #define).
|
||||
/// - If a fault occurred inside the SHA-256 code, the error
|
||||
/// code from one of the update, finalize, result, or reset
|
||||
/// methods is returned.
|
||||
/// - If the fault is that the output does not match the test
|
||||
/// vector, EMSHAResult::TestFailure is returned.
|
||||
EMSHAResult SHA256SelfTest();
|
||||
|
||||
|
||||
} // end of namespace emsha
|
||||
|
||||
|
||||
#endif // EMSHA_SHA256_H
|
||||
Reference in New Issue
Block a user