Table of Contents

Class S100Cipher

Namespace
EncDotNet.S100.ExchangeSets.Protection
Assembly
EncDotNet.S100.ExchangeSets.dll

Implements the symmetric (confidentiality) cryptography of the S-100 Part 15 Data Protection Scheme: AES-128 in CBC mode with the modified initialization vector handling, plus the single-block key-wrapping used for cell keys and hardware identifiers.

public static class S100Cipher
Inheritance
S100Cipher
Inherited Members

Remarks

S-100 Edition 5.2.1 Part 15 §15-6. The scheme always uses a 128-bit key (§15-6.2.1) and PKCS#7 padding (§15-6.2.2). Dataset files use a modified CBC mode (§15-6.2.4): the plaintext is prepended with one random block and encrypted under a random initialization vector that is not transmitted; on decryption an arbitrary IV is used and the first recovered plaintext block is discarded.

Cell keys and hardware identifiers are exactly one AES block (16 bytes) and are wrapped with a single-block encryption with no chaining or padding (§15-7.3.1.1, §15-7.4.4).

Fields

BlockSize

The AES block size in bytes (128 bits).

public const int BlockSize = 16

Field Value

int

KeyLength

The S-100 Part 15 key length in bytes (128 bits).

public const int KeyLength = 16

Field Value

int

Methods

DecryptBlock(ReadOnlySpan<byte>, ReadOnlySpan<byte>)

Decrypts a single 16-byte block with AES-128 (no chaining, no padding). This is the inverse of EncryptBlock(ReadOnlySpan<byte>, ReadOnlySpan<byte>) and is used to unwrap a cell key from an encrypted key with the hardware id (§15-7.4.4) or a hardware id from a user permit with the manufacturer key (§15-7.3.1.1).

public static byte[] DecryptBlock(ReadOnlySpan<byte> block, ReadOnlySpan<byte> key)

Parameters

block ReadOnlySpan<byte>

The 16-byte ciphertext block.

key ReadOnlySpan<byte>

The 16-byte key.

Returns

byte[]

The 16-byte plaintext block.

DecryptDataset(ReadOnlySpan<byte>, ReadOnlySpan<byte>)

Decrypts a dataset (or other product file) that was encrypted with the S-100 Part 15 modified CBC mode.

public static byte[] DecryptDataset(ReadOnlySpan<byte> ciphertext, ReadOnlySpan<byte> cellKey)

Parameters

ciphertext ReadOnlySpan<byte>

The encrypted file content.

cellKey ReadOnlySpan<byte>

The 16-byte cell (product) key.

Returns

byte[]

The decrypted bytes with the random prefix block removed.

Remarks

S-100 Edition 5.2.1 Part 15 §15-6.2.4. The ciphertext is decrypted with AES-128-CBC under an arbitrary (zero) IV — which only corrupts the first plaintext block — the PKCS#7 padding is removed, and the leading random block is discarded, yielding the original (still compressed, if the product specification applies compression) bytes.

Exceptions

CryptographicException

The ciphertext is not a positive multiple of the block size, is shorter than the mandatory random block, or has invalid padding.

EncryptBlock(ReadOnlySpan<byte>, ReadOnlySpan<byte>)

Encrypts a single 16-byte block with AES-128 (no chaining, no padding). Used to wrap a hardware id with a manufacturer key (§15-7.3.1.1) or a cell key with a hardware id (§15-7.4.4).

public static byte[] EncryptBlock(ReadOnlySpan<byte> block, ReadOnlySpan<byte> key)

Parameters

block ReadOnlySpan<byte>

The 16-byte plaintext block.

key ReadOnlySpan<byte>

The 16-byte key.

Returns

byte[]

The 16-byte ciphertext block.

EncryptDataset(ReadOnlySpan<byte>, ReadOnlySpan<byte>)

Encrypts bytes with the S-100 Part 15 modified CBC mode. Provided to support round-trip testing and synthetic fixture generation; production reading only needs DecryptDataset(ReadOnlySpan<byte>, ReadOnlySpan<byte>).

public static byte[] EncryptDataset(ReadOnlySpan<byte> plaintext, ReadOnlySpan<byte> cellKey)

Parameters

plaintext ReadOnlySpan<byte>

The bytes to encrypt (already compressed, if applicable).

cellKey ReadOnlySpan<byte>

The 16-byte cell (product) key.

Returns

byte[]

The encrypted file content.

Remarks

S-100 Edition 5.2.1 Part 15 §15-6.2.4. A cryptographically random block is prepended to plaintext, the result is PKCS#7-padded and encrypted with AES-128-CBC under a random IV that is intentionally not returned.

EncryptDataset(ReadOnlySpan<byte>, ReadOnlySpan<byte>, ReadOnlySpan<byte>, ReadOnlySpan<byte>)

Encrypts bytes with the S-100 Part 15 modified CBC mode using the given prefix block and initialization vector instead of random ones, so the output is reproducible. For synthetic test fixtures only.

public static byte[] EncryptDataset(ReadOnlySpan<byte> plaintext, ReadOnlySpan<byte> cellKey, ReadOnlySpan<byte> prefixBlock, ReadOnlySpan<byte> iv)

Parameters

plaintext ReadOnlySpan<byte>

The bytes to encrypt (already compressed, if applicable).

cellKey ReadOnlySpan<byte>

The 16-byte cell (product) key.

prefixBlock ReadOnlySpan<byte>

The 16-byte block prepended to the plaintext.

iv ReadOnlySpan<byte>

The 16-byte initialization vector, which is not transmitted.

Returns

byte[]

The encrypted file content.

Remarks

S-100 Edition 5.2.1 Part 15 §15-6.2.4 requires the prefix block and the IV to be random; a data server must use EncryptDataset(ReadOnlySpan<byte>, ReadOnlySpan<byte>). Fixed values here let generated fixtures diff cleanly between runs.

The output decrypts with DecryptDataset(ReadOnlySpan<byte>, ReadOnlySpan<byte>) like any other, because decryption discards the first block whatever the IV.