Cryptographic Operations

Application-Wide Policy

Application::cryptologyConfiguration() lazily constructs the process-wide CryptologyConfiguration. Its storage belongs to the shared application data, so applications connected with Application::linkWith() observe the same configuration across module and DLL boundaries. Configuration access and changes are thread-safe, and list or recommendation operations use one coherent snapshot.

setHardwareAccelerationEnabled(false) is an operational escape hatch for deployments where a compiled accelerated backend fails on the installed platform. Configure it during early startup, before constructing cryptographic workers. The flag permits automatic backend selection when enabled; it does not claim that hardware support is present. Changes apply only to subsequently constructed workers.

setMaximumStatus() sets a downgrade-only ceiling for an individual hash algorithm or symmetric encryption type. The effective selector status is the less permissive of library policy and this ceiling, so configuration cannot promote a Legacy or Disallowed algorithm. clearMaximumStatus() removes one ceiling and reset() restores all defaults. Policy changes affect selector results, not explicit hashing, encryption, or decryption required for existing data.

Cryptographic Hashing

HashAlgorithm describes a fixed-output hash and its current intrinsic metadata. Hasher calculates a digest incrementally with copy-on-write state.

Algorithm Selection

HashRequirements combines status, security, and throughput requirements for selecting a HashAlgorithm. HashSelector applies these requirements to one coherent snapshot of the application-wide cryptology policy. Its status(), isSafe(), allAccepted(), matching(), and recommended() operations always observe the current policy. Configured status limits are ceilings: they can downgrade an algorithm, but never promote a library status. Explicit Hasher construction remains available for protocols and migration work even when selection policy disallows the algorithm. See Using Hash Algorithms for selection and persistence workflows and Supported Hash Algorithms for the algorithm catalog and current safety guidance.

Hashing Data

Hasher accepts text or byte data in one or more updates and returns a ByteBlock digest. Binary updates use ConstByteSpan or an owning byte block. Standard byte, unsigned-byte, and character spans can cross that boundary without copying through mem::toConstByteSpan(); no public std::span<const std::byte> overload is provided. secureErase() wipes uniquely owned message-dependent state and restores a fresh state for the same algorithm. For shared copy-on-write state, it installs a fresh worker without copying secret state and leaves copied hashers unchanged. An invalid placeholder treats secure erasure as a no-op. See Using Hash Algorithms for lifecycle, representation, storage, and defensive-input guidance.

Message Authentication and Key Derivation

Hmac implements streaming HMAC with SHA-256 or SHA-384. Hkdf implements the generic RFC 5869 extract and expand operations for the same hash algorithms.

Message Authentication

An HMAC state retains secret key material and is therefore move-only. It accepts segmented bytes or the exact stored UTF-8 bytes of a string, caches the complete authenticator after finalization, and can reset to authenticate another message with the same key. verify() accepts only a complete hash-sized authenticator; equal-length values are compared without content-dependent short-circuiting. secureErase() immediately erases retained keyed and message-dependent state and leaves an invalid placeholder.

Key Derivation

An HKDF value stores only its selected hash algorithm. extract() returns a digest-sized pseudorandom key and expand() returns the requested output keying material. Every non-empty result uses sensitive storage that is securely erased when its final shared reference is released. An empty salt follows RFC 5869 and acts as a digest-sized all-zero salt. The shared-secret overload accepts a KeyAgreementSharedSecret and performs extraction through scoped plaintext access. Expansion requires a pseudorandom key at least as long as the digest and accepts at most 255 digest blocks: 8,160 bytes for SHA-256 or 12,240 bytes for SHA-384.

Symmetric Encryption

SymmetricEncryptionType identifies a complete symmetric encryption construction and describes its key, nonce, initialization-vector, tag, and output-length requirements. SymmetricEncryptor and SymmetricDecryptor are move-only facades for incremental processing.

Algorithm Selection

The accepted constructions for new data are aes-256-gcm, chacha20-poly1305, and aes-128-gcm. The default recommendation is aes-256-gcm. Use SymmetricEncryptionSelector to enumerate or recommend constructions using the current application-wide policy. The SymmetricEncryptionRequirements type can filter choices by status, minimum security, cipher family, and authenticated-encryption support. The selector preserves the preference order AES-256-GCM, ChaCha20-Poly1305, AES-128-GCM, then the legacy constructions. Configured status limits are downgrade-only ceilings and do not disable explicit construction for existing protocols.

Call SymmetricEncryptionType::maximumEncryptedLength() before processing to reserve a predictable output container size. The result includes CBC alignment and padding, but excludes a separately transported AEAD tag.

Authenticated Encryption

Add all authenticated associated data before the first non-empty payload part. Encryption returns the authentication tag separately after successful finalization. AEAD decryption can return plaintext incrementally, but that plaintext is unauthenticated and unsafe to consume, parse, display, or otherwise act upon until finalize(tag) succeeds. Discard every previously returned plaintext byte if authentication fails.

AES-GCM uses a fixed 96-bit nonce and a full 128-bit authentication tag. A nonce must be unique for every message encrypted under the same key; nonce reuse destroys GCM’s confidentiality and authentication guarantees. A single message accepts at most \(2^{36} - 32\) payload bytes and \(2^{61} - 1\) byte-aligned authenticated-data bytes, as constrained by NIST SP 800-38D.

