[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

8. Public Key cryptography (II)

This chapter documents the alternative interface to asymmetric cryptography (ac) that is not based on S-expressions, but on native C data structures. As opposed to the pk interface described in the former chapter, this one follows an open/use/close paradigm like other building blocks of the library.

This interface has a few known problems; most noteworthy an inherent tendency to leak memory. It might not be available in forthcoming versions Libgcrypt.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

8.1 Available asymmetric algorithms

Libgcrypt supports the RSA (Rivest-Shamir-Adleman) algorithms as well as DSA (Digital Signature Algorithm) and Elgamal. The versatile interface allows to add more algorithms in the future.

Data type: gcry_ac_id_t

The following constants are defined for this type:

GCRY_AC_RSA

Rivest-Shamir-Adleman

GCRY_AC_DSA

Digital Signature Algorithm

GCRY_AC_ELG

Elgamal

GCRY_AC_ELG_E

Elgamal, encryption only.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

8.2 Working with sets of data

In the context of this interface the term `data set' refers to a list of `named MPI values' that is used by functions performing cryptographic operations; a named MPI value is a an MPI value, associated with a label.

Such data sets are used for representing keys, since keys simply consist of a variable amount of numbers. Furthermore some functions return data sets to the caller that are to be provided to other functions.

This section documents the data types, symbols and functions that are relevant for working with data sets.

Data type: gcry_ac_data_t

A single data set.

The following flags are supported:

GCRY_AC_FLAG_DEALLOC

Used for storing data in a data set. If given, the data will be released by the library. Note that whenever one of the ac functions is about to release objects because of this flag, the objects are expected to be stored in memory allocated through the Libgcrypt memory management. In other words: gcry_free() is used instead of free().

GCRY_AC_FLAG_COPY

Used for storing/retrieving data in/from a data set. If given, the library will create copies of the provided/contained data, which will then be given to the user/associated with the data set.

Function: gcry_error_t gcry_ac_data_new (gcry_ac_data_t *data)

Creates a new, empty data set and stores it in data.

Function: void gcry_ac_data_destroy (gcry_ac_data_t data)

Destroys the data set data.

Function: gcry_error_t gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags, char *name, gcry_mpi_t mpi)

Add the value mpi to data with the label name. If flags contains GCRY_AC_FLAG_DATA_COPY, the data set will contain copies of name and mpi. If flags contains GCRY_AC_FLAG_DATA_DEALLOC or GCRY_AC_FLAG_DATA_COPY, the values contained in the data set will be deallocated when they are to be removed from the data set.

Function: gcry_error_t gcry_ac_data_copy (gcry_ac_data_t *data_cp, gcry_ac_data_t data)

Create a copy of the data set data and store it in data_cp. FIXME: exact semantics undefined.

Function: unsigned int gcry_ac_data_length (gcry_ac_data_t data)

Returns the number of named MPI values inside of the data set data.

Function: gcry_error_t gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags, char *name, gcry_mpi_t *mpi)

Store the value labelled with name found in data in mpi. If flags contains GCRY_AC_FLAG_COPY, store a copy of the mpi value contained in the data set. mpi may be NULL (this might be useful for checking the existence of an MPI with extracting it).

Function: gcry_error_t gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags, unsigned int index, const char **name, gcry_mpi_t *mpi)

Stores in name and mpi the named mpi value contained in the data set data with the index idx. If flags contains GCRY_AC_FLAG_COPY, store copies of the values contained in the data set. name or mpi may be NULL.

Function: void gcry_ac_data_clear (gcry_ac_data_t data)

Destroys any values contained in the data set data.

Function: gcry_error_t gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp, const char **identifiers)

This function converts the data set data into a newly created S-Expression, which is to be stored in sexp; identifiers is a NULL terminated list of C strings, which specifies the structure of the S-Expression.

Example:

