Interface BotanLibrary


public interface BotanLibrary
JNR-FFI interface defining native function bindings to the Botan cryptography library.

This interface provides direct access to Botan's C FFI (Foreign Function Interface) through JNR-FFI. It defines Java method signatures that map to native Botan functions, handling type conversions and memory management for cross-language calls.

Purpose and Architecture

BotanLibrary serves as the low-level binding layer between Java and native Botan code:

  • Interface, not Implementation: This is a JNR-FFI interface - JNR automatically generates the implementation by binding to the native library at runtime
  • Direct Native Access: All methods directly correspond to Botan C FFI functions
  • Memory Safety: Uses JNR-FFI annotations (@In, @Out) to manage native memory safely
  • Singleton Access: Instances are created and managed by BotanInstance

Function Categories

The library provides bindings for the following Botan operations:

Utility Functions

Encoding Functions

Hash Functions (Message Digests)

Message Authentication Codes (MACs)

Symmetric Ciphers

Error Handling

All native functions return an integer error code:

Memory Management

Proper resource cleanup is critical when working with native objects:

  • Initialization functions (e.g., botan_hash_init) allocate native memory
  • Destroy functions (e.g., botan_hash_destroy) must be called to free memory
  • Java wrappers use Cleaner API to ensure automatic cleanup on garbage collection
  • PointerByReference is used for output parameters that receive native object handles

Usage Pattern

Direct usage of this interface is not recommended. Instead, use the high-level JCA wrapper classes:


 // DON'T use BotanLibrary directly:
 BotanLibrary lib = BotanInstance.singleton();
 PointerByReference hashRef = new PointerByReference();
 lib.botan_hash_init(hashRef, "SHA-256", 0);
 // ... manual memory management required ...
 lib.botan_hash_destroy(hashRef.getValue());

 // DO use JCA wrappers instead:
 MessageDigest sha256 = MessageDigest.getInstance("SHA-256", "Botan");
 byte[] hash = sha256.digest(data);
 // Automatic resource management via Cleaner
 

JNR-FFI Annotations

This interface uses JNR-FFI annotations to control parameter marshalling:

  • @In - Input parameter (Java to native)
  • @Out - Output parameter (native to Java)
  • PointerByReference - Reference to a native pointer (for object handles)
  • NativeLongByReference - Reference to a native long (for output sizes)
  • Pointer - Opaque native pointer (for object handles)

Thread Safety

The native Botan library functions are NOT thread-safe for individual objects:

  • Each native object (hash, MAC, cipher) must be accessed by only one thread
  • Different threads can use different native objects concurrently
  • Java wrapper classes inherit this thread-safety model

Native Library Requirements

This interface requires the Botan 3.x native library:

  • Library name: "botan-3"
  • Minimum version: Botan 3.0.0
  • FFI API: Uses Botan's C FFI (stable ABI)
  • Platform support: Linux, macOS, Windows

Implementation Notes

  • Auto-generated Implementation: JNR-FFI generates the implementation at runtime by analyzing this interface and creating native bindings
  • No Manual JNI: No need for hand-written JNI code - JNR handles everything
  • Type Mapping: JNR automatically maps Java types to C types (int→int, byte[]→uint8_t*, etc.)
  • Performance: Near-native performance due to efficient JNR code generation