ChaCha20-Poly1305 implements the IETF construction from RFC 8439 with a 256-bit key, fixed 96-bit nonce, and full 128-bit tag. It uses counter zero only to derive the Poly1305 one-time key and counters one through \(2^{32} - 1\) for payload. Consequently, one message accepts at most \((2^{32} - 1) \times 64\) payload bytes. As with AES-GCM, a nonce must never be reused with the same key.

Legacy Fast File Encryption Compatibility

The two AES-256-CBC constructions exist only for compatibility with Fast File Encryption data. They are marked Legacy, provide no authentication or integrity protection, and must not be used for new formats or projects. They deliberately remain separate types because their final-block behavior is incompatible. Their 16-byte IV must be unpredictable and unique for encryption under a given key. An IV is not secret, but changing it changes the first plaintext block during decryption. These constructions therefore require an independently authenticated container when integrity matters.

Random-Fill Padding

aes-256-cbc-random-fill implements the known-size Fast File Encryption mode. If the plaintext length is not a multiple of the 16-byte AES block size, encryption appends unpredictable random bytes until the final block is full. If the plaintext is already block-aligned, encryption appends no bytes; empty plaintext therefore remains empty. This is a non-standard, non-reversible fill scheme: ciphertext contains no indication of how many random bytes were added. Decryption consequently retains the random fill, and the container format must store the exact original plaintext length separately so the caller can crop the decrypted result.

ISO/IEC 9797-1 Method 2 Padding

aes-256-cbc-iso9797-method2 implements the chunked-stream Fast File Encryption mode. Encryption always appends one 0x80 marker byte followed by enough zero bytes to reach the next 16-byte boundary. An aligned or empty plaintext therefore gains one complete block. Decryption validates and removes this marker-and-zero suffix, making the padding reversible without an externally stored plaintext length.

Sensitive State and Erasure

SymmetricKey does not expose its bytes through the public API. Keys, tags, nonces, initialization vectors, and decrypted output use sensitive-marked storage. Call secureErase() when encryption or decryption work ends to erase retained key material and backend state immediately. The call leaves the facade in the same empty state as default construction; create or assign a new encryptor or decryptor before another operation.

Backend Availability

AES uses automatic, independent backend selection for block encryption and GHASH multiplication. The portable fallback uses fixed-iteration GF(28 ) arithmetic for the AES S-box and fixed-iteration GF(2128 ) multiplication for GHASH, without secret-indexed tables. On supported x86-64 processors the implementation uses AES-NI and PCLMULQDQ; on supported ARM64 processors it uses the Arm AES and PMULL instructions. If only one acceleration feature is available, the other operation remains on its portable implementation.

ChaCha20 and Poly1305 are independently dispatched. The portable ChaCha20 backend is scalar, and portable Poly1305 uses five 26-bit limbs with 64-bit products and no __int128 dependency. x86-64 uses SSE2 and ARM64 uses NEON for four-block batches, with scalar handling for short inputs and tails.

Architecture-specific backends are permission-based rather than a claim that every compiled instruction will work in the deployed environment. Set application().cryptologyConfiguration().setHardwareAccelerationEnabled(false) during early application startup to force portable AES, GHASH, ChaCha20, and Poly1305 backends. The change affects workers constructed afterwards; existing workers retain the backend with which they were created.

The implementation is designed to avoid secret-indexed memory access and data-dependent branches in its portable cryptographic primitives. This is a side-channel design goal, not a formal guarantee that an entire application, compiler, operating system, or hardware platform behaves in constant time.

The implemented constructions follow FIPS 197 for AES, NIST SP 800-38A for CBC, NIST SP 800-38D for GCM, and RFC 8439 for ChaCha20-Poly1305.

ChaCha20-Poly1305 Specification Mapping

The implementation deliberately keeps the RFC stages visible for security review:

  • RFC 8439 Section 2.1 maps to ChaCha20Operations quarter-round code and the ChaCha20PrimitiveTest known-answer test.

  • Sections 2.3 and 2.4 map to scalar and four-block ChaCha20Backend implementations, verified by block vectors and ChaCha20BackendFullTest differential tests.

  • Section 2.5 maps to PortablePoly1305 clamping, accumulation, reduction, and tag generation, with architecture kernels checked against it.

  • Section 2.6 maps to the counter-zero one-time-key step in ChaCha20Poly1305State and its RFC vector test.

  • Section 2.8 maps to shared AAD framing, padding, length serialization, counter advancement, and encryptor/decryptor workers, tested by RFC vectors, boundary tests, tamper tests, and the 325 pinned Wycheproof cases.

Specifications

Interface

class CryptologyConfiguration

Application-wide administrative limits for cryptographic algorithm selection and backend acceleration.

Status limits can only reduce the effective library policy. They never prevent explicit primitive use. Call core::application().cryptologyConfiguration() to access the shared instance.

See: Cryptographic Operations

Public Functions

CryptologyConfiguration()

Create the default configuration.

~CryptologyConfiguration()

Destroy this cryptology configuration.

bool hardwareAccelerationEnabled() const

Test whether architecture-specific cryptographic backends may be selected.

void setHardwareAccelerationEnabled(bool enabled)

Permit or prohibit architecture-specific cryptographic backends for subsequently created workers.

std::optional<CryptographicStatus> maximumStatus(HashAlgorithm algorithm) const

Get the administrative maximum status for a hash algorithm.

Parameters:

algorithm – The algorithm to inspect.

Throws:

err::ParameterError – If algorithm is invalid.

Returns:

The configured limit, or no value if no limit is configured.

void setMaximumStatus(HashAlgorithm algorithm, CryptographicStatus status)