If identifiers is a list of pointers to the strings "foo" and "bar" and if data is a data set containing the values "val1 = 0x01" and "val2 = 0x02", then the resulting S-Expression will look like this: (foo (bar ((val1 0x01) (val2 0x02))).

Function: gcry_error gcry_ac_data_from_sexp (gcry_ac_data_t *data, gcry_sexp_t sexp, const char **identifiers)

This function converts the S-Expression sexp into a newly created data set, which is to be stored in data; identifiers is a NULL terminated list of C strings, which specifies the structure of the S-Expression. If the list of identifiers does not match the structure of the S-Expression, the function fails.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

8.3 Working with IO objects

Note: IO objects are currently only used in the context of message encoding/decoding and encryption/signature schemes.

Data type: gcry_ac_io_t

gcry_ac_io_t is the type to be used for IO objects.

IO objects provide an uniform IO layer on top of different underlying IO mechanisms; either they can be used for providing data to the library (mode is GCRY_AC_IO_READABLE) or they can be used for retrieving data from the library (mode is GCRY_AC_IO_WRITABLE).

IO object need to be initialized by calling on of the following functions:

Function: void gcry_ac_io_init (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode, gcry_ac_io_type_t type, ...);

Initialize ac_io according to mode, type and the variable list of arguments. The list of variable arguments to specify depends on the given type.

Function: void gcry_ac_io_init_va (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode, gcry_ac_io_type_t type, va_list ap);

Initialize ac_io according to mode, type and the variable list of arguments ap. The list of variable arguments to specify depends on the given type.

The following types of IO objects exist:

GCRY_AC_IO_STRING

In case of GCRY_AC_IO_READABLE the IO object will provide data from a memory string. Arguments to specify at initialization time:

unsigned char *

Pointer to the beginning of the memory string

size_t

Size of the memory string

In case of GCRY_AC_IO_WRITABLE the object will store retrieved data in a newly allocated memory string. Arguments to specify at initialization time:

unsigned char **

Pointer to address, at which the pointer to the newly created memory string is to be stored

size_t *

Pointer to address, at which the size of the newly created memory string is to be stored

GCRY_AC_IO_CALLBACK

In case of GCRY_AC_IO_READABLE the object will forward read requests to a provided callback function. Arguments to specify at initialization time:

gcry_ac_data_read_cb_t

Callback function to use

void *

Opaque argument to provide to the callback function

In case of GCRY_AC_IO_WRITABLE the object will forward write requests to a provided callback function. Arguments to specify at initialization time:

gcry_ac_data_write_cb_t

Callback function to use

void *

Opaque argument to provide to the callback function


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

8.4 Working with handles

In order to use an algorithm, an according handle must be created. This is done using the following function:

Function: gcry_error_t gcry_ac_open (gcry_ac_handle_t *handle, int algorithm, int flags)

Creates a new handle for the algorithm algorithm and stores it in handle. flags is not used currently.

algorithm must be a valid algorithm ID, see See section Available algorithms, for a list of supported algorithms and the according constants. Besides using the listed constants directly, the functions gcry_pk_name_to_id may be used to convert the textual name of an algorithm into the according numeric ID.

Function: void gcry_ac_close (gcry_ac_handle_t handle)

Destroys the handle handle.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

8.5 Working with keys

Data type: gcry_ac_key_type_t

Defined constants:

GCRY_AC_KEY_TYPE_SECRET

Specifies a secret key.

GCRY_AC_KEY_TYPE_PUBLIC

Specifies a public key.

Data type: gcry_ac_key_t

This type represents a single `key', either a secret one or a public one.

Data type: gcry_ac_key_pair_t

This type represents a `key pair' containing a secret and a public key.

Key data structures can be created in two different ways; a new key pair can be generated, resulting in ready-to-use key. Alternatively a key can be initialized from a given data set.

Function: gcry_error_t gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle, gcry_ac_key_type_t type, gcry_ac_data_t data)

Creates a new key of type type, consisting of the MPI values contained in the data set data and stores it in key.

Function: gcry_error_t gcry_ac_key_pair_generate (gcry_ac_handle_t handle, unsigned int nbits, void *key_spec, gcry_ac_key_pair_t *key_pair, gcry_mpi_t **misc_data)

Generates a new key pair via the handle handle of NBITS bits and stores it in key_pair.

In case non-standard settings are wanted, a pointer to a structure of type gcry_ac_key_spec_<algorithm>_t, matching the selected algorithm, can be given as key_spec. misc_data is not used yet. Such a structure does only exist for RSA. A description of the members of the supported structures follows.

gcry_ac_key_spec_rsa_t
gcry_mpi_t e

Generate the key pair using a special e. The value of e has the following meanings:

= 0

