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. Must be a valid hash algorithm.

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. Must be a valid hash algorithm.

  • status – The highest status permitted by the application policy. Must be a valid cryptographic status.

void clearMaximumStatus(HashAlgorithm algorithm)

Clear the administrative maximum status for a hash algorithm.

Parameters:

algorithm – The algorithm whose limit is cleared. Must be a valid hash algorithm.

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

Get the administrative maximum status for a symmetric encryption type.

Parameters:

type – The encryption type to inspect. Must be a valid symmetric encryption type.

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. Must be a valid symmetric encryption type.

  • status – The highest status permitted by the application policy. Must be a valid cryptographic status.

void clearMaximumStatus(SymmetricEncryptionType type)

Clear the administrative maximum status for a symmetric encryption type.

Parameters:

type – The encryption type whose limit is cleared. Must be a valid symmetric encryption type.

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. Must be valid and must not differ from the selected mode 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)

Replace supplied roles at a named label, preserving an existing other role.

Parameters:
  • label – Nonempty validated application label; empty is reserved for built-in defaults.

  • configuration – One or both complete role configurations.

Throws:

CryptologyError – If a new label exceeds capacity or a supplied role is invalid.

void replaceTlsConfigurations(const TlsConfigurationSet &configurations)

Atomically replace all named profiles and shared settings after validating the complete set.

Parameters:

configurations – The new owned generation; duplicate roles at one label are invalid.

Throws:

CryptologyError – If any profile is invalid, duplicated, or exceeds capacity.

TlsSettings tlsSettings() const

Get a copy of the current shared TLS settings.

void clearTlsConfiguration(const text::String &label)

Remove both roles at a named label.

Parameters:

label – Nonempty application label.

void clearTlsConfiguration(const text::String &label, TlsRole role)

Remove one role at a named label.

Parameters:
  • label – Nonempty application label.

  • role – The local role to remove.

void clearTlsConfigurations()

Remove named profiles, retaining shared settings and built-in defaults.

bool hasTlsConfiguration(const text::String &label, TlsRole role) const

Test exact role presence, including the reserved built-in defaults.

Parameters:
  • label – Valid application label, or empty for the built-in default.

  • role – Local connection role.

Returns:

Whether the exact label contains this role.

auto resolveTlsConfiguration(const text::String &label, TlsRole role) const -> TlsConfigurationResolution

Resolve one role through its label ancestors and reserved default.

Parameters:
  • label – Valid application label, or empty for the built-in default.

  • role – Local connection role.

Throws:

CryptologyError – If the selected profile cannot be used for its role.

Returns:

The selected immutable role and effective certificate policy.

auto resolveTlsConfigurations(const text::StringList &labels, TlsRole role) const -> std::vector<TlsConfigurationResolution>

Resolve multiple labels against one coherent generation of the registry.

Parameters:
  • labels – Requested labels in result order.

  • role – Local connection role.

Throws:

CryptologyError – If any selected profile is unusable.

Returns:

One immutable resolution for each label.

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::ByteCount 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.

This hasher must be valid.

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. This hasher must be valid and must not have been finalized.

Parameters:

data – The next exact message bytes.

void update(const mem::ByteBlock &data)

Add a byte block.

This hasher must be valid and must not have been finalized.

Parameters:

data – The next exact message bytes.

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. This hasher must be valid and must not have been finalized.

Parameters:

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

mem::ByteBlock finalize()

Finalize the current stream and return its digest.

Repeated calls return the cached digest. This hasher must be valid.

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.

This hasher must be valid.

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. Must be SHA-256 or SHA-384.

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

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.

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

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

Parameters:
  • sharedSecret – The protected source keying material. Must not be empty.

  • salt – The optional salt bytes.

Returns:

A digest-sized pseudorandom key in sensitive storage.