Set an administrative maximum status for a hash algorithm.

Parameters:
  • algorithm – The algorithm to limit.

  • status – The highest status permitted by the application policy.

Throws:

err::ParameterError – If either value is invalid.

void clearMaximumStatus(HashAlgorithm algorithm)

Clear the administrative maximum status for a hash algorithm.

Parameters:

algorithm – The algorithm whose limit is cleared.

Throws:

err::ParameterError – If algorithm is invalid.

std::optional<CryptographicStatus> maximumStatus(SymmetricEncryptionType type) const

Get the administrative maximum status for a symmetric encryption type.

Parameters:

type – The encryption type to inspect.

Throws:

err::ParameterError – If type is invalid.

Returns:

The configured limit, or no value if no limit is configured.

void setMaximumStatus(SymmetricEncryptionType type, CryptographicStatus status)

Set an administrative maximum status for a symmetric encryption type.

Parameters:
  • type – The encryption type to limit.

  • status – The highest status permitted by the application policy.

Throws:

err::ParameterError – If either value is invalid.

void clearMaximumStatus(SymmetricEncryptionType type)

Clear the administrative maximum status for a symmetric encryption type.

Parameters:

type – The encryption type whose limit is cleared.

Throws:

err::ParameterError – If type is invalid.

ProtectedDataMode protectedDataMode() const

Get the configured protected-data provider selection mode.

void setProtectedDataMode(ProtectedDataMode mode)

Select protected-data provider initialization behavior.

Parameters:

mode – The provider selection mode.

Throws:
  • err::ParameterError – If mode is invalid.

  • err::LogicError – If a different mode is selected after provider initialization.

void validateProtectedDataSupport()

Initialize and self-test protected-data support at an explicit application startup point.

Throws:

CryptologyError – If the selected provider cannot be initialized or fails its self-test.

void setTlsConfiguration(const text::String &label, TlsConfiguration configuration)

Atomically register or replace one TLS configuration.

Parameters:
  • label – The exact hierarchical label, or an empty label for the global default.

  • configuration – The configuration copied into a new immutable registry entry.

Throws:
void clearTlsConfiguration(const text::String &label)

Remove one exact TLS configuration label.

Parameters:

label – The exact hierarchical label, or the empty global-default label.

Throws:

err::ParameterError – If the label is invalid.

void clearTlsConfigurations()

Remove every registered TLS configuration.

bool hasTlsConfiguration(const text::String &label) const

Test whether one exact TLS configuration label is registered.

Parent fallbacks are intentionally not considered.

Parameters:

label – The exact hierarchical label, or the empty global-default label.

Throws:

err::ParameterError – If the label is invalid.

Returns:

true if the exact label is registered.

TlsConfigurationResolution resolveTlsConfiguration(const text::String &label) const

Resolve a label to one complete immutable TLS configuration.

Resolution removes trailing slash-delimited segments and finally tries the empty global-default label.

Parameters:

label – The exact or descendant label to resolve.

Throws:
Returns:

The requested label, matched label, and immutable selected entry.

void reset()

Restore acceleration permission and clear status limits and registered TLS configurations.

Public Static Attributes

static constexpr auto cMaximumTlsConfigurations = std::size_t{256U}

Maximum number of exact labels in the application-wide TLS registry.

static constexpr auto cMaximumTlsConfigurationLabelLength = impl::tls_configuration_label::cMaximumLength

Maximum byte length of a TLS configuration label.

static constexpr auto cMaximumTlsConfigurationLabelSegments = impl::tls_configuration_label::cMaximumSegments

Maximum number of slash-delimited segments in a non-empty TLS configuration label.

enum class erbsland::cryptology::CryptographicSecurity : uint8_t

A coarse security level for selecting cryptographic algorithms.

The values describe relative library policy and do not promise safety for a particular time horizon.

See: Cryptographic Operations

Values:

enumerator Standard

The standard security level for general-purpose use.

enumerator High

A larger security margin for high-value or long-lived results.

enum class erbsland::cryptology::CryptographicStatus : uint8_t

The current usability status of a cryptographic algorithm.

This status is library policy and can change between releases as cryptographic guidance evolves.

See: Cryptographic Operations

Values:

enumerator Disallowed

Known to be unsuitable for cryptographic use.

enumerator Legacy

Available only for processing or migrating existing data.

enumerator Acceptable

Suitable for creating new cryptographic results.

class CryptologyError : public erbsland::err::RuntimeError

An error reported by a cryptographic operation or backend.

class HashAlgorithm

A fixed-output cryptographic hash algorithm supported by the library.

Algorithm metadata is library policy and can change between releases. Persisted data and protocols must store toString() for the selected algorithm instead of relying on a future recommendation returning the same value.

See: Cryptographic Operations

Public Types

enum Value

The raw hash algorithm value.

Values:

enumerator Sha3_256

SHA3-256 with a 256-bit digest.

enumerator Sha3_384

SHA3-384 with a 384-bit digest.

enumerator Sha3_512

SHA3-512 with a 512-bit digest.

enumerator Sha2_256

SHA-256 from the SHA-2 family.

enumerator Sha2_384

SHA-384 from the SHA-2 family.

enumerator Sha2_512

SHA-512 from the SHA-2 family.

enumerator Sha1

Legacy SHA-1, disallowed for new cryptographic results.

enumerator Md5

Legacy MD5, disallowed for new cryptographic results.

Public Functions

constexpr HashAlgorithm() noexcept = default