Let Libgcrypt decide what exponent should be used.

= 1

Request the use of a "secure" exponent; this is required by some specification to be 65537.

> 2

Try starting at this value until a working exponent is found. Note that the current implementation leaks some information about the private key because the incrementation used is not randomized. Thus, this function will be changed in the future to return a random exponent of the given size.

Example code:

 
{
  gcry_ac_key_pair_t key_pair;
  gcry_ac_key_spec_rsa_t  rsa_spec;

  rsa_spec.e = gcry_mpi_new (0);
  gcry_mpi_set_ui (rsa_spec.e, 1)

  err = gcry_ac_open  (&handle, GCRY_AC_RSA, 0);
  assert (! err);

  err = gcry_ac_key_pair_generate (handle, &key_pair, 1024, (void *) &rsa_spec);
  assert (! err);
}
Function: gcry_ac_key_t gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair, gcry_ac_key_type_t which)

Returns the key of type which out of the key pair key_pair.

Function: void gcry_ac_key_destroy (gcry_ac_key_t key)

Destroys the key key.

Function: void gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair)

Destroys the key pair key_pair.

Function: gcry_ac_data_t gcry_ac_key_data_get (gcry_ac_key_t key)

Returns the data set contained in the key key.

Function: gcry_error_t gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key)

Verifies that the private key key is sane via handle.

Function: gcry_error_t gcry_ac_key_get_nbits (gcry_ac_handle_t handle, gcry_ac_key_t key, unsigned int *nbits)

Stores the number of bits of the key key in nbits via handle.

Function: gcry_error_t gcry_ac_key_get_grip (gcry_ac_handle_t handle, gcry_ac_key_t key, unsigned char *key_grip)

Writes the 20 byte long key grip of the key key to key_grip via handle.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

8.6 Using cryptographic functions

The following flags might be relevant:

GCRY_AC_FLAG_NO_BLINDING

Disable any blinding, which might be supported by the chosen algorithm; blinding is the default.

There exist two kinds of cryptographic functions available through the ac interface: primitives, and high-level functions.

Primitives deal with MPIs (data sets) directly; what they provide is direct access to the cryptographic operations provided by an algorithm implementation.

High-level functions deal with octet strings, according to a specified "scheme". Schemes make use of "encoding methods", which are responsible for converting the provided octet strings into MPIs, which are then forwared to the cryptographic primitives. Since schemes are to be used for a special purpose in order to achieve a particular security goal, there exist "encryption schemes" and "signature schemes". Encoding methods can be used seperately or implicitly through schemes.

What follows is a description of the cryptographic primitives.

Function: gcry_error_t gcry_ac_data_encrypt (gcry_ac_handle_t handle, unsigned int flags, gcry_ac_key_t key, gcry_mpi_t data_plain, gcry_ac_data_t **data_encrypted)

Encrypts the plain text MPI value data_plain with the key public key under the control of the flags flags and stores the resulting data set into data_encrypted.

Function: gcry_error_t gcry_ac_data_decrypt (gcry_ac_handle_t handle, unsigned int flags, gcry_ac_key_t key, gcry_mpi_t *data_plain, gcry_ac_data_t data_encrypted)

Decrypts the encrypted data contained in the data set data_encrypted with the secret key KEY under the control of the flags flags and stores the resulting plain text MPI value in DATA_PLAIN.

Function: gcry_error_t gcry_ac_data_sign (gcry_ac_handle_t handle, gcry_ac_key_t key, gcry_mpi_t data, gcry_ac_data_t *data_signature)

Signs the data contained in data with the secret key key and stores the resulting signature in the data set data_signature.

Function: gcry_error_t gcry_ac_data_verify (gcry_ac_handle_t handle, gcry_ac_key_t key, gcry_mpi_t data, gcry_ac_data_t data_signature)

Verifies that the signature contained in the data set data_signature is indeed the result of signing the data contained in data with the secret key belonging to the public key key.

What follows is a description of the high-level functions.

The type "gcry_ac_em_t" is used for specifying encoding methods; the following methods are supported:

GCRY_AC_EME_PKCS_V1_5

PKCS-V1_5 Encoding Method for Encryption. Options must be provided through a pointer to a correctly initialized object of type gcry_ac_eme_pkcs_v1_5_t.

GCRY_AC_EMSA_PKCS_V1_5

