\documentclass[a4paper]{book} | |

\usepackage{hyperref} | |

\usepackage{makeidx} | |

\usepackage{amssymb} | |

\usepackage{color} | |

\usepackage{alltt} | |

\usepackage{graphicx} | |

\usepackage{layout} | |

\def\union{\cup} | |

\def\intersect{\cap} | |

\def\getsrandom{\stackrel{\rm R}{\gets}} | |

\def\cross{\times} | |

\def\cat{\hspace{0.5em} \| \hspace{0.5em}} | |

\def\catn{$\|$} | |

\def\divides{\hspace{0.3em} | \hspace{0.3em}} | |

\def\nequiv{\not\equiv} | |

\def\approx{\raisebox{0.2ex}{\mbox{\small $\sim$}}} | |

\def\lcm{{\rm lcm}} | |

\def\gcd{{\rm gcd}} | |

\def\log{{\rm log}} | |

\def\ord{{\rm ord}} | |

\def\abs{{\mathit abs}} | |

\def\rep{{\mathit rep}} | |

\def\mod{{\mathit\ mod\ }} | |

\renewcommand{\pmod}[1]{\ ({\rm mod\ }{#1})} | |

\newcommand{\floor}[1]{\left\lfloor{#1}\right\rfloor} | |

\newcommand{\ceil}[1]{\left\lceil{#1}\right\rceil} | |

\def\Or{{\rm\ or\ }} | |

\def\And{{\rm\ and\ }} | |

\def\iff{\hspace{1em}\Longleftrightarrow\hspace{1em}} | |

\def\implies{\Rightarrow} | |

\def\undefined{{\rm ``undefined"}} | |

\def\Proof{\vspace{1ex}\noindent {\bf Proof:}\hspace{1em}} | |

\let\oldphi\phi | |

\def\phi{\varphi} | |

\def\Pr{{\rm Pr}} | |

\newcommand{\str}[1]{{\mathbf{#1}}} | |

\def\F{{\mathbb F}} | |

\def\N{{\mathbb N}} | |

\def\Z{{\mathbb Z}} | |

\def\R{{\mathbb R}} | |

\def\C{{\mathbb C}} | |

\def\Q{{\mathbb Q}} | |

\def\twiddle{\raisebox{0.3ex}{\mbox{\tiny $\sim$}}} | |

\def\gap{\vspace{0.5ex}} | |

\makeindex | |

\begin{document} | |

\title{LibTomCrypt \\ Version 1.05} | |

\author{Tom St Denis \\ | |

\\ | |

tomstdenis@gmail.com \\ | |

http://libtomcrypt.org | |

} | |

\maketitle | |

This text and source code library are both hereby placed in the public domain. This book has been | |

formatted for A4 paper using the \LaTeX{} {\em book} macro package. | |

\vspace{15cm} | |

\begin{flushright}Open Source. Open Academia. Open Minds. | |

\mbox{ } | |

Tom St Denis, | |

Phone: 1-613-836-3160 | |

111 Banning Rd | |

Kanata, Ontario | |

K2L 1C3 | |

Canada | |

\end{flushright} | |

\newpage | |

\tableofcontents | |

\chapter{Introduction} | |

\section{What is the LibTomCrypt?} | |

LibTomCrypt is a portable ISO C cryptographic library that is meant to be a toolset for cryptographers who are | |

designing a cryptosystem. It supports symmetric ciphers, one-way hashes, pseudo-random number generators, | |

public key cryptography (via PKCS \#1 RSA, DH or ECCDH) and a plethora of support | |

routines. | |

The library was designed such that new ciphers/hashes/PRNGs can be added at runtime and the existing API | |

(and helper API functions) are able to use the new designs automatically. There exists self-check functions for each | |

block cipher and hash function to ensure that they compile and execute to the published design specifications. The library | |

also performs extensive parameter error checking to prevent any number of runtime exploits or errors. | |

\subsection{What the library IS for?} | |

The library serves as a toolkit for developers who have to solve cryptographic problems. Out of the box LibTomCrypt | |

does not process SSL or OpenPGP messages, it doesn't read x.591 certificates or write PEM encoded data. It does, however, | |

provide all of the tools required to build such functionality. LibTomCrypt was designed to be a flexible library that | |

was not tied to any particular cryptographic problem. | |

\section{Why did I write it?} | |

You may be wondering, ``Tom, why did you write a crypto library. I already have one.''. Well the reason falls into | |

two categories: | |

\begin{enumerate} | |

\item I am too lazy to figure out someone else's API. I'd rather invent my own simpler API and use that. | |

\item It was (still is) good coding practice. | |

\end{enumerate} | |

The idea is that I am not striving to replace OpenSSL or Crypto++ or Cryptlib or etc. I'm trying to write my | |

{\bf own} crypto library and hopefully along the way others will appreciate the work. | |

With this library all core functions (ciphers, hashes, prngs) have the {\bf exact} same prototype definition. They all load | |

and store data in a format independent of the platform. This means if you encrypt with Blowfish on a PPC it should decrypt | |

on an x86 with zero problems. The consistent API also means that if you learn how to use Blowfish with my library you | |

know how to use Safer+ or RC6 or Serpent or ... as well. With all of the core functions there are central descriptor tables | |

that can be used to make a program automatically pick between ciphers, hashes and PRNGs at runtime. That means your | |

application can support all ciphers/hashes/prngs without changing the source code. | |

Not only did I strive to make a consistent and simple API to work with but I also strived to make the library | |

configurable in terms of its build options. Out of the box the library will build with any modern version of GCC | |

without having to use configure scripts. This means that the library will work with platforms where development | |

tools may be limited (e.g. no autoconf). | |

On top of making the build simple and the API approachable I've also strived for a reasonably high level of | |

robustness and efficiency. LibTomCrypt traps and returns a series of errors ranging from invalid | |

arguments to buffer overflows/overruns. It is mostly thread safe and has been clocked on various platforms | |

with ``cycles per byte'' timings that are comparable (and often favourable) to other libraries such as OpenSSL and | |

Crypto++. | |

\subsection{Modular} | |

The LibTomCrypt package has also been written to be very modular. The block ciphers, one--way hashes and | |

pseudo--random number generators (PRNG) are all used within the API through ``descriptor'' tables which | |

are essentially structures with pointers to functions. While you can still call particular functions | |

directly (\textit{e.g. sha256\_process()}) this descriptor interface allows the developer to customize their | |

usage of the library. | |

For example, consider a hardware platform with a specialized RNG device. Obviously one would like to tap | |

that for the PRNG needs within the library (\textit{e.g. making a RSA key}). All the developer has to do | |

is write a descriptor and the few support routines required for the device. After that the rest of the | |

API can make use of it without change. Similiarly imagine a few years down the road when AES2 | |

(\textit{or whatever they call it}) has been invented. It can be added to the library and used within applications | |

with zero modifications to the end applications provided they are written properly. | |

This flexibility within the library means it can be used with any combination of primitive algorithms and | |

unlike libraries like OpenSSL is not tied to direct routines. For instance, in OpenSSL there are CBC block | |

mode routines for every single cipher. That means every time you add or remove a cipher from the library | |

you have to update the associated support code as well. In LibTomCrypt the associated code (\textit{chaining modes in this case}) | |

are not directly tied to the ciphers. That is a new cipher can be added to the library by simply providing | |

the key setup, ECB decrypt and encrypt and test vector routines. After that all five chaining mode routines | |

can make use of the cipher right away. | |

\section{License} | |

All of the source code except for the following files have been written by the author or donated to the project | |

under a public domain license: | |

\begin{enumerate} | |

\item rc2.c | |

\end{enumerate} | |

`mpi.c'' was originally written by Michael Fromberger (sting@linguist.dartmouth.edu) but has since been replaced with | |

my LibTomMath library which is public domain. | |

``rc2.c'' is based on publicly available code that is not attributed to a person from the given source. | |

The project is hereby released as public domain. | |

\section{Patent Disclosure} | |

The author (Tom St Denis) is not a patent lawyer so this section is not to be treated as legal advice. To the best | |

of the authors knowledge the only patent related issues within the library are the RC5 and RC6 symmetric block ciphers. | |

They can be removed from a build by simply commenting out the two appropriate lines in ``tomcrypt\_custom.h''. The rest | |

of the ciphers and hashes are patent free or under patents that have since expired. | |

The RC2 and RC4 symmetric ciphers are not under patents but are under trademark regulations. This means you can use | |

the ciphers you just can't advertise that you are doing so. | |

\section{Thanks} | |

I would like to give thanks to the following people (in no particular order) for helping me develop this project from | |

early on: | |

\begin{enumerate} | |

\item Richard van de Laarschot | |

\item Richard Heathfield | |

\item Ajay K. Agrawal | |

\item Brian Gladman | |

\item Svante Seleborg | |

\item Clay Culver | |

\item Jason Klapste | |

\item Dobes Vandermeer | |

\item Daniel Richards | |

\item Wayne Scott | |

\item Andrew Tyler | |

\item Sky Schulz | |

\item Christopher Imes | |

\end{enumerate} | |

There have been quite a few other people as well. Please check the change log to see who else has contributed from | |

time to time. | |

\chapter{The Application Programming Interface (API)} | |

\section{Introduction} | |

\index{CRYPT\_ERROR} \index{CRYPT\_OK} | |

In general the API is very simple to memorize and use. Most of the functions return either {\bf void} or {\bf int}. Functions | |

that return {\bf int} will return {\bf CRYPT\_OK} if the function was successful or one of the many error codes | |

if it failed. Certain functions that return int will return $-1$ to indicate an error. These functions will be explicitly | |

commented upon. When a function does return a CRYPT error code it can be translated into a string with | |

\index{error\_to\_string()} | |

\begin{verbatim} | |

const char *error_to_string(int err); | |

\end{verbatim} | |

An example of handling an error is: | |

\begin{verbatim} | |

void somefunc(void) | |

{ | |

int err; | |

/* call a cryptographic function */ | |

if ((err = some_crypto_function(...)) != CRYPT_OK) { | |

printf("A crypto error occured, %s\n", error_to_string(err)); | |

/* perform error handling */ | |

} | |

/* continue on if no error occured */ | |

} | |

\end{verbatim} | |

There is no initialization routine for the library and for the most part the code is thread safe. The only thread | |

related issue is if you use the same symmetric cipher, hash or public key state data in multiple threads. Normally | |

that is not an issue. | |

To include the prototypes for ``LibTomCrypt.a'' into your own program simply include ``tomcrypt.h'' like so: | |

\begin{verbatim} | |

#include <tomcrypt.h> | |

int main(void) { | |

return 0; | |

} | |

\end{verbatim} | |

The header file ``tomcrypt.h'' also includes ``stdio.h'', ``string.h'', ``stdlib.h'', ``time.h'', ``ctype.h'' and | |

``ltc\_tommath.h'' (the bignum library routines). | |

\section{Macros} | |

There are a few helper macros to make the coding process a bit easier. The first set are related to loading and storing | |

32/64-bit words in little/big endian format. The macros are: | |

\index{STORE32L} \index{STORE64L} \index{LOAD32L} \index{LOAD64L} \index{STORE32H} \index{STORE64H} \index{LOAD32H} \index{LOAD64H} \index{BSWAP} | |

\begin{small} | |

\begin{center} | |

\begin{tabular}{|c|c|c|} | |

\hline STORE32L(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $x \to y[0 \ldots 3]$ \\ | |

\hline STORE64L(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $x \to y[0 \ldots 7]$ \\ | |

\hline LOAD32L(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $y[0 \ldots 3] \to x$ \\ | |

\hline LOAD64L(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $y[0 \ldots 7] \to x$ \\ | |

\hline STORE32H(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $x \to y[3 \ldots 0]$ \\ | |

\hline STORE64H(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $x \to y[7 \ldots 0]$ \\ | |

\hline LOAD32H(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $y[3 \ldots 0] \to x$ \\ | |

\hline LOAD64H(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $y[7 \ldots 0] \to x$ \\ | |

\hline BSWAP(x) & {\bf unsigned long} x & Swaps byte order (32--bits only) \\ | |

\hline | |

\end{tabular} | |

\end{center} | |

\end{small} | |

There are 32 and 64-bit cyclic rotations as well: | |

\index{ROL} \index{ROR} \index{ROL64} \index{ROR64} \index{ROLc} \index{RORc} \index{ROL64c} \index{ROR64c} | |

\begin{center} | |

\begin{tabular}{|c|c|c|} | |

\hline ROL(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x << y, 0 \le y \le 31$ \\ | |

\hline ROLc(x, y) & {\bf unsigned long} x, {\bf const unsigned long} y & $x << y, 0 \le y \le 31$ \\ | |

\hline ROR(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x >> y, 0 \le y \le 31$ \\ | |

\hline RORc(x, y) & {\bf unsigned long} x, {\bf const unsigned long} y & $x >> y, 0 \le y \le 31$ \\ | |

\hline && \\ | |

\hline ROL64(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x << y, 0 \le y \le 63$ \\ | |

\hline ROL64c(x, y) & {\bf unsigned long} x, {\bf const unsigned long} y & $x << y, 0 \le y \le 63$ \\ | |

\hline ROR64(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x >> y, 0 \le y \le 63$ \\ | |

\hline ROR64c(x, y) & {\bf unsigned long} x, {\bf const unsigned long} y & $x >> y, 0 \le y \le 63$ \\ | |

\hline | |

\end{tabular} | |

\end{center} | |

\section{Functions with Variable Length Output} | |

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 <tomcrypt.h> | |

int main(void) { | |

rsa_key key; | |

unsigned char buffer[1024]; | |

unsigned long x; | |

int err; | |

/* ... Make up the RSA key somehow ... */ | |

/* lets export the key, set x to the size of the output buffer */ | |

x = sizeof(buffer); | |

if ((err = rsa_export(buffer, &x, PK_PUBLIC, &key)) != CRYPT_OK) { | |

printf("Export error: %s\n", error_to_string(err)); | |

return -1; | |

} | |

/* if rsa_export() was successful then x will have the size of the output */ | |

printf("RSA exported key takes %d bytes\n", x); | |

/* ... do something with the buffer */ | |

return 0; | |

} | |

\end{verbatim} | |

\end{small} | |

In the above example if the size of the RSA public key was more than 1024 bytes this function would return an error code | |

indicating a buffer overflow would have occurred. If the function succeeds it stores the length of the output | |

back into ``x'' so that the calling application will know how many bytes were used. | |

\section{Functions that need a PRNG} | |

\index{Pseudo Random Number Generator} \index{PRNG} | |

Certain functions such as ``rsa\_make\_key()'' require a Pseudo Random Number Generator (PRNG). These functions do not setup | |

the PRNG themselves so it is the responsibility of the calling function to initialize the PRNG before calling them. | |

Certain PRNG algorithms do not require a ``prng\_state'' argument (sprng for example). The ``prng\_state'' argument | |

may be passed as \textbf{NULL} in such situations. | |

\section{Functions that use Arrays of Octets} | |

Most functions require inputs that are arrays of the data type ``unsigned char''. Whether it is a symmetric key, IV | |

for a chaining mode or public key packet it is assumed that regardless of the actual size of ``unsigned char'' only the | |

lower eight bits contain data. For example, if you want to pass a 256 bit key to a symmetric ciphers setup routine | |

you must pass it in (a pointer to) an array of 32 ``unsigned char'' variables. Certain routines | |

(such as SAFER+) take special care to work properly on platforms where an ``unsigned char'' is not eight bits. | |

For the purposes of this library the term ``byte'' will refer to an octet or eight bit word. Typically an array of | |

type ``byte'' will be synonymous with an array of type ``unsigned char''. | |

\chapter{Symmetric Block Ciphers} | |

\section{Core Functions} | |

LibTomCrypt provides several block ciphers with an ECB block mode interface. It's important to first note that you | |

should never use the ECB modes directly to encrypt data. Instead you should use the ECB functions to make a chaining mode | |

or use one of the provided chaining modes. All of the ciphers are written as ECB interfaces since it allows the rest of | |

the API to grow in a modular fashion. | |

\subsection{Key Scheduling} | |

All ciphers store their scheduled keys in a single data type called ``symmetric\_key''. This allows all ciphers to | |

have the same prototype and store their keys as naturally as possible. This also removes the need for dynamic memory | |

allocation and allows you to allocate a fixed sized buffer for storing scheduled keys. All ciphers provide five visible | |

functions which are (given that XXX is the name of the cipher): | |

\index{Cipher Setup} | |

\begin{verbatim} | |

int XXX_setup(const unsigned char *key, int keylen, int rounds, | |

symmetric_key *skey); | |

\end{verbatim} | |

The XXX\_setup() routine will setup the cipher to be used with a given number of rounds and a given key length (in bytes). | |

The number of rounds can be set to zero to use the default, which is generally a good idea. | |

If the function returns successfully the variable ``skey'' will have a scheduled key stored in it. It's important to note | |

that you should only used this scheduled key with the intended cipher. For example, if you call ``blowfish\_setup()'' do not | |

pass the scheduled key onto ``rc5\_ecb\_encrypt()''. All setup functions do not allocate memory off the heap so when you are | |

done with a key you can simply discard it (e.g. they can be on the stack). | |

\subsection{ECB Encryption and Decryption} | |

To encrypt or decrypt a block in ECB mode there are these two function classes | |

\index{Cipher Encrypt} \index{Cipher Decrypt} | |

\begin{verbatim} | |

void XXX_ecb_encrypt(const unsigned char *pt, unsigned char *ct, | |

symmetric_key *skey); | |

void XXX_ecb_decrypt(const unsigned char *ct, unsigned char *pt, | |

symmetric_key *skey); | |

\end{verbatim} | |

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''\footnote{ct stands for ciphertext.} is the output. For the decryption function it's the opposite. To test a particular | |

cipher against test vectors\footnote{As published in their design papers.} call the self-test function | |

\subsection{Self--Testing} | |

\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. | |

\subsection{Key Sizing} | |

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 <tomcrypt.h> | |

int main(void) | |

{ | |

int keysize, err; | |

/* now given a 20 byte key what keysize does Twofish want to use? */ | |

keysize = 20; | |

if ((err = twofish_keysize(&keysize)) != CRYPT_OK) { | |

printf("Error getting key size: %s\n", error_to_string(err)); | |

return -1; | |

} | |

printf("Twofish suggested a key size of %d\n", keysize); | |

return 0; | |

} | |

\end{verbatim} | |

\end{small} | |

This should indicate a keysize of sixteen bytes is suggested. | |

\subsection{Cipher Termination} | |

When you are finished with a cipher you can de--initialize it with the done function. | |

\begin{verbatim} | |

void XXX_done(symmetric_key *skey); | |

\end{verbatim} | |

For the software based ciphers within LibTomCrypt this function will not do anything. However, user supplied | |

cipher descriptors may require calls to it for resource management. To be compliant all functions which call a cipher | |

setup function must also call the respective cipher done function when finished. | |

\subsection{Simple Encryption Demonstration} | |

An example snippet that encodes a block with Blowfish in ECB mode is below. | |

\begin{small} | |

\begin{verbatim} | |

#include <tomcrypt.h> | |

int main(void) | |

{ | |

unsigned char pt[8], ct[8], key[8]; | |

symmetric_key skey; | |

int err; | |

/* ... key is loaded appropriately in ``key'' ... */ | |

/* ... load a block of plaintext in ``pt'' ... */ | |

/* schedule the key */ | |

if ((err = blowfish_setup(key, /* the key we will use */ | |

8, /* key is 8 bytes (64-bits) long */ | |

0, /* 0 == use default # of rounds */ | |

&skey) /* where to put the scheduled key */ | |

) != CRYPT_OK) { | |

printf("Setup error: %s\n", error_to_string(err)); | |

return -1; | |

} | |

/* encrypt the block */ | |

blowfish_ecb_encrypt(pt, /* encrypt this 8-byte array */ | |

ct, /* store encrypted data here */ | |

&skey); /* our previously scheduled key */ | |

/* now ct holds the encrypted version of pt */ | |

/* decrypt the block */ | |

blowfish_ecb_decrypt(ct, /* decrypt this 8-byte array */ | |

pt, /* store decrypted data here */ | |

&skey); /* our previously scheduled key */ | |

/* now we have decrypted ct to the original plaintext in pt */ | |

/* Terminate the cipher context */ | |

blowfish_done(&skey); | |

return 0; | |

} | |

\end{verbatim} | |

\end{small} | |

\section{Key Sizes and Number of Rounds} | |

\index{Symmetric Keys} | |

As a general rule of thumb do not use symmetric keys under 80 bits if you can. Only a few of the ciphers support smaller | |

keys (mainly for test vectors anyways). Ideally your application should be making at least 256 bit keys. This is not | |

because you're supposed to be paranoid. It's because if your PRNG has a bias of any sort the more bits the better. For | |

example, if you have $\mbox{Pr}\left[X = 1\right] = {1 \over 2} \pm \gamma$ where $\vert \gamma \vert > 0$ then the | |

total amount of entropy in N bits is $N \cdot -log_2\left ({1 \over 2} + \vert \gamma \vert \right)$. So if $\gamma$ | |

were $0.25$ (a severe bias) a 256-bit string would have about 106 bits of entropy whereas a 128-bit string would have | |

only 53 bits of entropy. | |

The number of rounds of most ciphers is not an option you can change. Only RC5 allows you to change the number of | |

rounds. By passing zero as the number of rounds all ciphers will use their default number of rounds. Generally the | |

ciphers are configured such that the default number of rounds provide adequate security for the given block and key | |

size. | |

\section{The Cipher Descriptors} | |

\index{Cipher Descriptor} | |

To facilitate automatic routines an array of cipher descriptors is provided in the array ``cipher\_descriptor''. An element | |

of this array has the following format: | |

\begin{small} | |

\begin{verbatim} | |

struct _cipher_descriptor { | |

char *name; | |

unsigned char ID; | |

int min_key_length, | |

max_key_length, | |

block_length, | |

default_rounds; | |

int (*setup)(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | |

void (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | |

void (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | |

int (*test)(void); | |

void (*done)(symmetric_key *skey); | |

int (*keysize)(int *keysize); | |

void (*accel_ecb_encrypt)(const unsigned char *pt, | |

unsigned char *ct, | |

unsigned long blocks, symmetric_key *skey); | |

void (*accel_ecb_decrypt)(const unsigned char *ct, | |

unsigned char *pt, | |

unsigned long blocks, symmetric_key *skey); | |

void (*accel_cbc_encrypt)(const unsigned char *pt, | |

unsigned char *ct, | |

unsigned long blocks, unsigned char *IV, | |

symmetric_key *skey); | |

void (*accel_cbc_decrypt)(const unsigned char *ct, | |

unsigned char *pt, | |

unsigned long blocks, unsigned char *IV, | |

symmetric_key *skey); | |

void (*accel_ctr_encrypt)(const unsigned char *pt, | |

unsigned char *ct, | |

unsigned long blocks, unsigned char *IV, | |

int mode, symmetric_key *skey); | |

void (*accel_ccm_memory)( | |

const unsigned char *key, unsigned long keylen, | |

const unsigned char *nonce, unsigned long noncelen, | |

const unsigned char *header, unsigned long headerlen, | |

unsigned char *pt, unsigned long ptlen, | |

unsigned char *ct, | |

unsigned char *tag, unsigned long *taglen, | |

int direction); | |

}; | |

\end{verbatim} | |

\end{small} | |

Where ``name'' is the lower case ASCII version of the name. The fields ``min\_key\_length'' and ``max\_key\_length'' | |

are the minimum and maximum key sizes in bytes. The ``block\_length'' member is the block size of the cipher | |

in bytes. As a good rule of thumb it is assumed that the cipher supports | |

the min and max key lengths but not always everything in between. The ``default\_rounds'' field is the default number | |

of rounds that will be used. | |

The remaining fields are all pointers to the core functions for each cipher. The end of the cipher\_descriptor array is | |

marked when ``name'' equals {\bf NULL}. | |

As of this release the current cipher\_descriptors elements are | |

\index{Cipher descriptor table} | |

\begin{small} | |

\begin{center} | |

\begin{tabular}{|c|c|c|c|c|c|} | |

\hline Name & Descriptor Name & Block Size & Key Range & Rounds \\ | |

\hline Blowfish & blowfish\_desc & 8 & 8 $\ldots$ 56 & 16 \\ | |

\hline X-Tea & xtea\_desc & 8 & 16 & 32 \\ | |

\hline RC2 & rc2\_desc & 8 & 8 $\ldots$ 128 & 16 \\ | |

\hline RC5-32/12/b & rc5\_desc & 8 & 8 $\ldots$ 128 & 12 $\ldots$ 24 \\ | |

\hline RC6-32/20/b & rc6\_desc & 16 & 8 $\ldots$ 128 & 20 \\ | |

\hline SAFER+ & saferp\_desc &16 & 16, 24, 32 & 8, 12, 16 \\ | |

\hline AES & aes\_desc & 16 & 16, 24, 32 & 10, 12, 14 \\ | |

& aes\_enc\_desc & 16 & 16, 24, 32 & 10, 12, 14 \\ | |

\hline Twofish & twofish\_desc & 16 & 16, 24, 32 & 16 \\ | |

\hline DES & des\_desc & 8 & 7 & 16 \\ | |

\hline 3DES (EDE mode) & des3\_desc & 8 & 21 & 16 \\ | |

\hline CAST5 (CAST-128) & cast5\_desc & 8 & 5 $\ldots$ 16 & 12, 16 \\ | |

\hline Noekeon & noekeon\_desc & 16 & 16 & 16 \\ | |

\hline Skipjack & skipjack\_desc & 8 & 10 & 32 \\ | |

\hline Anubis & anubis\_desc & 16 & 16 $\ldots$ 40 & 12 $\ldots$ 18 \\ | |

\hline Khazad & khazad\_desc & 8 & 16 & 8 \\ | |

\hline | |

\end{tabular} | |

\end{center} | |

\end{small} | |

\subsection{Notes} | |

\begin{small} | |

\begin{enumerate} | |

\item | |

For AES (also known as Rijndael) there are four descriptors which complicate issues a little. The descriptors | |

rijndael\_desc and rijndael\_enc\_desc provide the cipher named ``rijndael''. The descriptors aes\_desc and | |

aes\_enc\_desc provide the cipher name ``aes''. Functionally both ``rijndael'' and ``aes'' are the same cipher. The | |

only difference is when you call find\_cipher() you have to pass the correct name. The cipher descriptors with ``enc'' | |

in the middle (e.g. rijndael\_enc\_desc) are related to an implementation of Rijndael with only the encryption routine | |

and tables. The decryption and self--test function pointers of both ``encrypt only'' descriptors are set to \textbf{NULL} and | |

should not be called. | |

The ``encrypt only'' descriptors are useful for applications that only use the encryption function of the cipher. Algorithms such | |

as EAX, PMAC and OMAC only require the encryption function. So far this ``encrypt only'' functionality has only been implemented for | |

Rijndael as it makes the most sense for this cipher. | |

\item | |

Note that for ``DES'' and ``3DES'' they use 8 and 24 byte keys but only 7 and 21 [respectively] bytes of the keys are in | |

fact used for the purposes of encryption. My suggestion is just to use random 8/24 byte keys instead of trying to make a 8/24 | |

byte string from the real 7/21 byte key. | |

\item | |

Note that ``Twofish'' has additional configuration options that take place at build time. These options are found in | |

the file ``tomcrypt\_cfg.h''. The first option is ``TWOFISH\_SMALL'' which when defined will force the Twofish code | |

to not pre-compute the Twofish ``$g(X)$'' function as a set of four $8 \times 32$ s-boxes. This means that a scheduled | |

key will require less ram but the resulting cipher will be slower. The second option is ``TWOFISH\_TABLES'' which when | |

defined will force the Twofish code to use pre-computed tables for the two s-boxes $q_0, q_1$ as well as the multiplication | |

by the polynomials 5B and EF used in the MDS multiplication. As a result the code is faster and slightly larger. The | |

speed increase is useful when ``TWOFISH\_SMALL'' is defined since the s-boxes and MDS multiply form the heart of the | |

Twofish round function. | |

\index{Twofish build options} | |

\begin{small} | |

\begin{center} | |

\begin{tabular}{|l|l|l|} | |

\hline TWOFISH\_SMALL & TWOFISH\_TABLES & Speed and Memory (per key) \\ | |

\hline undefined & undefined & Very fast, 4.2KB of ram. \\ | |

\hline undefined & defined & Faster keysetup, larger code. \\ | |

\hline defined & undefined & Very slow, 0.2KB of ram. \\ | |

\hline defined & defined & Faster, 0.2KB of ram, larger code. \\ | |

\hline | |

\end{tabular} | |

\end{center} | |

\end{small} | |

\end{enumerate} | |

\end{small} | |

To work with the cipher\_descriptor array there is a function: | |

\index{find\_cipher()} | |

\begin{verbatim} | |

int find_cipher(char *name) | |

\end{verbatim} | |

Which will search for a given name in the array. It returns negative one if the cipher is not found, otherwise it returns | |

the location in the array where the cipher was found. For example, to indirectly setup Blowfish you can also use: | |

\begin{small} | |

\begin{verbatim} | |

#include <tomcrypt.h> | |

int main(void) | |

{ | |

unsigned char key[8]; | |

symmetric_key skey; | |

int err; | |

/* you must register a cipher before you use it */ | |

if (register_cipher(&blowfish_desc)) == -1) { | |

printf("Unable to register Blowfish cipher."); | |

return -1; | |

} | |

/* generic call to function (assuming the key in key[] was already setup) */ | |

if ((err = cipher_descriptor[find_cipher("blowfish")].setup(key, 8, 0, &skey)) != | |

CRYPT_OK) { | |

printf("Error setting up Blowfish: %s\n", error_to_string(err)); | |

return -1; | |

} | |

/* ... use cipher ... */ | |

} | |

\end{verbatim} | |

\end{small} | |

A good safety would be to check the return value of ``find\_cipher()'' before accessing the desired function. In order | |

to use a cipher with the descriptor table you must register it first using: | |

\index{register\_cipher()} | |

\begin{verbatim} | |

int register_cipher(const struct _cipher_descriptor *cipher); | |

\end{verbatim} | |

Which accepts a pointer to a descriptor and returns the index into the global descriptor table. If an error occurs such | |

as there is no more room (it can have 32 ciphers at most) it will return {\bf{-1}}. If you try to add the same cipher more | |

than once it will just return the index of the first copy. To remove a cipher call: | |

\index{unregister\_cipher()} | |

\begin{verbatim} | |

int unregister_cipher(const struct _cipher_descriptor *cipher); | |

\end{verbatim} | |

Which returns {\bf CRYPT\_OK} if it removes it otherwise it returns {\bf CRYPT\_ERROR}. Consider: | |

\begin{small} | |

\begin{verbatim} | |

#include <tomcrypt.h> | |

int main(void) | |

{ | |

int err; | |

/* register the cipher */ | |

if (register_cipher(&rijndael_desc) == -1) { | |

printf("Error registering Rijndael\n"); | |

return -1; | |

} | |

/* use Rijndael */ | |

/* remove it */ | |

if ((err = unregister_cipher(&rijndael_desc)) != CRYPT_OK) { | |

printf("Error removing Rijndael: %s\n", error_to_string(err)); | |

return -1; | |

} | |

return 0; | |

} | |

\end{verbatim} | |

\end{small} | |

This snippet is a small program that registers only Rijndael only. | |

\section{Symmetric Modes of Operations} | |

\subsection{Background} | |

A typical symmetric block cipher can be used in chaining modes to effectively encrypt messages larger than the block | |

size of the cipher. Given a key $k$, a plaintext $P$ and a cipher $E$ we shall denote the encryption of the block | |

$P$ under the key $k$ as $E_k(P)$. In some modes there exists an initial vector denoted as $C_{-1}$. | |

\subsubsection{ECB Mode} | |

\index{ECB mode} | |

ECB or Electronic Codebook Mode is the simplest method to use. It is given as: | |

\begin{equation} | |

C_i = E_k(P_i) | |

\end{equation} | |

This mode is very weak since it allows people to swap blocks and perform replay attacks if the same key is used more | |

than once. | |

\subsubsection{CBC Mode} | |

\index{CBC mode} | |

CBC or Cipher Block Chaining mode is a simple mode designed to prevent trivial forms of replay and swap attacks on ciphers. | |

It is given as: | |

\begin{equation} | |

C_i = E_k(P_i \oplus C_{i - 1}) | |

\end{equation} | |

It is important that the initial vector be unique and preferably random for each message encrypted under the same key. | |

\subsubsection{CTR Mode} | |

\index{CTR mode} | |

CTR or Counter Mode is a mode which only uses the encryption function of the cipher. Given a initial vector which is | |

treated as a large binary counter the CTR mode is given as: | |

\begin{eqnarray} | |

C_{-1} = C_{-1} + 1\mbox{ }(\mbox{mod }2^W) \nonumber \\ | |

C_i = P_i \oplus E_k(C_{-1}) | |

\end{eqnarray} | |

Where $W$ is the size of a block in bits (e.g. 64 for Blowfish). As long as the initial vector is random for each message | |

encrypted under the same key replay and swap attacks are infeasible. CTR mode may look simple but it is as secure | |

as the block cipher is under a chosen plaintext attack (provided the initial vector is unique). | |

\subsubsection{CFB Mode} | |

\index{CFB mode} | |

CFB or Ciphertext Feedback Mode is a mode akin to CBC. It is given as: | |

\begin{eqnarray} | |

C_i = P_i \oplus C_{-1} \nonumber \\ | |

C_{-1} = E_k(C_i) | |

\end{eqnarray} | |

Note that in this library the output feedback width is equal to the size of the block cipher. That is this mode is used | |

to encrypt whole blocks at a time. However, the library will buffer data allowing the user to encrypt or decrypt partial | |

blocks without a delay. When this mode is first setup it will initially encrypt the initial vector as required. | |

\subsubsection{OFB Mode} | |

\index{OFB mode} | |

OFB or Output Feedback Mode is a mode akin to CBC as well. It is given as: | |

\begin{eqnarray} | |

C_{-1} = E_k(C_{-1}) \nonumber \\ | |

C_i = P_i \oplus C_{-1} | |

\end{eqnarray} | |

Like the CFB mode the output width in CFB mode is the same as the width of the block cipher. OFB mode will also | |

buffer the output which will allow you to encrypt or decrypt partial blocks without delay. | |

\subsection{Choice of Mode} | |

My personal preference is for the CTR mode since it has several key benefits: | |

\begin{enumerate} | |

\item No short cycles which is possible in the OFB and CFB modes. | |

\item Provably as secure as the block cipher being used under a chosen plaintext attack. | |

\item Technically does not require the decryption routine of the cipher. | |

\item Allows random access to the plaintext. | |

\item Allows the encryption of block sizes that are not equal to the size of the block cipher. | |

\end{enumerate} | |

The CTR, CFB and OFB routines provided allow you to encrypt block sizes that differ from the ciphers block size. They | |

accomplish this by buffering the data required to complete a block. This allows you to encrypt or decrypt any size | |

block of memory with either of the three modes. | |

The ECB and CBC modes process blocks of the same size as the cipher at a time. Therefore they are less flexible than the | |

other modes. | |

\subsection{Initialization} | |

\index{CBC Mode} \index{CTR Mode} | |

\index{OFB Mode} \index{CFB Mode} | |

The library provides simple support routines for handling CBC, CTR, CFB, OFB and ECB encoded messages. Assuming the mode | |

you want is XXX there is a structure called ``symmetric\_XXX'' that will contain the information required to | |

use that mode. They have identical setup routines (except CTR and ECB mode): | |

\index{ecb\_start()} \index{cfb\_start()} \index{cbc\_start()} \index{ofb\_start()} \index{ctr\_start()} | |

\begin{verbatim} | |

int XXX_start(int cipher, const unsigned char *IV, | |

const unsigned char *key, int keylen, | |

int num_rounds, symmetric_XXX *XXX); | |

int ctr_start( int cipher, | |

const unsigned char *IV, | |

const unsigned char *key, int keylen, | |

int num_rounds, int ctr_mode, | |

symmetric_CTR *ctr); | |

int ecb_start(int cipher, const unsigned char *key, int keylen, | |

int num_rounds, symmetric_ECB *ecb); | |

\end{verbatim} | |

In each case ``cipher'' is the index into the cipher\_descriptor array of the cipher you want to use. The ``IV'' value is | |

the initialization vector to be used with the cipher. You must fill the IV yourself and it is assumed they are the same | |

length as the block size\footnote{In otherwords the size of a block of plaintext for the cipher, e.g. 8 for DES, 16 for AES, etc.} | |

of the cipher you choose. It is important that the IV be random for each unique message you want to encrypt. The | |

parameters ``key'', ``keylen'' and ``num\_rounds'' are the same as in the XXX\_setup() function call. The final parameter | |

is a pointer to the structure you want to hold the information for the mode of operation. | |

In the case of CTR mode there is an additional parameter ``ctr\_mode'' which specifies the mode that the counter is to be used in. | |

If \textbf{CTR\_COUNTER\_LITTLE\_ENDIAN} was specified then the counter will be treated as a little endian value. Otherwise, if | |

\textbf{CTR\_COUNTER\_BIG\_ENDIAN} was specified the counter will be treated as a big endian value. | |

The routines return {\bf CRYPT\_OK} if the cipher initialized correctly, otherwise they return an error code. | |

\subsection{Encryption and Decryption} | |

To actually encrypt or decrypt the following routines are provided: | |

\index{ecb\_encrypt()} \index{ecb\_decrypt()} \index{cfb\_encrypt()} \index{cfb\_decrypt()} | |

\index{cbc\_encrypt()} \index{cbc\_decrypt()} \index{ofb\_encrypt()} \index{ofb\_decrypt()} \index{ctr\_encrypt()} \index{ctr\_decrypt()} | |

\begin{verbatim} | |

int XXX_encrypt(const unsigned char *pt, unsigned char *ct, | |

unsigned long len, symmetric_YYY *YYY); | |

int XXX_decrypt(const unsigned char *ct, unsigned char *pt, | |

unsigned long len, symmetric_YYY *YYY); | |

\end{verbatim} | |

Where ``XXX'' is one of $\lbrace ecb, cbc, ctr, cfb, ofb \rbrace$. | |

In all cases ``len'' is the size of the buffer (as number of octets) to encrypt or decrypt. The CTR, OFB and CFB modes are order sensitive but not | |

chunk sensitive. That is you can encrypt ``ABCDEF'' in three calls like ``AB'', ``CD'', ``EF'' or two like ``ABCDE'' and ``F'' | |

and end up with the same ciphertext. However, encrypting ``ABC'' and ``DABC'' will result in different ciphertexts. All | |

five of the modes will return {\bf CRYPT\_OK} on success from the encrypt or decrypt functions. | |

In the ECB and CBC cases ``len'' must be a multiple of the ciphers block size. In the CBC case you must manually pad the end of your message (either with | |

zeroes or with whatever your protocol requires). | |

To decrypt in either mode you simply perform the setup like before (recall you have to fetch the IV value you used) | |

and use the decrypt routine on all of the blocks. | |

\subsection{IV Manipulation} | |

To change or read the IV of a previously initialized chaining mode use the following two functions. | |

\index{cbc\_setiv()} \index{cbc\_getiv()} \index{ofb\_setiv()} \index{ofb\_getiv()} \index{cfb\_setiv()} \index{cfb\_getiv()} | |

\index{ctr\_setiv()} \index{ctr\_getiv()} | |

\begin{verbatim} | |

int XXX_getiv(unsigned char *IV, unsigned long *len, symmetric_XXX *XXX); | |

int XXX_setiv(const unsigned char *IV, unsigned long len, symmetric_XXX *XXX); | |

\end{verbatim} | |

The XXX\_getiv() functions will read the IV out of the chaining mode and store it into ``IV'' along with the length of the IV | |

stored in ``len''. The XXX\_setiv will initialize the chaining mode state as if the original IV were the new IV specified. The length | |

of the IV passed in must be the size of the ciphers block size. | |

The XXX\_setiv() functions are handy if you wish to change the IV without re--keying the cipher. | |

\subsection{Stream Termination} | |

To terminate an open stream call the done function. | |

\index{ecb\_done()} \index{cbc\_done()}\index{cfb\_done()}\index{ofb\_done()} \index{ctr\_done()} | |

\begin{verbatim} | |

int XXX_done(symmetric_XXX *XXX); | |

\end{verbatim} | |

This will terminate the stream (by terminating the cipher) and return \textbf{CRYPT\_OK} if successful. | |

\subsection{Examples} | |

\newpage | |

\begin{small} | |

\begin{verbatim} | |

#include <tomcrypt.h> | |

int main(void) | |

{ | |

unsigned char key[16], IV[16], buffer[512]; | |

symmetric_CTR ctr; | |

int x, err; | |

/* register twofish first */ | |

if (register_cipher(&twofish_desc) == -1) { | |

printf("Error registering cipher.\n"); | |

return -1; | |

} | |

/* somehow fill out key and IV */ | |

/* start up CTR mode */ | |

if ((err = ctr_start( | |

find_cipher("twofish"), /* index of desired cipher */ | |

IV, /* the initial vector */ | |

key, /* the secret key */ | |

16, /* length of secret key (16 bytes, 128 bits) */ | |

0, /* 0 == default # of rounds */ | |

CTR_COUNTER_LITTLE_ENDIAN, /* Little endian counter */ | |

&ctr) /* where to store initialized CTR state */ | |

) != CRYPT_OK) { | |

printf("ctr_start error: %s\n", error_to_string(err)); | |

return -1; | |

} | |

/* somehow fill buffer than encrypt it */ | |

if ((err = ctr_encrypt( buffer, /* plaintext */ | |

buffer, /* ciphertext */ | |

sizeof(buffer), /* length of data to encrypt */ | |

&ctr) /* previously initialized CTR state */ | |

) != CRYPT_OK) { | |

printf("ctr_encrypt error: %s\n", error_to_string(err)); | |

return -1; | |

} | |

/* make use of ciphertext... */ | |

/* now we want to decrypt so let's use ctr_setiv */ | |

if ((err = ctr_setiv( IV, /* the initial IV we gave to ctr_start */ | |

16, /* the IV is 16 bytes long */ | |

&ctr) /* the ctr state we wish to modify */ | |

) != CRYPT_OK) { | |

printf("ctr_setiv error: %s\n", error_to_string(err)); | |

return -1; | |

} | |

if ((err = ctr_decrypt( buffer, /* ciphertext */ | |

buffer, /* plaintext */ | |

sizeof(buffer), /* length of data to encrypt */ | |

&ctr) /* previously initialized CTR state */ | |

) != CRYPT_OK) { | |

printf("ctr_decrypt error: %s\n", error_to_string(err)); | |

return -1; | |

} | |

/* terminate the stream */ | |

if ((err = ctr_done(&ctr)) != CRYPT_OK) { | |

printf("ctr_done error: %s\n", error_to_string(err)); | |

return -1; | |

} | |

/* clear up and return */ | |

zeromem(key, sizeof(key)); | |

zeromem(&ctr, sizeof(ctr)); | |

return 0; | |

} | |

\end{verbatim} | |

\end{small} | |

\section{Encrypt and Authenticate Modes} | |

\subsection{EAX Mode} | |

LibTomCrypt provides support for a mode called EAX\footnote{See | |

M. Bellare, P. Rogaway, D. Wagner, A Conventional Authenticated-Encryption Mode.} in a manner similar to the | |

way it was intended to be used by the designers. First a short description of what EAX mode is before I explain how to use it. | |

EAX is a mode that requires a cipher, CTR and OMAC support and provides encryption and authentication\footnote{Note that since EAX only requires OMAC and CTR you may use ``encrypt only'' cipher descriptors with this mode.}. | |

It is initialized with a random ``nonce'' that can be shared publicly as well as a ``header'' which can be fixed and public as well as a random | |

secret symmetric key. | |

The ``header'' data is meant to be meta-data associated with a stream that isn't private (e.g. protocol messages). It can | |

be added at anytime during an EAX stream and is part of the authentication tag. That is, changes in the meta-data can | |

be detected by changes in the output tag. | |

The mode can then process plaintext producing ciphertext as well as compute a partial checksum. The actual checksum | |

called a ``tag'' is only emitted when the message is finished. In the interim though the user can process any arbitrary | |

sized message block to send to the recipient as ciphertext. This makes the EAX mode especially suited for streaming modes | |

of operation. | |

The mode is initialized with the following function. | |

\index{eax\_init()} | |

\begin{verbatim} | |

int eax_init(eax_state *eax, int cipher, | |

const unsigned char *key, unsigned long keylen, | |

const unsigned char *nonce, unsigned long noncelen, | |

const unsigned char *header, unsigned long headerlen); | |

\end{verbatim} | |

Where ``eax'' is the EAX state. ``cipher'' is the index of the desired cipher in the descriptor table. | |

``key'' is the shared secret symmetric key of length ``keylen''. ``nonce'' is the random public string of | |

length ``noncelen''. ``header'' is the random (or fixed or \textbf{NULL}) header for the message of length | |

``headerlen''. | |

When this function completes ``eax'' will be initialized such that you can now either have data decrypted or | |

encrypted in EAX mode. Note that if ``headerlen'' is zero you may pass ``header'' as \textbf{NULL} to indicate | |

there is no initial header data. | |

To encrypt or decrypt data in a streaming mode use the following. | |

\index{eax\_encrypt()} \index{eax\_decrypt()} | |

\begin{verbatim} | |

int eax_encrypt(eax_state *eax, const unsigned char *pt, | |

unsigned char *ct, unsigned long length); | |

int eax_decrypt(eax_state *eax, const unsigned char *ct, | |

unsigned char *pt, unsigned long length); | |

\end{verbatim} | |

The function ``eax\_encrypt'' will encrypt the bytes in ``pt'' of ``length'' bytes and store the ciphertext in | |

``ct''. Note that ``ct'' and ``pt'' may be the same region in memory. This function will also send the ciphertext | |

through the OMAC function. The function ``eax\_decrypt'' decrypts ``ct'' and stores it in ``pt''. This also allows | |

``pt'' and ``ct'' to be the same region in memory. | |

You cannot both encrypt or decrypt with the same ``eax'' context. For bi-directional communication you | |

will need to initialize two EAX contexts (preferably with different headers and nonces). | |

Note that both of these functions allow you to send the data in any granularity but the order is important. While | |

the eax\_init() function allows you to add initial header data to the stream you can also add header data during the | |

EAX stream with the following. | |

\index{eax\_addheader()} | |

\begin{verbatim} | |

int eax_addheader(eax_state *eax, | |

const unsigned char *header, unsigned long length); | |

\end{verbatim} | |

This will add the ``length'' bytes from ``header'' to the given ``eax'' stream. Once the message is finished the | |

``tag'' (checksum) may be computed with the following function. | |

\index{eax\_done()} | |

\begin{verbatim} | |

int eax_done(eax_state *eax, | |

unsigned char *tag, unsigned long *taglen); | |

\end{verbatim} | |

This will terminate the EAX state ``eax'' and store upto ``taglen'' bytes of the message tag in ``tag''. The function | |

then stores how many bytes of the tag were written out back into ``taglen''. | |

The EAX mode code can be tested to ensure it matches the test vectors by calling the following function. | |

\index{eax\_test()} | |

\begin{verbatim} | |

int eax_test(void); | |

\end{verbatim} | |

This requires that the AES (or Rijndael) block cipher be registered with the cipher\_descriptor table first. | |

\begin{verbatim} | |

#include <tomcrypt.h> | |

int main(void) | |

{ | |

int err; | |

eax_state eax; | |

unsigned char pt[64], ct[64], nonce[16], key[16], tag[16]; | |

unsigned long taglen; | |

if (register_cipher(&rijndael_desc) == -1) { | |

printf("Error registering Rijndael"); | |

return EXIT_FAILURE; | |

} | |

/* ... make up random nonce and key ... */ | |

/* initialize context */ | |

if ((err = eax_init( &eax, /* the context */ | |

find_cipher("rijndael"), /* cipher we want to use */ | |

nonce, /* our state nonce */ | |

16, /* none is 16 bytes */ | |

"TestApp", /* example header, identifies this program */ | |

7) /* length of the header */ | |

) != CRYPT_OK) { | |

printf("Error eax_init: %s", error_to_string(err)); | |

return EXIT_FAILURE; | |

} | |

/* now encrypt data, say in a loop or whatever */ | |

if ((err = eax_encrypt( &eax, /* eax context */ | |

pt, /* plaintext (source) */ | |

ct, /* ciphertext (destination) */ | |

sizeof(pt) /* size of plaintext */ | |

) != CRYPT_OK) { | |

printf("Error eax_encrypt: %s", error_to_string(err)); | |

return EXIT_FAILURE; | |

} | |

/* finish message and get authentication tag */ | |

taglen = sizeof(tag); | |

if ((err = eax_done( &eax, /* eax context */ | |

tag, /* where to put tag */ | |

&taglen /* length of tag space */ | |

) != CRYPT_OK) { | |

printf("Error eax_done: %s", error_to_string(err)); | |

return EXIT_FAILURE; | |

} | |

/* now we have the authentication tag in "tag" and it's taglen bytes long */ | |

} | |

\end{verbatim} | |

You can also perform an entire EAX state on a block of memory in a single function call with the | |

following functions. | |

\index{eax\_encrypt\_authenticate\_memory} \index{eax\_decrypt\_verify\_memory} | |

\begin{verbatim} | |

int eax_encrypt_authenticate_memory(int cipher, | |

const unsigned char *key, unsigned long keylen, | |

const unsigned char *nonce, unsigned long noncelen, | |

const unsigned char *header, unsigned long headerlen, | |

const unsigned char *pt, unsigned long ptlen, | |

unsigned char *ct, | |

unsigned char *tag, unsigned long *taglen); | |

int eax_decrypt_verify_memory(int cipher, | |

const unsigned char *key, unsigned long keylen, | |

const unsigned char *nonce, unsigned long noncelen, | |

const unsigned char *header, unsigned long headerlen, | |

const unsigned char *ct, unsigned long ctlen, | |

unsigned char *pt, | |

unsigned char *tag, unsigned long taglen, | |

int *res); | |

\end{verbatim} | |

Both essentially just call eax\_init() followed by eax\_encrypt() (or eax\_decrypt() respectively) and eax\_done(). The parameters | |

have the same meaning as with those respective functions. | |

The only difference is eax\_decrypt\_verify\_memory() does not emit a tag. Instead you pass it a tag as input and it compares it against | |

the tag it computed while decrypting the message. If the tags match then it stores a $1$ in ``res'', otherwise it stores a $0$. | |

\subsection{OCB Mode} | |

LibTomCrypt provides support for a mode called OCB\footnote{See | |

P. Rogaway, M. Bellare, J. Black, T. Krovetz, ``OCB: A Block Cipher Mode of Operation for Efficient Authenticated Encryption''.} | |

. OCB is an encryption protocol that simultaneously provides authentication. It is slightly faster to use than EAX mode | |

but is less flexible. Let's review how to initialize an OCB context. | |

\index{ocb\_init()} | |

\begin{verbatim} | |

int ocb_init(ocb_state *ocb, int cipher, | |

const unsigned char *key, unsigned long keylen, | |

const unsigned char *nonce); | |

\end{verbatim} | |

This will initialize the ``ocb'' context using cipher descriptor ``cipher''. It will use a ``key'' of length ``keylen'' | |

and the random ``nonce''. Note that ``nonce'' must be a random (public) string the same length as the block ciphers | |

block size (e.g. 16 bytes for AES). | |

This mode has no ``Associated Data'' like EAX mode does which means you cannot authenticate metadata along with the stream. | |

To encrypt or decrypt data use the following. | |

\index{ocb\_encrypt()} \index{ocb\_decrypt()} | |

\begin{verbatim} | |

int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct); | |

int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt); | |

\end{verbatim} | |

This will encrypt (or decrypt for the latter) a fixed length of data from ``pt'' to ``ct'' (vice versa for the latter). | |

They assume that ``pt'' and ``ct'' are the same size as the block cipher's block size. Note that you cannot call | |

both functions given a single ``ocb'' state. For bi-directional communication you will have to initialize two ``ocb'' | |

states (with different nonces). Also ``pt'' and ``ct'' may point to the same location in memory. | |

\subsubsection{State Termination} | |

When you are finished encrypting the message you call the following function to compute the tag. | |

\index{ocb\_done\_encrypt()} | |

\begin{verbatim} | |

int ocb_done_encrypt(ocb_state *ocb, | |

const unsigned char *pt, unsigned long ptlen, | |

unsigned char *ct, | |

unsigned char *tag, unsigned long *taglen); | |

\end{verbatim} | |

This will terminate an encrypt stream ``ocb''. If you have trailing bytes of plaintext that will not complete a block | |

you can pass them here. This will also encrypt the ``ptlen'' bytes in ``pt'' and store them in ``ct''. It will also | |

store upto ``taglen'' bytes of the tag into ``tag''. | |

Note that ``ptlen'' must be less than or equal to the block size of block cipher chosen. Also note that if you have | |

an input message equal to the length of the block size then you pass the data here (not to ocb\_encrypt()) only. | |

To terminate a decrypt stream and compared the tag you call the following. | |

\index{ocb\_done\_decrypt()} | |

\begin{verbatim} | |

int ocb_done_decrypt(ocb_state *ocb, | |

const unsigned char *ct, unsigned long ctlen, | |

unsigned char *pt, | |

const unsigned char *tag, unsigned long taglen, | |

int *res); | |

\end{verbatim} | |

Similarly to the previous function you can pass trailing message bytes into this function. This will compute the | |

tag of the message (internally) and then compare it against the ``taglen'' bytes of ``tag'' provided. By default | |

``res'' is set to zero. If all ``taglen'' bytes of ``tag'' can be verified then ``res'' is set to one (authenticated | |

message). | |

\subsubsection{Packet Functions} | |

To make life simpler the following two functions are provided for memory bound OCB. | |

\index{ocb\_encrypt\_authenticate\_memory()} | |

\begin{verbatim} | |

int ocb_encrypt_authenticate_memory(int cipher, | |

const unsigned char *key, unsigned long keylen, | |

const unsigned char *nonce, | |

const unsigned char *pt, unsigned long ptlen, | |

unsigned char *ct, | |

unsigned char *tag, unsigned long *taglen); | |

\end{verbatim} | |

This will OCB encrypt the message ``pt'' of length ``ptlen'' and store the ciphertext in ``ct''. The length ``ptlen'' | |

can be any arbitrary length. | |

\index{ocb\_decrypt\_verify\_memory()} | |

\begin{verbatim} | |

int ocb_decrypt_verify_memory(int cipher, | |

const unsigned char *key, unsigned long keylen, | |

const unsigned char *nonce, | |

const unsigned char *ct, unsigned long ctlen, | |

unsigned char *pt, | |

const unsigned char *tag, unsigned long taglen, | |

int *res); | |

\end{verbatim} | |

Similarly this will OCB decrypt and compare the internally computed tag against the tag provided. ``res'' is set | |

appropriately. | |

\subsection{CCM Mode} | |

CCM is a NIST proposal for Encrypt+Authenticate that is centered around using AES (or any 16--byte cipher) as a primitive. Unlike EAX and OCB mode | |

it is only meant for ``packet'' mode where the length of the input is known in advance. Since it is a packet mode function CCM only has one | |

function that performs the protocol. | |

\index{ccm\_memory()} | |

\begin{verbatim} | |

int ccm_memory(int cipher, | |

const unsigned char *key, unsigned long keylen, | |

const unsigned char *nonce, unsigned long noncelen, | |

const unsigned char *header, unsigned long headerlen, | |

unsigned char *pt, unsigned long ptlen, | |

unsigned char *ct, | |

unsigned char *tag, unsigned long *taglen, | |

int direction); | |

\end{verbatim} | |

This performs the ``CCM'' operation on the data. The ``cipher'' variable indicates which cipher in the descriptor table to use. It must have a | |

16--byte block size for CCM. The key is ``key'' with a length of ``keylen'' octets. The nonce or salt is ``nonce'' of | |

length ``noncelen'' octets. The header is meta--data you want to send with the message but not have encrypted, it is stored in ``header'' | |

of length ``headerlen'' octets. The header can be zero octets long (if $headerlen = 0$ then you can pass ``header'' as \textbf{NULL}). | |

The plaintext is stored in ``pt'' and the ciphertext in ``ct''. The length of both are expected to be equal and is passed in as ``ptlen''. It is | |

allowable that $pt = ct$. The ``direction'' variable indicates whether encryption (direction $=$ \textbf{CCM\_ENCRYPT}) or | |

decryption (direction $=$ \textbf{CCM\_DECRYPT}) is to be performed. | |

As implemented this copy of CCM cannot handle a header or plaintext longer than $2^{32} - 1$ octets long. | |

You can test the implementation of CCM with the following function. | |

\index{ccm\_test()} | |

\begin{verbatim} | |

int ccm_test(void); | |

\end{verbatim} | |

This will return \textbf{CRYPT\_OK} if the CCM routine passes known test vectors. | |

\subsection{GCM Mode} | |

Galois counter mode is an IEEE proposal for authenticated encryption. Like EAX and OCB it can be used in a streaming capacity however, unlike EAX it cannot | |

accept ``additional authentication data'' (meta--data) after plaintext has been processed. This mode also only works with block ciphers with a sixteen | |

byte block. | |

A GCM stream is meant to be processed in three modes each one sequential serial. First the initial vector (per session) data is processed. This should be | |

unique to every session. Next the the optional additional authentication data is processed and finally the plaintext. | |

\subsubsection{Initialization} | |

To initialize the GCM context with a secret key call the following function. | |

\index{gcm\_init()} | |

\begin{verbatim} | |

int gcm_init(gcm_state *gcm, int cipher, | |

const unsigned char *key, int keylen); | |

\end{verbatim} | |

This initializes the GCM state ``gcm'' for the given cipher indexed by ``cipher'' with a secret key ``key'' of length ``keylen'' octets. The cipher chosen | |

must have a 16--byte block size (e.g. AES). | |

\subsubsection{Initial Vector} | |

After the state has been initialized (or reset) the next step is to add the session (or packet) initial vector. It should be unique per packet encrypted. | |

\index{gcm\_add\_iv()} | |

\begin{verbatim} | |

int gcm_add_iv(gcm_state *gcm, | |

const unsigned char *IV, unsigned long IVlen); | |

\end{verbatim} | |

This adds the initial vector octets from ``IV'' of length ``IVlen'' to the GCM state ``gcm''. You can call this function as many times as required | |

to process the entire IV. | |

Note that the GCM protocols provides a ``shortcut'' for 12--byte IVs where no preprocessing is to be done. If you want to minimize per packet latency it's ideal | |

to only use 12--byte IVs. You can just increment it like a counter for each packet and the CTR [privacy] will be ensured. | |

\subsubsection{Additional Authentication Data} | |

After the entire IV has been processed the additional authentication data can be processed. Unlike the IV a packet/session does not require additional | |

authentication data (AAD) for security. The AAD is meant to be used as side--channel data you want to be authenticated with the packet. Note that once | |

you begin adding AAD to the GCM state you cannot return to adding IV data until the state is reset. | |

\index{gcm\_add\_aad()} | |

\begin{verbatim} | |

int gcm_add_aad(gcm_state *gcm, | |

const unsigned char *adata, unsigned long adatalen); | |

\end{verbatim} | |

This adds the additional authentication data ``adata'' of length ``adatalen'' to the GCM state ``gcm''. | |

\subsubsection{Plaintext Processing} | |

After the AAD has been processed the plaintext (or ciphertext depending on the direction) can be processed. | |

\index{gcm\_process()} | |

\begin{verbatim} | |

int gcm_process(gcm_state *gcm, | |

unsigned char *pt, unsigned long ptlen, | |

unsigned char *ct, | |

int direction); | |

\end{verbatim} | |

This processes message data where ``pt'' is the plaintext and ``ct'' is the ciphertext. The length of both are equal and stored in ``ptlen''. Depending on the | |

mode ``pt'' is the input and ``ct'' is the output (or vice versa). When ``direction'' equals \textbf{GCM\_ENCRYPT} the plaintext is read, encrypted and stored | |

in the ciphertext buffer. When ``direction'' equals \textbf{GCM\_DECRYPT} the opposite occurs. | |

\subsubsection{State Termination} | |

To terminate a GCM state and retrieve the message authentication tag call the following function. | |

\index{gcm\_done()} | |

\begin{verbatim} | |

int gcm_done(gcm_state *gcm, | |

unsigned char *tag, unsigned long *taglen); | |

\end{verbatim} | |

This terminates the GCM state ``gcm'' and stores the tag in ``tag'' of length ``taglen'' octets. | |

\subsubsection{State Reset} | |

The call to gcm\_init() will perform considerable pre--computation (when \textbf{GCM\_TABLES} is defined) and if you're going to be dealing with a lot of packets | |

it is very costly to have to call it repeatedly. To aid in this endeavour the reset function has been provided. | |

\index{gcm\_reset()} | |

\begin{verbatim} | |

int gcm_reset(gcm_state *gcm); | |

\end{verbatim} | |

This will reset the GCM state ``gcm'' to the state that gcm\_init() left it. The user would then call gcm\_add\_iv(), gcm\_add\_aad(), etc. | |

\subsubsection{One--Shot Packet} | |

To process a single packet under any given key the following helper function can be used. | |

\index{gcm\_memory()} | |

\begin{verbatim} | |

int gcm_memory( int cipher, | |

const unsigned char *key, unsigned long keylen, | |

const unsigned char *IV, unsigned long IVlen, | |

const unsigned char *adata, unsigned long adatalen, | |

unsigned char *pt, unsigned long ptlen, | |

unsigned char *ct, | |

unsigned char *tag, unsigned long *taglen, | |

int direction); | |

\end{verbatim} | |

This will initialize the GCM state with the given key, IV and AAD value then proceed to encrypt or decrypt the message text and store the final | |

message tag. The definition of the variables is the same as it is for all the manual functions. | |

If you are processing many packets under the same key you shouldn't use this function as it invokes the pre--computation with each call. | |

\subsubsection{Example Usage} | |

The following is an example usage of how to use GCM over multiple packets with a shared secret key. | |

\begin{small} | |

\begin{verbatim} | |

#include <tomcrypt.h> | |

int send_packet(const unsigned char *pt, unsigned long ptlen, | |

const unsigned char *iv, unsigned long ivlen, | |

const unsigned char *aad, unsigned long aadlen, | |

gcm_state *gcm) | |

{ | |

int err; | |

unsigned long taglen; | |

unsigned char tag[16]; | |

/* reset the state */ | |

if ((err = gcm_reset(gcm)) != CRYPT_OK) { | |

return err; | |

} | |

/* Add the IV */ | |

if ((err = gcm_add_iv(gcm, iv, ivlen)) != CRYPT_OK) { | |

return err; | |

} | |

/* Add the AAD (note: aad can be NULL if aadlen == 0) */ | |

if ((err = gcm_add_aad(gcm, aad, aadlen)) != CRYPT_OK) { | |

return err; | |

} | |

/* process the plaintext */ | |

if ((err = gcm_process(gcm, pt, ptlen, pt, GCM_ENCRYPT)) != CRYPT_OK) { | |

return err; | |

} | |

/* Finish up and get the MAC tag */ | |

taglen = sizeof(tag); | |

if ((err = gcm_done(gcm, tag, &taglen)) != CRYPT_OK) { | |

return err; | |

} | |

/* ... send a header describing the lengths ... */ | |

/* depending on the protocol and how IV is generated you may have to send it too... */ | |

send(socket, iv, ivlen, 0); | |

/* send the aad */ | |

send(socket, aad, aadlen, 0); | |

/* send the ciphertext */ | |

send(socket, pt, ptlen, 0); | |

/* send the tag */ | |

send(socket, tag, taglen, 0); | |

return CRYPT_OK; | |

} | |

int main(void) | |

{ | |

gcm_state gcm; | |

unsigned char key[16], IV[12], pt[PACKET_SIZE]; | |

int err, x; | |

unsigned long ptlen; | |

/* somehow fill key/IV with random values */ | |

/* register AES */ | |

register_cipher(&aes_desc); | |

/* init the GCM state */ | |

if ((err = gcm_init(&gcm, find_cipher("aes"), key, 16)) != CRYPT_OK) { | |

whine_and_pout(err); | |

} | |

/* handle us some packets */ | |

for (;;) { | |

ptlen = make_packet_we_want_to_send(pt); | |

/* use IV as counter (12 byte counter) */ | |

for (x = 11; x >= 0; x--) { | |

if (++IV[x]) { | |

break; | |

} | |

} | |

if ((err = send_packet(pt, ptlen, iv, 12, NULL, 0, &gcm)) != CRYPT_OK) { | |

whine_and_pout(err); | |

} | |

} | |

return EXIT_SUCCESS; | |

} | |

\end{verbatim} | |

\end{small} | |

\chapter{One-Way Cryptographic Hash Functions} | |

\section{Core Functions} | |

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} | |

int XXX_process(hash_state *md, const unsigned char *in, unsigned long inlen); | |

\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} | |

int 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 <tomcrypt.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 in out[0..15] */ | |

md5_done(&md, out); | |

return 0; | |

} | |

\end{verbatim} | |

\end{small} | |

\section{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 */ | |

void (*init) (hash_state *hash); | |

int (*process)(hash_state *hash, | |

const unsigned char *in, unsigned long inlen); | |

int (*done) (hash_state *hash, unsigned char *out); | |

int (*test) (void); | |

}; | |

\end{verbatim} | |

Similarly ``name'' is the name of the hash function in ASCII (all lowercase). ``hashsize'' is the size of the digest output | |

in bytes. The remaining fields are pointers to the functions that do the respective tasks. There is a function to | |

search the array as well called ``int find\_hash(char *name)''. It returns -1 if the hash is not found, otherwise the | |

position in the descriptor table of the hash. | |

You can use the table to indirectly call a hash function that is chosen at runtime. For example: | |

\begin{small} | |

\begin{verbatim} | |

#include <tomcrypt.h> | |

int main(void) | |

{ | |

unsigned char buffer[100], hash[MAXBLOCKSIZE]; | |

int idx, x; | |

hash_state md; | |

/* register hashes .... */ | |

if (register_hash(&md5_desc) == -1) { | |

printf("Error registering MD5.\n"); | |

return -1; | |

} | |

/* register other hashes ... */ | |

/* prompt for name and strip newline */ | |

printf("Enter hash name: \n"); | |

fgets(buffer, sizeof(buffer), stdin); | |

buffer[strlen(buffer) - 1] = 0; | |

/* get hash index */ | |

idx = find_hash(buffer); | |

if (idx == -1) { | |

printf("Invalid hash name!\n"); | |

return -1; | |

} | |

/* hash input until blank line */ | |

hash_descriptor[idx].init(&md); | |

while (fgets(buffer, sizeof(buffer), stdin) != NULL) | |

hash_descriptor[idx].process(&md, buffer, strlen(buffer)); | |

hash_descriptor[idx].done(&md, hash); | |

/* dump to screen */ | |

for (x = 0; x < hash_descriptor[idx].hashsize; x++) | |

printf("%02x ", hash[x]); | |

printf("\n"); | |

return 0; | |

} | |

\end{verbatim} | |

\end{small} | |

Note the usage of ``MAXBLOCKSIZE''. In Libtomcrypt no symmetric block, key or hash digest is larger than MAXBLOCKSIZE in | |

length. This provides a simple size you can set your automatic arrays to that will not get overrun. | |

There are three helper functions as well: | |

\index{hash\_memory()} \index{hash\_file()} | |

\begin{verbatim} | |

int hash_memory(int hash, | |

const unsigned char *in, unsigned long inlen, | |

unsigned char *out, unsigned long *outlen); | |

int hash_file(int hash, const char *fname, | |

unsigned char *out, unsigned long *outlen); | |

int hash_filehandle(int hash, FILE *in, | |

unsigned char *out, unsigned long *outlen); | |

\end{verbatim} | |

The ``hash'' parameter is the location in the descriptor table of the hash (\textit{e.g. the return of find\_hash()}). | |

The ``*outlen'' variable is used to keep track of the output size. You must set it to the size of your output buffer before | |

calling the functions. When they complete succesfully they store the length of the message digest back in it. The functions | |

are otherwise straightforward. The ``hash\_filehandle'' function assumes that ``in'' is an file handle opened in binary mode. | |

It will hash to the end of file and not reset the file position when finished. | |

To perform the above hash with md5 the following code could be used: | |

\begin{small} | |

\begin{verbatim} | |

#include <tomcrypt.h> | |

int main(void) | |

{ | |

int idx, err; | |

unsigned long len; | |

unsigned char out[MAXBLOCKSIZE]; | |

/* register the hash */ | |

if (register_hash(&md5_desc) == -1) { | |

printf("Error registering MD5.\n"); | |

return -1; | |

} | |

/* get the index of the hash */ | |

idx = find_hash("md5"); | |

/* call the hash */ | |

len = sizeof(out); | |

if ((err = hash_memory(idx, "hello world", 11, out, &len)) != CRYPT_OK) { | |

printf("Error hashing data: %s\n", error_to_string(err)); | |

return -1; | |

} | |

return 0; | |

} | |

\end{verbatim} | |

\end{small} | |

The following hashes are provided as of this release: | |

\index{Hash descriptor table} | |

\begin{center} | |

\begin{tabular}{|c|c|c|} | |

\hline Name & Descriptor Name & Size of Message Digest (bytes) \\ | |

\hline WHIRLPOOL & whirlpool\_desc & 64 \\ | |

\hline SHA-512 & sha512\_desc & 64 \\ | |

\hline SHA-384 & sha384\_desc & 48 \\ | |

\hline SHA-256 & sha256\_desc & 32 \\ | |

\hline SHA-224 & sha224\_desc & 28 \\ | |

\hline TIGER-192 & tiger\_desc & 24 \\ | |

\hline SHA-1 & sha1\_desc & 20 \\ | |

\hline RIPEMD-160 & rmd160\_desc & 20 \\ | |

\hline RIPEMD-128 & rmd128\_desc & 16 \\ | |

\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: | |

\index{register\_hash()} \index{unregister\_hash()} | |

\begin{verbatim} | |

int register_hash(const struct _hash_descriptor *hash); | |

int unregister_hash(const struct _hash_descriptor *hash); | |

\end{verbatim} | |

\section{Cipher Hash Construction} | |

\index{Cipher Hash Construction} | |

An addition to the suite of hash functions is the ``Cipher Hash Construction'' or ``CHC'' mode. In this mode | |

applicable block ciphers (such as AES) can be turned into hash functions that other LTC functions can use. In | |

particular this allows a cryptosystem to be designed using very few moving parts. | |

In order to use the CHC system the developer will have to take a few extra steps. First the ``chc\_desc'' hash | |

descriptor must be registered with register\_hash(). At this point the CHC hash cannot be used to hash | |

data. While it is in the hash system you still have to tell the CHC code which cipher to use. This is accomplished | |

via the chc\_register() function. | |

\index{chc\_register()} | |

\begin{verbatim} | |

int chc_register(int cipher); | |

\end{verbatim} | |

A cipher has to be registered with CHC (and also in the cipher descriptor tables with | |

register\_cipher()). The chc\_register() function will bind a cipher to the CHC system. Only one cipher can | |

be bound to the CHC hash at a time. There are additional requirements for the system to work. | |

\begin{enumerate} | |

\item The cipher must have a block size greater than 64--bits. | |

\item The cipher must allow an input key the size of the block size. | |

\end{enumerate} | |

Example of using CHC with the AES block cipher. | |

\begin{verbatim} | |

#include <tomcrypt.h> | |

int main(void) | |

{ | |

int err; | |

/* register cipher and hash */ | |

if (register_cipher(&aes_enc_desc) == -1) { | |

printf("Could not register cipher\n"); | |

return EXIT_FAILURE; | |

} | |

if (register_hash(&chc_desc) == -1) { | |

printf("Could not register hash\n"); | |

return EXIT_FAILURE; | |

} | |

/* start chc with AES */ | |

if ((err = chc_register(find_cipher("aes"))) != CRYPT_OK) { | |

printf("Error binding AES to CHC: %s\n", error_to_string(err)); | |

} | |

/* now you can use chc_hash in any LTC function [aside from pkcs...] */ | |

/* ... */ | |

\end{verbatim} | |

\section{Notice} | |

It is highly recommended that you \textbf{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. | |

\chapter{Message Authentication Codes} | |

\section{HMAC Protocol} | |

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: | |

\index{hmac\_init()} | |

\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: | |

\index{hmac\_process()} | |

\begin{verbatim} | |

int hmac_process(hmac_state *hmac, | |

const unsigned char *in, unsigned long inlen); | |

\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: | |

\index{hmac\_done()} | |

\begin{verbatim} | |

int hmac_done(hmac_state *hmac, | |

unsigned char *out, unsigned long *outlen); | |

\end{verbatim} | |

``hmac'' is the HMAC state you are working with. ``out'' is the array of octets where the HMAC code should be stored. You must | |

set ``outlen'' to the size of the destination buffer before calling this function. It is updated with the length of the HMAC code | |

produced (depending on which hash was picked). If ``outlen'' is less than the size of the message digest (and ultimately | |

the HMAC code) then the HMAC code is truncated as per FIPS-198 specifications (e.g. take the first ``outlen'' bytes). | |

There are two utility functions provided to make using HMACs easier todo. They accept the key and information about the | |

message (file pointer, address in memory) and produce the HMAC result in one shot. These are useful if you want to avoid | |

calling the three step process yourself. | |

\index{hmac\_memory()} | |

\begin{verbatim} | |

int hmac_memory(int hash, | |

const unsigned char *key, unsigned long keylen, | |

const unsigned char *in, unsigned long inlen, | |

unsigned char *out, unsigned long *outlen); | |

\end{verbatim} | |

This will produce an HMAC code for the array of octets in ``in'' of length ``inlen''. 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 ``out'' and the length in ``outlen''. The value of ``outlen'' must be set | |

to the size of the destination buffer before calling this function. Similarly for files there is the following function: | |

\index{hmac\_file()} | |

\begin{verbatim} | |

int hmac_file(int hash, const char *fname, | |

const unsigned char *key, unsigned long keylen, | |

unsigned char *out, unsigned long *outlen); | |

\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 of length ``keylen''. ``out'' is the array of octets where the | |

result should be stored. | |

To test if the HMAC code is working there is the following function: | |

\index{hmac\_test()} | |

\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 <tomcrypt.h> | |

int main(void) | |

{ | |

int idx, err; | |

hmac_state hmac; | |

unsigned char key[16], dst[MAXBLOCKSIZE]; | |

unsigned long dstlen; | |

/* 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 ((err = hmac_init(&hmac, idx, key, 16)) != CRYPT_OK) { | |

printf("Error setting up hmac: %s\n", error_to_string(err)); | |

return -1; | |

} | |

/* process a few octets */ | |

if((err = hmac_process(&hmac, "hello", 5) != CRYPT_OK) { | |

printf("Error processing hmac: %s\n", error_to_string(err)); | |

return -1; | |

} | |

/* get result (presumably to use it somehow...) */ | |

dstlen = sizeof(dst); | |

if ((err = hmac_done(&hmac, dst, &dstlen)) != CRYPT_OK) { | |

printf("Error finishing hmac: %s\n", error_to_string(err)); | |

return -1; | |

} | |

printf("The hmac is %lu bytes long\n", dstlen); | |

/* return */ | |

return 0; | |

} | |

\end{verbatim} | |

\end{small} | |

\section{OMAC Support} | |

OMAC\footnote{\url{http://crypt.cis.ibaraki.ac.jp/omac/omac.html}}, which stands for \textit{One-Key CBC MAC} is an | |

algorithm which produces a Message Authentication Code (MAC) using only a block cipher such as AES. From an API | |

standpoint the OMAC routines work much like the HMAC routines do. Instead in this case a cipher is used instead of a hash. | |

To start an OMAC state you call | |

\index{omac\_init()} | |

\begin{verbatim} | |

int omac_init(omac_state *omac, int cipher, | |

const unsigned char *key, unsigned long keylen); | |

\end{verbatim} | |

The ``omac'' variable is the state for the OMAC algorithm. ``cipher'' is the index into the cipher\_descriptor table | |

of the cipher\footnote{The cipher must have a 64 or 128 bit block size. Such as CAST5, Blowfish, DES, AES, Twofish, etc.} you | |

wish to use. ``key'' and ``keylen'' are the keys used to authenticate the data. | |

To send data through the algorithm call | |

\index{omac\_process()} | |

\begin{verbatim} | |

int omac_process(omac_state *state, | |

const unsigned char *in, unsigned long inlen); | |

\end{verbatim} | |

This will send ``inlen'' bytes from ``in'' through the active OMAC state ``state''. Returns \textbf{CRYPT\_OK} if the | |

function succeeds. The function is not sensitive to the granularity of the data. For example, | |

\begin{verbatim} | |

omac_process(&mystate, "hello", 5); | |

omac_process(&mystate, " world", 6); | |

\end{verbatim} | |

Would produce the same result as, | |

\begin{verbatim} | |

omac_process(&mystate, "hello world", 11); | |

\end{verbatim} | |

When you are done processing the message you can call the following to compute the message tag. | |

\index{omac\_done()} | |

\begin{verbatim} | |

int omac_done(omac_state *state, | |

unsigned char *out, unsigned long *outlen); | |

\end{verbatim} | |

Which will terminate the OMAC and output the \textit{tag} (MAC) to ``out''. Note that unlike the HMAC and other code | |

``outlen'' can be smaller than the default MAC size (for instance AES would make a 16-byte tag). Part of the OMAC | |

specification states that the output may be truncated. So if you pass in $outlen = 5$ and use AES as your cipher than | |

the output MAC code will only be five bytes long. If ``outlen'' is larger than the default size it is set to the default | |

size to show how many bytes were actually used. | |

Similar to the HMAC code the file and memory functions are also provided. To OMAC a buffer of memory in one shot use the | |

following function. | |

\index{omac\_memory()} | |

\begin{verbatim} | |

int omac_memory(int cipher, | |

const unsigned char *key, unsigned long keylen, | |

const unsigned char *in, unsigned long inlen, | |

unsigned char *out, unsigned long *outlen); | |

\end{verbatim} | |

This will compute the OMAC of ``inlen'' bytes of ``in'' using the key ``key'' of length ``keylen'' bytes and the cipher | |

specified by the ``cipher'''th entry in the cipher\_descriptor table. It will store the MAC in ``out'' with the same | |

rules as omac\_done. | |

To OMAC a file use | |

\index{omac\_file()} | |

\begin{verbatim} | |

int omac_file(int cipher, | |

const unsigned char *key, unsigned long keylen, | |

const char *filename, | |

unsigned char *out, unsigned long *outlen); | |

\end{verbatim} | |

Which will OMAC the entire contents of the file specified by ``filename'' using the key ``key'' of length ``keylen'' bytes | |

and the cipher specified by the ``cipher'''th entry in the cipher\_descriptor table. It will store the MAC in ``out'' with | |

the same rules as omac\_done. | |

To test if the OMAC code is working there is the following function: | |

\index{omac\_test()} | |

\begin{verbatim} | |

int omac_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 | |

OMAC system is given below. | |

\begin{small} | |

\begin{verbatim} | |

#include <tomcrypt.h> | |

int main(void) | |

{ | |

int idx, err; | |

omac_state omac; | |

unsigned char key[16], dst[MAXBLOCKSIZE]; | |

unsigned long dstlen; | |

/* register Rijndael */ | |

if (register_cipher(&rijndael_desc) == -1) { | |

printf("Error registering Rijndael\n"); | |

return -1; | |

} | |

/* get index of Rijndael in cipher descriptor table */ | |

idx = find_cipher("rijndael"); | |

/* we would make up our symmetric key in "key[]" here */ | |

/* start the OMAC */ | |

if ((err = omac_init(&omac, idx, key, 16)) != CRYPT_OK) { | |

printf("Error setting up omac: %s\n", error_to_string(err)); | |

return -1; | |

} | |

/* process a few octets */ | |

if((err = omac_process(&omac, "hello", 5) != CRYPT_OK) { | |

printf("Error processing omac: %s\n", error_to_string(err)); | |

return -1; | |

} | |

/* get result (presumably to use it somehow...) */ | |

dstlen = sizeof(dst); | |

if ((err = omac_done(&omac, dst, &dstlen)) != CRYPT_OK) { | |

printf("Error finishing omac: %s\n", error_to_string(err)); | |

return -1; | |

} | |

printf("The omac is %lu bytes long\n", dstlen); | |

/* return */ | |

return 0; | |

} | |

\end{verbatim} | |

\end{small} | |

\section{PMAC Support} | |

The PMAC\footnote{J.Black, P.Rogaway, ``A Block--Cipher Mode of Operation for Parallelizable Message Authentication''} | |

protocol is another MAC algorithm that relies solely on a symmetric-key block cipher. It uses essentially the same | |

API as the provided OMAC code. | |

A PMAC state is initialized with the following. | |

\index{pmac\_init()} | |

\begin{verbatim} | |

int pmac_init(pmac_state *pmac, int cipher, | |

const unsigned char *key, unsigned long keylen); | |

\end{verbatim} | |

Which initializes the ``pmac'' state with the given ``cipher'' and ``key'' of length ``keylen'' bytes. The chosen cipher | |

must have a 64 or 128 bit block size (e.x. AES). | |

To MAC data simply send it through the process function. | |

\index{pmac\_process()} | |

\begin{verbatim} | |

int pmac_process(pmac_state *state, | |

const unsigned char *in, unsigned long inlen); | |

\end{verbatim} | |

This will process ``inlen'' bytes of ``in'' in the given ``state''. The function is not sensitive to the granularity of the | |

data. For example, | |

\begin{verbatim} | |

pmac_process(&mystate, "hello", 5); | |

pmac_process(&mystate, " world", 6); | |

\end{verbatim} | |

Would produce the same result as, | |

\begin{verbatim} | |

pmac_process(&mystate, "hello world", 11); | |

\end{verbatim} | |

When a complete message has been processed the following function can be called to compute the message tag. | |

\index{pmac\_done()} | |

\begin{verbatim} | |

int pmac_done(pmac_state *state, | |

unsigned char *out, unsigned long *outlen); | |

\end{verbatim} | |

This will store upto ``outlen'' bytes of the tag for the given ``state'' into ``out''. Note that if ``outlen'' is larger | |

than the size of the tag it is set to the amount of bytes stored in ``out''. | |

Similar to the PMAC code the file and memory functions are also provided. To PMAC a buffer of memory in one shot use the | |

following function. | |

\index{pmac\_memory()} | |

\begin{verbatim} | |

int pmac_memory(int cipher, | |

const unsigned char *key, unsigned long keylen, | |

const unsigned char *in, unsigned long inlen, | |

unsigned char *out, unsigned long *outlen); | |

\end{verbatim} | |

This will compute the PMAC of ``msglen'' bytes of ``msg'' using the key ``key'' of length ``keylen'' bytes and the cipher | |

specified by the ``cipher'''th entry in the cipher\_descriptor table. It will store the MAC in ``out'' with the same | |

rules as omac\_done. | |

To PMAC a file use | |

\index{pmac\_file()} | |

\begin{verbatim} | |

int pmac_file(int cipher, | |

const unsigned char *key, unsigned long keylen, | |

const char *filename, | |

unsigned char *out, unsigned long *outlen); | |

\end{verbatim} | |

Which will PMAC the entire contents of the file specified by ``filename'' using the key ``key'' of length ``keylen'' bytes | |

and the cipher specified by the ``cipher'''th entry in the cipher\_descriptor table. It will store the MAC in ``out'' with | |

the same rules as omac\_done. | |

To test if the PMAC code is working there is the following function: | |

\index{pmac\_test()} | |

\begin{verbatim} | |

int pmac_test(void); | |

\end{verbatim} | |

Which returns {\bf CRYPT\_OK} if the code passes otherwise it returns an error code. | |

\section{Pelican MAC} | |

Pelican MAC is a new (experimental) MAC by the AES team that uses four rounds of AES as a ``mixing function''. It achieves a very high | |

rate of processing and is potentially very secure. It requires AES to be enabled to function. You do not have to register\_cipher() AES first though | |

as it calls AES directly. | |

\index{pelican\_init()} | |

\begin{verbatim} | |

int pelican_init(pelican_state *pelmac, const unsigned char *key, unsigned long keylen); | |

\end{verbatim} | |

This will initialize the Pelican state with the given AES key. Once this has been done you can begin processing data. | |

\index{pelican\_process()} | |

\begin{verbatim} | |

int pelican_process(pelican_state *pelmac, const unsigned char *in, unsigned long inlen); | |

\end{verbatim} | |

This will process ``inlen'' bytes of ``in'' through the Pelican MAC. It's best that you pass in multiples of 16 bytes as it makes the | |

routine more efficient but you may pass in any length of text. You can call this function as many times as required to process | |

an entire message. | |

\index{pelican\_done()} | |

\begin{verbatim} | |

int pelican_done(pelican_state *pelmac, unsigned char *out); | |

\end{verbatim} | |

This terminates a Pelican MAC and writes the 16--octet tag to ``out''. | |

\subsection{Example} | |

\begin{verbatim} | |

#include <tomcrypt.h> | |

int main(void) | |

{ | |

pelican_state pelstate; | |

unsigned char key[32], tag[16]; | |

int err; | |

/* somehow initialize a key */ | |

/* initialize pelican mac */ | |

if ((err = pelican_init(&pelstate, /* the state */ | |

key, /* user key */ | |

32 /* key length in octets */ | |

)) != CRYPT_OK) { | |

printf("Error initializing Pelican: %s", error_to_string(err)); | |

return EXIT_FAILURE; | |

} | |

/* MAC some data */ | |

if ((err = pelican_process(&pelstate, /* the state */ | |

"hello world", /* data to mac */ | |

11 /* length of data */ | |

)) != CRYPT_OK) { | |

printf("Error processing Pelican: %s", error_to_string(err)); | |

return EXIT_FAILURE; | |

} | |

/* Terminate the MAC */ | |

if ((err = pelican_done(&pelstate, /* the state */ | |

tag /* where to store the tag */ | |

)) != CRYPT_OK) { | |

printf("Error terminating Pelican: %s", error_to_string(err)); | |

return EXIT_FAILURE; | |

} | |

/* tag[0..15] has the MAC output now */ | |

return EXIT_SUCCESS; | |

} | |

\end{verbatim} | |

\chapter{Pseudo-Random Number Generators} | |

\section{Core Functions} | |

The library provides an array of core functions for Pseudo-Random Number Generators (PRNGs) as well. A cryptographic PRNG is | |

used to expand a shorter bit string into a longer bit string. PRNGs are used wherever random data is required such as Public Key (PK) | |

key generation. There is a universal structure called ``prng\_state''. To initialize a PRNG call: | |

\index{PRNG start} | |

\begin{verbatim} | |

int XXX_start(prng_state *prng); | |

\end{verbatim} | |

This will setup the PRNG for future use and not seed it. In order for the PRNG to be cryptographically useful you must give it | |

entropy. Ideally you'd have some OS level source to tap like in UNIX. To add entropy to the PRNG call: | |

\index{PRNG add\_entropy} | |

\begin{verbatim} | |

int XXX_add_entropy(const unsigned char *in, unsigned long inlen, | |

prng_state *prng); | |

\end{verbatim} | |

Which returns {\bf CRYPTO\_OK} if the entropy was accepted. Once you think you have enough entropy you call another | |

function to put the entropy into action. | |

\index{PRNG ready} | |

\begin{verbatim} | |

int XXX_ready(prng_state *prng); | |

\end{verbatim} | |

Which returns {\bf CRYPTO\_OK} if it is ready. Finally to actually read bytes call: | |

\index{PRNG read} | |

\begin{verbatim} | |

unsigned long XXX_read(unsigned char *out, unsigned long outlen, | |

prng_state *prng); | |

\end{verbatim} | |

Which returns the number of bytes read from the PRNG. When you are finished with a PRNG state you call | |

the following. | |

\index{PRNG done} | |

\begin{verbatim} | |

void XXX_done(prng_state *prng); | |

\end{verbatim} | |

This will terminate a PRNG state and free any memory (if any) allocated. To export a PRNG state | |

so that you can later resume the PRNG call the following. | |

\index{PRNG export} | |

\begin{verbatim} | |

int XXX_export(unsigned char *out, unsigned long *outlen, | |

prng_state *prng); | |

\end{verbatim} | |

This will write a ``PRNG state'' to the buffer ``out'' of length ``outlen'' bytes. The idea of | |

the export is meant to be used as a ``seed file''. That is, when the program starts up there will not likely | |

be that much entropy available. To import a state to seed a PRNG call the following function. | |

\index{PRNG import} | |

\begin{verbatim} | |

int XXX_import(const unsigned char *in, unsigned long inlen, | |

prng_state *prng); | |

\end{verbatim} | |

This will call the start and add\_entropy functions of the given PRNG. It will use the state in | |

``in'' of length ``inlen'' as the initial seed. You must pass the same seed length as was exported | |

by the corresponding export function. | |

Note that importing a state will not ``resume'' the PRNG from where it left off. That is, if you export | |

a state, emit (say) 8 bytes and then import the previously exported state the next 8 bytes will not | |

specifically equal the 8 bytes you generated previously. | |

When a program is first executed the normal course of operation is | |

\begin{enumerate} | |

\item Gather entropy from your sources for a given period of time or number of events. | |

\item Start, use your entropy via add\_entropy and ready the PRNG yourself. | |

\end{enumerate} | |

When your program is finished you simply call the export function and save the state to a medium (disk, | |

flash memory, etc). The next time your application starts up you can detect the state, feed it to the | |

import function and go on your way. It is ideal that (as soon as possible) after startup you export a | |

fresh state. This helps in the case that the program aborts or the machine is powered down without | |

being given a chance to exit properly. | |

Note that even if you have a state to import it is important to add new entropy to the state. However, | |

there is less pressure to do so. | |

To test a PRNG for operational conformity call the following functions. | |

\index{PRNG test} | |

\begin{verbatim} | |

int XXX_test(void); | |

\end{verbatim} | |

This will return \textbf{CRYPT\_OK} if PRNG is operating properly. | |

\subsection{Remarks} | |

It is possible to be adding entropy and reading from a PRNG at the same time. For example, if you first seed the PRNG | |

and call ready() you can now read from it. You can also keep adding new entropy to it. The new entropy will not be used | |

in the PRNG until ready() is called again. This allows the PRNG to be used and re-seeded at the same time. No real error | |

checking is guaranteed to see if the entropy is sufficient or if the PRNG is even in a ready state before reading. | |

\subsection{Example} | |

Below is a simple snippet to read 10 bytes from yarrow. Its important to note that this snippet is | |

{\bf NOT} secure since the entropy added is not random. | |

\begin{verbatim} | |

#include <tomcrypt.h> | |

int main(void) | |

{ | |

prng_state prng; | |

unsigned char buf[10]; | |

int err; | |

/* start it */ | |

if ((err = yarrow_start(&prng)) != CRYPT_OK) { | |

printf("Start error: %s\n", error_to_string(err)); | |

} | |

/* add entropy */ | |

if ((err = yarrow_add_entropy("hello world", 11, &prng)) != CRYPT_OK) { | |

printf("Add_entropy error: %s\n", error_to_string(err)); | |

} | |

/* ready and read */ | |

if ((err = yarrow_ready(&prng)) != CRYPT_OK) { | |

printf("Ready error: %s\n", error_to_string(err)); | |

} | |

printf("Read %lu bytes from yarrow\n", yarrow_read(buf, 10, &prng)); | |

return 0; | |

} | |

\end{verbatim} | |

\section{PRNG Descriptors} | |

\index{PRNG Descriptor} | |

PRNGs have descriptors too (surprised?). Stored in the structure ``prng\_descriptor''. The format of an element is: | |

\begin{verbatim} | |

struct _prng_descriptor { | |

char *name; | |

int export_size; /* size in bytes of exported state */ | |

int (*start) (prng_state *); | |

int (*add_entropy)(const unsigned char *, unsigned long, prng_state *); | |

int (*ready) (prng_state *); | |

unsigned long (*read)(unsigned char *, unsigned long len, prng_state *); | |

void (*done)(prng_state *); | |

int (*export)(unsigned char *, unsigned long *, prng_state *); | |

int (*import)(const unsigned char *, unsigned long, prng_state *); | |

int (*test)(void); | |

}; | |

\end{verbatim} | |

There is a ``int find\_prng(char *name)'' function as well. Returns -1 if the PRNG is not found, otherwise it returns | |

the position in the prng\_descriptor array. | |

Just like the ciphers and hashes you must register your prng before you can use it. The two functions provided work | |

exactly as those for the cipher registry functions. They are: | |

\begin{verbatim} | |

int register_prng(const struct _prng_descriptor *prng); | |

int unregister_prng(const struct _prng_descriptor *prng); | |

\end{verbatim} | |

\subsection{PRNGs Provided} | |

\begin{figure}[here] | |

\begin{center} | |

\begin{small} | |

\begin{tabular}{|c|c|l|} | |

\hline \textbf{Name} & \textbf{Descriptor} & \textbf{Usage} \\ | |

\hline Yarrow & yarrow\_desc & Fast short-term PRNG \\ | |

\hline Fortuna & fortuna\_desc & Fast long-term PRNG (recommended) \\ | |

\hline RC4 & rc4\_desc & Stream Cipher \\ | |

\hline SOBER-128 & sober128\_desc & Stream Cipher (also very fast PRNG) \\ | |

\hline | |

\end{tabular} | |

\end{small} | |

\end{center} | |

\caption{List of Provided PRNGs} | |

\end{figure} | |

\subsubsection{Yarrow} | |

Yarrow is fast PRNG meant to collect an unspecified amount of entropy from sources | |

(keyboard, mouse, interrupts, etc) and produce an unbounded string of random bytes. | |

\textit{Note:} This PRNG is still secure for most taskings but is no longer recommended. Users | |

should use Fortuna instead. | |

\subsubsection{Fortuna} | |

Fortuna is a fast attack tolerant and more thoroughly designed PRNG suitable for long term | |

usage. It is faster than the default implementation of Yarrow\footnote{Yarrow has been implemented | |

to work with most cipher and hash combos based on which you have chosen to build into the library.} while | |

providing more security. | |

Fortuna is slightly less flexible than Yarrow in the sense that it only works with the AES block cipher | |

and SHA--256 hash function. Technically Fortuna will work with any block cipher that accepts a 256--bit | |

key and any hash that produces at least a 256--bit output. However, to make the implementation simpler | |

it has been fixed to those choices. | |

Fortuna is more secure than Yarrow in the sense that attackers who learn parts of the entropy being | |

added to the PRNG learn far less about the state than that of Yarrow. Without getting into to many | |

details Fortuna has the ability to recover from state determination attacks where the attacker starts | |

to learn information from the PRNGs output about the internal state. Yarrow on the other hand cannot | |

recover from that problem until new entropy is added to the pool and put to use through the ready() function. | |

\subsubsection{RC4} | |

RC4 is an old stream cipher that can also double duty as a PRNG in a pinch. You ``key'' it by | |

calling add\_entropy() and setup the key by calling ready(). You can only add upto 256 bytes via | |

add\_entropy(). | |

When you read from RC4 the output of the RC4 algorithm is XOR'd against your buffer you provide. In this | |

manner you can use rc4\_read() as an encrypt (and decrypt) function. | |

You really shouldn't use RC4 anymore. This isn't because RC4 is weak (though biases are known to exist) just | |

simply that faster alternatives exist. | |

\subsubsection{SOBER-128} | |

SOBER-128 is a stream cipher designed by the QUALCOMM Australia team. Like RC4 you ``key'' it by | |

calling add\_entropy(). There is no need to call ready() for this PRNG as it does not do anything. | |

Note that this cipher has several oddities about how it operates. The first time you call | |

add\_entropy() that sets the cipher's key. Every other time you call the same function it sets | |

the cipher's IV variable. The IV mechanism allows you to encrypt several messages with the same | |

key and not re--use the same key material. | |

Unlike Yarrow and Fortuna all of the entropy (and hence security) of this algorithm rests in the data | |

you pass it on the first call to add\_entropy(). All buffers sent to add\_entropy() must have a length | |

that is a multiple of four bytes. | |

Like RC4 the output of SOBER--128 is XOR'ed against the buffer you provide it. In this manner you can use | |

sober128\_read() as an encrypt (and decrypt) function. | |

Since SOBER-128 has a fixed keying scheme and is very fast (faster than RC4) the ideal usage of SOBER-128 is to | |

key it from the output of Fortuna (or Yarrow) and use it to encrypt messages. It is also ideal for | |

simulations which need a high quality (and fast) stream of bytes. | |

\subsubsection{Example Usage} | |

\begin{small} | |

\begin{verbatim} | |

#include <tomcrypt.h> | |

int main(void) | |

{ | |

prng_state prng; | |

unsigned char buf[32]; | |

int err; | |

if ((err = rc4_start(&prng)) != CRYPT_OK) { | |

printf("RC4 init error: %s\n", error_to_string(err)); | |

exit(-1); | |

} | |

/* use ``key'' as the key */ | |

if ((err = rc4_add_entropy("key", 3, &prng)) != CRYPT_OK) { | |

printf("RC4 add entropy error: %s\n", error_to_string(err)); | |

exit(-1); | |

} | |

/* setup RC4 for use */ | |

if ((err = rc4_ready(&prng)) != CRYPT_OK) { | |

printf("RC4 ready error: %s\n", error_to_string(err)); | |

exit(-1); | |

} | |

/* encrypt buffer */ | |

strcpy(buf,"hello world"); | |

if (rc4_read(buf, 11, &prng) != 11) { | |

printf("RC4 read error\n"); | |

exit(-1); | |

} | |

return 0; | |

} | |

\end{verbatim} | |

\end{small} | |

To decrypt you have to do the exact same steps. | |

\section{The Secure RNG} | |

\index{Secure RNG} | |

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 <tomcrypt.h> | |

int main(void) | |

{ | |

ecc_key mykey; | |

prng_state prng; | |

int err; | |

/* register yarrow */ | |

if (register_prng(&yarrow_desc) == -1) { | |

printf("Error registering Yarrow\n"); | |

return -1; | |

} | |

/* setup the PRNG */ | |

if ((err = rng_make_prng(128, find_prng("yarrow"), &prng, NULL)) != CRYPT_OK) { | |

printf("Error setting up PRNG, %s\n", error_to_string(err)); | |

return -1; | |

} | |

/* make a 192-bit ECC key */ | |

if ((err = ecc_make_key(&prng, find_prng("yarrow"), 24, &mykey)) != CRYPT_OK) { | |

printf("Error making key: %s\n", error_to_string(err)); | |

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 <tomcrypt.h> | |

int main(void) | |

{ | |

ecc_key mykey; | |

int err; | |

/* register SPRNG */ | |

if (register_prng(&sprng_desc) == -1) { | |

printf("Error registering SPRNG\n"); | |

return -1; | |

} | |

/* make a 192-bit ECC key */ | |

if ((err = ecc_make_key(NULL, find_prng("sprng"), 24, &mykey)) != CRYPT_OK) { | |

printf("Error making key: %s\n", error_to_string(err)); | |

return -1; | |

} | |

return 0; | |

} | |

\end{verbatim} | |

\end{small} | |

\chapter{RSA Public Key Cryptography} | |

\section{Introduction} | |

RSA wrote the PKCS \#1 specifications which detail RSA Public Key Cryptography. In the specifications are | |

padding algorithms for encryption and signatures. The standard includes the ``v2.1'' algorithms. | |

To simplify matters a little the v2.1 encryption and signature padding algorithms are called OAEP and PSS | |

respectively. | |

\section{PKCS \#1 Encryption} | |

PKCS \#1 RSA Encryption amounts to OAEP padding of the input message followed by the modular exponentiation. As far as this portion of | |

the library is concerned we are only dealing with th OAEP padding of the message. | |

\subsection{OAEP Encoding} | |

\index{pkcs\_1\_oaep\_encode()} | |

\begin{alltt} | |

int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, | |

const unsigned char *lparam, unsigned long lparamlen, | |

unsigned long modulus_bitlen, prng_state *prng, | |

int prng_idx, int hash_idx, | |

unsigned char *out, unsigned long *outlen); | |

\end{alltt} | |

This accepts ``msg'' as input of length ``msglen'' which will be OAEP padded. The ``lparam'' variable is an additional system specific | |

tag that can be applied to the encoding. This is useful to identify which system encoded the message. If no variance is desired then | |

``lparam'' can be set to \textbf{NULL}. | |

OAEP encoding requires the length of the modulus in bits in order to calculate the size of the output. This is passed as the parameter | |

``modulus\_bitlen''. ``hash\_idx'' is the index into the hash descriptor table of the hash desired. PKCS \#1 allows any hash to be | |

used but both the encoder and decoder must use the same hash in order for this to succeed. The size of hash output affects the maximum | |

sized input message. ``prng\_idx'' and ``prng'' are the random number generator arguments required to randomize the padding process. | |

The padded message is stored in ``out'' along with the length in ``outlen''. | |

If $h$ is the length of the hash and $m$ the length of the modulus (both in octets) then the maximum payload for ``msg'' is | |

$m - 2h - 2$. For example, with a $1024$--bit RSA key and SHA--1 as the hash the maximum payload is $86$ bytes. | |

Note that when the message is padded it still has not been RSA encrypted. You must pass the output of this function to | |

rsa\_exptmod() to encrypt it. | |

\subsection{OAEP Decoding} | |

\index{pkcs\_1\_oaep\_decode()} | |

\begin{alltt} | |

int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, | |

const unsigned char *lparam, unsigned long lparamlen, | |

unsigned long modulus_bitlen, int hash_idx, | |

unsigned char *out, unsigned long *outlen, | |

int *res); | |

\end{alltt} | |

This function decodes an OAEP encoded message and outputs the original message that was passed to the OAEP encoder. ``msg'' is the | |

output of pkcs\_1\_oaep\_encode() of length ``msglen''. ``lparam'' is the same system variable passed to the OAEP encoder. If it does not | |

match what was used during encoding this function will not decode the packet. ``modulus\_bitlen'' is the size of the RSA modulus in bits | |

and must match what was used during encoding. Similarly the ``hash\_idx'' index into the hash descriptor table must match what was used | |

during encoding. | |

If the function succeeds it decodes the OAEP encoded message into ``out'' of length ``outlen'' and stores a | |

$1$ in ``res''. If the packet is invalid it stores $0$ in ``res'' and if the function fails for another reason | |

it returns an error code. | |

\section{PKCS \#1 Digital Signatures} | |

\subsection{PSS Encoding} | |

PSS encoding is the second half of the PKCS \#1 standard which is padding to be applied to messages that are signed. | |

\index{pkcs\_1\_pss\_encode()} | |

\begin{alltt} | |

int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, | |

unsigned long saltlen, prng_state *prng, | |

int prng_idx, int hash_idx, | |

unsigned long modulus_bitlen, | |

unsigned char *out, unsigned long *outlen); | |

\end{alltt} | |

This function assumes the message to be PSS encoded has previously been hashed. The input hash ``msghash'' is of length | |

``msghashlen''. PSS allows a variable length random salt (it can be zero length) to be introduced in the signature process. | |

``hash\_idx'' is the index into the hash descriptor table of the hash to use. ``prng\_idx'' and ``prng'' are the random | |

number generator information required for the salt. | |

Similar to OAEP encoding ``modulus\_bitlen'' is the size of the RSA modulus (in bits). It limits the size of the salt. If $m$ is the length | |

of the modulus $h$ the length of the hash output (in octets) then there can be $m - h - 2$ bytes of salt. | |

This function does not actually sign the data it merely pads the hash of a message so that it can be processed by rsa\_exptmod(). | |

\subsection{PSS Decoding} | |

To decode a PSS encoded signature block you have to use the following. | |

\index{pkcs\_1\_pss\_decode()} | |

\begin{alltt} | |

int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, | |

const unsigned char *sig, unsigned long siglen, | |

unsigned long saltlen, int hash_idx, | |

unsigned long modulus_bitlen, int *res); | |

\end{alltt} | |

This will decode the PSS encoded message in ``sig'' of length ``siglen'' and compare it to values in ``msghash'' of length | |

``msghashlen''. If the block is a valid PSS block and the decoded hash equals the hash supplied ``res'' is set to non--zero. Otherwise, | |

it is set to zero. The rest of the parameters are as in the PSS encode call. | |

It's important to use the same ``saltlen'' and hash for both encoding and decoding as otherwise the procedure will not work. | |

\section{RSA Operations} | |

\subsection{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 \equiv 1\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. | |

\subsection{RSA Key Generation} | |

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 (\textit{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. | |

\index{PK\_PRIVATE} \index{PK\_PUBLIC} | |

There are two types of RSA keys. The types are {\bf PK\_PRIVATE} and {\bf PK\_PUBLIC}. The first type is a private | |

RSA key which includes the CRT parameters\footnote{As of v0.99 the PK\_PRIVATE\_OPTIMIZED type has been deprecated | |

and has been replaced by the PK\_PRIVATE type.} in the form of a RSAPrivateKey. The second type is a public RSA key | |

which only includes the modulus and public exponent. It takes the form of a RSAPublicKey. | |

\subsection{RSA Exponentiation} | |

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, prng_state *prng, int prng_idx, | |

rsa_key *key); | |

\end{verbatim} | |

This loads the bignum from ``in'' as a big endian word in the format PKCS specifies, 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). | |

Note that the output of his function is zero-padded as per PKCS \#1 specifications. This allows this routine to | |

interoprate with PKCS \#1 padding functions properly. | |

\subsection{RSA Key Encryption} | |

Normally RSA is used to encrypt short symmetric keys which are then used in block ciphers to encrypt a message. | |

To facilitate encrypting short keys the following functions have been provided. | |

\index{rsa\_encrypt\_key()} | |

\begin{verbatim} | |

int rsa_encrypt_key(const unsigned char *in, unsigned long inlen, | |

unsigned char *out, unsigned long *outlen, | |

const unsigned char *lparam, unsigned long lparamlen, | |

prng_state *prng, int prng_idx, int hash_idx, rsa_key *key); | |

\end{verbatim} | |

This function will OAEP pad ``in'' of length inlen bytes then RSA encrypt it and store the ciphertext | |

in ``out'' of length ``outlen''. The ``lparam'' and ``lparamlen'' are the same parameters you would pass | |

to pkcs\_1\_oaep\_encode(). | |

\index{rsa\_decrypt\_key()} | |

\begin{verbatim} | |

int rsa_decrypt_key(const unsigned char *in, unsigned long inlen, | |

unsigned char *out, unsigned long *outlen, | |

const unsigned char *lparam, unsigned long lparamlen, | |

int hash_idx, int *stat, | |

rsa_key *key); | |

\end{verbatim} | |

This function will RSA decrypt ``in'' of length ``inlen'' then OAEP depad the resulting data and store it in | |

``out'' of length ``outlen''. The ``lparam'' and ``lparamlen'' are the same parameters you would pass | |

to pkcs\_1\_oaep\_decode(). | |

If the RSA decrypted data isn't a valid OAEP packet then ``stat'' is set to $0$. Otherwise, it is set to $1$. | |

\subsection{RSA Hash Signatures} | |

Similar to RSA key encryption RSA is also used to ``digitally sign'' message digests (hashes). To facilitate this | |

process the following functions have been provided. | |

\index{rsa\_sign\_hash()} | |

\begin{verbatim} | |

int rsa_sign_hash(const unsigned char *in, unsigned long inlen, | |

unsigned char *out, unsigned long *outlen, | |

prng_state *prng, int prng_idx, | |

int hash_idx, unsigned long saltlen, | |

rsa_key *key); | |

\end{verbatim} | |

This will PSS encode the message hash ``in'' of length ``inlen''. Next the PSS encoded message will be RSA ``signed'' and | |

the output is stored in ``out'' of length ``outlen''. | |

\index{rsa\_verify\_hash()} | |

\begin{verbatim} | |

int rsa_verify_hash(const unsigned char *sig, unsigned long siglen, | |

const unsigned char *msghash, unsigned long msghashlen, | |

int hash_idx, unsigned long saltlen, | |

int *stat, rsa_key *key); | |

\end{verbatim} | |

This will RSA ``verify'' the signature in ``sig'' of length ``siglen''. Next the RSA decoded data is PSS decoded | |

and the extracted hash is compared against the message hash ``msghash'' of length ``msghashlen''. | |

If the RSA decoded data is not a valid PSS message or if the PSS decoded hash does not match the ``msghash'' | |

the value ``res'' is set to $0$. Otherwise, if the function succeeds and signature is valid ``res'' is set | |

to $1$. | |

\begin{verbatim} | |

#include <tomcrypt.h> | |

int main(void) | |

{ | |

int err, hash_idx, prng_idx, res; | |

unsigned long l1, l2; | |

unsigned char pt[16], pt2[16], out[1024]; | |

rsa_key key; | |

/* register prng/hash */ | |

if (register_prng(&sprng_desc) == -1) { | |

printf("Error registering sprng"); | |

return EXIT_FAILURE; | |

} | |

if (register_hash(&sha1_desc) == -1) { | |

printf("Error registering sha1"); | |

return EXIT_FAILURE; | |

} | |

hash_idx = find_hash("sha1"); | |

prng_idx = find_prng("sprng"); | |

/* make an RSA-1024 key */ | |

if ((err = rsa_make_key(NULL, /* PRNG state */ | |

prng_idx, /* PRNG idx */ | |

1024/8, /* 1024-bit key */ | |

65537, /* we like e=65537 */ | |

&key) /* where to store the key */ | |

) != CRYPT_OK) { | |

printf("rsa_make_key %s", error_to_string(err)); | |

return EXIT_FAILURE; | |

} | |

/* fill in pt[] with a key we want to send ... */ | |

l1 = sizeof(out); | |

if ((err = rsa_encrypt_key(pt, /* data we wish to encrypt */ | |

16, /* data is 16 bytes long */ | |

out, /* where to store ciphertext */ | |

&l1, /* length of ciphertext */ | |

"TestApp", /* our lparam for this program */ | |

7, /* lparam is 7 bytes long */ | |

NULL, /* PRNG state */ | |

prng_idx, /* prng idx */ | |

hash_idx, /* hash idx */ | |

&key) /* our RSA key */ | |

) != CRYPT_OK) { | |

printf("rsa_encrypt_key %s", error_to_string(err)); | |

return EXIT_FAILURE; | |

} | |

/* now let's decrypt the encrypted key */ | |

l2 = sizeof(pt2); | |

if ((err = rsa_decrypt_key(out, /* encrypted data */ | |

l1, /* length of ciphertext */ | |

pt2, /* where to put plaintext */ | |

&l2, /* plaintext length */ | |

"TestApp", /* lparam for this program */ | |

7, /* lparam is 7 bytes long */ | |

hash_idx, /* hash idx */ | |

&res, /* validity of data */ | |

&key) /* our RSA key */ | |

) != CRYPT_OK) { | |

printf("rsa_decrypt_key %s", error_to_string(err)); | |

return EXIT_FAILURE; | |

} | |

/* if all went well pt == pt2, l2 == 16, res == 1 */ | |

} | |

\end{verbatim} | |

\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} \over 2$. 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 96 to 512 bytes which correspond | |

to key sizes of 768 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 768 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. | |

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, unsigned long inlen, 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, err, inlen; | |

dh_key mykey, theirkey; | |

/* make up our private key */ | |

if ((err = dh_make_key(prng, wprng, 128, &mykey)) != CRYPT_OK) { | |

return err; | |

} | |

/* export our key as public */ | |

x = sizeof(buf); | |

if ((err = dh_export(buf, &x, PK_PUBLIC, &mykey)) != CRYPT_OK) { | |

res = err; | |

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 ((inlen = recv(sock, buf2, sizeof(buf2), 0)) <= 0) { | |

res = CRYPT_ERROR; | |

goto done2; | |

} | |

} else { | |

/* mode >0 so we send second */ | |

if ((inlen = recv(< |