Create the default SHA3-256 algorithm.

inline constexpr HashAlgorithm(const Value value) noexcept

Create an algorithm from its raw value.

Parameters:

value – The raw algorithm value.

inline constexpr Value toRawValue() const noexcept

Get the raw algorithm value.

unit::ByteLength digestSize() const noexcept

Get the length of the generated digest.

CryptographicSecurity security() const noexcept

Get the current coarse security level.

HashThroughput throughput() const noexcept

Get the relative throughput of the bundled implementation.

text::String toString() const

Convert the algorithm to its stable lowercase identifier.

Public Static Functions

static std::optional<HashAlgorithm> fromString(const text::String &text) noexcept

Parse an exact lowercase algorithm identifier.

Parameters:

text – The identifier to parse.

Returns:

The matching algorithm, or no value for unsupported text.

static HashAlgorithm fromStringOrThrow(const text::String &text)

Parse an exact lowercase algorithm identifier.

Parameters:

text – The identifier to parse.

Throws:

err::ParseError – If text is not a supported algorithm identifier.

Returns:

The matching algorithm.

static std::span<const HashAlgorithm> all() noexcept

Get all supported hash algorithms in stable preference order.

class Hasher

A state object for calculating a fixed-output cryptographic hash.

A default-constructed hasher is invalid and acts as a placeholder. Copies use copy-on-write state: they initially share a worker and detach before mutation. After finalization, the cached digest remains available until reset(); calling update() before resetting is a logic error.

See: Cryptographic Operations

Public Functions

Hasher() noexcept = default

Create an invalid placeholder.

explicit Hasher(HashAlgorithm algorithm)

Create a hasher for an algorithm.

Parameters:

algorithm – The fixed-output hash algorithm.

Hasher &operator=(const Hasher&)

Copy another hasher into this hasher.

Hasher &operator=(Hasher&&) noexcept

Move another hasher into this hasher.

void reset()

Reset the worker to hash a new stream with the same algorithm.

Throws:

err::LogicError – If this hasher is invalid.

void secureErase()

Securely erase message-dependent state and reset this hasher.

void update(mem::ConstByteSpan data)

Add Erbsland Core byte data.

Empty spans are accepted.

Parameters:

data – The next exact message bytes.

Throws:

err::LogicError – If this hasher is invalid or already finalized.

void update(const mem::ByteBlock &data)

Add a byte block.

Parameters:

data – The next exact message bytes.

Throws:

err::LogicError – If this hasher is invalid or already finalized.

void update(const text::String &text)

Add the exact bytes in a UTF-8 string’s internal buffer.

No validation, normalization, byte order mark, or encoding conversion is performed.

Parameters:

text – The UTF-8 text whose stored bytes are added.

Throws:

err::LogicError – If this hasher is invalid or already finalized.

mem::ByteBlock finalize()

Finalize the current stream and return its digest.

Repeated calls return the cached digest.

Throws:

err::LogicError – If this hasher is invalid.

Returns:

The fixed-size digest.

bool isValid() const noexcept

Test if this hasher has an algorithm and worker state.

HashAlgorithm algorithm() const

Get the configured algorithm.

Throws:

err::LogicError – If this hasher is invalid.

struct HashRequirements

Requirements for selecting a hash algorithm.

The defaults request an acceptable general-purpose algorithm without imposing a throughput minimum.

See: Cryptographic Operations

Public Members

CryptographicStatus requiredStatus = {CryptographicStatus::Acceptable}

The exact required status.

CryptographicSecurity minimumSecurity = {CryptographicSecurity::Standard}

The minimum security level.

HashThroughput minimumThroughput = {HashThroughput::Low}

The minimum relative hash throughput.

class HashSelector

Select hash algorithms using requirements and the live application-wide cryptology policy.

Each operation uses one coherent configuration snapshot. Explicit Hasher construction is unaffected by policy.

See: Cryptographic Operations

Public Functions

HashSelector() = default

Create a selector with the default requirements.

inline explicit HashSelector(HashRequirements requirements) noexcept

Create a selector with explicit requirements.

Parameters:

requirements – The requirements used by matches(), matching(), and recommended().

bool isSafe(HashAlgorithm algorithm) const

Test whether an algorithm is acceptable with at least standard security.

bool matches(HashAlgorithm algorithm) const

Test whether an algorithm satisfies this selector’s requirements.

inline const HashRequirements &requirements() const noexcept

Get the selector requirements.

CryptographicStatus status(HashAlgorithm algorithm) const

Get the algorithm’s effective status under the live application-wide policy.

util::List<HashAlgorithm> allAccepted() const

Get all algorithms currently acceptable with at least standard security.

util::List<HashAlgorithm> matching() const

Get all algorithms that satisfy this selector’s requirements.

std::optional<HashAlgorithm> recommended() const

Get the preferred algorithm satisfying this selector’s requirements.

Selection prefers throughput, then security, then stable declaration order.

enum class erbsland::cryptology::HashThroughput : uint8_t

The relative throughput of a fixed-output streaming hash implementation.

Values compare hashing algorithms in this library and are not comparable to key algorithms or password KDFs.

See: Cryptographic Operations

Values:

enumerator Low

The lowest relative hash throughput.

enumerator Medium

A balance between relative hash throughput and security.

enumerator High

The highest relative hash throughput.

class Hkdf

The RFC 5869 HMAC-based extract-and-expand key derivation function.

