mirror of
https://github.com/espressif/openthread.git
synced 2026-09-21 08:27:33 +00:00
[crypto] add 'Sha256::Hash' type (#5946)
This commit adds new public type 'otCryptoSha256Hash' and its internal mirror `Sha256::Hash` type which represent a SHA-256 hash value.
This commit is contained in:
@@ -54,7 +54,25 @@ extern "C" {
|
||||
*
|
||||
*/
|
||||
|
||||
#define OT_CRYPTO_HMAC_SHA_HASH_SIZE 32 ///< Length of HMAC SHA (in bytes).
|
||||
#define OT_CRYPTO_SHA256_HASH_SIZE 32 ///< Length of SHA256 hash (in bytes).
|
||||
|
||||
/**
|
||||
* @struct otCryptoSha256Hash
|
||||
*
|
||||
* This structure represents a SHA-256 hash.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
struct otCryptoSha256Hash
|
||||
{
|
||||
uint8_t m8[OT_CRYPTO_SHA256_HASH_SIZE]; ///< Hash bytes.
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This structure represents a SHA-256 hash.
|
||||
*
|
||||
*/
|
||||
typedef struct otCryptoSha256Hash otCryptoSha256Hash;
|
||||
|
||||
/**
|
||||
* This function performs HMAC computation.
|
||||
@@ -63,14 +81,14 @@ extern "C" {
|
||||
* @param[in] aKeyLength The key length in bytes.
|
||||
* @param[in] aBuf A pointer to the input buffer.
|
||||
* @param[in] aBufLength The length of @p aBuf in bytes.
|
||||
* @param[out] aHash A pointer to the output hash buffer.
|
||||
* @param[out] aHash A pointer to a `otCryptoSha256Hash` structure to output the hash value.
|
||||
*
|
||||
*/
|
||||
void otCryptoHmacSha256(const uint8_t *aKey,
|
||||
uint16_t aKeyLength,
|
||||
const uint8_t *aBuf,
|
||||
uint16_t aBufLength,
|
||||
uint8_t * aHash);
|
||||
void otCryptoHmacSha256(const uint8_t * aKey,
|
||||
uint16_t aKeyLength,
|
||||
const uint8_t * aBuf,
|
||||
uint16_t aBufLength,
|
||||
otCryptoSha256Hash *aHash);
|
||||
|
||||
/**
|
||||
* This method performs AES CCM computation.
|
||||
|
||||
@@ -53,7 +53,7 @@ extern "C" {
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (55)
|
||||
#define OPENTHREAD_API_VERSION (56)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -44,11 +44,11 @@
|
||||
|
||||
using namespace ot::Crypto;
|
||||
|
||||
void otCryptoHmacSha256(const uint8_t *aKey,
|
||||
uint16_t aKeyLength,
|
||||
const uint8_t *aBuf,
|
||||
uint16_t aBufLength,
|
||||
uint8_t * aHash)
|
||||
void otCryptoHmacSha256(const uint8_t * aKey,
|
||||
uint16_t aKeyLength,
|
||||
const uint8_t * aBuf,
|
||||
uint16_t aBufLength,
|
||||
otCryptoSha256Hash *aHash)
|
||||
{
|
||||
HmacSha256 hmac;
|
||||
|
||||
@@ -56,7 +56,7 @@ void otCryptoHmacSha256(const uint8_t *aKey,
|
||||
|
||||
hmac.Start(aKey, aKeyLength);
|
||||
hmac.Update(aBuf, aBufLength);
|
||||
hmac.Finish(aHash);
|
||||
hmac.Finish(*static_cast<HmacSha256::Hash *>(aHash));
|
||||
}
|
||||
|
||||
void otCryptoAesCcm(const uint8_t *aKey,
|
||||
|
||||
@@ -51,10 +51,10 @@ void HkdfSha256::Extract(const uint8_t *aSalt, uint16_t aSaltLength, const uint8
|
||||
|
||||
void HkdfSha256::Expand(const uint8_t *aInfo, uint16_t aInfoLength, uint8_t *aOutputKey, uint16_t aOutputKeyLength)
|
||||
{
|
||||
HmacSha256 hmac;
|
||||
uint8_t hash[kHashSize];
|
||||
uint8_t iter = 0;
|
||||
uint16_t copyLength;
|
||||
HmacSha256 hmac;
|
||||
HmacSha256::Hash hash;
|
||||
uint8_t iter = 0;
|
||||
uint16_t copyLength;
|
||||
|
||||
// The aOutputKey is calculated as follows [RFC5889]:
|
||||
//
|
||||
@@ -71,11 +71,11 @@ void HkdfSha256::Expand(const uint8_t *aInfo, uint16_t aInfoLength, uint8_t *aOu
|
||||
|
||||
while (aOutputKeyLength > 0)
|
||||
{
|
||||
hmac.Start(mPrk, sizeof(mPrk));
|
||||
hmac.Start(mPrk.GetBytes(), sizeof(mPrk));
|
||||
|
||||
if (iter != 0)
|
||||
{
|
||||
hmac.Update(hash, sizeof(hash));
|
||||
hmac.Update(hash.GetBytes(), sizeof(hash));
|
||||
}
|
||||
|
||||
hmac.Update(aInfo, aInfoLength);
|
||||
@@ -86,7 +86,7 @@ void HkdfSha256::Expand(const uint8_t *aInfo, uint16_t aInfoLength, uint8_t *aOu
|
||||
|
||||
copyLength = (aOutputKeyLength > sizeof(hash)) ? sizeof(hash) : aOutputKeyLength;
|
||||
|
||||
memcpy(aOutputKey, hash, copyLength);
|
||||
memcpy(aOutputKey, hash.GetBytes(), copyLength);
|
||||
aOutputKey += copyLength;
|
||||
aOutputKeyLength -= copyLength;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#include "hmac_sha256.hpp"
|
||||
#include "crypto/hmac_sha256.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Crypto {
|
||||
@@ -84,12 +84,7 @@ public:
|
||||
void Expand(const uint8_t *aInfo, uint16_t aInfoLength, uint8_t *aOutputKey, uint16_t aOutputKeyLength);
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kHashSize = HmacSha256::kHashSize,
|
||||
};
|
||||
|
||||
uint8_t mPrk[kHashSize]; // Pseudo-Random Key (derived from Extract step).
|
||||
HmacSha256::Hash mPrk; // Pseudo-Random Key (derived from Extract step).
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -59,9 +59,9 @@ void HmacSha256::Update(const uint8_t *aBuf, uint16_t aBufLength)
|
||||
mbedtls_md_hmac_update(&mContext, aBuf, aBufLength);
|
||||
}
|
||||
|
||||
void HmacSha256::Finish(uint8_t aHash[kHashSize])
|
||||
void HmacSha256::Finish(Hash &aHash)
|
||||
{
|
||||
mbedtls_md_hmac_finish(&mContext, aHash);
|
||||
mbedtls_md_hmac_finish(&mContext, aHash.m8);
|
||||
}
|
||||
|
||||
} // namespace Crypto
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
|
||||
#include <mbedtls/md.h>
|
||||
|
||||
#include "crypto/sha256.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Crypto {
|
||||
|
||||
@@ -57,10 +59,11 @@ namespace Crypto {
|
||||
class HmacSha256
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kHashSize = 32, ///< SHA-256 hash size (bytes)
|
||||
};
|
||||
/**
|
||||
* This type represents a HMAC SHA-256 hash.
|
||||
*
|
||||
*/
|
||||
typedef Sha256::Hash Hash;
|
||||
|
||||
/**
|
||||
* Constructor for initialization of mbedtls_md_context_t.
|
||||
@@ -95,10 +98,10 @@ public:
|
||||
/**
|
||||
* This method finalizes the hash computation.
|
||||
*
|
||||
* @param[out] aHash A pointer to the output buffer.
|
||||
* @param[out] aHash A reference to a `Hash` to output the calculated hash.
|
||||
*
|
||||
*/
|
||||
void Finish(uint8_t aHash[kHashSize]);
|
||||
void Finish(Hash &aHash);
|
||||
|
||||
private:
|
||||
mbedtls_md_context_t mContext;
|
||||
|
||||
@@ -56,9 +56,9 @@ void Sha256::Update(const uint8_t *aBuf, uint16_t aBufLength)
|
||||
mbedtls_sha256_update_ret(&mContext, aBuf, aBufLength);
|
||||
}
|
||||
|
||||
void Sha256::Finish(uint8_t aHash[kHashSize])
|
||||
void Sha256::Finish(Hash &aHash)
|
||||
{
|
||||
mbedtls_sha256_finish_ret(&mContext, aHash);
|
||||
mbedtls_sha256_finish_ret(&mContext, aHash.m8);
|
||||
}
|
||||
|
||||
} // namespace Crypto
|
||||
|
||||
@@ -40,6 +40,11 @@
|
||||
|
||||
#include <mbedtls/sha256.h>
|
||||
|
||||
#include <openthread/crypto.h>
|
||||
|
||||
#include "common/clearable.hpp"
|
||||
#include "common/equatable.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Crypto {
|
||||
|
||||
@@ -57,6 +62,27 @@ namespace Crypto {
|
||||
class Sha256
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This type represents a SHA-256 hash.
|
||||
*
|
||||
*/
|
||||
class Hash : public otCryptoSha256Hash, public Clearable<Hash>, public Equatable<Hash>
|
||||
{
|
||||
public:
|
||||
enum : uint8_t
|
||||
{
|
||||
kSize = OT_CRYPTO_SHA256_HASH_SIZE, ///< SHA-256 hash size (bytes)
|
||||
};
|
||||
|
||||
/**
|
||||
* This method returns a pointer to a byte array containing the hash value.
|
||||
*
|
||||
* @returns A pointer to a byte array containing the hash.
|
||||
*
|
||||
*/
|
||||
const uint8_t *GetBytes(void) { return m8; }
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kHashSize = 32, ///< SHA-256 hash size (bytes)
|
||||
@@ -92,10 +118,10 @@ public:
|
||||
/**
|
||||
* This method finalizes the hash computation.
|
||||
*
|
||||
* @param[out] aHash A pointer to the output buffer.
|
||||
* @param[out] aHash A reference to a `Hash` to output the calculated hash.
|
||||
*
|
||||
*/
|
||||
void Finish(uint8_t aHash[kHashSize]);
|
||||
void Finish(Hash &aHash);
|
||||
|
||||
private:
|
||||
mbedtls_sha256_context mContext;
|
||||
|
||||
@@ -727,14 +727,14 @@ int Dtls::HandleMbedtlsExportKeys(const unsigned char *aMasterSecret,
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aMasterSecret);
|
||||
|
||||
uint8_t kek[Crypto::Sha256::kHashSize];
|
||||
Crypto::Sha256 sha256;
|
||||
Crypto::Sha256::Hash kek;
|
||||
Crypto::Sha256 sha256;
|
||||
|
||||
sha256.Start();
|
||||
sha256.Update(aKeyBlock, 2 * static_cast<uint16_t>(aMacLength + aKeyLength + aIvLength));
|
||||
sha256.Finish(kek);
|
||||
|
||||
Get<KeyManager>().SetKek(kek);
|
||||
Get<KeyManager>().SetKek(kek.GetBytes());
|
||||
|
||||
if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8)
|
||||
{
|
||||
|
||||
@@ -287,14 +287,14 @@ bool SteeringData::DoesAllMatch(uint8_t aMatch) const
|
||||
|
||||
void ComputeJoinerId(const Mac::ExtAddress &aEui64, Mac::ExtAddress &aJoinerId)
|
||||
{
|
||||
Crypto::Sha256 sha256;
|
||||
uint8_t hash[Crypto::Sha256::kHashSize];
|
||||
Crypto::Sha256 sha256;
|
||||
Crypto::Sha256::Hash hash;
|
||||
|
||||
sha256.Start();
|
||||
sha256.Update(aEui64.m8, sizeof(aEui64));
|
||||
sha256.Finish(hash);
|
||||
|
||||
memcpy(&aJoinerId, hash, sizeof(aJoinerId));
|
||||
memcpy(&aJoinerId, hash.GetBytes(), sizeof(aJoinerId));
|
||||
aJoinerId.SetLocal(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -517,8 +517,8 @@ private:
|
||||
|
||||
union HashKeys
|
||||
{
|
||||
uint8_t mHash[Crypto::HmacSha256::kHashSize];
|
||||
Keys mKeys;
|
||||
Crypto::HmacSha256::Hash mHash;
|
||||
Keys mKeys;
|
||||
};
|
||||
|
||||
void ComputeKeys(uint32_t aKeySequence, HashKeys &aHashKeys);
|
||||
|
||||
@@ -272,12 +272,12 @@ otError Slaac::GenerateIid(Ip6::NetifUnicastAddress &aAddress,
|
||||
*
|
||||
*/
|
||||
|
||||
otError error = OT_ERROR_FAILED;
|
||||
const uint8_t netIface[] = {'w', 'p', 'a', 'n'};
|
||||
uint8_t dadCounter = aDadCounter ? *aDadCounter : 0;
|
||||
IidSecretKey secretKey;
|
||||
Crypto::Sha256 sha256;
|
||||
uint8_t hash[Crypto::Sha256::kHashSize];
|
||||
otError error = OT_ERROR_FAILED;
|
||||
const uint8_t netIface[] = {'w', 'p', 'a', 'n'};
|
||||
uint8_t dadCounter = aDadCounter ? *aDadCounter : 0;
|
||||
IidSecretKey secretKey;
|
||||
Crypto::Sha256 sha256;
|
||||
Crypto::Sha256::Hash hash;
|
||||
|
||||
static_assert(sizeof(hash) >= Ip6::InterfaceIdentifier::kSize,
|
||||
"SHA-256 hash size is too small to use as IPv6 address IID");
|
||||
@@ -299,7 +299,7 @@ otError Slaac::GenerateIid(Ip6::NetifUnicastAddress &aAddress,
|
||||
sha256.Update(secretKey.m8, sizeof(IidSecretKey));
|
||||
sha256.Finish(hash);
|
||||
|
||||
aAddress.GetAddress().GetIid().SetBytes(&hash[0]);
|
||||
aAddress.GetAddress().GetIid().SetBytes(hash.GetBytes());
|
||||
|
||||
// If the IID is reserved, try again with a new dadCounter
|
||||
if (aAddress.GetAddress().GetIid().IsReserved())
|
||||
|
||||
@@ -38,17 +38,17 @@ void TestHmacSha256(void)
|
||||
{
|
||||
static const struct
|
||||
{
|
||||
const char *key;
|
||||
const char *data;
|
||||
uint8_t hash[ot::Crypto::HmacSha256::kHashSize];
|
||||
const char * key;
|
||||
const char * data;
|
||||
otCryptoSha256Hash hash;
|
||||
} tests[] = {
|
||||
{
|
||||
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
|
||||
"Hi There",
|
||||
{
|
||||
{{
|
||||
0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b,
|
||||
0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7,
|
||||
},
|
||||
}},
|
||||
},
|
||||
{
|
||||
nullptr,
|
||||
@@ -61,8 +61,8 @@ void TestHmacSha256(void)
|
||||
|
||||
// Make sure hmac is destructed before freeing instance.
|
||||
{
|
||||
ot::Crypto::HmacSha256 hmac;
|
||||
uint8_t hash[ot::Crypto::HmacSha256::kHashSize];
|
||||
ot::Crypto::HmacSha256 hmac;
|
||||
ot::Crypto::HmacSha256::Hash hash;
|
||||
|
||||
VerifyOrQuit(instance != nullptr, "Null OpenThread instance");
|
||||
|
||||
@@ -72,7 +72,8 @@ void TestHmacSha256(void)
|
||||
hmac.Update(reinterpret_cast<const uint8_t *>(tests[i].data), static_cast<uint16_t>(strlen(tests[i].data)));
|
||||
hmac.Finish(hash);
|
||||
|
||||
VerifyOrQuit(memcmp(hash, tests[i].hash, sizeof(tests[i].hash)) == 0, "HMAC-SHA-256 failed");
|
||||
VerifyOrQuit(hash == static_cast<const ot::Crypto::HmacSha256::Hash &>(tests[i].hash),
|
||||
"HMAC-SHA-256 failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user