Next: , Previous: Cryptographic Functions, Up: Public Key cryptography


6.5 General public-key related Functions

A couple of utility functions are available to retrieve the length of the key, map algorithm identifiers and perform sanity checks:

— Function: const char * gcry_pk_algo_name (int algo)

Map the public key algorithm id algo to a string representation of the algorithm name. For unknown algorithms this functions returns the string "?". This function should not be used to test for the availability of an algorithm.

— Function: int gcry_pk_map_name (const char *name)

Map the algorithm name to a public key algorithm Id. Returns 0 if the algorithm name is not known.

— Function: int gcry_pk_test_algo (int algo)

Return 0 if the public key algorithm algo is available for use. Note that this is implemented as a macro.

— Function: unsigned int gcry_pk_get_nbits (gcry_sexp_t key)

Return what is commonly referred as the key length for the given public or private in key.

— Function: unsigned char * gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)

Return the so called "keygrip" which is the SHA-1 hash of the public key parameters expressed in a way depended on the algorithm. array must either provide space for 20 bytes or be NULL. In the latter case a newly allocated array of that size is returned. On success a pointer to the newly allocated space or to array is returned. NULL is returned to indicate an error which is most likely an unknown algorithm or one where a "keygrip" has not yet been defined. The function accepts public or secret keys in key.

— Function: gcry_error_t gcry_pk_testkey (gcry_sexp_t key)

Return zero if the private key key is `sane', an error code otherwise. Note that it is not possible to check the `saneness' of a public key.

— Function: gcry_error_t gcry_pk_algo_info (int algo, int what, void *buffer, size_t *nbytes)

Depending on the value of what return various information about the public key algorithm with the id algo. Note that the function returns -1 on error and the actual error code must be retrieved using the function gcry_errno. The currently defined values for what are:

GCRYCTL_TEST_ALGO:
Return 0 if the specified algorithm is available for use. buffer must be NULL, nbytes may be passed as NULL or point to a variable with the required usage of the algorithm. This may be 0 for "don't care" or the bit-wise OR of these flags:
GCRY_PK_USAGE_SIGN
Algorithm is usable for signing.
GCRY_PK_USAGE_ENCR
Algorithm is usable for encryption.

Unless you need to test for the allowed usage, it is in general better to use the macro gcry_pk_test_algo instead.

GCRYCTL_GET_ALGO_USAGE:
Return the usage flags for the given algorithm. An invalid algorithm return 0. Disabled algorithms are ignored here because we want to know whether the algorithm is at all capable of a certain usage.
GCRYCTL_GET_ALGO_NPKEY
Return the number of elements the public key for algorithm algo consist of. Return 0 for an unknown algorithm.
GCRYCTL_GET_ALGO_NSKEY
Return the number of elements the private key for algorithm algo consist of. Note that this value is always larger than that of the public key. Return 0 for an unknown algorithm.
GCRYCTL_GET_ALGO_NSIGN
Return the number of elements a signature created with the algorithm algo consists of. Return 0 for an unknown algorithm or for an algorithm not capable of creating signatures.
GCRYCTL_GET_ALGO_NENC
Return the number of elements a encrypted message created with the algorithm algo consists of. Return 0 for an unknown algorithm or for an algorithm not capable of encryption.

Please note that parameters not required should be passed as NULL.

— Function: gcry_error_t gcry_pk_ctl (int cmd, void *buffer, size_t buflen)

This is a general purpose function to perform certain control operations. cmd controls what is to be done. The return value is 0 for success or an error code. Currently supported values for cmd are:

GCRYCTL_DISABLE_ALGO
Disable the algorithm given as an algorithm id in buffer. buffer must point to an int variable with the algorithm id and buflen must have the value sizeof (int).

Libgcrypt also provides a function to generate public key pairs:

— Function: gcry_error_t gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t parms)

This function create a new public key pair using information given in the S-expression parms and stores the private and the public key in one new S-expression at the address given by r_key. In case of an error, r_key is set to NULL. The return code is 0 for success or an error code otherwise.

Here is an example for parms to create an 2048 bit RSA key:

          (genkey
            (rsa
              (nbits 4:2048)))

To create an Elgamal key, substitute "elg" for "rsa" and to create a DSA key use "dsa". Valid ranges for the key length depend on the algorithms; all commonly used key lengths are supported. Currently supported parameters are:

nbits
This is always required to specify the length of the key. The argument is a string with a number in C-notation. The value should be a multiple of 8.
curve name
For ECC a named curve may be used instead of giving the number of requested bits. This allows to request a specific curve to override a default selection Libgcrypt would have taken if nbits has been given. The available names are listed with the description of the ECC public key parameters.
rsa-use-e
This is only used with RSA to give a hint for the public exponent. The value will be used as a base to test for a usable exponent. Some values are special:
0
Use a secure and fast value. This is currently the number 41.
1
Use a value as required by some crypto policies. This is currently the number 65537.
2
Reserved
> 2
Use the given value.

If this parameter is not used, Libgcrypt uses for historic reasons 65537.

qbits
This is only meanigful for DSA keys. If it is given the DSA key is generated with a Q parameyer of this size. If it is not given or zero Q is deduced from NBITS in this way:
512 <= N <= 1024
Q = 160
N = 2048
Q = 224
N = 3072
Q = 256
N = 7680
Q = 384
N = 15360
Q = 512
Note that in this case only the values for N, as given in the table, are allowed. When specifying Q all values of N in the range 512 to 15680 are valid as long as they are multiples of 8.
transient-key
This is only meaningful for RSA and DSA keys. This is a flag with no value. If given the RSA or DSA key is created using a faster and a somewhat less secure random number generator. This flag may be used for keys which are only used for a short time and do not require full cryptographic strength.
domain
This is only meaningful for DLP algorithms. If specified keys are generated with domain parameters taken from this list. The exact format of this parameter depends on the actual algorithm. It is currently only implemented for DSA using this format:
               (genkey
                 (dsa
                   (domain
                     (p p-mpi)
                     (q q-mpi)
                     (g q-mpi))))

nbits and qbits may not be specified because they are derived from the domain parameters.

derive-parms
This is currently only implemented for RSA and DSA keys. It is not allowed to use this together with a domain specification. If given, it is used to derive the keys using the given parameters.

If given for an RSA key the X9.31 key generation algorithm is used even if libgcrypt is not in FIPS mode. If given for a DSA key, the FIPS 186 algorithm is used even if libgcrypt is not in FIPS mode.

               (genkey
                 (rsa
                   (nbits 4:1024)
                   (rsa-use-e 1:3)
                   (derive-parms
                     (Xp1 #1A1916DDB29B4EB7EB6732E128#)
                     (Xp2 #192E8AAC41C576C822D93EA433#)
                     (Xp  #D8CD81F035EC57EFE822955149D3BFF70C53520D
                           769D6D76646C7A792E16EBD89FE6FC5B605A6493
                           39DFC925A86A4C6D150B71B9EEA02D68885F5009
                           B98BD984#)
                     (Xq1 #1A5CF72EE770DE50CB09ACCEA9#)
                     (Xq2 #134E4CAA16D2350A21D775C404#)
                     (Xq  #CC1092495D867E64065DEE3E7955F2EBC7D47A2D
                           7C9953388F97DDDC3E1CA19C35CA659EDC2FC325
                           6D29C2627479C086A699A49C4C9CEE7EF7BD1B34
                           321DE34A#))))
               (genkey
                 (dsa
                   (nbits 4:1024)
                   (derive-parms
                     (seed seed-mpi))))

use-x931
Force the use of the ANSI X9.31 key generation algorithm instead of the default algorithm. This flag is only meaningful for RSA and usually not required. Note that this algorithm is implicitly used if either derive-parms is given or Libgcrypt is in FIPS mode.
use-fips186
Force the use of the FIPS 186 key generation algorithm instead of the default algorithm. This flag is only meaningful for DSA and usually not required. Note that this algorithm is implicitly used if either derive-parms is given or Libgcrypt is in FIPS mode. As of now FIPS 186-2 is implemented; after the approval of FIPS 186-3 the code will be changed to implement 186-3.
use-fips186-2
Force the use of the FIPS 186-2 key generation algorithm instead of the default algorithm. This algorithm is slighlty different from FIPS 186-3 and allows only 1024 bit keys. This flag is only meaningful for DSA and only required for FIPS testing backward compatibility.

The key pair is returned in a format depending on the algorithm. Both private and public keys are returned in one container and may be accompanied by some miscellaneous information.

As an example, here is what the Elgamal key generation returns:

          (key-data
            (public-key
              (elg
                (p p-mpi)
                (g g-mpi)
                (y y-mpi)))
            (private-key
              (elg
                (p p-mpi)
                (g g-mpi)
                (y y-mpi)
                (x x-mpi)))
            (misc-key-info
              (pm1-factors n1 n2 ... nn))

As you can see, some of the information is duplicated, but this provides an easy way to extract either the public or the private key. Note that the order of the elements is not defined, e.g. the private key may be stored before the public key. n1 n2 ... nn is a list of prime numbers used to composite p-mpi; this is in general not a very useful information and only available if the key generation algorithm provides them.