This value stores only the selected algorithm. Every non-empty result uses sensitive storage; no input keying material or pseudorandom key is retained after an operation returns. extract() implements RFC 5869 section 2.2 and expand() implements section 2.3. Specification: https://www.rfc-editor.org/rfc/rfc5869.html#section-2

See: Cryptographic Operations

Public Functions

explicit Hkdf(HashAlgorithm algorithm)

Create HKDF for SHA-256 or SHA-384.

Parameters:

algorithm – The underlying HMAC hash algorithm.

Throws:

err::ParameterError – If the algorithm is unsupported.

mem::ByteBlock extract(mem::ConstByteSpan inputKeyMaterial, mem::ConstByteSpan salt = {}) const

Extract a digest-sized pseudorandom key from input keying material.

An empty salt is interpreted as a digest-sized all-zero salt as defined by RFC 5869.

Parameters:
  • inputKeyMaterial – The source keying material.

  • salt – The optional salt bytes.

Returns:

A digest-sized pseudorandom key in sensitive storage.

mem::ByteBlock extract(const KeyAgreementSharedSecret &sharedSecret, mem::ConstByteSpan salt = {}) const

Extract a pseudorandom key from a protected key-agreement shared secret.

Parameters:
  • sharedSecret – The protected source keying material.

  • salt – The optional salt bytes.

Throws:

err::LogicError – If sharedSecret is empty.

Returns:

A digest-sized pseudorandom key in sensitive storage.

auto expand(mem::ConstByteSpan pseudoRandomKey, mem::ConstByteSpan info, unit::ByteLength outputLength) const -> mem::ByteBlock

Expand a pseudorandom key into output keying material.

Parameters:
  • pseudoRandomKey – A pseudorandom key of at least the digest size.

  • info – Optional application and context information.

  • outputLength – The requested output length, at most 255 times the digest size.

Throws:

err::ParameterError – If the key is too short or the output length exceeds the RFC limit.

Returns:

Output keying material in sensitive storage when non-empty.

inline HashAlgorithm algorithm() const noexcept

Get the configured underlying hash algorithm.

class Hmac

A move-only streaming RFC 2104 HMAC state for SHA-256 or SHA-384.

A default-constructed, moved-from, or securely erased instance is an invalid placeholder. The complete authenticator is cached after finalization; use reset() to authenticate another message with the same key. The construction follows RFC 2104 section 2; verification deliberately accepts only the complete hash-sized value. Specification: https://www.rfc-editor.org/rfc/rfc2104.html#section-2

See: Cryptographic Operations

Public Functions

Hmac() noexcept

Create an invalid placeholder.

Hmac(HashAlgorithm algorithm, mem::ByteBlock key)

Create keyed HMAC state, sharing and marking the key allocation as sensitive.

HMAC accepts keys of any length, although weak keys are unsuitable for secure applications.

Parameters:
  • algorithm – SHA-256 or SHA-384.

  • key – The exact secret key bytes.

Throws:

err::ParameterError – If the algorithm is unsupported.

Hmac(HashAlgorithm algorithm, mem::ConstByteSpan key)

Create keyed HMAC state by copying the key into sensitive storage.

Parameters:
  • algorithm – SHA-256 or SHA-384.

  • key – The exact secret key bytes.

Throws:

err::ParameterError – If the algorithm is unsupported.

~Hmac()

Securely erase keyed HMAC state.

Hmac &operator=(Hmac &&other) noexcept

Move keyed HMAC state into this instance, securely replacing any current state.

void reset()

Reset the message while retaining the same algorithm and key.

Throws:

err::LogicError – If this is an invalid placeholder.

void secureErase() noexcept

Securely erase the key and message state, leaving an invalid placeholder.

void update(mem::ConstByteSpan data)

Add exact message bytes.

Empty spans are accepted.

Parameters:

data – The next authenticated message bytes.

Throws:
  • err::LogicError – If this state is invalid or finalized.

  • err::ParameterError – If the hash message-length limit would be exceeded.

void update(const mem::ByteBlock &data)

Add a byte block.

Parameters:

data – The next authenticated message bytes.

Throws:
  • err::LogicError – If this state is invalid or finalized.

  • err::ParameterError – If the hash message-length limit would be exceeded.

void update(const text::String &text)

Add the exact bytes in a UTF-8 string’s internal buffer.

Parameters:

text – The UTF-8 text whose stored bytes are authenticated.

Throws:
  • err::LogicError – If this state is invalid or finalized.

  • err::ParameterError – If the hash message-length limit would be exceeded.

mem::ByteBlock finalize()

Finalize the message or return the cached complete authenticator.

Throws:

err::LogicError – If this is an invalid placeholder.

Returns:

The full hash-sized HMAC value in ordinary storage.

bool verify(mem::ConstByteSpan expected)

Verify a complete authenticator without content-dependent short-circuiting.

A length mismatch returns immediately with false.

Parameters:

expected – The expected full hash-sized authenticator.

Throws:

err::LogicError – If this is an invalid placeholder.

Returns:

true if the complete authenticator matches.

bool verify(const mem::ByteBlock &expected)

Verify a complete authenticator in an owning byte block.

Parameters:

expected – The expected full hash-sized authenticator.

Throws:

err::LogicError – If this is an invalid placeholder.

Returns:

true if the complete authenticator matches.

inline bool isValid() const noexcept

Test if keyed worker state is present.

HashAlgorithm algorithm() const

Get the underlying hash algorithm.

Throws:

err::LogicError – If this is an invalid placeholder.

class CryptographicDataBlock

