Net-Dropbear

 view release on metacpan or  search on metacpan

dropbear/libtomcrypt/doc/crypt.tex  view on Meta::CPAN


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 set of routines
are to make a Diffie-Hellman private key pair:
\index{dh\_make\_key()}
\begin{verbatim}
int dh_set_pg_groupsize(int groupsize, dh_key *key);
int dh_generate_key(prng_state *prng, int wprng, dh_key *key);
\end{verbatim}
The ``groupsize'' is the size of the modulus you want in bytes.  Currently support sizes are 96 to 1024 bytes which correspond
to key sizes of 768 to 8192 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 ``groupsize == 32'' it will use a 768 bit key but if you pass
``groupsize == 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.

The next two routines are for exporting/importing Diffie-Hellman keys in/from DER encoded ASN.1.  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, unsigned long inlen, dh_key *key);
\end{verbatim}

The ASN.1 sequence used to represent a DH key is as following:

\begin{verbatim}
DiffieHellmanKey ::= SEQUENCE {
      version Version,
      flags   Flags,
      p       INTEGER, -- prime
      g       INTEGER, -- base/group
      n       INTEGER  -- either x when private key or y when public key }

Version  ::=  INTEGER  {  v1(0)  }

Flags    ::=  BIT STRING {
      privateKey      (0) -- this BIT is '1' if it's a private key
                          --          or '0' if it's a public 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\_groupsize()}
\begin{verbatim}
int dh_get_groupsize(dh_key *key);
\end{verbatim}
This returns the size in bytes of the modulus chosen for that key.

\mysection{Other Diffie-Hellman Functions}

To be able to import Diffie-Hellman keys LibTomCrypt provides several API functions.
\\

To import the prime and group from binary format:
\index{dh\_set\_pg()}
\begin{verbatim}
int dh_set_pg(const unsigned char *p, unsigned long plen,
              const unsigned char *g, unsigned long glen,
              dh_key *key);
\end{verbatim}
This sets the prime \textit{p} of length \textit{plen} and the generator/base \textit{g} of length \textit{glen} in the DH key \textit{key}.
\\

To import the prime and group from an ASN.1 encoded DHparam Sequence:
\index{dh\_set\_pg\_dhparam()}
\begin{verbatim}
int dh_set_pg_dhparam(const unsigned char *dhparam, unsigned long dhparamlen, dh_key *key);
\end{verbatim}
This sets the parameters in \textit{dhparam} of \textit{dhparamlen} in the DH key \textit{key}.
\\

To import a private or public key from binary data:
\index{dh\_set\_key()}
\begin{verbatim}
int dh_set_key(const unsigned char *in, unsigned long inlen, int type, dh_key *key);
\end{verbatim}
This will import, depending on \textit{type} which can be either \textit{PK\_PRIVATE} or \textit{PK\_PUBLIC},
the according part of the DH key \textit{key} from \textit{in} of length \textit{inlen}.
After import the key will be verified and in case of an error it will be free'd.

\mysection{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 det...
\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, err, inlen;
   dh_key mykey, theirkey;

dropbear/libtomcrypt/doc/crypt.tex  view on Meta::CPAN

                           ecc_key *key);
\end{verbatim}
This will import the ECC key from \textit{in}, and store it in the ecc\_key structure pointed to by \textit{key}.  If the operation fails it will free
any allocated memory automatically.

\subsection{Extended Key Import}

The following function imports a LibTomCrypt format ECC key using a specified set of curve parameters:
\index{ecc\_import\_ex()}
\begin{verbatim}
int  ecc_import_ex(const unsigned char *in,
                         unsigned long  inlen,
                               ecc_key *key,
                const ltc_ecc_set_type *dp);
\end{verbatim}
This will import the key from the array pointed to by \textit{in} of length \textit{inlen} octets.  The key is stored in
the ECC structure pointed to by \textit{key}.  The curve is specified by the parameters pointed to by \textit{dp}.  The function will free
all internally allocated memory upon error.

\subsection{ANSI X9.63 Export}
The following function exports an ECC public key in the ANSI X9.63 format:

\index{ecc\_ansi\_x963\_export()}
\begin{verbatim}
int ecc_ansi_x963_export(      ecc_key *key,
                         unsigned char *out,
                         unsigned long *outlen);
\end{verbatim}
The ECC key pointed to by \textit{key} is exported in public fashion to the array pointed to by \textit{out}.  The ANSI X9.63 format used is from
section 4.3.6 of the standard.  It does not allow for the export of private keys.

\subsection{ANSI X9.63 Import}
The following function imports an ANSI X9.63 section 4.3.6 format public ECC key:

\index{ecc\_ansi\_x963\_import()}
\begin{verbatim}
int ecc_ansi_x963_import(const unsigned char *in,
                               unsigned long  inlen,
                                     ecc_key *key);
\end{verbatim}
This will import the key stored in the array pointed to by \textit{in} of length \textit{inlen} octets.  The imported key is stored in the ECC key pointed to by
\textit{key}.  The function will free any allocated memory upon error.

\subsection{Extended ANSI X9.63 Import}
The following function allows the importing of an ANSI x9.63 section 4.3.6 format public ECC key using user specified domain parameters:

\index{ecc\_ansi\_x963\_import\_ex()}
\begin{verbatim}
int ecc_ansi_x963_import_ex(const unsigned char *in,
                                  unsigned long  inlen,
                                        ecc_key *key,
                               ltc_ecc_set_type *dp);
\end{verbatim}
This will import the key stored in the array pointed to by \textit{in} of length \textit{inlen} octets using the domain parameters pointed to by \textit{dp}.
The imported key is stored in the ECC key pointed to by \textit{key}.  The function will free any allocated memory upon error.

\subsection{ECC Shared Secret}
To construct a Diffie-Hellman shared secret with a private and public ECC key, use the following function:
\index{ecc\_shared\_secret()}
\begin{verbatim}
int ecc_shared_secret(      ecc_key *private_key,
                            ecc_key *public_key,
                      unsigned char *out,
                      unsigned long *outlen);
\end{verbatim}
The \textit{private\_key} is typically the local private key, and \textit{public\_key} is the key the remote party has shared.
Note: this function stores only the $x$ co-ordinate of the shared elliptic point as described in ANSI X9.63 ECC--DH.

\mysection{ECC Diffie-Hellman Encryption}
ECC--DH Encryption is performed by producing a random key, hashing it, and XOR'ing the digest against the plaintext.  It is not strictly ANSI X9.63 compliant
but it is very similar.  It has been extended by using an ASN.1 sequence and hash object identifiers to allow portable usage.  The following function
encrypts a short string (no longer than the message digest) using this technique:

\subsection{ECC-DH Encryption}
\index{ecc\_encrypt\_key()}
\begin{verbatim}
int ecc_encrypt_key(const unsigned char *in,
                          unsigned long  inlen,
                          unsigned char *out,
                          unsigned long *outlen,
                             prng_state *prng,
                                    int  wprng,
                                    int  hash,
                                ecc_key *key);
\end{verbatim}

As the name implies this function encrypts a (symmetric) key, and is not intended for encrypting long messages directly.  It will encrypt the
plaintext in the array pointed to by \textit{in} of length \textit{inlen} octets.  It uses the public ECC key pointed to by \textit{key}, and
hash algorithm indexed by \textit{hash} to construct a shared secret which may be XOR'ed against the plaintext.  The ciphertext is stored in
the output buffer pointed to by \textit{out} of length \textit{outlen} octets.

The data is encrypted to the public ECC \textit{key} such that only the holder of the private key can decrypt the payload.  To have multiple
recipients multiple call to this function for each public ECC key is required.

\subsection{ECC-DH Decryption}
\index{ecc\_decrypt\_key()}
\begin{verbatim}
int ecc_decrypt_key(const unsigned char *in,
                          unsigned long  inlen,
                          unsigned char *out,
                          unsigned long *outlen,
                                ecc_key *key);
\end{verbatim}

This function will decrypt an encrypted payload.  The \textit{key} provided must be the private key corresponding to the public key
used during encryption.  If the wrong key is provided the function will not specifically return an error code.  It is important
to use some form of challenge response in that case (e.g. compute a MAC of a known string).

\subsection{ECC Encryption Format}
The packet format for the encrypted keys is the following ASN.1 SEQUENCE:

\begin{verbatim}
ECCEncrypt ::= SEQUENCE {
   hashID        OBJECT IDENTIFIER, -- OID of hash used
   pubkey        OCTET STRING     , -- Encapsulated ECCPublicKey
   skey          OCTET STRING       -- xor of plaintext and
                                    --"hash of shared secret"
}
\end{verbatim}

\mysection{EC DSA Signatures}



( run in 1.474 second using v1.01-cache-2.11-cpan-39bf76dae61 )