QNX Cryptography Library

Updated: April 19, 2023

The QNX cryptography library (qcrypto library) is a generic cryptographic shim layer that provides a consistent API to the various cryptographic primitives offered by third-party libraries.

The library's unified API provides a configurable plugin system that allows a system integrator to choose a cryptography provider without re-writing software. It is designed to maximize interoperability between library implementations by providing configuration parameters that allow systems to switch to the cryptographic backend of their choice.

The qcrypto library also enforces a certain level of security by following best practices where possible to ensure that users of the library use appropriate security parameters and key lengths. The sources for security best practices include the following information:

Using qcrypto

The following components are needed to run qcrypto on a system:

Features that use qcrypto

Dynamically loading the qcrypto library

If you need to support dynamically loading the cryptography library at runtime instead of linking to it directly, link your binary with libqcrypto_dyn.so and call qcrypto_load() to safely load the library before calling the other APIs. (The qcrypto_unload() function unloads it.) This dynamic shim layer is transparent and the API calls are identical in both libraries.

Supported algorithms

The qcrypto library framework allows you to add newer algorithms to a system using plugins. The algorithms that each plugin supports depends entirely on which algorithms the third-party cryptography library supports. In some cases, to encourage users to avoid using insecure primitives, qcrypto has purposefully avoided adding support for algorithms that are considered obsolete and unsafe. Some other algorithms require careful consideration when you define certain values, such as the initialization vector in many AES modes.

Algorithm naming

The qcrypto library tries to use uniform and unambiguous naming for algorithms. All algorithm names are lowercase ASCII strings and, where possible, the common naming used by RFCs. For example:

Plugins

The qcrypto library uses plugins to interface with different cryptographic providers. Currently, the library provides the following plugins. See the documentation for each plugin for details: Plugins are provided by libraries that use the following naming format:
qcrypto-plugin.so

For example, qcrypto-openssl.so and qcrypto-certicom.so.

The qcrypto library allows you to create custom plugins. For more information, see Adding cryptographic primitives.”

Supported cryptographic primitives

The qcrypto library APIs include functions for working with the following cryptographic primitives:

Initialization

You need to initialize the library before you can successfully call any other algorithm functions. Use qcrypto_init() to initialize the qcrypto library and qcrypto_uninit() to un-initialize it.

Using algorithms

After the library is initialized, the following steps are the usual work flow for using cryptographic primitives:
  1. Use a qcrypto_*_request() function to get an instance of the desired algorithm (e.g., qcrypto_cipher_request()).
  2. Manipulate the primitive using the qcrypto functions defined for it.
  3. Call qcrypto_release_ctx() when you no longer need the algorithm.
The same work flow applies to handling cryptographic keys, whether you are generating them for the first time or loading them from memory or files. See the section that discusses each of the various supported cryptographic primitives for examples of how to use them.

Reusing an algorithm instance

An instance of an algorithm (a context) can be reused if the caller reinitializes it using its initialization function. Reinitializing allows you to reuse an instance without clearing memory all the time and may improve performance.

Requesting an algorithm

When you call qcrypto_*_request(), the function searches for the specified algorithm. If a matching tag isn't found or the algorithm is not found in a matching plugin, the algorithm resolution fails.

For more information on how tags work with requests, see “Tags” in the “Configuration file” section.

Error handling and logging

Use qcrypto_strerror() to retrieve the textual representation of qcrypto library error codes.

By default, logging prints errors and other conditions to slogger2 and is handled by QNX helper logging functionality (libqh). For additional logging options, see the QNX Helpers Developer's Guide.

Error codes

For the error codes that the qcrypto library uses and returns, see QNX cryptography library error codes.”

General functions

The qcrypto library provides the following general-purpose and cryptography-related functions:

Selecting the buffer size

The qcrypto_*_final() functions (e.g., qcrypto_cipher_final()) take pointers to a buffer for a value and its size. When buffer is NULL, the function returns the size of the data it wants to write in size and allows the caller to allocate a buffer large enough for the data. This type of call is useful for data like key values, which can vary widely in size, unlike digests, which have known, fixed lengths.