Shared storage behavior for strongly typed cryptographic byte blocks.

Every non-empty allocation is permanently marked as sensitive and securely erased on final release.

See: Cryptographic Operations

Subclassed by erbsland::cryptology::SymmetricIv, erbsland::cryptology::SymmetricKey, erbsland::cryptology::SymmetricNonce, erbsland::cryptology::SymmetricTag

Public Functions

inline bool isEmpty() const noexcept

Test if no data is set.

inline unit::ByteLength byteLength() const noexcept

Get the number of bytes.

inline std::size_t bitLength() const noexcept

Get the number of bits.

enum class erbsland::cryptology::SymmetricCipher : uint8_t

A symmetric cipher family.

See: Cryptographic Operations

Values:

enumerator None

No cipher family for an invalid encryption type.

enumerator Aes

The Advanced Encryption Standard cipher family.

enumerator ChaCha20

The ChaCha20 stream cipher.

class SymmetricDecryptor

A move-only state object for streaming symmetric decryption.

A default-constructed or securely erased decryptor is an empty placeholder. AEAD plaintext returned by decrypt() is unauthenticated and must not be trusted or acted upon until finalize(tag) succeeds.

See: Cryptographic Operations

Public Functions

SymmetricDecryptor() noexcept = default

Create an empty placeholder.

SymmetricDecryptor(SymmetricEncryptionType type, const SymmetricKey &key, const SymmetricNonce &nonce)

Create an AEAD decryptor.

Parameters:
  • type – The authenticated encryption construction.

  • key – The exact-size secret key.

  • nonce – The exact-size nonce.

Throws:
  • err::ParameterError – If the type or data lengths do not match.

  • CryptologyError – If no backend is available or backend initialization fails.

SymmetricDecryptor(SymmetricEncryptionType type, const SymmetricKey &key, const SymmetricIv &iv)

Create an IV-based decryptor.

Parameters:
  • type – The unauthenticated encryption construction.

  • key – The exact-size secret key.

  • iv – The exact-size initialization vector.

Throws:
  • err::ParameterError – If the type or data lengths do not match.

  • CryptologyError – If no backend is available or backend initialization fails.

~SymmetricDecryptor()

Release the backend and securely erase retained cryptographic state.

SymmetricDecryptor &operator=(SymmetricDecryptor &&other) noexcept

Move decryption state into this instance, securely replacing any current state.

void secureErase() noexcept

Securely erase the worker, key, nonce or IV, and message state, leaving an empty placeholder.

void addAuthenticatedData(mem::ConstByteSpan data)

Add authenticated associated data.

Empty spans are accepted and do not begin payload processing.

Parameters:

data – The next associated-data bytes.

Throws:

err::LogicError – If this decryptor is empty, unauthenticated, failed, finalized, or processing payload.

void addAuthenticatedData(const mem::ByteBlock &data)

Add authenticated associated data from an owning byte block.

Parameters:

data – The next associated-data bytes.

Throws:

err::LogicError – If this decryptor is empty, unauthenticated, failed, finalized, or processing payload.

mem::ByteBlock decrypt(mem::ConstByteSpan data)

Decrypt payload bytes.

For AEAD types, returned plaintext is unauthenticated until finalize(tag) succeeds.

Parameters:

data – The next encrypted bytes.

Throws:
  • err::LogicError – If this decryptor is empty, failed, or finalized.

  • CryptologyError – If the backend rejects malformed encrypted data or otherwise fails.

Returns:

The sensitive-marked plaintext currently available.

mem::ByteBlock decrypt(const mem::ByteBlock &data)

Decrypt payload bytes from an owning byte block.

For AEAD types, returned plaintext is unauthenticated until finalize(tag) succeeds.

Parameters:

data – The next encrypted bytes.

Throws:
  • err::LogicError – If this decryptor is empty, failed, or finalized.

  • CryptologyError – If the backend rejects malformed encrypted data or otherwise fails.

Returns:

The sensitive-marked plaintext currently available.

mem::ByteBlock finalize(const SymmetricTag &tag)

Finalize and authenticate AEAD decryption.

Previously returned plaintext becomes authenticated only when this call succeeds.

Parameters:

tag – The exact-size expected authentication tag.

Throws:
  • err::ParameterError – If the tag length does not match the selected type.

  • err::LogicError – If this decryptor is unauthenticated, empty, failed, or already finalized.

  • CryptologyError – If authentication or the backend fails.

Returns:

Any sensitive-marked final plaintext output.

mem::ByteBlock finalize()

Finalize unauthenticated CBC decryption and remove padding when the selected mode defines it.

Random-fill CBC cannot remove its final fill bytes; the caller must crop the output using the externally stored original length.

Throws:
  • err::LogicError – If this decryptor is AEAD, empty, failed, or already finalized.

  • CryptologyError – If ciphertext alignment, padding, or the backend is invalid.

Returns:

Any sensitive-marked final plaintext output.

inline bool isEmpty() const noexcept

Test if no decryption worker or secret state is present.

SymmetricEncryptionType type() const

Get the configured encryption type.

Throws:

err::LogicError – If this decryptor is empty.

struct SymmetricEncryptionRequirements

Requirements for selecting a symmetric encryption type.

The defaults request an accepted authenticated type with at least standard security.

See: Cryptographic Operations

Public Members

CryptographicStatus requiredStatus = {CryptographicStatus::Acceptable}

The exact required status.

CryptographicSecurity minimumSecurity = {CryptographicSecurity::Standard}

