Certain functions such as (for example) ``rsa\_export()'' give an output that is variable length. To prevent buffer overflows you
must pass it the length of the buffer\footnote{Extensive error checking is not in place but it will be in future releases so it is a good idea to follow through with these guidelines.} where
the output will be stored. For example:
\begin{small}
\begin{verbatim}
#include <mycrypt.h>
int main(void) {
rsa_key key;
unsigned char buffer[1024];
unsigned long x;
int errno;
/* ... Make up the RSA key somehow */
/* lets export the key, set x to the size of the output buffer */
x = sizeof(buffer);
if ((errno = rsa_export(buffer, &x, PK_PUBLIC, &key)) != CRYPT_OK) {
These two functions will encrypt or decrypt (respectively) a single block of text\footnote{The size of which depends on
which cipher you are using.} and store the result where you want it. It is possible that the input and output buffer are
the same buffer. For the encrypt function ``pt''\footnote{pt stands for plaintext.} is the input and ``ct'' is the output.
For the decryption function its the opposite. To test a particular cipher against test vectors\footnote{As published in their design papers.} call: \index{Cipher Testing}
\begin{verbatim}
int XXX_test(void);
\end{verbatim}
This function will return {\bf CRYPT\_OK} if the cipher matches the test vectors from the design publication it is
based upon. Finally for each cipher there is a function which will help find a desired key size:
\begin{verbatim}
int XXX_keysize(int *keysize);
\end{verbatim}
Essentially it will round the input keysize in ``keysize'' down to the next appropriate key size. This function
return {\bf CRYPT\_OK} if the key size specified is acceptable. For example:
\begin{small}
\begin{verbatim}
#include <mycrypt.h>
int main(void)
{
int keysize, errno;
/* now given a 20 byte key what keysize does Twofish want to use? */
keysize = 20;
if ((errno = twofish_keysize(&keysize)) != CRYPT_OK) {
Like the ciphers there are hash core functions and a universal data type to hold the hash state called ``hash\_state''.
To initialize hash XXX (where XXX is the name) call:
\index{Hash Functions}
\begin{verbatim}
void XXX_init(hash_state *md);
\end{verbatim}
This simply sets up the hash to the default state governed by the specifications of the hash. To add data to the
message being hashed call:
\begin{verbatim}
void XXX_process(hash_state *md, const unsigned char *in, unsigned long len);
\end{verbatim}
Essentially all hash messages are virtually infinitely\footnote{Most hashes are limited to $2^{64}$ bits or 2,305,843,009,213,693,952 bytes.} long message which
are buffered. The data can be passed in any sized chunks as long as the order of the bytes are the same the message digest
(hash output) will be the same. For example, this means that:
\begin{verbatim}
md5_process(&md, "hello ", 6);
md5_process(&md, "world", 5);
\end{verbatim}
Will produce the same message digest as the single call:
\index{Message Digest}
\begin{verbatim}
md5_process(&md, "hello world", 11);
\end{verbatim}
To finally get the message digest (the hash) call:
\begin{verbatim}
void XXX_done(hash_state *md,
unsigned char *out);
\end{verbatim}
This function will finish up the hash and store the result in the ``out'' array. You must ensure that ``out'' is long
enough for the hash in question. Often hashes are used to get keys for symmetric ciphers so the ``XXX\_done()'' functions
will wipe the ``md'' variable before returning automatically.
To test a hash function call:
\begin{verbatim}
int XXX_test(void);
\end{verbatim}
This will return {\bf CRYPTO\_OK} if the hash matches the test vectors, otherwise it returns an error code. An
example snippet that hashes a message with md5 is given below.
\begin{small}
\begin{verbatim}
#include <mycrypt.h>
int main(void)
{
hash_state md;
unsigned char *in = "hello world", out[16];
/* setup the hash */
md5_init(&md);
/* add the message */
md5_process(&md, in, strlen(in));
/* get the hash */
md5_done(&md, out);
return 0;
}
\end{verbatim}
\end{small}
\section{Hash Descriptors}
\index{Hash Descriptors}
Like the set of ciphers the set of hashes have descriptors too. They are stored in an array called ``hash\_descriptor'' and
are defined by:
\begin{verbatim}
struct _hash_descriptor {
char *name;
unsigned long hashsize; /* digest output size in bytes */
unsigned long blocksize; /* the block size the hash uses */
The following hashes are provided as of this release:
\begin{center}
\begin{tabular}{|c|c|c|}
\hline Name & Descriptor Name & Size of Message Digest (bytes) \\
\hline SHA-512 & sha512\_desc & 64 \\
\hline SHA-384 & sha384\_desc & 48 \\
\hline SHA-256 & sha256\_desc & 32 \\
\hline TIGER-192 & tiger\_desc & 24 \\
\hline SHA-1 & sha1\_desc & 20 \\
\hline MD5 & md5\_desc & 16 \\
\hline MD4 & md4\_desc & 16 \\
\hline MD2 & md2\_desc & 16 \\
\hline
\end{tabular}
\end{center}
Similar to the cipher descriptor table you must register your hash algorithms before you can use them. These functions
work exactly like those of the cipher registration code. The functions are:
\begin{verbatim}
int register_hash(const struct _hash_descriptor *hash);
int unregister_hash(const struct _hash_descriptor *hash);
\end{verbatim}
\subsection{Notice}
It is highly recommended that you not use the MD4 or MD5 hashes for the purposes of digital signatures or authentication codes.
These hashes are provided for completeness and they still can be used for the purposes of password hashing or one-way accumulators
(e.g. Yarrow).
The other hashes such as the SHA-1, SHA-2 (that includes SHA-512, SHA-384 and SHA-256) and TIGER-192 are still considered secure
for all purposes you would normally use a hash for.
\section{Hash based Message Authenication Codes}
Thanks to Dobes Vandermeer the library now includes support for hash based message authenication codes or HMAC for short. An HMAC
of a message is a keyed authenication code that only the owner of a private symmetric key will be able to verify. The purpose is
to allow an owner of a private symmetric key to produce an HMAC on a message then later verify if it is correct. Any impostor or
eavesdropper will not be able to verify the authenticity of a message.
The HMAC support works much like the normal hash functions except that the initialization routine requires you to pass a key
and its length. The key is much like a key you would pass to a cipher. That is, it is simply an array of octets stored in
chars. The initialization routine is:
\begin{verbatim}
int hmac_init(hmac_state *hmac, int hash,
const unsigned char *key, unsigned long keylen);
\end{verbatim}
The ``hmac'' parameter is the state for the HMAC code. ``hash'' is the index into the descriptor table of the hash you want
to use to authenticate the message. ``key'' is the pointer to the array of chars that make up the key. ``keylen'' is the
length (in octets) of the key you want to use to authenticate the message. To send octets of a message through the HMAC system you must use the following function:
\begin{verbatim}
int hmac_process(hmac_state *hmac, const unsigned char *buf,
unsigned long len);
\end{verbatim}
``hmac'' is the HMAC state you are working with. ``buf'' is the array of octets to send into the HMAC process. ``len'' is the
number of octets to process. Like the hash process routines you can send the data in arbitrarly sized chunks. When you
are finished with the HMAC process you must call the following function to get the HMAC code:
\begin{verbatim}
int hmac_done(hmac_state *hmac, unsigned char *hash);
\end{verbatim}
``hmac'' is the HMAC state you are working with. ``hash'' is the array of octets where the HMAC code should be stored. You
must ensure that your destination array is the right size (or just make it of size MAXBLOCKSIZE to be sure). There are
two utility functions provided to make using HMACs easier todo.
\begin{verbatim}
int hmac_memory(int hash, const unsigned char *key, unsigned long keylen,
const unsigned char *data, unsigned long len,
unsigned char *dst);
\end{verbatim}
This will produce an HMAC code for the array of octets in ``data'' of length ``len''. The index into the hash descriptor table must be provided in ``hash''
It uses the key from ``key'' with a key length of ``keylen''. The result is stored in the array of octets``dst''.
Similarly for files there is the following function:
\begin{verbatim}
int hmac_file(int hash, const char *fname, const unsigned char *key,
unsigned long keylen, unsigned char *dst);
\end{verbatim}
``hash'' is the index into the hash descriptor table of the hash you want to use. ``fname'' is the filename to process. ``key''
is the array of octets to use as the key. ``keylen'' is the length of the key. ``dst'' is the array of octets where the result
should be stored.
To test if the HMAC code is working there is the following function:
\begin{verbatim}
int hmac_test(void);
\end{verbatim}
Which returns {\bf CRYPT\_OK} if the code passes otherwise it returns an error code. Some example code for using the
HMAC system is given below.
\begin{small}
\begin{verbatim}
#include <mycrypt.h>
int main(void)
{
int idx, errno;
hmac_state hmac;
unsigned char key[16], dst[MAXBLOCKSIZE];
/* register SHA-1 */
if (register_hash(&sha1_desc) == -1) {
printf("Error registering SHA1\n");
return -1;
}
/* get index of SHA1 in hash descriptor table */
idx = find_hash("sha1");
/* we would make up our symmetric key in "key[]" here */
/* start the HMAC */
if ((errno = hmac_init(&hmac, idx, key, 16)) != CRYPT_OK) {
printf("Error setting up hmac: %s\n", error_to_string(errno));
An RNG is related to a PRNG except that it doesn't expand a smaller seed to get the data. They generate their random bits
by performing some computation on fresh input bits. Possibly the hardest thing to get correctly in a cryptosystem is the
PRNG. Computers are deterministic beasts that try hard not to stray from pre-determined paths. That makes gathering
entropy needed to seed the PRNG a hard task.
There is one small function that may help on certain platforms:
\index{rng\_get\_bytes()}
\begin{verbatim}
unsigned long rng_get_bytes(unsigned char *buf, unsigned long len,
void (*callback)(void));
\end{verbatim}
Which will try one of three methods of getting random data. The first is to open the popular ``/dev/random'' device which
on most *NIX platforms provides cryptographic random bits\footnote{This device is available in Windows through the Cygwin compiler suite. It emulates ``/dev/random'' via the Microsoft CSP.}.
The second method is to try the Microsoft Cryptographic Service Provider and read the RNG. The third method is an ANSI C
clock drift method that is also somewhat popular but gives bits of lower entropy. The ``callback'' parameter is a pointer to a function that returns void. Its used when the slower ANSI C RNG must be
used so the calling application can still work. This is useful since the ANSI C RNG has a throughput of three
bytes a second. The callback pointer may be set to {\bf NULL} to avoid using it if you don't want to. The function
returns the number of bytes actually read from any RNG source. There is a function to help setup a PRNG as well:
\index{rng\_make\_prng()}
\begin{verbatim}
int rng_make_prng(int bits, int wprng, prng_state *prng,
void (*callback)(void));
\end{verbatim}
This will try to setup the prng with a state of at least ``bits'' of entropy. The ``callback'' parameter works much like
the callback in ``rng\_get\_bytes()''. It is highly recommended that you use this function to setup your PRNGs unless you have a
platform where the RNG doesn't work well. Example usage of this function is given below.
\begin{small}
\begin{verbatim}
#include <mycrypt.h>
int main(void)
{
ecc_key mykey;
prng_state prng;
int errno;
/* register yarrow */
if (register_prng(&yarrow_desc) == -1) {
printf("Error registering Yarrow\n");
return -1;
}
/* setup the PRNG */
if ((errno = rng_make_prng(128, find_prng("yarrow"), &prng, NULL)) != CRYPT_OK) {
printf("Error setting up PRNG, %s\n", error_to_string(errno));
return -1;
}
/* make a 192-bit ECC key */
if ((errno = ecc_make_key(&prng, find_prng("yarrow"), 24, &mykey)) != CRYPT_OK) {
printf("Error making key: %s\n", error_to_string(errno));
return -1;
}
return 0;
}
\end{verbatim}
\end{small}
\subsection{The Secure PRNG Interface}
It is possible to access the secure RNG through the PRNG interface and in turn use it within dependent functions such
as the PK API. This simplifies the cryptosystem on platforms where the secure RNG is fast. The secure PRNG never
requires to be started, that is you need not call the start, add\_entropy or ready functions. For example, consider
the previous example using this PRNG.
\begin{small}
\begin{verbatim}
#include <mycrypt.h>
int main(void)
{
ecc_key mykey;
int errno;
/* register SPRNG */
if (register_prng(&sprng_desc) == -1) {
printf("Error registering SPRNG\n");
return -1;
}
/* make a 192-bit ECC key */
if ((errno = ecc_make_key(NULL, find_prng("sprng"), 24, &mykey)) != CRYPT_OK) {
printf("Error making key: %s\n", error_to_string(errno));
return -1;
}
return 0;
}
\end{verbatim}
\end{small}
\chapter{RSA Routines}
\section{Background}
RSA is a public key algorithm that is based on the inability to find the ``e-th'' root modulo a composite of unknown
factorization. Normally the difficulty of breaking RSA is associated with the integer factoring problem but they are
not strictly equivalent.
The system begins with with two primes $p$ and $q$ and their product $N = pq$. The order or ``Euler totient'' of the
multiplicative sub-group formed modulo $N$ is given as $\phi(N)=(p -1)(q -1)$ which can be reduced to
$\mbox{lcm}(p -1, q -1)$. The public key consists of the composite $N$ and some integer $e$ such that
$\mbox{gcd}(e, \phi(N))=1$. The private key consists of the composite $N$ and the inverse of $e$ modulo $\phi(N)$
often simply denoted as $de \equiv1\mbox{}(\mbox{mod }\phi(N))$.
A person who wants to encrypt with your public key simply forms an integer (the plaintext) $M$ such that
$1 < M < N-2$ and computes the ciphertext $C = M^e\mbox{}(\mbox{mod }N)$. Since finding the inverse exponent $d$
given only $N$ and $e$ appears to be intractable only the owner of the private key can decrypt the ciphertext and compute
$C^d \equiv\left(M^e \right)^d \equiv M^1\equiv M\mbox{}(\mbox{mod }N)$. Similarly the owner of the private key
can sign a message by ``decrypting'' it. Others can verify it by ``encrypting'' it.
Currently RSA is a difficult system to cryptanalyze provided that both primes are large and not close to each other.
Ideally $e$ should be larger than $100$ to prevent direct analysis. For example, if $e$ is three and you do not pad
the plaintext to be encrypted than it is possible that $M^3 < N$ in which case finding the cube-root would be trivial.
The most often suggested value for $e$ is $65537$ since it is large enough to make such attacks impossible and also well
designed for fast exponentiation (requires 16 squarings and one multiplication).
It is important to pad the input to RSA since it has particular mathematical structure. For instance
$M_1^dM_2^d =(M_1M_2)^d$ which can be used to forge a signature. Suppose $M_3= M_1M_2$ is a message you want
to have a forged signature for. Simply get the signatures for $M_1$ and $M_2$ on their own and multiply the result
together. Similar tricks can be used to deduce plaintexts from ciphertexts. It is important not only to sign
the hash of documents only but also to pad the inputs with data to remove such structure.
\section{Core Functions}
For RSA routines a single ``rsa\_key'' structure is used. To make a new RSA key call:
\index{rsa\_make\_key()}
\begin{verbatim}
int rsa_make_key(prng_state *prng,
int wprng, int size,
long e, rsa_key *key);
\end{verbatim}
Where ``wprng'' is the index into the PRNG descriptor array. ``size'' is the size in bytes of the RSA modulus desired.
``e'' is the encryption exponent desired, typical values are 3, 17, 257 and 65537. I suggest you stick with 65537 since its big
enough to prevent trivial math attacks and not super slow. ``key'' is where the key is placed. All keys must be at
least 128 bytes and no more than 512 bytes in size (that is from 1024 to 4096 bits).
Note that the ``rsa\_make\_key()'' function allocates memory at runtime when you make the key. Make sure to call
``rsa\_free()'' (see below) when you are finished with the key. If ``rsa\_make\_key()'' fails it will automatically
free the ram allocated itself.
There are three types of RSA keys. The types are {\bf PK\_PRIVATE\_OPTIMIZED}, {\bf PK\_PRIVATE} and {\bf PK\_PUBLIC}. The first
two are private keys where the ``optimized'' type uses the Chinese Remainder Theorem to speed up decryption/signatures. By
default all new keys are of the ``optimized'' type. The non-optimized private type is provided for backwards compatibility
as well as to save space since the optimized key requires about four times as much memory.
To do raw work with the RSA function call:
\index{rsa\_exptmod()}
\begin{verbatim}
int rsa_exptmod(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
int which, rsa_key *key);
\end{verbatim}
This loads the bignum from ``in'' as a big endian word, raises it to either ``e'' or ``d'' and stores the result
in ``out'' and the size of the result in ``outlen''. ``which'' is set to {\bf PK\_PUBLIC} to use ``e''
(i.e. for encryption/verifying) and set to {\bf PK\_PRIVATE} to use ``d'' as the exponent (i.e. for decrypting/signing).
\section{Packet Routines}
The remaining RSA functions are non-standard but should (to the best of my knowledge) be secure if used correctly. To
encrypt a buffer of memory in a hybrid fashion call:
\index{rsa\_encrypt()}
\begin{verbatim}
int rsa_encrypt(const unsigned char *in, unsigned long len,
unsigned char *out, unsigned long *outlen,
prng_state *prng, int wprng, int cipher,
rsa_key *key);
\end{verbatim}
This will encrypt the message with the cipher specified by ``cipher'' under a random key made by a PRNG specified by
``wprng'' and RSA encrypt the symmetric key with ``key''. This stores all the relevant information in ``out'' and sets
the length in ``outlen''. You must ensure that ``outlen'' is set to the buffer size before calling this.
The rsa\_encrypt() function will use up to a 256-bit symmetric key (limited by the max key length of the cipher being
used). To decrypt packets made by this routine call:
\index{rsa\_decrypt()}
\begin{verbatim}
int rsa_decrypt(const unsigned char *in, unsigned long len,
unsigned char *out, unsigned long *outlen,
rsa_key *key);
\end{verbatim}
Which works akin to rsa\_encrypt(). ``in'' is the ciphertext and ``out'' is where the plaintext will be stored. Similarly
to sign/verify there are:
\index{rsa\_sign()}\index{rsa\_verify()}
\begin{verbatim}
int rsa_sign(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
int hash, rsa_key *key);
int rsa_verify(const unsigned char *sig,
const unsigned char *msg,
unsigned long inlen, int *stat,
rsa_key *key);
\end{verbatim}
The verify function sets ``stat'' to 1 if it passes or to 0 if it fails. The ``sig'' parameter is the output of the
rsa\_sign() function and ``msg'' is the original msg that was signed. An important fact to note is that with
the padding scheme used in ``rsa\_sign()'' you cannot use the SHA-384 or SHA-512 hash function with 1024 bit
RSA keys. This is because the padding makes the values too large to fit in the space allowed. You can use SHA-384
with 1160 and above bit RSA keys. You can use SHA-512 with 1544 and above bit RSA keys.
There are related functions to sign and verify hashes.
\begin{verbatim}
int rsa_sign_hash(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
rsa_key *key);
int rsa_verify_hash(const unsigned char *sig, const unsigned char *hash,
int *stat, rsa_key *key);
\end{verbatim}
Which works just like the two previous functions except the data is not hashed before being signed.
There are times where you may want to encrypt a message to multiple recipients via RSA public keys. The simplest way to
accomplish this is to make up your own symmetric key and then RSA encrypt the symmetric key using all of the recipients
public keys. To facilitate this task two functions\footnote{Donated by Clay Culver.} are available:
\begin{verbatim}
int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen,
unsigned char *outkey, unsigned long *outlen,
prng_state *prng, int wprng, rsa_key *key);
int rsa_decrypt_key(const unsigned char *in, unsigned char *outkey,
unsigned long *keylen, rsa_key *key);
\end{verbatim}
The ``rsa\_encrypt\_key()'' function accepts a symmetric key (limited to 32 bytes) as input in ``inkey''. ``inlen''
is the size of the input key in bytes. The function will then ``rsa\_pad()'' the key and encrypt it using the RSA
algorithm. It will store the result in ``outkey'' along with the length in ``outlen''. The ``rsa\_decrypt\_key()'' function
performs the opposite. The ``in'' variable is where the RSA packet goes and it will store the original symmetric key in
the ``outkey'' variable along with its length in ``keylen''.
To import/export RSA keys as a memory buffer (e.g. to store them to disk) call:
\begin{verbatim}
int rsa_export(unsigned char *out, unsigned long *outlen,
int type, rsa_key *key);
int rsa_import(const unsigned char *in, rsa_key *key);
\end{verbatim}
The ``type'' parameter is {\bf PK\_PUBLIC}, {\bf PK\_PRIVATE} or {\bf PK\_PRIVATE\_OPTIMIZED} to export either a public or
private key. The latter type will export a key with the optimized parameters. To free the memory used by an RSA key call:
\index{rsa\_free()}
\begin{verbatim}
void rsa_free(rsa_key *key);
\end{verbatim}
Note that if the key fails to ``rsa\_import()'' you do not have to free the memory allocated for it.
\section{Remarks}
It is important that you match your RSA key size with the function you are performing. The internal padding for both
signatures and encryption triple the size of the plaintext you send to rsa\_exptmod(). This means to encrypt or sign
a message of N bytes with rsa\_exptmod() you must have a modulus of 1+3N bytes. Note that this doesn't affect the length
of the plaintext you pass into functions like rsa\_encrypt(). This restriction applies only to data that is passed through
RSA directly.
The following table gives the size requirements for various hashes.
\begin{center}
\begin{tabular}{|c|c|c|}
\hline Name & Size of Message Digest (bytes) & RSA Key Size (bits)\\
\hline SHA-512 & 64 & 1544\\
\hline SHA-384 & 48 & 1160 \\
\hline SHA-256 & 32 & 776\\
\hline TIGER-192 & 24 & 584\\
\hline SHA-1 & 20 & 488\\
\hline MD5 & 16 & 392\\
\hline MD4 & 16 & 392\\
\hline
\end{tabular}
\end{center}
The symmetric ciphers will use at a maximum a 256-bit key which means at the least a 776-bit RSA key is
required to use all of the symmetric ciphers with the RSA routines. It is suggested that you make keys that
are at a minimum 1024 bits in length. If you want to use any of the large size message digests
(SHA-512 or SHA-384) you will have to use a larger key.
\chapter{Diffie-Hellman Key Exchange}
\section{Background}
Diffie-Hellman was the original public key system proposed. The system is based upon the group structure
of finite fields. For Diffie-Hellman a prime $p$ is chosen and a ``base'' $b$ such that $b^x\mbox{}(\mbox{mod }p)$
generates a large sub-group of prime order (for unique values of $x$).
A secret key is an exponent $x$ and a public key is the value of $y \equiv g^x\mbox{}(\mbox{mod }p)$. The term
``discrete logarithm'' denotes the action of finding $x$ given only $y$, $g$ and $p$. The key exchange part of
Diffie-Hellman arises from the fact that two users A and B with keys $(A_x, A_y)$ and $(B_x, B_y)$ can exchange
a shared key $K \equiv B_y^{A_x}\equiv A_y^{B_x}\equiv g^{A_xB_x}\mbox{}(\mbox{mod }p)$.
From this public encryption and signatures can be developed. The trivial way to encrypt (for example) using a public key
$y$ is to perform the key exchange offline. The sender invents a key $k$ and its public copy
$k' \equiv g^k\mbox{}(\mbox{mod }p)$ and uses $K \equiv k'^{A_x}\mbox{}(\mbox{mod }p)$ as a key to encrypt
the message with. Typically $K$ would be sent to a one-way hash and the message digested used as a key in a
symmetric cipher.
It is important that the order of the sub-group that $g$ generates not only be large but also prime. There are
discrete logarithm algorithms that take $\sqrt r$ time given the order $r$. The discrete logarithm can be computed
modulo each prime factor of $r$ and the results combined using the Chinese Remainder Theorem. In the cases where
$r$ is ``B-Smooth'' (e.g. all small factors or powers of small prime factors) the solution is trivial to find.
To thwart such attacks the primes and bases in the library have been designed and fixed. Given a prime $p$ the order of
the sub-group generated is a large prime namely ${p -1}\over2$. Such primes are known as ``strong primes'' and the
smaller prime (e.g. the order of the base) are known as Sophie-Germaine primes.
\section{Core Functions}
This library also provides core Diffie-Hellman functions so you can negotiate keys over insecure mediums. The routines
provided are relatively easy to use and only take two function calls to negotiate a shared key. There is a structure
called ``dh\_key'' which stores the Diffie-Hellman key in a format these routines can use. The first routine is to
make a Diffie-Hellman private key pair:
\index{dh\_make\_key()}
\begin{verbatim}
int dh_make_key(prng_state *prng, int wprng,
int keysize, dh_key *key);
\end{verbatim}
The ``keysize'' is the size of the modulus you want in bytes. Currently support sizes are 64 to 512 bytes which correspond
to key sizes of 512 to 4096 bits. The smaller the key the faster it is to use however it will be less secure. When
specifying a size not explicitly supported by the library it will round {\em up} to the next key size. If the size is
above 512 it will return an error. So if you pass ``keysize == 32'' it will use a 512 bit key but if you pass
``keysize == 20000'' it will return an error. The primes and generators used are built-into the library and were designed
to meet very specific goals. The primes are strong primes which means that if $p$ is the prime then
$p-1$ is equal to $2r$ where $r$ is a large prime. The bases are chosen to generate a group of order $r$ to prevent
leaking a bit of the key. This means the bases generate a very large prime order group which is good to make cryptanalysis
hard.
As for Diffie-Hellman key sizes its recommended that you use at least a 768-bit key. Since a 512-bit key has never been broken (its much
harder than 512-bit RSA to attack) a 512-bit key setting is supported. You can use it if you want I just suggest you don't.
The next two routines are for exporting/importing Diffie-Hellman keys in a binary format. This is useful for transport
over communication mediums.
\index{dh\_export()}\index{dh\_import()}
\begin{verbatim}
int dh_export(unsigned char *out, unsigned long *outlen,
int type, dh_key *key);
int dh_import(const unsigned char *in, dh_key *key);
\end{verbatim}
These two functions work just like the ``rsa\_export()'' and ``rsa\_import()'' functions except these work with
Diffie-Hellman keys. Its important to note you do not have to free the ram for a ``dh\_key'' if an import fails. You can free a
``dh\_key'' using:
\begin{verbatim}
void dh_free(dh_key *key);
\end{verbatim}
After you have exported a copy of your public key (using {\bf PK\_PUBLIC} as ``type'') you can now create a shared secret
with the other user using:
\index{dh\_shared\_secret()}
\begin{verbatim}
int dh_shared_secret(dh_key *private_key,
dh_key *public_key,
unsigned char *out, unsigned long *outlen);
\end{verbatim}
Where ``private\_key'' is the key you made and ``public\_key'' is the copy of the public key the other user sent you. The result goes
into ``out'' and the length into ``outlen''. If all went correctly the data in ``out'' should be identical for both parties. It is important to
note that the two keys have to be the same size in order for this to work. There is a function to get the size of a
key:
\index{dh\_get\_size()}
\begin{verbatim}
int dh_get_size(dh_key *key);
\end{verbatim}
This returns the size in bytes of the modulus chosen for that key.
\subsection{Remarks on Usage}
Its important that you hash the shared key before trying to use it as a key for a symmetric cipher or something. An
example program that communicates over sockets, using MD5 and 1024-bit DH keys is\footnote{This function is a small example. It is suggested that proper packaging be used. For example, if the public key sent is truncated these routines will not detect that.}:
\newpage
\begin{small}
\begin{verbatim}
int establish_secure_socket(int sock, int mode, unsigned char *key,
prng_state *prng, int wprng)
{
unsigned char buf[4096], buf2[4096];
unsigned long x, len;
int res, errno;
dh_key mykey, theirkey;
/* make up our private key */
if ((errno = dh_make_key(prng, wprng, 128, &mykey)) != CRYPT_OK) {
return errno;
}
/* export our key as public */
x = sizeof(buf);
if ((errno = dh_export(buf, &x, PK_PUBLIC, &mykey)) != CRYPT_OK) {
res = errno;
goto done2;
}
if (mode == 0) {
/* mode 0 so we send first */
if (send(sock, buf, x, 0) != x) {
res = CRYPT_ERROR;
goto done2;
}
/* get their key */
if (recv(sock, buf2, sizeof(buf2), 0) <= 0) {
res = CRYPT_ERROR;
goto done2;
}
} else {
/* mode >0 so we send second */
if (recv(sock, buf2, sizeof(buf2), 0) <= 0) {
res = CRYPT_ERROR;
goto done2;
}
if (send(sock, buf, x, 0) != x) {
res = CRYPT_ERROR;
goto done2;
}
}
if ((errno = dh_import(buf2, &theirkey)) != CRYPT_OK) {
res = errno;
goto done2;
}
/* make shared secret */
x = sizeof(buf);
if ((errno = dh_shared_secret(&mykey, &theirkey, buf, &x)) != CRYPT_OK) {
res = errno;
goto done;
}
/* hash it */
len = 16; /* default is MD5 so "key" must be at least 16 bytes long */