auto expand(mem::ConstByteSpan pseudoRandomKey, mem::ConstByteSpan info, unit::ByteCount 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.

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.

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.

~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.

This HMAC state must be valid.

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. This HMAC state must be valid and must not have been finalized.

Parameters:

data – The next authenticated message bytes. Their addition must not exceed the hash message-length limit.

void update(const mem::ByteBlock &data)

Add a byte block.

This HMAC state must be valid and must not have been finalized.

Parameters:

data – The next authenticated message bytes. Their addition must not exceed the hash message-length limit.

void update(const text::String &text)

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

This HMAC state must be valid and must not have been finalized.

Parameters:

text – The UTF-8 text whose stored bytes are authenticated. Their addition must not exceed the hash message-length limit.

mem::ByteBlock finalize()

Finalize the message or return the cached complete authenticator.

This HMAC state must be valid.

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. This HMAC state must be valid.

Parameters:

expected – The expected full hash-sized authenticator.

Returns:

true if the complete authenticator matches.

bool verify(const mem::ByteBlock &expected)

Verify a complete authenticator in an owning byte block.

This HMAC state must be valid.

Parameters:

expected – The expected full hash-sized authenticator.

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.

This HMAC state must be valid.

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::ByteCount 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. Must be a valid AEAD type matching the key and nonce lengths.

  • key – The exact-size secret key.

  • nonce – The exact-size nonce.

Throws:

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. Must be a valid IV-based type matching the key and IV lengths.

  • key – The exact-size secret key.

  • iv – The exact-size initialization vector.

Throws:

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. This decryptor must use AEAD and must not be empty, failed, finalized, or already processing payload.

Parameters:

data – The next associated-data bytes.

void addAuthenticatedData(const mem::ByteBlock &data)

Add authenticated associated data from an owning byte block.

This decryptor must use AEAD and must not be empty, failed, finalized, or already processing payload.

Parameters:

data – The next associated-data bytes.

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

Decrypt payload bytes.

For AEAD types, returned plaintext is unauthenticated until finalize(tag) succeeds. This decryptor must not be empty, failed, or finalized.

Parameters:

data – The next encrypted bytes.

Throws:

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. This decryptor must not be empty, failed, or finalized.

Parameters:

data – The next encrypted bytes.

Throws:

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. This decryptor must use AEAD and must not be empty, failed, or finalized.

Parameters:

tag – The exact-size expected authentication tag.

Throws:

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. This decryptor must use an unauthenticated CBC type and must not be empty, failed, or finalized.

Throws:

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.

This decryptor must not be 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::ByteCount keyLength() const noexcept

Get the required key length.

unit::ByteCount nonceLength() const noexcept

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

unit::ByteCount tagLength() const noexcept

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

unit::ByteCount ivLength() const noexcept

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

unit::ByteCount maximumEncryptedLength(unit::ByteCount 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. Must be a valid AEAD type matching the key and nonce lengths.

  • key – The exact-size secret key.

  • nonce – The exact-size nonce.

Throws:

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. Must be a valid IV-based type matching the key and IV lengths.

  • key – The exact-size secret key.

  • iv – The exact-size initialization vector.

Throws:

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. This encryptor must use AEAD and must not be empty, failed, finalized, or already processing payload.

Parameters:

data – The next associated-data bytes.

void addAuthenticatedData(const mem::ByteBlock &data)

Add authenticated associated data from an owning byte block.

This encryptor must use AEAD and must not be empty, failed, finalized, or already processing payload.

Parameters:

data – The next associated-data bytes.

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

Encrypt payload bytes.

Empty spans are accepted. CBC workers buffer partial blocks according to their selected padding mode. This encryptor must not be empty, failed, or finalized.

Parameters:

data – The next plaintext bytes.

Throws:

CryptologyError – If the backend fails.

Returns:

The encrypted output currently available.

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

Encrypt payload bytes from an owning byte block.

This encryptor must not be empty, failed, or finalized.

Parameters:

data – The next plaintext bytes.

Throws:

CryptologyError – If the backend fails.

Returns:

The encrypted output currently available.

mem::ByteBlock finalize()

Finalize encryption.

This encryptor must not be empty, failed, or finalized.

Throws:

CryptologyError – If the backend fails.

Returns:

Any final encrypted output, including selected CBC padding.

SymmetricTag tag() const

Get the AEAD authentication tag after finalization.

This encryptor must use AEAD and must have 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.

This encryptor must not be 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.