The minimum security level.

bool requireAead = {true}

Require authenticated encryption.

std::optional<SymmetricCipher> requiredCipher

The required cipher family, if any.

class SymmetricEncryptionSelector

Select symmetric encryption constructions using requirements and the live application-wide cryptology policy.

Each operation uses one coherent configuration snapshot. Explicit encryptor and decryptor construction is unaffected.

See: Cryptographic Operations

Public Functions

SymmetricEncryptionSelector() = default

Create a selector with the default requirements.

inline explicit SymmetricEncryptionSelector(SymmetricEncryptionRequirements requirements) noexcept

Create a selector with explicit requirements.

Parameters:

requirements – The requirements used by matches(), matching(), and recommended().

bool matches(SymmetricEncryptionType type) const

Test whether an encryption type satisfies this selector’s requirements.

inline const SymmetricEncryptionRequirements &requirements() const noexcept

Get the selector requirements.

CryptographicStatus status(SymmetricEncryptionType type) const

Get the encryption type’s effective status under the live application-wide policy.

util::List<SymmetricEncryptionType> allAccepted() const

Get all currently acceptable encryption types in stable preference order.

util::List<SymmetricEncryptionType> matching() const

Get all encryption types that satisfy this selector’s requirements.

std::optional<SymmetricEncryptionType> recommended() const

Get the first preferred encryption type satisfying this selector’s requirements.

class SymmetricEncryptionType

A complete symmetric encryption construction supported by the library.

Algorithm metadata is library policy and can change between releases. Persisted data and protocols must store toString() for the selected type instead of relying on a future recommendation returning the same value.

See: Cryptographic Operations

Public Types

enum Value

The raw symmetric encryption value.

Values:

enumerator None

No encryption type; used for invalid placeholders.

enumerator Aes256Gcm

AES-256 in Galois/Counter Mode.

enumerator ChaCha20Poly1305

ChaCha20 with Poly1305 authentication.

enumerator Aes128Gcm

AES-128 in Galois/Counter Mode.

enumerator Aes256CbcRandomFill

Legacy AES-256-CBC with external-length random-fill padding.

enumerator Aes256CbcIso9797Method2

Legacy AES-256-CBC with ISO/IEC 9797-1 method 2 padding.

Public Functions

constexpr SymmetricEncryptionType() noexcept = default

Create an invalid encryption type.

inline constexpr SymmetricEncryptionType(const Value value) noexcept

Create an encryption type from its raw value.

Parameters:

value – The raw encryption type value.

inline constexpr bool isValid() const noexcept

Test if this value identifies an encryption type.

bool isAead() const noexcept

Test if this type provides authenticated encryption with associated data.

bool requiresIv() const noexcept

Test if this type requires an initialization vector instead of a nonce.

inline constexpr Value toRawValue() const noexcept

Get the raw encryption type value.

SymmetricCipher cipher() const noexcept

Get the cipher family, or None for an invalid encryption type.

std::size_t keyBitCount() const noexcept

Get the required key width in bits.

unit::ByteLength keyLength() const noexcept

Get the required key length.

unit::ByteLength nonceLength() const noexcept

Get the required nonce length, or zero when this type does not use a nonce.

unit::ByteLength tagLength() const noexcept

Get the required authentication-tag length, or zero for unauthenticated encryption.

unit::ByteLength ivLength() const noexcept

Get the required initialization-vector length, or zero when this type does not use one.

unit::ByteLength maximumEncryptedLength(unit::ByteLength originalLength) const noexcept

Calculate an upper bound for the encrypted payload length.

Authentication tags are separate and are not included. Infinite and overflowing lengths saturate.

Parameters:

originalLength – The original plaintext length.

Returns:

The maximum encrypted payload length for this type.

CryptographicSecurity security() const noexcept

Get the current coarse security level.

text::String toString() const

Convert the encryption type to its stable lowercase identifier.

Public Static Functions

static std::optional<SymmetricEncryptionType> fromString(const text::String &text) noexcept

Parse an exact lowercase encryption type identifier.

Parameters:

text – The identifier to parse.

Returns:

The matching type, or no value for unsupported text.

static SymmetricEncryptionType fromStringOrThrow(const text::String &text)

Parse an exact lowercase encryption type identifier.

Parameters:

text – The identifier to parse.

Throws:

err::ParseError – If text is not a supported identifier.

Returns:

The matching encryption type.

static std::span<const SymmetricEncryptionType> all() noexcept

Get all supported encryption types in stable preference order.

class SymmetricEncryptor

A move-only state object for streaming symmetric encryption.

A default-constructed or securely erased encryptor is an empty placeholder. Associated data must precede payload data, finalization is allowed once, and AEAD tags are available only after successful finalization.

See: Cryptographic Operations

Public Functions

SymmetricEncryptor() noexcept = default

Create an empty placeholder.

SymmetricEncryptor(SymmetricEncryptionType type, const SymmetricKey &key, const SymmetricNonce &nonce)

Create an AEAD encryptor.

Parameters:
  • type – The authenticated encryption construction.

  • key – The exact-size secret key.

  • nonce – The exact-size nonce.

Throws:
  • err::ParameterError – If the type or data lengths do not match.

  • CryptologyError – If no backend is available or backend initialization fails.

SymmetricEncryptor(SymmetricEncryptionType type, const SymmetricKey &key, const SymmetricIv &iv)

Create an IV-based encryptor.

