To use a cipher algorithm, you must first allocate an according handle. This is to be done using the open function:
gcry_error_t
gcry_cipher_open (gcry_cipher_hd_t *hd, int algo, int mode, unsigned int flags)
¶This function creates the context handle required for most of the other cipher functions and returns a handle to it in ‘hd’. In case of an error, an according error code is returned.
The ID of algorithm to use must be specified via algo. See Available ciphers for a list of supported ciphers and the according constants.
Besides using the constants directly, the function
gcry_cipher_map_name
may be used to convert the textual name of
an algorithm into the according numeric ID.
The cipher mode to use must be specified via mode. See
Available cipher modes for a list of supported cipher modes
and the according constants. Note that some modes are incompatible
with some algorithms - in particular, stream mode
(GCRY_CIPHER_MODE_STREAM
) only works with stream ciphers.
Poly1305 AEAD mode (GCRY_CIPHER_MODE_POLY1305
) only works with
ChaCha20 stream cipher. The block cipher modes
(GCRY_CIPHER_MODE_ECB
, GCRY_CIPHER_MODE_CBC
,
GCRY_CIPHER_MODE_CFB
, GCRY_CIPHER_MODE_OFB
,
GCRY_CIPHER_MODE_CTR
and GCRY_CIPHER_MODE_EAX
) will work
with any block cipher algorithm. GCM mode
(GCRY_CIPHER_MODE_GCM
), CCM mode (GCRY_CIPHER_MODE_CCM
),
OCB mode (GCRY_CIPHER_MODE_OCB
), XTS mode
(GCRY_CIPHER_MODE_XTS
), SIV mode
(GCRY_CIPHER_MODE_SIV
) and GCM-SIV mode
(GCRY_CIPHER_MODE_GCM_SIV
) will only work with block cipher
algorithms which have the block size of 16 bytes.
The third argument flags can either be passed as 0
or as
the bit-wise OR of the following constants.
GCRY_CIPHER_SECURE
Make sure that all operations are allocated in secure memory. This is useful when the key material is highly confidential.
GCRY_CIPHER_ENABLE_SYNC
¶This flag enables the CFB sync mode, which is a special feature of
Libgcrypt’s CFB mode implementation to allow for OpenPGP’s CFB variant.
See gcry_cipher_sync
.
GCRY_CIPHER_CBC_CTS
¶Enable cipher text stealing (CTS) for the CBC mode. Cannot be used simultaneously with GCRY_CIPHER_CBC_MAC. CTS mode makes it possible to transform data of almost arbitrary size (only limitation is that it must be greater than the algorithm’s block size).
GCRY_CIPHER_CBC_MAC
¶Compute CBC-MAC keyed checksums. This is the same as CBC mode, but only output the last block. Cannot be used simultaneously with GCRY_CIPHER_CBC_CTS.
Use the following function to release an existing handle:
void
gcry_cipher_close (gcry_cipher_hd_t h)
¶This function releases the context created by gcry_cipher_open
.
It also zeroises all sensitive information associated with this cipher
handle.
In order to use a handle for performing cryptographic operations, a ‘key’ has to be set first:
gcry_error_t
gcry_cipher_setkey (gcry_cipher_hd_t h, const void *k, size_t l)
¶Set the key k used for encryption or decryption in the context denoted by the handle h. The length l (in bytes) of the key k must match the required length of the algorithm set for this context or be in the allowed range for algorithms with variable key size. The function checks this and returns an error if there is a problem. A caller should always check for an error.
Most crypto modes requires an initialization vector (IV), which usually is a non-secret random string acting as a kind of salt value. The CTR mode requires a counter, which is also similar to a salt value. To set the IV or CTR, use these functions:
gcry_error_t
gcry_cipher_setiv (gcry_cipher_hd_t h, const void *k, size_t l)
¶Set the initialization vector used for encryption or decryption. The vector is passed as the buffer K of length l bytes and copied to internal data structures. The function checks that the IV matches the requirement of the selected algorithm and mode.
This function is also used by AEAD modes and with Salsa20 and ChaCha20 stream ciphers to set or update the required nonce. In these cases it needs to be called after setting the key.
gcry_error_t
gcry_cipher_setctr (gcry_cipher_hd_t h, const void *c, size_t l)
¶Set the counter vector used for encryption or decryption. The counter is passed as the buffer c of length l bytes and copied to internal data structures. The function checks that the counter matches the requirement of the selected algorithm (i.e.,, it must have the same size as the block size).
gcry_error_t
gcry_cipher_reset (gcry_cipher_hd_t h)
¶Set the given handle’s context back to the state it had after the last
call to gcry_cipher_setkey
and clear the initialization vector.
Note that gcry_cipher_reset
is implemented as a macro.
Authenticated Encryption with Associated Data (AEAD) block cipher modes require the handling of the authentication tag and the additional authenticated data, which can be done by using the following functions:
gcry_error_t
gcry_cipher_authenticate (gcry_cipher_hd_t h, const void *abuf, size_t abuflen)
¶Process the buffer abuf of length abuflen as the additional authenticated data (AAD) for AEAD cipher modes.
gcry_error_t
gcry_cipher_gettag (gcry_cipher_hd_t h, void *tag, size_t taglen)
¶This function is used to read the authentication tag after encryption. The function finalizes and outputs the authentication tag to the buffer tag of length taglen bytes.
Depending on the used mode certain restrictions for taglen are enforced: For GCM taglen must be at least 16 or one of the allowed truncated lengths (4, 8, 12, 13, 14, or 15).
gcry_error_t
gcry_cipher_checktag (gcry_cipher_hd_t h, const void *tag, size_t taglen)
¶Check the authentication tag after decryption. The authentication
tag is passed as the buffer tag of length taglen bytes
and compared to internal authentication tag computed during
decryption. Error code GPG_ERR_CHECKSUM
is returned if
the authentication tag in the buffer tag does not match
the authentication tag calculated during decryption.
Depending on the used mode certain restrictions for taglen are enforced: For GCM taglen must either be 16 or one of the allowed truncated lengths (4, 8, 12, 13, 14, or 15).
For encryption of AEAD cipher modes, it should be possible to generate
an initialization vector internally within libgcrypt implementation,
in coordinated way, instead of calling gcry_cipher_setiv
with
arbitrary value, so that it can ensure the security properties of AEAD
block cipher. For this purpose, the following two functions are provided:
gcry_error_t
gcry_cipher_setup_geniv (gcry_cipher_hd_t h, int method, const void *fixed_iv, size_t fixed_ivlen, const void *dyn_iv, size_t dyn_ivlen)
¶Set up an initialization vector generation for AEAD cipher modes.
Generation is specified by method, fixed part of initialization
vector by fixed_iv and fixed_ivlen, and dynamic part of
initialization vector by dyn_iv and dyn_ivlen.
For method, valid values are GCRY_CIPHER_GENIV_METHOD_CONCAT
and GCRY_CIPHER_GENIV_METHOD_XOR
.
gcry_error_t
gcry_cipher_geniv (gcry_cipher_hd_t h, void *iv, size_t ivlen)
¶Generate the initialization vector into the output buffer iv
with length ivlen. The initialization vector will be used by
following gcry_cipher_encrypt
call.
The actual encryption and decryption is done by using one of the following functions. They may be used as often as required to process all the data.
gcry_error_t
gcry_cipher_encrypt (gcry_cipher_hd_t h, unsigned char *out, size_t outsize, const unsigned char *in, size_t inlen)
¶gcry_cipher_encrypt
is used to encrypt the data. This function
can either work in place or with two buffers. It uses the cipher
context already setup and described by the handle h. There are 2
ways to use the function: If in is passed as NULL
and
inlen is 0
, in-place encryption of the data in out of
length outsize takes place. With in being not NULL
,
inlen bytes are encrypted to the buffer out which must have
at least a size of inlen. outsize must be set to the
allocated size of out, so that the function can check that there
is sufficient space. Note that overlapping buffers are not allowed.
Depending on the selected algorithms and encryption mode, the length of the buffers must be a multiple of the block size.
Some encryption modes require that gcry_cipher_final
is used
before the final data chunk is passed to this function.
The function returns 0
on success or an error code.
gcry_error_t
gcry_cipher_decrypt (gcry_cipher_hd_t h, unsigned char *out, size_t outsize, const unsigned char *in, size_t inlen)
¶gcry_cipher_decrypt
is used to decrypt the data. This function
can either work in place or with two buffers. It uses the cipher
context already setup and described by the handle h. There are 2
ways to use the function: If in is passed as NULL
and
inlen is 0
, in-place decryption of the data in out or
length outsize takes place. With in being not NULL
,
inlen bytes are decrypted to the buffer out which must have
at least a size of inlen. outsize must be set to the
allocated size of out, so that the function can check that there
is sufficient space. Note that overlapping buffers are not allowed.
Depending on the selected algorithms and encryption mode, the length of the buffers must be a multiple of the block size.
Some encryption modes require that gcry_cipher_final
is used
before the final data chunk is passed to this function.
The function returns 0
on success or an error code.
The OCB mode features integrated padding and must thus be told about the end of the input data. This is done with:
gcry_error_t
gcry_cipher_final (gcry_cipher_hd_t h)
¶Set a flag in the context to tell the encrypt and decrypt functions that their next call will provide the last chunk of data. Only the first call to this function has an effect and only for modes which support it. Checking the error is in general not necessary. This is implemented as a macro.
The SIV mode and the GCM-SIV mode requires decryption tag to be input before decryption. This is done with:
gcry_error_t
gcry_cipher_set_decryption_tag (gcry_cipher_hd_t h, const void *tag, size_t taglen)
¶Set decryption tag for SIV or GCM-SIV mode decryption. This is implemented as a macro.
OpenPGP (as defined in RFC-4880) requires a special sync operation in some places. The following function is used for this:
gcry_error_t
gcry_cipher_sync (gcry_cipher_hd_t h)
¶Perform the OpenPGP sync operation on context h. Note that this
is a no-op unless the context was created with the flag
GCRY_CIPHER_ENABLE_SYNC
.
Some of the described functions are implemented as macros utilizing a catch-all control function. This control function is rarely used directly but there is nothing which would inhibit it:
gcry_error_t
gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
¶gcry_cipher_ctl
controls various aspects of the cipher module and
specific cipher contexts. Usually some more specialized functions or
macros are used for this purpose. The semantics of the function and its
parameters depends on the command cmd and the passed context
handle h. Please see the comments in the source code
(src/global.c
) for details.
GCRYCTL_SET_ALLOW_WEAK_KEY:
This may be used to allow use of weak keys for certain block ciphers.
buffer must be given as NULL
. To allow weak keys for
a cipher context h, set buflen to ’1’. To disallow weak
keys, set buflen to ’0’.
Default setting for a cipher context is to disallow weak keys.
Note that even if weak keys are allowed, gcry_cipher_setkey
will
return error code GPG_ERR_WEAK_KEY
if a weak key is detected.
However, the cipher context is configured with the weak key and can
proceed with encryption/decryption. When weak keys are disallowed,
error code GPG_ERR_WEAK_KEY
is returned and the cipher context
is cannot be used for encryption/decryption.
gcry_error_t
gcry_cipher_info (gcry_cipher_hd_t h, int what, void *buffer, size_t *nbytes)
¶gcry_cipher_info
is used to retrieve various
information about a cipher context or the cipher module in general.
GCRYCTL_GET_TAGLEN:
Return the length of the tag for an AE algorithm mode. An error is
returned for modes which do not support a tag. buffer must be
given as NULL
. On success the result is stored nbytes. The
taglen is returned in bytes.