PKCS-V1_5 Encoding Method for Signatures with Appendix. Options must be provided through a pointer to a correctly initialized object of type gcry_ac_emsa_pkcs_v1_5_t.

Option structure types:

gcry_ac_eme_pkcs_v1_5_t
gcry_ac_key_t key
gcry_ac_handle_t handle
gcry_ac_emsa_pkcs_v1_5_t
gcry_md_algo_t md
size_t em_n

Encoding methods can be used directly through the following functions:

Function: gcry_error_t gcry_ac_data_encode (gcry_ac_em_t method, unsigned int flags, void *options, unsigned char *m, size_t m_n, unsigned char **em, size_t *em_n)

Encodes the message contained in m of size m_n according to method, flags and options. The newly created encoded message is stored in em and em_n.

Function: gcry_error_t gcry_ac_data_decode (gcry_ac_em_t method, unsigned int flags, void *options, unsigned char *em, size_t em_n, unsigned char **m, size_t *m_n)

Decodes the message contained in em of size em_n according to method, flags and options. The newly created decoded message is stored in m and m_n.

The type "gcry_ac_scheme_t" is used for specifying schemes; the following schemes are supported:

GCRY_AC_ES_PKCS_V1_5

PKCS-V1_5 Encryption Scheme. No options can be provided.

GCRY_AC_SSA_PKCS_V1_5

PKCS-V1_5 Signature Scheme (with Appendix). Options can be provided through a pointer to a correctly initialized object of type gcry_ac_ssa_pkcs_v1_5_t.

Option structure types:

gcry_ac_ssa_pkcs_v1_5_t
gcry_md_algo_t md

The functions implementing schemes:

Function: gcry_error_t gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle, gcry_ac_scheme_t scheme, unsigned int flags, void *opts, gcry_ac_key_t key, gcry_ac_io_t *io_message, gcry_ac_io_t *io_cipher)

Encrypts the plain text readable from io_message through handle with the public key key according to scheme, flags and opts. If opts is not NULL, it has to be a pointer to a structure specific to the chosen scheme (gcry_ac_es_*_t). The encrypted message is written to io_cipher.

Function: gcry_error_t gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle, gcry_ac_scheme_t scheme, unsigned int flags, void *opts, gcry_ac_key_t key, gcry_ac_io_t *io_cipher, gcry_ac_io_t *io_message)

Decrypts the cipher text readable from io_cipher through handle with the secret key key according to scheme, flags and opts. If opts is not NULL, it has to be a pointer to a structure specific to the chosen scheme (gcry_ac_es_*_t). The decrypted message is written to io_message.

Function: gcry_error_t gcry_ac_data_sign_scheme (gcry_ac_handle_t handle, gcry_ac_scheme_t scheme, unsigned int flags, void *opts, gcry_ac_key_t key, gcry_ac_io_t *io_message, gcry_ac_io_t *io_signature)

Signs the message readable from io_message through handle with the secret key key according to scheme, flags and opts. If opts is not NULL, it has to be a pointer to a structure specific to the chosen scheme (gcry_ac_ssa_*_t). The signature is written to io_signature.

Function: gcry_error_t gcry_ac_data_verify_scheme (gcry_ac_handle_t handle, gcry_ac_scheme_t scheme, unsigned int flags, void *opts, gcry_ac_key_t key, gcry_ac_io_t *io_message, gcry_ac_io_t *io_signature)

Verifies through handle that the signature readable from io_signature is indeed the result of signing the message readable from io_message with the secret key belonging to the public key key according to scheme and opts. If opts is not NULL, it has to be an anonymous structure (gcry_ac_ssa_*_t) specific to the chosen scheme.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

8.7 Handle-independent functions

These two functions are deprecated; do not use them for new code.

Function: gcry_error_t gcry_ac_id_to_name (gcry_ac_id_t algorithm, const char **name)

Stores the textual representation of the algorithm whose id is given in algorithm in name. Deprecated; use gcry_pk_algo_name.

Function: gcry_error_t gcry_ac_name_to_id (const char *name, gcry_ac_id_t *algorithm)

Stores the numeric ID of the algorithm whose textual representation is contained in name in algorithm. Deprecated; use gcry_pk_map_name.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by root on December, 21 2007 using texi2html 1.76.