Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions src/bip324.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#include <iterator>
#include <string>

BIP324Cipher::BIP324Cipher(const CKey& key, std::span<const std::byte> ent32) noexcept
BIP324Cipher::BIP324Cipher(const CKey& key, std::span<const std::byte, 32> ent32) noexcept
: m_key(key)
{
m_our_pubkey = m_key.EllSwiftCreate(ent32);
Expand Down Expand Up @@ -79,17 +79,15 @@ void BIP324Cipher::Encrypt(std::span<const std::byte> contents, std::span<const
len[0] = std::byte{(uint8_t)(contents.size() & 0xFF)};
len[1] = std::byte{(uint8_t)((contents.size() >> 8) & 0xFF)};
len[2] = std::byte{(uint8_t)((contents.size() >> 16) & 0xFF)};
m_send_l_cipher->Crypt(len, output.first(LENGTH_LEN));
m_send_l_cipher->Crypt(len, output.first<LENGTH_LEN>());

// Encrypt plaintext.
std::byte header[HEADER_LEN] = {ignore ? IGNORE_BIT : std::byte{0}};
m_send_p_cipher->Encrypt(header, contents, aad, output.subspan(LENGTH_LEN));
}

uint32_t BIP324Cipher::DecryptLength(std::span<const std::byte> input) noexcept
uint32_t BIP324Cipher::DecryptLength(std::span<const std::byte, LENGTH_LEN> input) noexcept
{
assert(input.size() == LENGTH_LEN);

std::byte buf[LENGTH_LEN];
// Decrypt length
m_recv_l_cipher->Crypt(input, buf);
Expand Down
4 changes: 2 additions & 2 deletions src/bip324.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class BIP324Cipher
BIP324Cipher() = delete;

/** Initialize a BIP324 cipher with specified key and encoding entropy (testing only). */
BIP324Cipher(const CKey& key, std::span<const std::byte> ent32) noexcept;
BIP324Cipher(const CKey& key, std::span<const std::byte, 32> ent32) noexcept;

/** Initialize a BIP324 cipher with specified key (testing only). */
BIP324Cipher(const CKey& key, const EllSwiftPubKey& pubkey) noexcept;
Expand Down Expand Up @@ -74,7 +74,7 @@ class BIP324Cipher
*
* It must hold that input.size() == LENGTH_LEN.
*/
unsigned DecryptLength(std::span<const std::byte> input) noexcept;
unsigned DecryptLength(std::span<const std::byte, LENGTH_LEN> input) noexcept;

/** Decrypt a packet. Only after Initialize().
*
Expand Down
24 changes: 10 additions & 14 deletions src/common/pcp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,8 @@ std::string PCPResultString(uint8_t result_code)
}

//! Wrap address in IPv6 according to RFC6887. wrapped_addr needs to be able to store 16 bytes.
[[nodiscard]] bool PCPWrapAddress(std::span<uint8_t> wrapped_addr, const CNetAddr &addr)
[[nodiscard]] bool PCPWrapAddress(std::span<uint8_t, ADDR_IPV6_SIZE> wrapped_addr, const CNetAddr &addr)
{
Assume(wrapped_addr.size() == ADDR_IPV6_SIZE);
if (addr.IsIPv4()) {
struct in_addr addr4;
if (!addr.GetInAddr(&addr4)) return false;
Expand Down Expand Up @@ -434,25 +433,22 @@ std::variant<MappingResult, MappingError> PCPRequestPortMap(const PCPMappingNonc
// Make sure there's space for the request header and MAP specific request data.
std::vector<uint8_t> request(PCP_HDR_SIZE + PCP_MAP_SIZE);
// Fill in request header, See RFC6887 Figure 2.
size_t ofs = 0;
request[ofs + PCP_HDR_VERSION_OFS] = PCP_VERSION;
request[ofs + PCP_HDR_OP_OFS] = PCP_REQUEST | PCP_OP_MAP;
WriteBE32(request.data() + ofs + PCP_HDR_LIFETIME_OFS, lifetime);
if (!PCPWrapAddress(std::span(request).subspan(ofs + PCP_REQUEST_HDR_IP_OFS, ADDR_IPV6_SIZE), internal)) return MappingError::NETWORK_ERROR;

ofs += PCP_HDR_SIZE;
request[PCP_HDR_VERSION_OFS] = PCP_VERSION;
request[PCP_HDR_OP_OFS] = PCP_REQUEST | PCP_OP_MAP;
WriteBE32(request.data() + PCP_HDR_LIFETIME_OFS, lifetime);
if (!PCPWrapAddress(std::span(request).subspan<PCP_REQUEST_HDR_IP_OFS, ADDR_IPV6_SIZE>(), internal)) return MappingError::NETWORK_ERROR;

// Fill in MAP request packet, See RFC6887 Figure 9.
// Randomize mapping nonce (this is repeated in the response, to be able to
// correlate requests and responses, and used to authenticate changes to the mapping).
constexpr size_t ofs = PCP_HDR_SIZE;
std::memcpy(request.data() + ofs + PCP_MAP_NONCE_OFS, nonce.data(), PCP_MAP_NONCE_SIZE);
request[ofs + PCP_MAP_PROTOCOL_OFS] = PCP_PROTOCOL_TCP;
WriteBE16(request.data() + ofs + PCP_MAP_INTERNAL_PORT_OFS, port);
WriteBE16(request.data() + ofs + PCP_MAP_EXTERNAL_PORT_OFS, port);
if (!PCPWrapAddress(std::span(request).subspan(ofs + PCP_MAP_EXTERNAL_IP_OFS, ADDR_IPV6_SIZE), bind)) return MappingError::NETWORK_ERROR;
if (!PCPWrapAddress(std::span(request).subspan<PCP_MAP_EXTERNAL_IP_OFS, ADDR_IPV6_SIZE>(), bind)) return MappingError::NETWORK_ERROR;

ofs += PCP_MAP_SIZE;
Assume(ofs == request.size());
Assume(ofs + PCP_MAP_SIZE == request.size());

// Receive loop.
bool is_natpmp = false;
Expand All @@ -477,8 +473,8 @@ std::variant<MappingResult, MappingError> PCPRequestPortMap(const PCPMappingNonc
LogPrintLevel(BCLog::NET, BCLog::Level::Warning, "pcp: Mapping nonce mismatch\n");
return false; // Wasn't response to what we expected, try receiving next packet.
}
uint8_t protocol = response[PCP_HDR_SIZE + 12];
uint16_t internal_port = ReadBE16(response.data() + PCP_HDR_SIZE + 16);
uint8_t protocol = response[PCP_HDR_SIZE + PCP_MAP_PROTOCOL_OFS];
uint16_t internal_port = ReadBE16(response.data() + PCP_HDR_SIZE + PCP_MAP_INTERNAL_PORT_OFS);
if (protocol != PCP_PROTOCOL_TCP || internal_port != port) {
LogPrintLevel(BCLog::NET, BCLog::Level::Warning, "pcp: Response protocol or port doesn't match request\n");
return false; // Wasn't response to what we expected, try receiving next packet.
Expand Down
10 changes: 4 additions & 6 deletions src/crypto/chacha20.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@

#define REPEAT10(a) do { {a}; {a}; {a}; {a}; {a}; {a}; {a}; {a}; {a}; {a}; } while(0)

void ChaCha20Aligned::SetKey(std::span<const std::byte> key) noexcept
void ChaCha20Aligned::SetKey(std::span<const std::byte, KEYLEN> key) noexcept
{
assert(key.size() == KEYLEN);
input[0] = ReadLE32(key.data() + 0);
input[1] = ReadLE32(key.data() + 4);
input[2] = ReadLE32(key.data() + 8);
Expand All @@ -44,7 +43,7 @@ ChaCha20Aligned::~ChaCha20Aligned()
memory_cleanse(input, sizeof(input));
}

ChaCha20Aligned::ChaCha20Aligned(std::span<const std::byte> key) noexcept
ChaCha20Aligned::ChaCha20Aligned(std::span<const std::byte, KEYLEN> key) noexcept
{
SetKey(key);
}
Expand Down Expand Up @@ -334,17 +333,16 @@ ChaCha20::~ChaCha20()
memory_cleanse(m_buffer.data(), m_buffer.size());
}

void ChaCha20::SetKey(std::span<const std::byte> key) noexcept
void ChaCha20::SetKey(std::span<const std::byte, KEYLEN> key) noexcept
{
m_aligned.SetKey(key);
m_bufleft = 0;
memory_cleanse(m_buffer.data(), m_buffer.size());
}

FSChaCha20::FSChaCha20(std::span<const std::byte> key, uint32_t rekey_interval) noexcept :
FSChaCha20::FSChaCha20(std::span<const std::byte, KEYLEN> key, uint32_t rekey_interval) noexcept :
m_chacha20(key), m_rekey_interval(rekey_interval)
{
assert(key.size() == KEYLEN);
}

void FSChaCha20::Crypt(std::span<const std::byte> input, std::span<std::byte> output) noexcept
Expand Down
10 changes: 5 additions & 5 deletions src/crypto/chacha20.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ class ChaCha20Aligned
ChaCha20Aligned() noexcept = delete;

/** Initialize a cipher with specified 32-byte key. */
ChaCha20Aligned(std::span<const std::byte> key) noexcept;
ChaCha20Aligned(std::span<const std::byte, KEYLEN> key) noexcept;

/** Destructor to clean up private memory. */
~ChaCha20Aligned();

/** Set 32-byte key, and seek to nonce 0 and block position 0. */
void SetKey(std::span<const std::byte> key) noexcept;
void SetKey(std::span<const std::byte, KEYLEN> key) noexcept;

/** Type for 96-bit nonces used by the Set function below.
*
Expand Down Expand Up @@ -89,13 +89,13 @@ class ChaCha20
ChaCha20() noexcept = delete;

/** Initialize a cipher with specified 32-byte key. */
ChaCha20(std::span<const std::byte> key) noexcept : m_aligned(key) {}
ChaCha20(std::span<const std::byte, KEYLEN> key) noexcept : m_aligned(key) {}

/** Destructor to clean up private memory. */
~ChaCha20();

/** Set 32-byte key, and seek to nonce 0 and block position 0. */
void SetKey(std::span<const std::byte> key) noexcept;
void SetKey(std::span<const std::byte, KEYLEN> key) noexcept;

/** 96-bit nonce type. */
using Nonce96 = ChaCha20Aligned::Nonce96;
Expand Down Expand Up @@ -150,7 +150,7 @@ class FSChaCha20
FSChaCha20& operator=(FSChaCha20&&) = delete;

/** Construct an FSChaCha20 cipher that rekeys every rekey_interval Crypt() calls. */
FSChaCha20(std::span<const std::byte> key, uint32_t rekey_interval) noexcept;
FSChaCha20(std::span<const std::byte, KEYLEN> key, uint32_t rekey_interval) noexcept;

/** Encrypt or decrypt a chunk. */
void Crypt(std::span<const std::byte> input, std::span<std::byte> output) noexcept;
Expand Down
14 changes: 6 additions & 8 deletions src/crypto/chacha20poly1305.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,12 @@
#include <assert.h>
#include <cstddef>

AEADChaCha20Poly1305::AEADChaCha20Poly1305(std::span<const std::byte> key) noexcept : m_chacha20(key)
AEADChaCha20Poly1305::AEADChaCha20Poly1305(std::span<const std::byte, KEYLEN> key) noexcept : m_chacha20(key)
{
assert(key.size() == KEYLEN);
}

void AEADChaCha20Poly1305::SetKey(std::span<const std::byte> key) noexcept
void AEADChaCha20Poly1305::SetKey(std::span<const std::byte, KEYLEN> key) noexcept
{
assert(key.size() == KEYLEN);
m_chacha20.SetKey(key);
}

Expand All @@ -36,7 +34,7 @@ int timingsafe_bcmp_internal(const unsigned char* b1, const unsigned char* b2, s
}

/** Compute poly1305 tag. chacha20 must be set to the right nonce, block 0. Will be at block 1 after. */
void ComputeTag(ChaCha20& chacha20, std::span<const std::byte> aad, std::span<const std::byte> cipher, std::span<std::byte> tag) noexcept
void ComputeTag(ChaCha20& chacha20, std::span<const std::byte> aad, std::span<const std::byte> cipher, std::span<std::byte, Poly1305::TAGLEN> tag) noexcept
{
static const std::byte PADDING[16] = {{}};

Expand All @@ -45,7 +43,7 @@ void ComputeTag(ChaCha20& chacha20, std::span<const std::byte> aad, std::span<co
chacha20.Keystream(first_block);

// Use the first 32 bytes of the first keystream block as poly1305 key.
Poly1305 poly1305{std::span{first_block}.first(Poly1305::KEYLEN)};
Poly1305 poly1305{std::span{first_block}.first<Poly1305::KEYLEN>()};

// Compute tag:
// - Process the padded AAD with Poly1305.
Expand Down Expand Up @@ -77,7 +75,7 @@ void AEADChaCha20Poly1305::Encrypt(std::span<const std::byte> plain1, std::span<

// Seek to block 0, and compute tag using key drawn from there.
m_chacha20.Seek(nonce, 0);
ComputeTag(m_chacha20, aad, cipher.first(cipher.size() - EXPANSION), cipher.last(EXPANSION));
ComputeTag(m_chacha20, aad, cipher.first(cipher.size() - EXPANSION), cipher.last<EXPANSION>());
}

bool AEADChaCha20Poly1305::Decrypt(std::span<const std::byte> cipher, std::span<const std::byte> aad, Nonce96 nonce, std::span<std::byte> plain1, std::span<std::byte> plain2) noexcept
Expand Down Expand Up @@ -111,7 +109,7 @@ void FSChaCha20Poly1305::NextPacket() noexcept
std::byte one_block[ChaCha20Aligned::BLOCKLEN];
m_aead.Keystream({0xFFFFFFFF, m_rekey_counter}, one_block);
// Switch keys.
m_aead.SetKey(std::span{one_block}.first(KEYLEN));
m_aead.SetKey(std::span{one_block}.first<KEYLEN>());
// Wipe the generated keystream (a copy remains inside m_aead, which will be cleaned up
// once it cycles again, or is destroyed).
memory_cleanse(one_block, sizeof(one_block));
Expand Down
6 changes: 3 additions & 3 deletions src/crypto/chacha20poly1305.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ class AEADChaCha20Poly1305
static constexpr unsigned EXPANSION = Poly1305::TAGLEN;

/** Initialize an AEAD instance with a specified 32-byte key. */
AEADChaCha20Poly1305(std::span<const std::byte> key) noexcept;
AEADChaCha20Poly1305(std::span<const std::byte, KEYLEN> key) noexcept;

/** Switch to another 32-byte key. */
void SetKey(std::span<const std::byte> key) noexcept;
void SetKey(std::span<const std::byte, KEYLEN> key) noexcept;

/** 96-bit nonce type. */
using Nonce96 = ChaCha20::Nonce96;
Expand Down Expand Up @@ -111,7 +111,7 @@ class FSChaCha20Poly1305
FSChaCha20Poly1305& operator=(FSChaCha20Poly1305&&) = delete;

/** Construct an FSChaCha20Poly1305 cipher that rekeys every rekey_interval operations. */
FSChaCha20Poly1305(std::span<const std::byte> key, uint32_t rekey_interval) noexcept :
FSChaCha20Poly1305(std::span<const std::byte, KEYLEN> key, uint32_t rekey_interval) noexcept :
m_aead(key), m_rekey_interval(rekey_interval) {}

/** Encrypt a message with a specified aad.
Expand Down
2 changes: 1 addition & 1 deletion src/crypto/hkdf_sha256_32.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class CHKDF_HMAC_SHA256_L32
{
private:
unsigned char m_prk[32];
static const size_t OUTPUT_SIZE = 32;
static constexpr size_t OUTPUT_SIZE = 32;

public:
CHKDF_HMAC_SHA256_L32(const unsigned char* ikm, size_t ikmlen, const std::string& salt);
Expand Down
2 changes: 1 addition & 1 deletion src/crypto/hmac_sha256.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class CHMAC_SHA256
CSHA256 inner;

public:
static const size_t OUTPUT_SIZE = 32;
static constexpr size_t OUTPUT_SIZE = 32;

CHMAC_SHA256(const unsigned char* key, size_t keylen);
CHMAC_SHA256& Write(const unsigned char* data, size_t len)
Expand Down
2 changes: 1 addition & 1 deletion src/crypto/hmac_sha512.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class CHMAC_SHA512
CSHA512 inner;

public:
static const size_t OUTPUT_SIZE = 64;
static constexpr size_t OUTPUT_SIZE = 64;

CHMAC_SHA512(const unsigned char* key, size_t keylen);
CHMAC_SHA512& Write(const unsigned char* data, size_t len)
Expand Down
6 changes: 2 additions & 4 deletions src/crypto/poly1305.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,8 @@ class Poly1305
static constexpr unsigned KEYLEN{32};

/** Construct a Poly1305 object with a given 32-byte key. */
Poly1305(std::span<const std::byte> key) noexcept
Poly1305(std::span<const std::byte, KEYLEN> key) noexcept
{
assert(key.size() == KEYLEN);
poly1305_donna::poly1305_init(&m_ctx, UCharCast(key.data()));
}

Expand All @@ -60,9 +59,8 @@ class Poly1305
}

/** Write authentication tag to 16-byte out. */
void Finalize(std::span<std::byte> out) noexcept
void Finalize(std::span<std::byte, TAGLEN> out) noexcept
{
assert(out.size() == TAGLEN);
poly1305_donna::poly1305_finish(&m_ctx, UCharCast(out.data()));
}
};
Expand Down
2 changes: 1 addition & 1 deletion src/crypto/ripemd160.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class CRIPEMD160
uint64_t bytes{0};

public:
static const size_t OUTPUT_SIZE = 20;
static constexpr size_t OUTPUT_SIZE = 20;

CRIPEMD160();
CRIPEMD160& Write(const unsigned char* data, size_t len);
Expand Down
2 changes: 1 addition & 1 deletion src/crypto/sha1.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class CSHA1
uint64_t bytes{0};

public:
static const size_t OUTPUT_SIZE = 20;
static constexpr size_t OUTPUT_SIZE = 20;

CSHA1();
CSHA1& Write(const unsigned char* data, size_t len);
Expand Down
2 changes: 1 addition & 1 deletion src/crypto/sha256.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class CSHA256
uint64_t bytes{0};

public:
static const size_t OUTPUT_SIZE = 32;
static constexpr size_t OUTPUT_SIZE = 32;

CSHA256();
CSHA256& Write(const unsigned char* data, size_t len);
Expand Down
3 changes: 1 addition & 2 deletions src/crypto/sha3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,8 @@ SHA3_256& SHA3_256::Write(std::span<const unsigned char> data)
return *this;
}

SHA3_256& SHA3_256::Finalize(std::span<unsigned char> output)
SHA3_256& SHA3_256::Finalize(std::span<unsigned char, OUTPUT_SIZE> output)
{
assert(output.size() == OUTPUT_SIZE);
std::fill(m_buffer + m_bufsize, m_buffer + sizeof(m_buffer), 0);
m_buffer[m_bufsize] ^= 0x06;
m_state[m_pos] ^= ReadLE64(m_buffer);
Expand Down
2 changes: 1 addition & 1 deletion src/crypto/sha3.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class SHA3_256

SHA3_256() = default;
SHA3_256& Write(std::span<const unsigned char> data);
SHA3_256& Finalize(std::span<unsigned char> output);
SHA3_256& Finalize(std::span<unsigned char, OUTPUT_SIZE> output);
SHA3_256& Reset();
};

Expand Down
10 changes: 4 additions & 6 deletions src/hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,9 @@ class CHash256 {
private:
CSHA256 sha;
public:
static const size_t OUTPUT_SIZE = CSHA256::OUTPUT_SIZE;
static constexpr size_t OUTPUT_SIZE = CSHA256::OUTPUT_SIZE;

void Finalize(std::span<unsigned char> output) {
assert(output.size() == OUTPUT_SIZE);
void Finalize(std::span<unsigned char, OUTPUT_SIZE> output) {
unsigned char buf[CSHA256::OUTPUT_SIZE];
sha.Finalize(buf);
sha.Reset().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(output.data());
Expand All @@ -50,10 +49,9 @@ class CHash160 {
private:
CSHA256 sha;
public:
static const size_t OUTPUT_SIZE = CRIPEMD160::OUTPUT_SIZE;
static constexpr size_t OUTPUT_SIZE = CRIPEMD160::OUTPUT_SIZE;

void Finalize(std::span<unsigned char> output) {
assert(output.size() == OUTPUT_SIZE);
void Finalize(std::span<unsigned char, OUTPUT_SIZE> output) {
unsigned char buf[CSHA256::OUTPUT_SIZE];
sha.Finalize(buf);
CRIPEMD160().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(output.data());
Expand Down
Loading
Loading