Implementation Notes


Implementation Notes #

This covers the application specific details and protocols that axpad implements on top of the AXPad method for its operation.

The AXPad parameters #

The AXPad parameters influence the following:

  • The size of the true random material
  • The colission resistance of the selector address
  • The time the initialization requires
  • The number of XOR operations and so the processing speed

At the end of an analysis and several testing the AXPad (method) parameters that axpad (the utility) implements have been carefully chosen as follows:

#define SelectorBytes 64
#define PadBytes 16384

The random material signature on disk #

The 32 byte random material signature on disk is the SHA256 checksum of the following:

  • The 256MB raw material data and
  • a 32 byte internal signature secret.

Initial material processing #

The input random material in memory consists of 64*256 pads with a length of 16384 bytes each. The initialization is done pad-wise by mapping a 32 byte SHA256 result with XOR. This pad specific SHA256 is the checksum of the following data:

  • the 32 signature bytes of the material on disk
  • the pad contents
  • the 32 bytes SHA256 checksum of the passphrase (if specified with --passphrase)

At the end of the processing of all pads a new in-memory SHA256 checksum of the complete material is computed. After this processing it’s impossible to recompute the contents on disk backwards based on the new in-memory “real” contents of the material.

Self referential seeding #

The selector of selectors width is 64 bytes and is needed to deliver random data in self-referential mode when the --urandom option is not set.

The first 32 bytes are set to the SHA256 result including the following data:

  • the result of gettimeofday() (size sizeof(struct timeval))
  • the result of clock() (size sizeof(clock_t))
  • the result of getpid() (size sizeof(pid_t))
  • the result of getppid() (size sizeof(pid_t))

The second 32 bytes are set to the SHA256 result of the following data:

  • the first 32 bytes (size 32)
  • the result of a second call of gettimeofday() (size sizeof(struct timeval))
  • the result of a second call of clock() (size sizeof(clock_t))

The selector of selectors contents are not reported and are set to zero on exit.

Semantics of the timestamp header field #

The timestamp header field uint8_t timestamp[8]; is initialized with random bytes. If the option --timestamp is present, the lower 5 bytes are set to the current time at header creation.

The following two bits implement a chain of header - payload data for each file being encrypted:

  • timestamp[0] & 0b10000000 is the first header bit
  • timestamp[0] & 0b01000000 is the last header bit
  • if there’s only one header, both bits are set

Semantics of the sequence number header field #

The sequence number field in the header uint8_t sequence_number[4]; starts with a random value and is incremented by 1 for consecutive headers (with overflow).

Partial header obfuscation #

If we are looking at the bytestream consisting of alternating headers and encrypted payload data everything has perfect random properties except the 16 header bytes timestamp[8] + sequence_number[4] + message_length[4].

To mitigate this, these 16 bytes are encrypted with the first 16 bytes of the pad at the inverted selector address as contained in the header itself. As a result, the complete bytestream of consecutive header/payload ciphertext data is random and the existence of a material that could successfully decrypt cannot be proven.

Software dependencies #

axpad does not depend on any shared libraries exept those, that the operating system requires for basic execution. axpad´s SHA256 implementation is independent and statically linked.

On macOS this can be verified as follows:

$ which axpad
$ otool -L /usr/local/bin/axpad
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1336.61.1)

On Linux like this:

$ which axpad
$ ldd /usr/local/bin/axpad (0x00007fff52bcb000) => /lib64/ (0x00007f6ca6400000)
	/lib64/ (0x00007f6ca67a6000)

axpad retrieves needed random bytes from the supplied random material by default, so, per default, there’s no dependency from any operating system provided random number generator during encryption. However, this can be overridden with the --urandom option, in that case /dev/urandom is providing the randomness (and it depends by purpose from that special character device).

Licensing and license revocation #

The permanent licensing enables a machine of your choice for licensed axpad operation and works completely offline. axpad implements absolutely no networking functionality and never is “calling home” for whatever reason.

There’s one single offline mechanism that allows us to deal with compromised license keys that are potentially available at suspicious “dark” channels: The license revocation list disables specific license keys and makes only upcoming axpad releases (e.g. with feature enhancements or bug fixes) practically unusable for these revoked license keys. How this is done exactly is confidential.

If you suspect that your license key has been compromised and you are also able to identify as a legitimate customer, please contact us at We’ll send you an replacement key at absolutely no cost and include your old, compromised key in the revocation list.

Caveats and attack possibilities #

The machine or system that axpad runs on may be compromised at a very low (and potentially completely unexpected) level. Any countermeasures here are outside the scope of any third party utility.

  • Compromising the security of an interactively typed passphrase remains possible (e.g. by hidden camera, keylogger software/hardware or even just keyboard typing sounds).
  • The data in apparently deleted and overwritten blocks is still accessible on modern SSDs (although this requires remarkable efforts). SSD controller manufacturers usually provide a “secure erase” functionality. The details here are also outside the scope of axpad.