Since:
0.1.0
Author:
Yasser Aziza
See Also:
  • Method Summary

    Modifier and Type
    Method
    Description
    int
    botan_base64_decode(String input, long inputLength, byte[] output, jnr.ffi.byref.NativeLongByReference outputLength)
    Performs base64 decoding.
    int
    botan_base64_encode(byte[] input, long inputLength, byte[] output, jnr.ffi.byref.NativeLongByReference outputLength)
    Performs base64 encoding.
    int
    botan_cipher_clear(jnr.ffi.Pointer cipher)
    Resets the key, nonce, AD and all other state on this cipher object.
    int
    botan_cipher_destroy(jnr.ffi.Pointer cipher)
    Destroys the cipher object.
    int
    botan_cipher_get_default_nonce_length(jnr.ffi.Pointer cipher, jnr.ffi.byref.NativeLongByReference nonceLength)
    Gets the default nonce length of this cipher.
    int
    botan_cipher_get_keyspec(jnr.ffi.Pointer cipher, jnr.ffi.byref.NativeLongByReference minKeylen, jnr.ffi.byref.NativeLongByReference maxKeylen, jnr.ffi.byref.NativeLongByReference modKeylen)
    Gets information about the supported key lengths.
    int
    botan_cipher_get_tag_length(jnr.ffi.Pointer cipher, jnr.ffi.byref.NativeLongByReference tagLength)
    Gets the tag length of the cipher (0 for non-AEAD modes).
    int
    botan_cipher_get_update_granularity(jnr.ffi.Pointer cipher, jnr.ffi.byref.NativeLongByReference updateGranularity)
    Returns the update granularity of the cipher; botan_cipher_update must be called with blocks of this size, except for the final.
    int
    botan_cipher_init(jnr.ffi.byref.PointerByReference cipher, String name, long flags)
    Initializes a cipher object.
    int
    botan_cipher_output_length(jnr.ffi.Pointer cipher, long inputLength, jnr.ffi.byref.NativeLongByReference outputLength)
    Returns the output length of this cipher, for a particular input length.
    int
    botan_cipher_reset(jnr.ffi.Pointer cipher)
    Resets the message specific state for this cipher.
    int
    botan_cipher_set_associated_data(jnr.ffi.Pointer cipher, byte[] ad, long adLen)
    Sets the associated data.
    int
    botan_cipher_set_key(jnr.ffi.Pointer cipher, byte[] key, long keyLength)
    Sets the key for this cipher object.
    int
    botan_cipher_start(jnr.ffi.Pointer cipher, byte[] nonce, long nonceLength)
    Begin processing a new message using the provided nonce.
    int
    botan_cipher_update(jnr.ffi.Pointer cipher, long flags, byte[] output, long outputSize, jnr.ffi.byref.NativeLongByReference outputWritten, byte[] input, long inputSize, jnr.ffi.byref.NativeLongByReference inputConsumed)
    Encrypts some data.
    int
    botan_cipher_valid_nonce_length(jnr.ffi.Pointer cipher, long nonceLength)
    Returns if the specified nonce length is valid for this cipher.
    Converts an error code into a string.
    int
    botan_ffi_supports_api(long apiVersion)
    Returns the version of the currently supported FFI API.
    int
    botan_hash_block_size(jnr.ffi.Pointer hash, jnr.ffi.byref.NativeLongByReference size)
    Writes the block size of the hash function to the given reference.
    int
    botan_hash_clear(jnr.ffi.Pointer hash)
    Reinitializes the state of the hash computation.
    int
    botan_hash_copy_state(jnr.ffi.byref.PointerByReference dest, jnr.ffi.Pointer source)
    Copy the state of a hash function object.
    int
    botan_hash_destroy(jnr.ffi.Pointer hash)
    Frees all resources of the hash object.
    int
    botan_hash_final(jnr.ffi.Pointer hash, byte[] out)
    Finalizes the hash computation and writes the output to out[0:botan_hash_output_length()] then reinitializes for computing another digest as if botan_hash_clear had been called.
    int
    botan_hash_init(jnr.ffi.byref.PointerByReference hash, String hashName, long flags)
    Initializes a hash function object.
    int
    botan_hash_output_length(jnr.ffi.Pointer hash, jnr.ffi.byref.NativeLongByReference length)
    Writes the output length of the hash function to the given reference.
    int
    botan_hash_update(jnr.ffi.Pointer hash, byte[] input, long length)
    Sends more input to the hash function.
    int
    botan_hex_decode(byte[] input, long inputLength, byte[] output, jnr.ffi.byref.NativeLongByReference outputLength)
    Performs hex decoding.
    int
    botan_hex_encode(byte[] input, long inputLength, byte[] output, long flags)
    Performs hex encoding.
    int
    botan_mac_clear(jnr.ffi.Pointer mac)
    Reinitializes the state of the MAC computation.
    int
    botan_mac_destroy(jnr.ffi.Pointer mac)
    Frees all resources of the MAC object.
    int
    botan_mac_final(jnr.ffi.Pointer mac, byte[] out)
    Finalizes the MAC computation and writes the output to out[0:botan_mac_output_length()] then reinitializes for computing another MAC as if botan_mac_clear had been called.
    int
    botan_mac_get_keyspec(jnr.ffi.Pointer mac, jnr.ffi.byref.NativeLongByReference minimumKeyLength, jnr.ffi.byref.NativeLongByReference maximumKeyLength, jnr.ffi.byref.NativeLongByReference keyLengthModulo)
    Gets the key length limits of this auth code
    int
    botan_mac_init(jnr.ffi.byref.PointerByReference mac, String name, long flags)
    Initializes a message authentication code object.
    int
    botan_mac_output_length(jnr.ffi.Pointer mac, jnr.ffi.byref.NativeLongByReference length)
    Writes the output length of the message authentication code to the given reference.
    int
    botan_mac_set_key(jnr.ffi.Pointer mac, byte[] key, long length)
    Sets the key on the MAC.
    int
    botan_mac_update(jnr.ffi.Pointer mac, byte[] buffer, long length)
    Sends more input to the message authentication code.
    Returns a free-form version string, e.g., 2.0.0
  • Method Details

    • botan_error_description

      String botan_error_description(int err)
      Converts an error code into a string. Returns "Unknown error" if the error code is not a known one.
      Parameters:
      err - error code
      Returns:
      String description
    • botan_ffi_supports_api

      int botan_ffi_supports_api(long apiVersion)
      Returns the version of the currently supported FFI API. This is expressed in the form YYYYMMDD of the release date of this version of the API.
      Parameters:
      apiVersion - supported API version
      Returns:
      0 if the given API version is supported
    • botan_version_string

      String botan_version_string()
      Returns a free-form version string, e.g., 2.0.0
      Returns:
      String version
    • botan_hex_encode

      int botan_hex_encode(byte[] input, long inputLength, byte[] output, long flags)
      Performs hex encoding.
      Parameters:
      input - is some binary data
      inputLength - length of x in bytes
      output - an array of at least x*2 bytes
      flags - output be upper or lower case?
      Returns:
      0 on success, a negative value on failure
    • botan_hex_decode

      int botan_hex_decode(byte[] input, long inputLength, byte[] output, jnr.ffi.byref.NativeLongByReference outputLength)
      Performs hex decoding.
      Parameters:
      input - a string of hex chars (whitespace is ignored)
      inputLength - the length of the input
      output - the output buffer should be at least strlen(input)/2 bytes
      outputLength - the size of the output
      Returns:
      0 on success, a negative value on failure
    • botan_base64_encode

      int botan_base64_encode(byte[] input, long inputLength, byte[] output, jnr.ffi.byref.NativeLongByReference outputLength)
      Performs base64 encoding.
      Parameters:
      input - the input buffer
      inputLength - the length of the input
      output - the output buffer
      outputLength - the size of the output
      Returns:
      0 on success, a negative value on failure
    • botan_base64_decode

      int botan_base64_decode(String input, long inputLength, byte[] output, jnr.ffi.byref.NativeLongByReference outputLength)
      Performs base64 decoding.
      Parameters:
      input - the input buffer
      inputLength - the length of the input
      output - the output buffer
      outputLength - the size of the output
      Returns:
      0 on success, a negative value on failure
    • botan_hash_init

      int botan_hash_init(jnr.ffi.byref.PointerByReference hash, String hashName, long flags)
      Initializes a hash function object.
      Parameters:
      hash - hash object
      hashName - name of the hash function, e.g., "SHA-384"
      flags - should be 0 in current API revision, all other uses are reserved and return BOTAN_FFI_ERROR_BAD_FLAG
      Returns:
      0 on success, a negative value on failure
    • botan_hash_copy_state

      int botan_hash_copy_state(jnr.ffi.byref.PointerByReference dest, jnr.ffi.Pointer source)
      Copy the state of a hash function object.
      Parameters:
      dest - destination hash object
      source - source hash object
      Returns:
      0 on success, a negative value on failure
    • botan_hash_output_length

      int botan_hash_output_length(jnr.ffi.Pointer hash, jnr.ffi.byref.NativeLongByReference length)
      Writes the output length of the hash function to the given reference.
      Parameters:
      hash - hash object
      length - output buffer to hold the hash function output length
      Returns:
      0 on success, a negative value on failure
    • botan_hash_block_size

      int botan_hash_block_size(jnr.ffi.Pointer hash, jnr.ffi.byref.NativeLongByReference size)
      Writes the block size of the hash function to the given reference.
      Parameters:
      hash - hash object
      size - output buffer to hold the hash function output length
      Returns:
      0 on success, a negative value on failure
    • botan_hash_update

      int botan_hash_update(jnr.ffi.Pointer hash, byte[] input, long length)
      Sends more input to the hash function.
      Parameters:
      hash - hash object
      input - input buffer
      length - number of bytes to read from the input buffer
      Returns:
      0 on success, a negative value on failure
    • botan_hash_final

      int botan_hash_final(jnr.ffi.Pointer hash, byte[] out)
      Finalizes the hash computation and writes the output to out[0:botan_hash_output_length()] then reinitializes for computing another digest as if botan_hash_clear had been called.
      Parameters:
      hash - hash object
      out - output buffer
      Returns:
      0 on success, a negative value on failure
    • botan_hash_clear

      int botan_hash_clear(jnr.ffi.Pointer hash)
      Reinitializes the state of the hash computation. A hash can be computed (with update/final) immediately.
      Parameters:
      hash - hash object
      Returns:
      0 on success, a negative value on failure
    • botan_hash_destroy

      int botan_hash_destroy(jnr.ffi.Pointer hash)
      Frees all resources of the hash object.
      Parameters:
      hash - hash object
      Returns:
      0 if success, error if invalid object handle
    • botan_mac_init

      int botan_mac_init(jnr.ffi.byref.PointerByReference mac, String name, long flags)
      Initializes a message authentication code object.
      Parameters:
      mac - MAC object
      name - name of the hash function, e.g., "HMAC(SHA-384)"
      flags - should be 0 in current API revision, all other uses are reserved and return a negative value (error code)
      Returns:
      0 on success, a negative value on failure
    • botan_mac_output_length

      int botan_mac_output_length(jnr.ffi.Pointer mac, jnr.ffi.byref.NativeLongByReference length)
      Writes the output length of the message authentication code to the given reference.
      Parameters:
      mac - MAC object
      length - output buffer to hold the MAC output length
      Returns:
      0 on success, a negative value on failure
    • botan_mac_set_key

      int botan_mac_set_key(jnr.ffi.Pointer mac, byte[] key, long length)
      Sets the key on the MAC.
      Parameters:
      mac - MAC object
      key - buffer holding the key
      length - size of the key buffer in bytes
      Returns:
      0 on success, a negative value on failure
    • botan_mac_update

      int botan_mac_update(jnr.ffi.Pointer mac, byte[] buffer, long length)
      Sends more input to the message authentication code.
      Parameters:
      mac - MAC object
      buffer - input buffer
      length - number of bytes to read from the input buffer
      Returns:
      0 on success, a negative value on failure
    • botan_mac_final

      int botan_mac_final(jnr.ffi.Pointer mac, byte[] out)
      Finalizes the MAC computation and writes the output to out[0:botan_mac_output_length()] then reinitializes for computing another MAC as if botan_mac_clear had been called.
      Parameters:
      mac - MAC object
      out - output buffer
      Returns:
      0 on success, a negative value on failure
    • botan_mac_clear

      int botan_mac_clear(jnr.ffi.Pointer mac)
      Reinitializes the state of the MAC computation. A MAC can be computed (with update/final) immediately.
      Parameters:
      mac - MAC object
      Returns:
      0 on success, a negative value on failure
    • botan_mac_destroy

      int botan_mac_destroy(jnr.ffi.Pointer mac)
      Frees all resources of the MAC object.
      Parameters:
      mac - MAC object
      Returns:
      0 if success, error if invalid object handle
    • botan_mac_get_keyspec

      int botan_mac_get_keyspec(jnr.ffi.Pointer mac, jnr.ffi.byref.NativeLongByReference minimumKeyLength, jnr.ffi.byref.NativeLongByReference maximumKeyLength, jnr.ffi.byref.NativeLongByReference keyLengthModulo)
      Gets the key length limits of this auth code
      Parameters:
      mac - MAC object
      minimumKeyLength - if non-NULL, will be set to minimum keylength of MAC
      maximumKeyLength - if non-NULL, will be set to maximum keylength of MAC
      keyLengthModulo - if non-NULL will be set to byte multiple of valid keys
    • botan_cipher_init

      int botan_cipher_init(jnr.ffi.byref.PointerByReference cipher, String name, long flags)
      Initializes a cipher object.
      Parameters:
      cipher - cipher object
      name - name of the cipher including operating mode and padding
      flags -
      Returns:
      0 on success, a negative value on failure
    • botan_cipher_output_length

      int botan_cipher_output_length(jnr.ffi.Pointer cipher, long inputLength, jnr.ffi.byref.NativeLongByReference outputLength)
      Returns the output length of this cipher, for a particular input length.
      Parameters:
      cipher - cipher object
      inputLength - input length
      outputLength - output length
      Returns:
      0 on success, a negative value on failure
    • botan_cipher_valid_nonce_length

      int botan_cipher_valid_nonce_length(jnr.ffi.Pointer cipher, long nonceLength)
      Returns if the specified nonce length is valid for this cipher.
      Parameters:
      cipher - cipher object
      nonceLength - nonce length
      Returns:
      0 on success, a negative value on failure
    • botan_cipher_get_tag_length

      int botan_cipher_get_tag_length(jnr.ffi.Pointer cipher, jnr.ffi.byref.NativeLongByReference tagLength)
      Gets the tag length of the cipher (0 for non-AEAD modes).
      Parameters:
      cipher - cipher object
      tagLength - tag length
      Returns:
      0 on success, a negative value on failure
    • botan_cipher_get_default_nonce_length

      int botan_cipher_get_default_nonce_length(jnr.ffi.Pointer cipher, jnr.ffi.byref.NativeLongByReference nonceLength)
      Gets the default nonce length of this cipher.
      Parameters:
      cipher - cipher object
      nonceLength - nonce length
      Returns:
      0 on success, a negative value on failure
    • botan_cipher_get_update_granularity

      int botan_cipher_get_update_granularity(jnr.ffi.Pointer cipher, jnr.ffi.byref.NativeLongByReference updateGranularity)
      Returns the update granularity of the cipher; botan_cipher_update must be called with blocks of this size, except for the final.
      Parameters:
      cipher - cipher object
      updateGranularity - update granularity
      Returns:
      0 on success, a negative value on failure
    • botan_cipher_get_keyspec

      int botan_cipher_get_keyspec(jnr.ffi.Pointer cipher, jnr.ffi.byref.NativeLongByReference minKeylen, jnr.ffi.byref.NativeLongByReference maxKeylen, jnr.ffi.byref.NativeLongByReference modKeylen)
      Gets information about the supported key lengths.
      Parameters:
      cipher - cipher object
      minKeylen - minimal key length
      maxKeylen - maximal key length
      modKeylen - mod key length
      Returns:
      0 on success, a negative value on failure
    • botan_cipher_set_key

      int botan_cipher_set_key(jnr.ffi.Pointer cipher, byte[] key, long keyLength)
      Sets the key for this cipher object.
      Parameters:
      cipher - cipher object
      key - key
      keyLength - key length
      Returns:
      0 on success, a negative value on failure
    • botan_cipher_reset

      int botan_cipher_reset(jnr.ffi.Pointer cipher)
      Resets the message specific state for this cipher. Without resetting the keys, this resets the nonce, and any state associated with any message bits that have been processed so far. It is conceptually equivalent to calling botan_cipher_clear followed by botan_cipher_set_key with the original key.
      Parameters:
      cipher - cipher object
      Returns:
      0 on success, a negative value on failure
    • botan_cipher_set_associated_data

      int botan_cipher_set_associated_data(jnr.ffi.Pointer cipher, byte[] ad, long adLen)
      Sets the associated data. Will fail if cipher is not an AEAD.
      Parameters:
      cipher - cipher object
      ad - associated data
      adLen - associated data length
      Returns:
      0 on success, a negative value on failure
    • botan_cipher_start

      int botan_cipher_start(jnr.ffi.Pointer cipher, byte[] nonce, long nonceLength)
      Begin processing a new message using the provided nonce.
      Parameters:
      cipher - cipher object
      nonce - nonce data
      nonceLength - nonce data length
      Returns:
      0 on success, a negative value on failure
    • botan_cipher_update

      int botan_cipher_update(jnr.ffi.Pointer cipher, long flags, byte[] output, long outputSize, jnr.ffi.byref.NativeLongByReference outputWritten, byte[] input, long inputSize, jnr.ffi.byref.NativeLongByReference inputConsumed)
      Encrypts some data.
      Parameters:
      cipher - cipher object
      flags -
      output - cipher output bytes
      outputSize - cipher output size
      outputWritten - written output size
      input - cipher input bytes
      inputSize - cipher input size
      inputConsumed - cipher input consumed
      Returns:
      0 on success, a negative value on failure
    • botan_cipher_clear

      int botan_cipher_clear(jnr.ffi.Pointer cipher)
      Resets the key, nonce, AD and all other state on this cipher object.
      Parameters:
      cipher - cipher object
      Returns:
      0 if success, error if invalid object handle
    • botan_cipher_destroy

      int botan_cipher_destroy(jnr.ffi.Pointer cipher)
      Destroys the cipher object.
      Parameters:
      cipher - cipher object
      Returns:
      0 if success, error if invalid object handle