Parameters:
  • type – The unauthenticated encryption construction.

  • key – The exact-size secret key.

  • iv – The exact-size initialization vector.

Throws:
  • err::ParameterError – If the type or data lengths do not match.

  • CryptologyError – If no backend is available or backend initialization fails.

~SymmetricEncryptor()

Securely release the encryption backend state.

SymmetricEncryptor &operator=(SymmetricEncryptor &&other) noexcept

Move encryption state into this instance, securely replacing any current state.

void secureErase() noexcept

Securely erase the worker, key, nonce or IV, and message state, leaving an empty placeholder.

void addAuthenticatedData(mem::ConstByteSpan data)

Add authenticated associated data.

Empty spans are accepted and do not begin payload processing.

Parameters:

data – The next associated-data bytes.

Throws:

err::LogicError – If this encryptor is empty, unauthenticated, failed, finalized, or processing payload.

void addAuthenticatedData(const mem::ByteBlock &data)

Add authenticated associated data from an owning byte block.

Parameters:

data – The next associated-data bytes.

Throws:

err::LogicError – If this encryptor is empty, unauthenticated, failed, finalized, or processing payload.

mem::ByteBlock encrypt(mem::ConstByteSpan data)

Encrypt payload bytes.

Empty spans are accepted. CBC workers buffer partial blocks according to their selected padding mode.

Parameters:

data – The next plaintext bytes.

Throws:
Returns:

The encrypted output currently available.

mem::ByteBlock encrypt(const mem::ByteBlock &data)

Encrypt payload bytes from an owning byte block.

Parameters:

data – The next plaintext bytes.

Throws:
Returns:

The encrypted output currently available.

mem::ByteBlock finalize()

Finalize encryption.

Throws:
Returns:

Any final encrypted output, including selected CBC padding.

SymmetricTag tag() const

Get the AEAD authentication tag after finalization.

Throws:

err::LogicError – If this encryptor is not AEAD or has not finalized successfully.

Returns:

The cached authentication tag.

inline bool isEmpty() const noexcept

Test if no encryption worker or secret state is present.

SymmetricEncryptionType type() const

Get the configured encryption type.

Throws:

err::LogicError – If this encryptor is empty.

class SymmetricIv : public erbsland::cryptology::CryptographicDataBlock

An initialization vector for a symmetric encryption construction.

See: Cryptographic Operations

Public Functions

SymmetricIv() = default

Create an empty initialization-vector placeholder.

inline explicit SymmetricIv(mem::ByteBlock data) noexcept

Create an initialization vector sharing an owning byte block.

Parameters:

data – The IV bytes whose shared allocation is marked as sensitive.

inline explicit SymmetricIv(mem::ConstByteSpan data)

Create an initialization vector by copying borrowed bytes.

Parameters:

data – The IV bytes to copy into sensitive storage.

inline const mem::ByteBlock &data() const noexcept

Access the owning initialization-vector bytes.

inline mem::ConstByteSpan span() const noexcept

Access a borrowed view of the initialization-vector bytes.

inline text::String toString() const

Convert the initialization vector to compact lowercase hexadecimal text for display or diagnostics.

class SymmetricKey : public erbsland::cryptology::CryptographicDataBlock

Secret key material for symmetric encryption.

The public API deliberately provides no access to the stored bytes or their text representation.

See: Cryptographic Operations

Public Functions

SymmetricKey() = default

Create an empty key placeholder.

inline explicit SymmetricKey(mem::ByteBlock data) noexcept

Create a key sharing an owning byte block.

Parameters:

data – The key bytes whose shared allocation is marked as sensitive.

inline explicit SymmetricKey(mem::ConstByteSpan data)

Create a key by copying borrowed bytes.

Parameters:

data – The key bytes to copy into sensitive storage.

class SymmetricNonce : public erbsland::cryptology::CryptographicDataBlock

A nonce for an authenticated symmetric encryption construction.

See: Cryptographic Operations

Public Functions

SymmetricNonce() = default

Create an empty nonce placeholder.

inline explicit SymmetricNonce(mem::ByteBlock data) noexcept

Create a nonce sharing an owning byte block.

Parameters:

data – The nonce bytes whose shared allocation is marked as sensitive.

inline explicit SymmetricNonce(mem::ConstByteSpan data)

Create a nonce by copying borrowed bytes.

Parameters:

data – The nonce bytes to copy into sensitive storage.

inline const mem::ByteBlock &data() const noexcept

Access the owning nonce bytes.

inline mem::ConstByteSpan span() const noexcept

Access a borrowed view of the nonce bytes.

inline text::String toString() const

Convert the nonce to compact lowercase hexadecimal text for display or diagnostics.

class SymmetricTag : public erbsland::cryptology::CryptographicDataBlock

An authentication tag produced or consumed by an AEAD construction.

See: Cryptographic Operations

Public Functions

SymmetricTag() = default

Create an empty tag placeholder.

inline explicit SymmetricTag(mem::ByteBlock data) noexcept

Create a tag sharing an owning byte block.

Parameters:

data – The tag bytes whose shared allocation is marked as sensitive.

inline explicit SymmetricTag(mem::ConstByteSpan data)

Create a tag by copying borrowed bytes.

Parameters:

data – The tag bytes to copy into sensitive storage.

inline const mem::ByteBlock &data() const noexcept

Access the owning tag bytes.

inline mem::ConstByteSpan span() const noexcept

Access a borrowed view of the tag bytes.

inline text::String toString() const

Convert the tag to compact lowercase hexadecimal text for display or diagnostics.