annotate crypt.tex @ 15:6362d3854bb4 libtomcrypt-orig

0.96 release of LibTomCrypt
author Matt Johnston <matt@ucc.asn.au>
date Tue, 15 Jun 2004 14:07:21 +0000
parents 7faae8f46238
children 5d99163f7e32
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1 \documentclass[b5paper]{book}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2 \usepackage{hyperref}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3 \usepackage{makeidx}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
4 \usepackage{amssymb}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
5 \usepackage{color}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
6 \usepackage{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
7 \usepackage{graphicx}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
8 \usepackage{layout}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
9 \def\union{\cup}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
10 \def\intersect{\cap}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
11 \def\getsrandom{\stackrel{\rm R}{\gets}}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
12 \def\cross{\times}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
13 \def\cat{\hspace{0.5em} \| \hspace{0.5em}}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
14 \def\catn{$\|$}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
15 \def\divides{\hspace{0.3em} | \hspace{0.3em}}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
16 \def\nequiv{\not\equiv}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
17 \def\approx{\raisebox{0.2ex}{\mbox{\small $\sim$}}}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
18 \def\lcm{{\rm lcm}}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
19 \def\gcd{{\rm gcd}}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
20 \def\log{{\rm log}}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
21 \def\ord{{\rm ord}}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
22 \def\abs{{\mathit abs}}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
23 \def\rep{{\mathit rep}}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
24 \def\mod{{\mathit\ mod\ }}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
25 \renewcommand{\pmod}[1]{\ ({\rm mod\ }{#1})}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
26 \newcommand{\floor}[1]{\left\lfloor{#1}\right\rfloor}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
27 \newcommand{\ceil}[1]{\left\lceil{#1}\right\rceil}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
28 \def\Or{{\rm\ or\ }}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
29 \def\And{{\rm\ and\ }}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
30 \def\iff{\hspace{1em}\Longleftrightarrow\hspace{1em}}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
31 \def\implies{\Rightarrow}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
32 \def\undefined{{\rm ``undefined"}}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
33 \def\Proof{\vspace{1ex}\noindent {\bf Proof:}\hspace{1em}}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
34 \let\oldphi\phi
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
35 \def\phi{\varphi}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
36 \def\Pr{{\rm Pr}}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
37 \newcommand{\str}[1]{{\mathbf{#1}}}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
38 \def\F{{\mathbb F}}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
39 \def\N{{\mathbb N}}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
40 \def\Z{{\mathbb Z}}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
41 \def\R{{\mathbb R}}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
42 \def\C{{\mathbb C}}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
43 \def\Q{{\mathbb Q}}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
44
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
45 \def\twiddle{\raisebox{0.3ex}{\mbox{\tiny $\sim$}}}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
46
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
47 \def\gap{\vspace{0.5ex}}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
48 \makeindex
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
49 \begin{document}
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
50 \title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.96}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
51 \author{Tom St Denis \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
52 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
53 [email protected] \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
54 http://libtomcrypt.org \\ \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
55 Phone: 1-613-836-3160\\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
56 111 Banning Rd \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
57 Kanata, Ontario \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
58 K2L 1C3 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
59 Canada
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
60 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
61 \maketitle
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
62 This text and source code library are both hereby placed in the public domain. This book has been
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
63 formatted for B5 [176x250] paper using the \LaTeX{} {\em book} macro package.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
64
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
65 \vspace{10cm}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
66
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
67 \begin{flushright}Open Source. Open Academia. Open Minds.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
68
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
69 \mbox{ }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
70
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
71 Tom St Denis,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
72
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
73 Ontario, Canada
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
74 \end{flushright}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
75 \newpage
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
76 \tableofcontents
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
77 \chapter{Introduction}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
78 \section{What is the LibTomCrypt?}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
79 LibTomCrypt is a portable ANSI C cryptographic library that supports symmetric ciphers, one-way hashes,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
80 pseudo-random number generators, public key cryptography (via RSA,DH or ECC/DH) and a plethora of support
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
81 routines. It is designed to compile out of the box with the GNU C Compiler (GCC) version 2.95.3 (and higher)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
82 and with MSVC version 6 in win32.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
83
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
84 The library has been successfully tested on quite a few other platforms ranging from the ARM7TDMI in a
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
85 Gameboy Advanced to various PowerPC processors and even the MIPS processor in the PlayStation 2. Suffice it
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
86 to say the code is portable.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
87
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
88 The library is designed so new ciphers/hashes/PRNGs can be added at runtime and the existing API (and helper API functions) will
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
89 be able to use the new designs automatically. There exist self-check functions for each cipher and hash to ensure that
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
90 they compile and execute to the published design specifications. The library also performs extensive parameter error checking
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
91 and will give verbose error messages when possible.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
92
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
93 Essentially the library saves the time of having to implement the ciphers, hashes, prngs yourself. Typically implementing
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
94 useful cryptography is an error prone business which means anything that can save considerable time and effort is a good
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
95 thing.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
96
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
97 \subsection{What the library IS for?}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
98
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
99 The library typically serves as a basis for other protocols and message formats. For example, it should be possible to
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
100 take the RSA routines out of this library, apply the appropriate message padding and get PKCS compliant RSA routines.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
101 Similarly SSL protocols could be formed on top of the low-level symmetric cipher functions. The goal of this package is
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
102 to provide these low level core functions in a robust and easy to use fashion.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
103
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
104 The library also serves well as a toolkit for applications where they don't need to be OpenPGP, PKCS, etc. compliant.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
105 Included are fully operational public key routines for encryption, decryption, signature generation and verification.
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
106 These routines are fully portable but are not conformant to any known set of standards\footnote{With the exception of
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
107 the RSA code which is based on the PKCS \#1 standards.}. They are all based on established
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
108 number theory and cryptography.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
109
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
110 \subsection{What the library IS NOT for?}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
111
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
112 The library is not designed to be in anyway an implementation of the SSL or OpenPGP standards. The library
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
113 is not designed to be compliant with any known form of API or programming hierarchy. It is not a port of any other
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
114 library and it is not platform specific (like the MS CSP). So if you're looking to drop in some buzzword
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
115 compliant crypto library this is not for you. The library has been written from scratch to provide basic functions as
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
116 well as non-standard higher level functions.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
117
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
118 This is not to say that the library is a ``homebrew'' project. All of the symmetric ciphers and one-way hash functions
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
119 conform to published test vectors. The public key functions are derived from publicly available material and the majority
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
120 of the code has been reviewed by a growing community of developers.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
121
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
122 \subsubsection{Why not?}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
123 You may be asking why I didn't choose to go all out and support standards like P1363, PKCS and the whole lot. The reason
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
124 is quite simple too much money gets in the way. When I tried to access the P1363 draft documents and was denied (it
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
125 requires a password) I realized that they're just a business anyways. See what happens is a company will sit down and
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
126 invent a ``standard''. Then they try to sell it to as many people as they can. All of a sudden this ``standard'' is
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
127 everywhere. Then the standard is updated every so often to keep people dependent. Then you become RSA. If people are
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
128 supposed to support these standards they had better make them more accessible.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
129
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
130 \section{Why did I write it?}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
131 You may be wondering, ``Tom, why did you write a crypto library. I already have one.''. Well the reason falls into
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
132 two categories:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
133 \begin{enumerate}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
134 \item I am too lazy to figure out someone else's API. I'd rather invent my own simpler API and use that.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
135 \item It was (still is) good coding practice.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
136 \end{enumerate}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
137
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
138 The idea is that I am not striving to replace OpenSSL or Crypto++ or Cryptlib or etc. I'm trying to write my
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
139 {\bf own} crypto library and hopefully along the way others will appreciate the work.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
140
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
141 With this library all core functions (ciphers, hashes, prngs) have the {\bf exact} same prototype definition. They all load
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
142 and store data in a format independent of the platform. This means if you encrypt with Blowfish on a PPC it should decrypt
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
143 on an x86 with zero problems. The consistent API also means that if you learn how to use blowfish with my library you
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
144 know how to use Safer+ or RC6 or Serpent or ... as well. With all of the core functions there are central descriptor tables
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
145 that can be used to make a program automatically pick between ciphers, hashes and PRNGs at runtime. That means your
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
146 application can support all ciphers/hashes/prngs without changing the source code.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
147
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
148 \subsection{Modular}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
149 The LibTomCrypt package has also been written to be very modular. The block ciphers, one-way hashes and
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
150 pseudo-random number generators (PRNG) are all used within the API through ``descriptor'' tables which
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
151 are essentially structures with pointers to functions. While you can still call particular functions
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
152 directly (\textit{e.g. sha256\_process()}) this descriptor interface allows the developer to customize their
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
153 usage of the library.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
154
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
155 For example, consider a hardware platform with a specialized RNG device. Obviously one would like to tap
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
156 that for the PRNG needs within the library (\textit{e.g. making a RSA key}). All the developer has todo
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
157 is write a descriptor and the few support routines required for the device. After that the rest of the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
158 API can make use of it without change. Similiarly imagine a few years down the road when AES2 (\textit{or whatever they call it}) is
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
159 invented. It can be added to the library and used within applications with zero modifications to the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
160 end applications provided they are written properly.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
161
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
162 This flexibility within the library means it can be used with any combination of primitive algorithms and
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
163 unlike libraries like OpenSSL is not tied to direct routines. For instance, in OpenSSL there are CBC block
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
164 mode routines for every single cipher. That means every time you add or remove a cipher from the library
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
165 you have to update the associated support code as well. In LibTomCrypt the associated code (\textit{chaining modes in this case})
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
166 are not directly tied to the ciphers. That is a new cipher can be added to the library by simply providing
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
167 the key setup, ECB decrypt and encrypt and test vector routines. After that all five chaining mode routines
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
168 can make use of the cipher right away.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
169
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
170
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
171 \section{License}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
172
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
173 All of the source code except for the following files have been written by the author or donated to the project
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
174 under a public domain license:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
175
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
176 \begin{enumerate}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
177 \item rc2.c
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
178 \item safer.c
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
179 \end{enumerate}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
180
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
181 `mpi.c'' was originally written by Michael Fromberger ([email protected]) but has since been replaced with my LibTomMath
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
182 library.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
183
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
184 ``rc2.c'' is based on publicly available code that is not attributed to a person from the given source. ``safer.c''
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
185 was written by Richard De Moliner ([email protected]) and is public domain.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
186
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
187 The project is hereby released as public domain.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
188
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
189 \section{Patent Disclosure}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
190
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
191 The author (Tom St Denis) is not a patent lawyer so this section is not to be treated as legal advice. To the best
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
192 of the authors knowledge the only patent related issues within the library are the RC5 and RC6 symmetric block ciphers.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
193 They can be removed from a build by simply commenting out the two appropriate lines in the makefile script. The rest
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
194 of the ciphers and hashes are patent free or under patents that have since expired.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
195
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
196 The RC2 and RC4 symmetric ciphers are not under patents but are under trademark regulations. This means you can use
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
197 the ciphers you just can't advertise that you are doing so.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
198
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
199 \section{Building the library}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
200
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
201 To build the library on a GCC equipped platform simply type ``make'' at your command prompt. It will build the library
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
202 file ``libtomcrypt.a''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
203
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
204 To install the library copy all of the ``.h'' files into your ``\#include'' path and the single libtomcrypt.a file into
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
205 your library path.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
206
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
207 With MSVC you can build the library with ``nmake -f makefile.msvc''. This will produce a ``tomcrypt.lib'' file which
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
208 is the core library. Copy the header files into your MSVC include path and the library in the lib path (typically
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
209 under where VC98 is installed).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
210
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
211 \section{Building against the library}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
212
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
213 In the recent versions the build steps have changed. The build options are now stored in ``mycrypt\_custom.h'' and
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
214 no longer in the makefile. If you change a build option in that file you must re-build the library from clean to
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
215 ensure the build is intact. The perl script ``config.pl'' will help setup the custom header and a custom makefile
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
216 if you want one (the provided ``makefile'' will work with custom configs).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
217
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
218 \section{Thanks}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
219 I would like to give thanks to the following people (in no particular order) for helping me develop this project:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
220 \begin{enumerate}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
221 \item Richard van de Laarschot
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
222 \item Richard Heathfield
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
223 \item Ajay K. Agrawal
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
224 \item Brian Gladman
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
225 \item Svante Seleborg
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
226 \item Clay Culver
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
227 \item Jason Klapste
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
228 \item Dobes Vandermeer
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
229 \item Daniel Richards
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
230 \item Wayne Scott
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
231 \item Andrew Tyler
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
232 \item Sky Schulz
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
233 \item Christopher Imes
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
234 \end{enumerate}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
235
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
236 \chapter{The Application Programming Interface (API)}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
237 \section{Introduction}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
238 \index{CRYPT\_ERROR} \index{CRYPT\_OK}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
239
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
240 In general the API is very simple to memorize and use. Most of the functions return either {\bf void} or {\bf int}. Functions
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
241 that return {\bf int} will return {\bf CRYPT\_OK} if the function was successful or one of the many error codes
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
242 if it failed. Certain functions that return int will return $-1$ to indicate an error. These functions will be explicitly
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
243 commented upon. When a function does return a CRYPT error code it can be translated into a string with
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
244
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
245 \index{error\_to\_string()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
246 \begin{verbatim}
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
247 const char *error_to_string(int err);
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
248 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
249
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
250 An example of handling an error is:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
251 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
252 void somefunc(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
253 {
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
254 int err;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
255
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
256 /* call a cryptographic function */
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
257 if ((err = some_crypto_function(...)) != CRYPT_OK) {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
258 printf("A crypto error occured, %s\n", error_to_string(err));
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
259 /* perform error handling */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
260 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
261 /* continue on if no error occured */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
262 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
263 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
264
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
265 There is no initialization routine for the library and for the most part the code is thread safe. The only thread
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
266 related issue is if you use the same symmetric cipher, hash or public key state data in multiple threads. Normally
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
267 that is not an issue.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
268
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
269 To include the prototypes for ``LibTomCrypt.a'' into your own program simply include ``mycrypt.h'' like so:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
270 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
271 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
272 int main(void) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
273 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
274 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
275 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
276
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
277 The header file ``mycrypt.h'' also includes ``stdio.h'', ``string.h'', ``stdlib.h'', ``time.h'', ``ctype.h'' and ``mpi.h''
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
278 (the bignum library routines).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
279
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
280 \section{Macros}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
281
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
282 There are a few helper macros to make the coding process a bit easier. The first set are related to loading and storing
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
283 32/64-bit words in little/big endian format. The macros are:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
284
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
285 \index{STORE32L} \index{STORE64L} \index{LOAD32L} \index{LOAD64L}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
286 \index{STORE32H} \index{STORE64H} \index{LOAD32H} \index{LOAD64H} \index{BSWAP}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
287 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
288 \begin{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
289 \begin{tabular}{|c|c|c|}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
290 \hline STORE32L(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $x \to y[0 \ldots 3]$ \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
291 \hline STORE64L(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $x \to y[0 \ldots 7]$ \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
292 \hline LOAD32L(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $y[0 \ldots 3] \to x$ \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
293 \hline LOAD64L(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $y[0 \ldots 7] \to x$ \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
294 \hline STORE32H(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $x \to y[3 \ldots 0]$ \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
295 \hline STORE64H(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $x \to y[7 \ldots 0]$ \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
296 \hline LOAD32H(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $y[3 \ldots 0] \to x$ \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
297 \hline LOAD64H(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $y[7 \ldots 0] \to x$ \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
298 \hline BSWAP(x) & {\bf unsigned long} x & Swaps the byte order of x. \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
299 \hline
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
300 \end{tabular}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
301 \end{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
302 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
303
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
304 There are 32-bit cyclic rotations as well:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
305 \index{ROL} \index{ROR}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
306 \begin{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
307 \begin{tabular}{|c|c|c|}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
308 \hline ROL(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x << y$ \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
309 \hline ROR(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x >> y$ \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
310 \hline
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
311 \end{tabular}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
312 \end{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
313
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
314 \section{Functions with Variable Length Output}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
315 Certain functions such as (for example) ``rsa\_export()'' give an output that is variable length. To prevent buffer overflows you
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
316 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
317 the output will be stored. For example:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
318 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
319 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
320 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
321 int main(void) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
322 rsa_key key;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
323 unsigned char buffer[1024];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
324 unsigned long x;
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
325 int err;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
326
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
327 /* ... Make up the RSA key somehow */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
328
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
329 /* lets export the key, set x to the size of the output buffer */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
330 x = sizeof(buffer);
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
331 if ((err = rsa_export(buffer, &x, PK_PUBLIC, &key)) != CRYPT_OK) {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
332 printf("Export error: %s\n", error_to_string(err));
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
333 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
334 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
335
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
336 /* if rsa_export() was successful then x will have the size of the output */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
337 printf("RSA exported key takes %d bytes\n", x);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
338
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
339 /* ... do something with the buffer */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
340
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
341 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
342 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
343 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
344 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
345 In the above example if the size of the RSA public key was more than 1024 bytes this function would not store anything in
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
346 either ``buffer'' or ``x'' and simply return an error code. If the function suceeds it stores the length of the output
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
347 back into ``x'' so that the calling application will know how many bytes used.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
348
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
349 \section{Functions that need a PRNG}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
350 Certain functions such as ``rsa\_make\_key()'' require a PRNG. These functions do not setup the PRNG themselves so it is
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
351 the responsibility of the calling function to initialize the PRNG before calling them.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
352
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
353 \section{Functions that use Arrays of Octets}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
354 Most functions require inputs that are arrays of the data type ``unsigned char''. Whether it is a symmetric key, IV
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
355 for a chaining mode or public key packet it is assumed that regardless of the actual size of ``unsigned char'' only the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
356 lower eight bits contain data. For example, if you want to pass a 256 bit key to a symmetric ciphers setup routine
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
357 you must pass it in (a pointer to) an array of 32 ``unsigned char'' variables. Certain routines
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
358 (such as SAFER+) take special care to work properly on platforms where an ``unsigned char'' is not eight bits.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
359
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
360 For the purposes of this library the term ``byte'' will refer to an octet or eight bit word. Typically an array of
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
361 type ``byte'' will be synonymous with an array of type ``unsigned char''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
362
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
363 \chapter{Symmetric Block Ciphers}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
364 \section{Core Functions}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
365
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
366 Libtomcrypt provides several block ciphers all in a plain vanilla ECB block mode. Its important to first note that you
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
367 should never use the ECB modes directly to encrypt data. Instead you should use the ECB functions to make a chaining mode
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
368 or use one of the provided chaining modes. All of the ciphers are written as ECB interfaces since it allows the rest of
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
369 the API to grow in a modular fashion.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
370
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
371 All ciphers store their scheduled keys in a single data type called ``symmetric\_key''. This allows all ciphers to
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
372 have the same prototype and store their keys as naturally as possible. All ciphers provide five visible functions which
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
373 are (given that XXX is the name of the cipher):
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
374 \index{Cipher Setup}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
375 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
376 int XXX_setup(const unsigned char *key, int keylen, int rounds,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
377 symmetric_key *skey);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
378 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
379
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
380 The XXX\_setup() routine will setup the cipher to be used with a given number of rounds and a given key length (in bytes).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
381 The number of rounds can be set to zero to use the default, which is generally a good idea.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
382
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
383 If the function returns successfully the variable ``skey'' will have a scheduled key stored in it. Its important to note
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
384 that you should only used this scheduled key with the intended cipher. For example, if you call
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
385 ``blowfish\_setup()'' do not pass the scheduled key onto ``rc5\_ecb\_encrypt()''. All setup functions do not allocate
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
386 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).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
387
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
388 To encrypt or decrypt a block in ECB mode there are these two functions:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
389 \index{Cipher Encrypt} \index{Cipher Decrypt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
390 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
391 void XXX_ecb_encrypt(const unsigned char *pt, unsigned char *ct,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
392 symmetric_key *skey);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
393
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
394 void XXX_ecb_decrypt(const unsigned char *ct, unsigned char *pt,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
395 symmetric_key *skey);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
396 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
397 These two functions will encrypt or decrypt (respectively) a single block of text\footnote{The size of which depends on
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
398 which cipher you are using.} and store the result where you want it. It is possible that the input and output buffer are
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
399 the same buffer. For the encrypt function ``pt''\footnote{pt stands for plaintext.} is the input and ``ct'' is the output.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
400 For the decryption function its the opposite. To test a particular cipher against test vectors\footnote{As published in their design papers.} call: \index{Cipher Testing}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
401 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
402 int XXX_test(void);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
403 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
404 This function will return {\bf CRYPT\_OK} if the cipher matches the test vectors from the design publication it is
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
405 based upon. Finally for each cipher there is a function which will help find a desired key size:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
406 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
407 int XXX_keysize(int *keysize);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
408 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
409 Essentially it will round the input keysize in ``keysize'' down to the next appropriate key size. This function
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
410 return {\bf CRYPT\_OK} if the key size specified is acceptable. For example:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
411 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
412 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
413 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
414 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
415 {
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
416 int keysize, err;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
417
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
418 /* now given a 20 byte key what keysize does Twofish want to use? */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
419 keysize = 20;
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
420 if ((err = twofish_keysize(&keysize)) != CRYPT_OK) {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
421 printf("Error getting key size: %s\n", error_to_string(err));
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
422 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
423 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
424 printf("Twofish suggested a key size of %d\n", keysize);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
425 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
426 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
427 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
428 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
429 This should indicate a keysize of sixteen bytes is suggested. An example snippet that encodes a block with
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
430 Blowfish in ECB mode is below.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
431
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
432 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
433 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
434 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
435 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
436 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
437 unsigned char pt[8], ct[8], key[8];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
438 symmetric_key skey;
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
439 int err;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
440
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
441 /* ... key is loaded appropriately in ``key'' ... */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
442 /* ... load a block of plaintext in ``pt'' ... */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
443
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
444 /* schedule the key */
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
445 if ((err = blowfish_setup(key, /* the key we will use */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
446 8, /* key is 8 bytes (64-bits) long */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
447 0, /* 0 == use default # of rounds */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
448 &skey) /* where to put the scheduled key */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
449 ) != CRYPT_OK) {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
450 printf("Setup error: %s\n", error_to_string(err));
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
451 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
452 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
453
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
454 /* encrypt the block */
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
455 blowfish_ecb_encrypt(pt, /* encrypt this 8-byte array */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
456 ct, /* store encrypted data here */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
457 &skey); /* our previously scheduled key */
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
458
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
459 /* decrypt the block */
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
460 blowfish_ecb_decrypt(ct, /* decrypt this 8-byte array */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
461 pt, /* store decrypted data here */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
462 &skey); /* our previously scheduled key */
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
463
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
464 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
465 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
466 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
467 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
468
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
469 \section{Key Sizes and Number of Rounds}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
470 \index{Symmetric Keys}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
471 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
472 keys (mainly for test vectors anyways). Ideally your application should be making at least 256 bit keys. This is not
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
473 because you're supposed to be paranoid. Its because if your PRNG has a bias of any sort the more bits the better. For
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
474 example, if you have $\mbox{Pr}\left[X = 1\right] = {1 \over 2} \pm \gamma$ where $\vert \gamma \vert > 0$ then the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
475 total amount of entropy in N bits is $N \cdot -log_2\left ({1 \over 2} + \vert \gamma \vert \right)$. So if $\gamma$
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
476 were $0.25$ (a severe bias) a 256-bit string would have about 106 bits of entropy whereas a 128-bit string would have
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
477 only 53 bits of entropy.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
478
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
479 The number of rounds of most ciphers is not an option you can change. Only RC5 allows you to change the number of
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
480 rounds. By passing zero as the number of rounds all ciphers will use their default number of rounds. Generally the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
481 ciphers are configured such that the default number of rounds provide adequate security for the given block size.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
482
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
483 \section{The Cipher Descriptors}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
484 \index{Cipher Descriptor}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
485 To facilitate automatic routines an array of cipher descriptors is provided in the array ``cipher\_descriptor''. An element
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
486 of this array has the following format:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
487
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
488 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
489 struct _cipher_descriptor {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
490 char *name;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
491 unsigned long min_key_length, max_key_length,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
492 block_length, default_rounds;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
493 int (*setup) (const unsigned char *key, int keylength,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
494 int num_rounds, symmetric_key *skey);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
495 void (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
496 symmetric_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
497 void (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
498 symmetric_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
499 int (*test) (void);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
500 int (*keysize) (int *desired_keysize);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
501 };
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
502 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
503
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
504 Where ``name'' is the lower case ASCII version of the name. The fields ``min\_key\_length'', ``max\_key\_length'' and
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
505 ``block\_length'' are all the number of bytes not bits. As a good rule of thumb it is assumed that the cipher supports
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
506 the min and max key lengths but not always everything in between. The ``default\_rounds'' field is the default number
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
507 of rounds that will be used.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
508
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
509 The remaining fields are all pointers to the core functions for each cipher. The end of the cipher\_descriptor array is
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
510 marked when ``name'' equals {\bf NULL}.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
511
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
512 As of this release the current cipher\_descriptors elements are
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
513
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
514 \index{Cipher descriptor table}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
515 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
516 \begin{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
517 \begin{tabular}{|c|c|c|c|c|c|}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
518 \hline Name & Descriptor Name & Block Size & Key Range & Rounds \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
519 \hline Blowfish & blowfish\_desc & 8 & 8 $\ldots$ 56 & 16 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
520 \hline X-Tea & xtea\_desc & 8 & 16 & 32 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
521 \hline RC2 & rc2\_desc & 8 & 8 $\ldots$ 128 & 16 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
522 \hline RC5-32/12/b & rc5\_desc & 8 & 8 $\ldots$ 128 & 12 $\ldots$ 24 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
523 \hline RC6-32/20/b & rc6\_desc & 16 & 8 $\ldots$ 128 & 20 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
524 \hline SAFER+ & saferp\_desc &16 & 16, 24, 32 & 8, 12, 16 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
525 \hline Safer K64 & safer\_k64\_desc & 8 & 8 & 6 $\ldots$ 13 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
526 \hline Safer SK64 & safer\_sk64\_desc & 8 & 8 & 6 $\ldots$ 13 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
527 \hline Safer K128 & safer\_k128\_desc & 8 & 16 & 6 $\ldots$ 13 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
528 \hline Safer SK128 & safer\_sk128\_desc & 8 & 16 & 6 $\ldots$ 13 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
529 \hline AES & aes\_desc & 16 & 16, 24, 32 & 10, 12, 14 \\
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
530 & aes\_enc\_desc & 16 & 16, 24, 32 & 10, 12, 14 \\
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
531 \hline Twofish & twofish\_desc & 16 & 16, 24, 32 & 16 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
532 \hline DES & des\_desc & 8 & 7 & 16 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
533 \hline 3DES (EDE mode) & des3\_desc & 8 & 21 & 16 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
534 \hline CAST5 (CAST-128) & cast5\_desc & 8 & 5 $\ldots$ 16 & 12, 16 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
535 \hline Noekeon & noekeon\_desc & 16 & 16 & 16 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
536 \hline Skipjack & skipjack\_desc & 8 & 10 & 32 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
537 \hline
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
538 \end{tabular}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
539 \end{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
540 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
541
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
542 \subsection{Notes}
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
543 \begin{small}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
544 \begin{enumerate}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
545 \item
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
546 For AES (also known as Rijndael) there are four descriptors which complicate issues a little. The descriptors
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
547 rijndael\_desc and rijndael\_enc\_desc provide the cipher named ``rijndael''. The descriptors aes\_desc and
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
548 aes\_enc\_desc provide the cipher name ``aes''. Functionally both ``rijndael'' and ``aes'' are the same cipher. The
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
549 only difference is when you call find\_cipher() you have to pass the correct name. The cipher descriptors with ``enc''
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
550 in the middle (e.g. rijndael\_enc\_desc) are related to an implementation of Rijndael with only the encryption routine
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
551 and tables. The decryption and self--test function pointers of both ``encrypt only'' descriptors are set to \textbf{NULL} and
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
552 should not be called.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
553
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
554 The ``encrypt only'' descriptors are useful for applications that only use the encryption function of the cipher. Algorithms such
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
555 as EAX, PMAC and OMAC only require the encryption function. So far this ``encrypt only'' functionality has only been implemented for
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
556 Rijndael as it makes the most sense for this cipher.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
557
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
558 \item
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
559 For the 64-bit SAFER famliy of ciphers (e.g K64, SK64, K128, SK128) the ecb\_encrypt() and ecb\_decrypt()
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
560 functions are the same. So if you want to use those functions directly just call safer\_ecb\_encrypt()
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
561 or safer\_ecb\_decrypt() respectively.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
562
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
563 \item
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
564 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
565 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
566 byte string from the real 7/21 byte key.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
567
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
568 \item
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
569 Note that ``Twofish'' has additional configuration options that take place at build time. These options are found in
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
570 the file ``mycrypt\_cfg.h''. The first option is ``TWOFISH\_SMALL'' which when defined will force the Twofish code
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
571 to not pre-compute the Twofish ``$g(X)$'' function as a set of four $8 \times 32$ s-boxes. This means that a scheduled
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
572 key will require less ram but the resulting cipher will be slower. The second option is ``TWOFISH\_TABLES'' which when
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
573 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
574 by the polynomials 5B and EF used in the MDS multiplication. As a result the code is faster and slightly larger. The
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
575 speed increase is useful when ``TWOFISH\_SMALL'' is defined since the s-boxes and MDS multiply form the heart of the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
576 Twofish round function.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
577
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
578 \index{Twofish build options}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
579 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
580 \begin{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
581 \begin{tabular}{|l|l|l|}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
582 \hline TWOFISH\_SMALL & TWOFISH\_TABLES & Speed and Memory (per key) \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
583 \hline undefined & undefined & Very fast, 4.2KB of ram. \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
584 \hline undefined & defined & As above, faster keysetup, larger code (1KB more). \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
585 \hline defined & undefined & Very slow, 0.2KB of ram. \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
586 \hline defined & defined & Somewhat faster, 0.2KB of ram, larger code. \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
587 \hline
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
588 \end{tabular}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
589 \end{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
590 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
591
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
592 \end{enumerate}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
593 \end{small}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
594
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
595 To work with the cipher\_descriptor array there is a function:
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
596 \index{find\_cipher()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
597 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
598 int find_cipher(char *name)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
599 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
600 Which will search for a given name in the array. It returns negative one if the cipher is not found, otherwise it returns
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
601 the location in the array where the cipher was found. For example, to indirectly setup Blowfish you can also use:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
602 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
603 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
604 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
605 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
606 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
607 unsigned char key[8];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
608 symmetric_key skey;
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
609 int err;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
610
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
611 /* you must register a cipher before you use it */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
612 if (register_cipher(&blowfish_desc)) == -1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
613 printf("Unable to register Blowfish cipher.");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
614 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
615 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
616
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
617 /* generic call to function (assuming the key in key[] was already setup) */
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
618 if ((err = cipher_descriptor[find_cipher("blowfish")].setup(key, 8, 0, &skey)) != CRYPT_OK) {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
619 printf("Error setting up Blowfish: %s\n", error_to_string(err));
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
620 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
621 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
622
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
623 /* ... use cipher ... */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
624 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
625 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
626 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
627
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
628 A good safety would be to check the return value of ``find\_cipher()'' before accessing the desired function. In order
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
629 to use a cipher with the descriptor table you must register it first using:
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
630 \index{register\_cipher()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
631 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
632 int register_cipher(const struct _cipher_descriptor *cipher);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
633 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
634 Which accepts a pointer to a descriptor and returns the index into the global descriptor table. If an error occurs such
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
635 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
636 than once it will just return the index of the first copy. To remove a cipher call:
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
637 \index{unregister\_cipher()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
638 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
639 int unregister_cipher(const struct _cipher_descriptor *cipher);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
640 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
641 Which returns {\bf CRYPT\_OK} if it removes it otherwise it returns {\bf CRYPT\_ERROR}. Consider:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
642 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
643 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
644 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
645 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
646 {
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
647 int err;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
648
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
649 /* register the cipher */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
650 if (register_cipher(&rijndael_desc) == -1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
651 printf("Error registering Rijndael\n");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
652 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
653 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
654
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
655 /* use Rijndael */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
656
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
657 /* remove it */
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
658 if ((err = unregister_cipher(&rijndael_desc)) != CRYPT_OK) {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
659 printf("Error removing Rijndael: %s\n", error_to_string(err));
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
660 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
661 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
662
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
663 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
664 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
665 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
666 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
667 This snippet is a small program that registers only Rijndael only.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
668
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
669 \section{Symmetric Modes of Operations}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
670 \subsection{Background}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
671 A typical symmetric block cipher can be used in chaining modes to effectively encrypt messages larger than the block
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
672 size of the cipher. Given a key $k$, a plaintext $P$ and a cipher $E$ we shall denote the encryption of the block
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
673 $P$ under the key $k$ as $E_k(P)$. In some modes there exists an initial vector denoted as $C_{-1}$.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
674
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
675 \subsubsection{ECB Mode}
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
676 \index{ECB mode}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
677 ECB or Electronic Codebook Mode is the simplest method to use. It is given as:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
678 \begin{equation}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
679 C_i = E_k(P_i)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
680 \end{equation}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
681 This mode is very weak since it allows people to swap blocks and perform replay attacks if the same key is used more
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
682 than once.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
683
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
684 \subsubsection{CBC Mode}
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
685 \index{CBC mode}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
686 CBC or Cipher Block Chaining mode is a simple mode designed to prevent trivial forms of replay and swap attacks on ciphers.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
687 It is given as:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
688 \begin{equation}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
689 C_i = E_k(P_i \oplus C_{i - 1})
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
690 \end{equation}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
691 It is important that the initial vector be unique and preferably random for each message encrypted under the same key.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
692
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
693 \subsubsection{CTR Mode}
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
694 \index{CTR mode}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
695 CTR or Counter Mode is a mode which only uses the encryption function of the cipher. Given a initial vector which is
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
696 treated as a large binary counter the CTR mode is given as:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
697 \begin{eqnarray}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
698 C_{-1} = C_{-1} + 1\mbox{ }(\mbox{mod }2^W) \nonumber \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
699 C_i = P_i \oplus E_k(C_{-1})
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
700 \end{eqnarray}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
701 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
702 encrypted under the same key replay and swap attacks are infeasible. CTR mode may look simple but it is as secure
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
703 as the block cipher is under a chosen plaintext attack (provided the initial vector is unique).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
704
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
705 \subsubsection{CFB Mode}
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
706 \index{CFB mode}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
707 CFB or Ciphertext Feedback Mode is a mode akin to CBC. It is given as:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
708 \begin{eqnarray}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
709 C_i = P_i \oplus C_{-1} \nonumber \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
710 C_{-1} = E_k(C_i)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
711 \end{eqnarray}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
712 Note that in this library the output feedback width is equal to the size of the block cipher. That is this mode is used
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
713 to encrypt whole blocks at a time. However, the library will buffer data allowing the user to encrypt or decrypt partial
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
714 blocks without a delay. When this mode is first setup it will initially encrypt the initial vector as required.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
715
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
716 \subsubsection{OFB Mode}
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
717 \index{OFB mode}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
718 OFB or Output Feedback Mode is a mode akin to CBC as well. It is given as:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
719 \begin{eqnarray}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
720 C_{-1} = E_k(C_{-1}) \nonumber \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
721 C_i = P_i \oplus C_{-1}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
722 \end{eqnarray}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
723 Like the CFB mode the output width in CFB mode is the same as the width of the block cipher. OFB mode will also
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
724 buffer the output which will allow you to encrypt or decrypt partial blocks without delay.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
725
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
726 \subsection{Choice of Mode}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
727 My personal preference is for the CTR mode since it has several key benefits:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
728 \begin{enumerate}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
729 \item No short cycles which is possible in the OFB and CFB modes.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
730 \item Provably as secure as the block cipher being used under a chosen plaintext attack.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
731 \item Technically does not require the decryption routine of the cipher.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
732 \item Allows random access to the plaintext.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
733 \item Allows the encryption of block sizes that are not equal to the size of the block cipher.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
734 \end{enumerate}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
735 The CTR, CFB and OFB routines provided allow you to encrypt block sizes that differ from the ciphers block size. They
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
736 accomplish this by buffering the data required to complete a block. This allows you to encrypt or decrypt any size
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
737 block of memory with either of the three modes.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
738
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
739 The ECB and CBC modes process blocks of the same size as the cipher at a time. Therefore they are less flexible than the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
740 other modes.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
741
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
742 \subsection{Implementation}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
743 \index{CBC Mode} \index{CTR Mode}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
744 \index{OFB Mode} \index{CFB Mode}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
745 The library provides simple support routines for handling CBC, CTR, CFB, OFB and ECB encoded messages. Assuming the mode
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
746 you want is XXX there is a structure called ``symmetric\_XXX'' that will contain the information required to
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
747 use that mode. They have identical setup routines (except ECB mode for obvious reasons):
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
748 \index{ecb\_start()} \index{cfb\_start()} \index{cbc\_start()} \index{ofb\_start()} \index{ctr\_start()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
749 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
750 int XXX_start(int cipher, const unsigned char *IV,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
751 const unsigned char *key, int keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
752 int num_rounds, symmetric_XXX *XXX);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
753
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
754 int ecb_start(int cipher, const unsigned char *key, int keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
755 int num_rounds, symmetric_ECB *ecb);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
756 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
757
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
758 In each case ``cipher'' is the index into the cipher\_descriptor array of the cipher you want to use. The ``IV'' value is
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
759 the initialization vector to be used with the cipher. You must fill the IV yourself and it is assumed they are the same
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
760 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.}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
761 of the cipher you choose. It is important that the IV be random for each unique message you want to encrypt. The
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
762 parameters ``key'', ``keylen'' and ``num\_rounds'' are the same as in the XXX\_setup() function call. The final parameter
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
763 is a pointer to the structure you want to hold the information for the mode of operation.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
764
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
765 Both routines return {\bf CRYPT\_OK} if the cipher initialized correctly, otherwise they return an error code. To
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
766 actually encrypt or decrypt the following routines are provided:
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
767 \index{ecb\_encrypt()} \index{ecb\_decrypt()} \index{cfb\_encrypt()} \index{cfb\_decrypt()}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
768 \index{cbc\_encrypt()} \index{cbc\_decrypt()} \index{ofb\_encrypt()} \index{ofb\_decrypt()} \index{ctr\_encrypt()} \index{ctr\_decrypt()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
769 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
770 int XXX_encrypt(const unsigned char *pt, unsigned char *ct,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
771 symmetric_XXX *XXX);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
772 int XXX_decrypt(const unsigned char *ct, unsigned char *pt,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
773 symmetric_XXX *XXX);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
774
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
775 int YYY_encrypt(const unsigned char *pt, unsigned char *ct,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
776 unsigned long len, symmetric_YYY *YYY);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
777 int YYY_decrypt(const unsigned char *ct, unsigned char *pt,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
778 unsigned long len, symmetric_YYY *YYY);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
779 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
780 Where ``XXX'' is one of (ecb, cbc) and ``YYY'' is one of (ctr, ofb, cfb). In the CTR, OFB and CFB cases ``len'' is the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
781 size of the buffer (as number of chars) to encrypt or decrypt. The CTR, OFB and CFB modes are order sensitive but not
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
782 chunk sensitive. That is you can encrypt ``ABCDEF'' in three calls like ``AB'', ``CD'', ``EF'' or two like ``ABCDE'' and ``F''
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
783 and end up with the same ciphertext. However, encrypting ``ABC'' and ``DABC'' will result in different ciphertexts. All
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
784 five of the modes will return {\bf CRYPT\_OK} on success from the encrypt or decrypt functions.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
785
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
786 To decrypt in either mode you simply perform the setup like before (recall you have to fetch the IV value you used)
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
787 and use the decrypt routine on all of the blocks.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
788
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
789 To change or read the IV of a previously initialized chaining mode use the following two functions.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
790
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
791 \index{cbc\_setiv()} \index{cbc\_getiv()} \index{ofb\_setiv()} \index{ofb\_getiv()} \index{cfb\_setiv()} \index{cfb\_getiv()}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
792 \index{ctr\_setiv()} \index{ctr\_getiv()}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
793 \begin{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
794 int XXX_getiv(unsigned char *IV, unsigned long *len, symmetric_XXX *XXX);
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
795 int XXX_setiv(const unsigned char *IV, unsigned long len, symmetric_XXX *XXX);
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
796 \end{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
797
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
798 The XXX\_getiv function will read the IV out of the chaining mode and store it into ``IV'' along with the length of the IV
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
799 stored in ``len''. The XXX\_setiv will initialize the chaining mode state as if the original IV were the new IV specified. The length
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
800 of the IV passed in must be the size of the ciphers block size.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
801
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
802 The XXX\_setiv functions are handy if you wish to change the IV without re--keying the cipher.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
803
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
804 \newpage
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
805 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
806 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
807 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
808 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
809 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
810 unsigned char key[16], IV[16], buffer[512];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
811 symmetric_CTR ctr;
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
812 int x, err;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
813
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
814 /* register twofish first */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
815 if (register_cipher(&twofish_desc) == -1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
816 printf("Error registering cipher.\n");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
817 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
818 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
819
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
820 /* somehow fill out key and IV */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
821
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
822 /* start up CTR mode */
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
823 if ((err = ctr_start(find_cipher("twofish"), /* index of desired cipher */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
824 IV, /* the initial vector */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
825 key, /* the secret key */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
826 16, /* length of secret key (16 bytes, 128 bits) */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
827 0, /* 0 == default # of rounds */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
828 &ctr) /* where to store initialized CTR state */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
829 ) != CRYPT_OK) {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
830 printf("ctr_start error: %s\n", error_to_string(err));
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
831 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
832 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
833
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
834 /* somehow fill buffer than encrypt it */
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
835 if ((err = ctr_encrypt( buffer, /* plaintext */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
836 buffer, /* ciphertext */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
837 sizeof(buffer), /* length of data to encrypt */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
838 &ctr) /* previously initialized CTR state */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
839 ) != CRYPT_OK) {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
840 printf("ctr_encrypt error: %s\n", error_to_string(err));
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
841 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
842 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
843
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
844 /* make use of ciphertext... */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
845
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
846 /* now we want to decrypt so let's use ctr_setiv */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
847 if ((err = ctr_setiv( IV, /* the initial IV we gave to ctr_start */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
848 16, /* the IV is 16 bytes long */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
849 &ctr) /* the ctr state we wish to modify */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
850 ) != CRYPT_OK) {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
851 printf("ctr_setiv error: %s\n", error_to_string(err));
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
852 return -1;
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
853 }
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
854
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
855 if ((err = ctr_decrypt( buffer, /* ciphertext */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
856 buffer, /* plaintext */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
857 sizeof(buffer), /* length of data to encrypt */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
858 &ctr) /* previously initialized CTR state */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
859 ) != CRYPT_OK) {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
860 printf("ctr_decrypt error: %s\n", error_to_string(err));
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
861 return -1;
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
862 }
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
863
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
864 /* clear up and return */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
865 zeromem(key, sizeof(key));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
866 zeromem(&ctr, sizeof(ctr));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
867
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
868 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
869 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
870 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
871 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
872
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
873 \section{Encrypt and Authenticate Modes}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
874
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
875 \subsection{EAX Mode}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
876 LibTomCrypt provides support for a mode called EAX\footnote{See
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
877 M. Bellare, P. Rogaway, D. Wagner, A Conventional Authenticated-Encryption Mode.} in a manner similar to the
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
878 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.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
879 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.}.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
880 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
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
881 secret symmetric key.
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
882
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
883 The ``header'' data is meant to be meta-data associated with a stream that isn't private (e.g. protocol messages). It can
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
884 be added at anytime during an EAX stream and is part of the authentication tag. That is, changes in the meta-data can
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
885 be detected by changes in the output tag.
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
886
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
887 The mode can then process plaintext producing ciphertext as well as compute a partial checksum. The actual checksum
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
888 called a ``tag'' is only emitted when the message is finished. In the interim though the user can process any arbitrary
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
889 sized message block to send to the recipient as ciphertext. This makes the EAX mode especially suited for streaming modes
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
890 of operation.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
891
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
892 The mode is initialized with the following function.
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
893 \index{eax\_init()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
894 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
895 int eax_init(eax_state *eax, int cipher,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
896 const unsigned char *key, unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
897 const unsigned char *nonce, unsigned long noncelen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
898 const unsigned char *header, unsigned long headerlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
899 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
900
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
901 Where ``eax'' is the EAX state. ``cipher'' is the index of the desired cipher in the descriptor table.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
902 ``key'' is the shared secret symmetric key of length ``keylen''. ``nonce'' is the random public string of
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
903 length ``noncelen''. ``header'' is the random (or fixed or \textbf{NULL}) header for the message of length
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
904 ``headerlen''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
905
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
906 When this function completes ``eax'' will be initialized such that you can now either have data decrypted or
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
907 encrypted in EAX mode. Note that if ``headerlen'' is zero you may pass ``header'' as \textbf{NULL} to indicate
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
908 there is no initial header data.
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
909
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
910 To encrypt or decrypt data in a streaming mode use the following.
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
911 \index{eax\_encrypt()} \index{eax\_decrypt()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
912 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
913 int eax_encrypt(eax_state *eax, const unsigned char *pt,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
914 unsigned char *ct, unsigned long length);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
915
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
916 int eax_decrypt(eax_state *eax, const unsigned char *ct,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
917 unsigned char *pt, unsigned long length);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
918 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
919 The function ``eax\_encrypt'' will encrypt the bytes in ``pt'' of ``length'' bytes and store the ciphertext in
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
920 ``ct''. Note that ``ct'' and ``pt'' may be the same region in memory. This function will also send the ciphertext
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
921 through the OMAC function. The function ``eax\_decrypt'' decrypts ``ct'' and stores it in ``pt''. This also allows
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
922 ``pt'' and ``ct'' to be the same region in memory.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
923
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
924 You cannot both encrypt or decrypt with the same ``eax'' context. For bi-directional communication you
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
925 will need to initialize two EAX contexts (preferably with different headers and nonces).
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
926
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
927 Note that both of these functions allow you to send the data in any granularity but the order is important. While
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
928 the eax\_init() function allows you to add initial header data to the stream you can also add header data during the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
929 EAX stream with the following.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
930
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
931 \index{eax\_addheader()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
932 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
933 int eax_addheader(eax_state *eax,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
934 const unsigned char *header, unsigned long length);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
935 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
936
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
937 This will add the ``length'' bytes from ``header'' to the given ``eax'' stream. Once the message is finished the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
938 ``tag'' (checksum) may be computed with the following function.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
939
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
940 \index{eax\_done()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
941 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
942 int eax_done(eax_state *eax,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
943 unsigned char *tag, unsigned long *taglen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
944 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
945 This will terminate the EAX state ``eax'' and store upto ``taglen'' bytes of the message tag in ``tag''. The function
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
946 then stores how many bytes of the tag were written out back into ``taglen''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
947
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
948 The EAX mode code can be tested to ensure it matches the test vectors by calling the following function.
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
949 \index{eax\_test()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
950 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
951 int eax_test(void);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
952 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
953 This requires that the AES (or Rijndael) block cipher be registered with the cipher\_descriptor table first.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
954
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
955 \begin{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
956 #include <mycrypt.h>
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
957 int main(void)
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
958 {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
959 int err;
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
960 eax_state eax;
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
961 unsigned char pt[64], ct[64], nonce[16], key[16], tag[16];
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
962 unsigned long taglen;
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
963
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
964 if (register_cipher(&rijndael_desc) == -1) {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
965 printf("Error registering Rijndael");
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
966 return EXIT_FAILURE;
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
967 }
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
968
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
969 /* ... make up random nonce and key ... */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
970
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
971 /* initialize context */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
972 if ((err = eax_init( &eax, /* the context */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
973 find_cipher("rijndael"), /* cipher we want to use */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
974 nonce, /* our state nonce */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
975 16, /* none is 16 bytes */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
976 "TestApp", /* example header, identifies this program */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
977 7) /* length of the header */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
978 ) != CRYPT_OK) {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
979 printf("Error eax_init: %s", error_to_string(err));
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
980 return EXIT_FAILURE;
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
981 }
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
982
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
983 /* now encrypt data, say in a loop or whatever */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
984 if ((err = eax_encrypt( &eax, /* eax context */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
985 pt, /* plaintext (source) */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
986 ct, /* ciphertext (destination) */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
987 sizeof(pt) /* size of plaintext */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
988 ) != CRYPT_OK) {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
989 printf("Error eax_encrypt: %s", error_to_string(err));
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
990 return EXIT_FAILURE;
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
991 }
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
992
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
993 /* finish message and get authentication tag */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
994 taglen = sizeof(tag);
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
995 if ((err = eax_done( &eax, /* eax context */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
996 tag, /* where to put tag */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
997 &taglen /* length of tag space */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
998 ) != CRYPT_OK) {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
999 printf("Error eax_done: %s", error_to_string(err));
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1000 return EXIT_FAILURE;
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1001 }
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1002
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1003 /* now we have the authentication tag in "tag" and it's taglen bytes long */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1004
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1005 }
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1006 \end{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1007
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1008 You can also perform an entire EAX state on a block of memory in a single function call with the
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1009 following functions.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1010
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1011
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1012 \index{eax\_encrypt\_authenticate\_memory} \index{eax\_decrypt\_verify\_memory}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1013 \begin{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1014 int eax_encrypt_authenticate_memory(int cipher,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1015 const unsigned char *key, unsigned long keylen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1016 const unsigned char *nonce, unsigned long noncelen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1017 const unsigned char *header, unsigned long headerlen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1018 const unsigned char *pt, unsigned long ptlen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1019 unsigned char *ct,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1020 unsigned char *tag, unsigned long *taglen);
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1021
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1022 int eax_decrypt_verify_memory(int cipher,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1023 const unsigned char *key, unsigned long keylen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1024 const unsigned char *nonce, unsigned long noncelen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1025 const unsigned char *header, unsigned long headerlen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1026 const unsigned char *ct, unsigned long ctlen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1027 unsigned char *pt,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1028 unsigned char *tag, unsigned long taglen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1029 int *res);
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1030 \end{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1031
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1032 Both essentially just call eax\_init() followed by eax\_encrypt() (or eax\_decrypt() respectively) and eax\_done(). The parameters
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1033 have the same meaning as with those respective functions.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1034
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1035 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
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1036 the tag it computed while decrypting the message. If the tags match then it stores a $1$ in ``res'', otherwise it stores a $0$.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1037
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1038 \subsection{OCB Mode}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1039 LibTomCrypt provides support for a mode called OCB\footnote{See
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1040 P. Rogaway, M. Bellare, J. Black, T. Krovetz, ``OCB: A Block Cipher Mode of Operation for Efficient Authenticated Encryption''.}
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1041 . OCB is an encryption protocol that simultaneously provides authentication. It is slightly faster to use than EAX mode
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1042 but is less flexible. Let's review how to initialize an OCB context.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1043
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1044 \index{ocb\_init()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1045 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1046 int ocb_init(ocb_state *ocb, int cipher,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1047 const unsigned char *key, unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1048 const unsigned char *nonce);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1049 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1050
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1051 This will initialize the ``ocb'' context using cipher descriptor ``cipher''. It will use a ``key'' of length ``keylen''
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1052 and the random ``nonce''. Note that ``nonce'' must be a random (public) string the same length as the block ciphers
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1053 block size (e.g. 16 bytes for AES).
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1054
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1055 This mode has no ``Associated Data'' like EAX mode does which means you cannot authenticate metadata along with the stream.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1056 To encrypt or decrypt data use the following.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1057
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1058 \index{ocb\_encrypt()} \index{ocb\_decrypt()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1059 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1060 int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1061 int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1062 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1063
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1064 This will encrypt (or decrypt for the latter) a fixed length of data from ``pt'' to ``ct'' (vice versa for the latter).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1065 They assume that ``pt'' and ``ct'' are the same size as the block cipher's block size. Note that you cannot call
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1066 both functions given a single ``ocb'' state. For bi-directional communication you will have to initialize two ``ocb''
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1067 states (with different nonces). Also ``pt'' and ``ct'' may point to the same location in memory.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1068
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1069 When you are finished encrypting the message you call the following function to compute the tag.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1070
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1071 \index{ocb\_done\_encrypt()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1072 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1073 int ocb_done_encrypt(ocb_state *ocb,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1074 const unsigned char *pt, unsigned long ptlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1075 unsigned char *ct,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1076 unsigned char *tag, unsigned long *taglen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1077 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1078
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1079 This will terminate an encrypt stream ``ocb''. If you have trailing bytes of plaintext that will not complete a block
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1080 you can pass them here. This will also encrypt the ``ptlen'' bytes in ``pt'' and store them in ``ct''. It will also
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1081 store upto ``taglen'' bytes of the tag into ``tag''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1082
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1083 Note that ``ptlen'' must be less than or equal to the block size of block cipher chosen. Also note that if you have
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1084 an input message equal to the length of the block size then you pass the data here (not to ocb\_encrypt()) only.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1085
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1086 To terminate a decrypt stream and compared the tag you call the following.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1087
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1088 \index{ocb\_done\_decrypt()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1089 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1090 int ocb_done_decrypt(ocb_state *ocb,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1091 const unsigned char *ct, unsigned long ctlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1092 unsigned char *pt,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1093 const unsigned char *tag, unsigned long taglen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1094 int *res);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1095 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1096
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1097 Similarly to the previous function you can pass trailing message bytes into this function. This will compute the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1098 tag of the message (internally) and then compare it against the ``taglen'' bytes of ``tag'' provided. By default
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1099 ``res'' is set to zero. If all ``taglen'' bytes of ``tag'' can be verified then ``res'' is set to one (authenticated
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1100 message).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1101
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1102 To make life simpler the following two functions are provided for memory bound OCB.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1103
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1104 \index{ocb\_encrypt\_authenticate\_memory()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1105 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1106 int ocb_encrypt_authenticate_memory(int cipher,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1107 const unsigned char *key, unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1108 const unsigned char *nonce,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1109 const unsigned char *pt, unsigned long ptlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1110 unsigned char *ct,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1111 unsigned char *tag, unsigned long *taglen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1112 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1113
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1114 This will OCB encrypt the message ``pt'' of length ``ptlen'' and store the ciphertext in ``ct''. The length ``ptlen''
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1115 can be any arbitrary length.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1116
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1117 \index{ocb\_decrypt\_verify\_memory()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1118 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1119 int ocb_decrypt_verify_memory(int cipher,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1120 const unsigned char *key, unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1121 const unsigned char *nonce,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1122 const unsigned char *ct, unsigned long ctlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1123 unsigned char *pt,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1124 const unsigned char *tag, unsigned long taglen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1125 int *res);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1126 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1127
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1128 Similarly this will OCB decrypt and compare the internally computed tag against the tag provided. ``res'' is set
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1129 appropriately.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1130
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1131 \chapter{One-Way Cryptographic Hash Functions}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1132 \section{Core Functions}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1133
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1134 Like the ciphers there are hash core functions and a universal data type to hold the hash state called ``hash\_state''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1135 To initialize hash XXX (where XXX is the name) call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1136 \index{Hash Functions}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1137 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1138 void XXX_init(hash_state *md);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1139 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1140
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1141 This simply sets up the hash to the default state governed by the specifications of the hash. To add data to the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1142 message being hashed call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1143 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1144 int XXX_process(hash_state *md, const unsigned char *in, unsigned long len);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1145 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1146
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1147 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1148 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1149 (hash output) will be the same. For example, this means that:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1150 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1151 md5_process(&md, "hello ", 6);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1152 md5_process(&md, "world", 5);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1153 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1154 Will produce the same message digest as the single call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1155 \index{Message Digest}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1156 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1157 md5_process(&md, "hello world", 11);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1158 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1159
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1160 To finally get the message digest (the hash) call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1161 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1162 int XXX_done(hash_state *md,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1163 unsigned char *out);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1164 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1165
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1166 This function will finish up the hash and store the result in the ``out'' array. You must ensure that ``out'' is long
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1167 enough for the hash in question. Often hashes are used to get keys for symmetric ciphers so the ``XXX\_done()'' functions
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1168 will wipe the ``md'' variable before returning automatically.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1169
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1170 To test a hash function call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1171 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1172 int XXX_test(void);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1173 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1174
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1175 This will return {\bf CRYPTO\_OK} if the hash matches the test vectors, otherwise it returns an error code. An
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1176 example snippet that hashes a message with md5 is given below.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1177 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1178 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1179 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1180 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1181 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1182 hash_state md;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1183 unsigned char *in = "hello world", out[16];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1184
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1185 /* setup the hash */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1186 md5_init(&md);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1187
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1188 /* add the message */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1189 md5_process(&md, in, strlen(in));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1190
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1191 /* get the hash in out[0..15] */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1192 md5_done(&md, out);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1193
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1194 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1195 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1196 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1197 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1198
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1199 \section{Hash Descriptors}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1200 Like the set of ciphers the set of hashes have descriptors too. They are stored in an array called ``hash\_descriptor'' and
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1201 are defined by:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1202 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1203 struct _hash_descriptor {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1204 char *name;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1205 unsigned long hashsize; /* digest output size in bytes */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1206 unsigned long blocksize; /* the block size the hash uses */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1207 void (*init) (hash_state *);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1208 int (*process)(hash_state *, const unsigned char *, unsigned long);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1209 int (*done) (hash_state *, unsigned char *);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1210 int (*test) (void);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1211 };
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1212 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1213
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1214 Similarly ``name'' is the name of the hash function in ASCII (all lowercase). ``hashsize'' is the size of the digest output
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1215 in bytes. The remaining fields are pointers to the functions that do the respective tasks. There is a function to
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1216 search the array as well called ``int find\_hash(char *name)''. It returns -1 if the hash is not found, otherwise the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1217 position in the descriptor table of the hash.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1218
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1219 You can use the table to indirectly call a hash function that is chosen at runtime. For example:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1220 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1221 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1222 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1223 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1224 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1225 unsigned char buffer[100], hash[MAXBLOCKSIZE];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1226 int idx, x;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1227 hash_state md;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1228
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1229 /* register hashes .... */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1230 if (register_hash(&md5_desc) == -1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1231 printf("Error registering MD5.\n");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1232 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1233 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1234
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1235 /* register other hashes ... */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1236
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1237 /* prompt for name and strip newline */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1238 printf("Enter hash name: \n");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1239 fgets(buffer, sizeof(buffer), stdin);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1240 buffer[strlen(buffer) - 1] = 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1241
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1242 /* get hash index */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1243 idx = find_hash(buffer);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1244 if (idx == -1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1245 printf("Invalid hash name!\n");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1246 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1247 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1248
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1249 /* hash input until blank line */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1250 hash_descriptor[idx].init(&md);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1251 while (fgets(buffer, sizeof(buffer), stdin) != NULL)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1252 hash_descriptor[idx].process(&md, buffer, strlen(buffer));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1253 hash_descriptor[idx].done(&md, hash);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1254
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1255 /* dump to screen */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1256 for (x = 0; x < hash_descriptor[idx].hashsize; x++)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1257 printf("%02x ", hash[x]);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1258 printf("\n");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1259 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1260 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1261 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1262 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1263
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1264 Note the usage of ``MAXBLOCKSIZE''. In Libtomcrypt no symmetric block, key or hash digest is larger than MAXBLOCKSIZE in
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1265 length. This provides a simple size you can set your automatic arrays to that will not get overrun.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1266
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1267 There are three helper functions as well:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1268 \index{hash\_memory()} \index{hash\_file()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1269 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1270 int hash_memory(int hash, const unsigned char *data,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1271 unsigned long len, unsigned char *dst,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1272 unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1273
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1274 int hash_file(int hash, const char *fname,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1275 unsigned char *dst,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1276 unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1277
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1278 int hash_filehandle(int hash, FILE *in,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1279 unsigned char *dst, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1280 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1281
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1282 The ``hash'' parameter is the location in the descriptor table of the hash (\textit{e.g. the return of find\_hash()}).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1283 The ``*outlen'' variable is used to keep track of the output size. You
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1284 must set it to the size of your output buffer before calling the functions. When they complete succesfully they store
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1285 the length of the message digest back in it. The functions are otherwise straightforward. The ``hash\_filehandle''
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1286 function assumes that ``in'' is an file handle opened in binary mode. It will hash to the end of file and not reset
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1287 the file position when finished.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1288
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1289 To perform the above hash with md5 the following code could be used:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1290 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1291 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1292 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1293 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1294 {
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1295 int idx, err;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1296 unsigned long len;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1297 unsigned char out[MAXBLOCKSIZE];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1298
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1299 /* register the hash */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1300 if (register_hash(&md5_desc) == -1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1301 printf("Error registering MD5.\n");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1302 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1303 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1304
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1305 /* get the index of the hash */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1306 idx = find_hash("md5");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1307
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1308 /* call the hash */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1309 len = sizeof(out);
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1310 if ((err = hash_memory(idx, "hello world", 11, out, &len)) != CRYPT_OK) {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1311 printf("Error hashing data: %s\n", error_to_string(err));
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1312 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1313 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1314 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1315 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1316 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1317 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1318
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1319 The following hashes are provided as of this release:
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1320 \index{Hash descriptor table}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1321 \begin{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1322 \begin{tabular}{|c|c|c|}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1323 \hline Name & Descriptor Name & Size of Message Digest (bytes) \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1324 \hline WHIRLPOOL & whirlpool\_desc & 64 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1325 \hline SHA-512 & sha512\_desc & 64 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1326 \hline SHA-384 & sha384\_desc & 48 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1327 \hline SHA-256 & sha256\_desc & 32 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1328 \hline SHA-224 & sha224\_desc & 28 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1329 \hline TIGER-192 & tiger\_desc & 24 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1330 \hline SHA-1 & sha1\_desc & 20 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1331 \hline RIPEMD-160 & rmd160\_desc & 20 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1332 \hline RIPEMD-128 & rmd128\_desc & 16 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1333 \hline MD5 & md5\_desc & 16 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1334 \hline MD4 & md4\_desc & 16 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1335 \hline MD2 & md2\_desc & 16 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1336 \hline
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1337 \end{tabular}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1338 \end{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1339
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1340 Similar to the cipher descriptor table you must register your hash algorithms before you can use them. These functions
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1341 work exactly like those of the cipher registration code. The functions are:
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1342 \index{register\_hash()} \index{unregister\_hash()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1343 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1344 int register_hash(const struct _hash_descriptor *hash);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1345 int unregister_hash(const struct _hash_descriptor *hash);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1346 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1347
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1348 \subsection{Notice}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1349 It is highly recommended that you \textbf{not} use the MD4 or MD5 hashes for the purposes of digital signatures or authentication codes.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1350 These hashes are provided for completeness and they still can be used for the purposes of password hashing or one-way accumulators
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1351 (e.g. Yarrow).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1352
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1353 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1354 for all purposes you would normally use a hash for.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1355
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1356 \chapter{Message Authentication Codes}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1357 \section{HMAC Protocol}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1358 Thanks to Dobes Vandermeer the library now includes support for hash based message authenication codes or HMAC for short. An HMAC
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1359 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1360 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1361 eavesdropper will not be able to verify the authenticity of a message.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1362
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1363 The HMAC support works much like the normal hash functions except that the initialization routine requires you to pass a key
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1364 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1365 chars. The initialization routine is:
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1366 \index{hmac\_init()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1367 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1368 int hmac_init(hmac_state *hmac, int hash,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1369 const unsigned char *key, unsigned long keylen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1370 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1371 The ``hmac'' parameter is the state for the HMAC code. ``hash'' is the index into the descriptor table of the hash you want
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1372 to use to authenticate the message. ``key'' is the pointer to the array of chars that make up the key. ``keylen'' is the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1373 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:
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1374 \index{hmac\_process()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1375 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1376 int hmac_process(hmac_state *hmac, const unsigned char *buf,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1377 unsigned long len);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1378 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1379 ``hmac'' is the HMAC state you are working with. ``buf'' is the array of octets to send into the HMAC process. ``len'' is the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1380 number of octets to process. Like the hash process routines you can send the data in arbitrarly sized chunks. When you
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1381 are finished with the HMAC process you must call the following function to get the HMAC code:
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1382 \index{hmac\_done()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1383 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1384 int hmac_done(hmac_state *hmac, unsigned char *hashOut,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1385 unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1386 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1387 ``hmac'' is the HMAC state you are working with. ``hashOut'' is the array of octets where the HMAC code should be stored. You must
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1388 set ``outlen'' to the size of the destination buffer before calling this function. It is updated with the length of the HMAC code
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1389 produced (depending on which hash was picked). If ``outlen'' is less than the size of the message digest (and ultimately
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1390 the HMAC code) then the HMAC code is truncated as per FIPS-198 specifications (e.g. take the first ``outlen'' bytes).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1391
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1392 There are two utility functions provided to make using HMACs easier todo. They accept the key and information about the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1393 message (file pointer, address in memory) and produce the HMAC result in one shot. These are useful if you want to avoid
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1394 calling the three step process yourself.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1395
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1396 \index{hmac\_memory()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1397 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1398 int hmac_memory(int hash, const unsigned char *key, unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1399 const unsigned char *data, unsigned long len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1400 unsigned char *dst, unsigned long *dstlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1401 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1402 This will produce an HMAC code for the array of octets in ``data'' of length ``len''. The index into the hash descriptor
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1403 table must be provided in ``hash''. It uses the key from ``key'' with a key length of ``keylen''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1404 The result is stored in the array of octets ``dst'' and the length in ``dstlen''. The value of ``dstlen'' must be set
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1405 to the size of the destination buffer before calling this function. Similarly for files there is the following function:
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1406 \index{hmac\_file()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1407 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1408 int hmac_file(int hash, const char *fname, const unsigned char *key,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1409 unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1410 unsigned char *dst, unsigned long *dstlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1411 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1412 ``hash'' is the index into the hash descriptor table of the hash you want to use. ``fname'' is the filename to process.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1413 ``key'' is the array of octets to use as the key of length ``keylen''. ``dst'' is the array of octets where the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1414 result should be stored.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1415
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1416 To test if the HMAC code is working there is the following function:
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1417 \index{hmac\_test()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1418 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1419 int hmac_test(void);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1420 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1421 Which returns {\bf CRYPT\_OK} if the code passes otherwise it returns an error code. Some example code for using the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1422 HMAC system is given below.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1423
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1424 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1425 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1426 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1427 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1428 {
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1429 int idx, err;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1430 hmac_state hmac;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1431 unsigned char key[16], dst[MAXBLOCKSIZE];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1432 unsigned long dstlen;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1433
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1434 /* register SHA-1 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1435 if (register_hash(&sha1_desc) == -1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1436 printf("Error registering SHA1\n");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1437 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1438 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1439
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1440 /* get index of SHA1 in hash descriptor table */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1441 idx = find_hash("sha1");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1442
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1443 /* we would make up our symmetric key in "key[]" here */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1444
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1445 /* start the HMAC */
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1446 if ((err = hmac_init(&hmac, idx, key, 16)) != CRYPT_OK) {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1447 printf("Error setting up hmac: %s\n", error_to_string(err));
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1448 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1449 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1450
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1451 /* process a few octets */
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1452 if((err = hmac_process(&hmac, "hello", 5) != CRYPT_OK) {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1453 printf("Error processing hmac: %s\n", error_to_string(err));
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1454 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1455 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1456
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1457 /* get result (presumably to use it somehow...) */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1458 dstlen = sizeof(dst);
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1459 if ((err = hmac_done(&hmac, dst, &dstlen)) != CRYPT_OK) {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1460 printf("Error finishing hmac: %s\n", error_to_string(err));
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1461 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1462 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1463 printf("The hmac is %lu bytes long\n", dstlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1464
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1465 /* return */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1466 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1467 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1468 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1469 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1470
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1471 \section{OMAC Support}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1472 OMAC\footnote{\url{http://crypt.cis.ibaraki.ac.jp/omac/omac.html}}, which stands for \textit{One-Key CBC MAC} is an
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1473 algorithm which produces a Message Authentication Code (MAC) using only a block cipher such as AES. From an API
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1474 standpoint the OMAC routines work much like the HMAC routines do. Instead in this case a cipher is used instead of a hash.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1475
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1476 To start an OMAC state you call
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1477 \index{omac\_init()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1478 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1479 int omac_init(omac_state *omac, int cipher,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1480 const unsigned char *key, unsigned long keylen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1481 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1482 The ``omac'' variable is the state for the OMAC algorithm. ``cipher'' is the index into the cipher\_descriptor table
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1483 of the cipher\footnote{The cipher must have a 64 or 128 bit block size. Such as CAST5, Blowfish, DES, AES, Twofish, etc.} you
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1484 wish to use. ``key'' and ``keylen'' are the keys used to authenticate the data.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1485
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1486 To send data through the algorithm call
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1487 \index{omac\_process()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1488 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1489 int omac_process(omac_state *state,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1490 const unsigned char *buf, unsigned long len);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1491 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1492 This will send ``len'' bytes from ``buf'' through the active OMAC state ``state''. Returns \textbf{CRYPT\_OK} if the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1493 function succeeds. The function is not sensitive to the granularity of the data. For example,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1494
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1495 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1496 omac_process(&mystate, "hello", 5);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1497 omac_process(&mystate, " world", 6);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1498 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1499
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1500 Would produce the same result as,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1501
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1502 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1503 omac_process(&mystate, "hello world", 11);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1504 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1505
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1506 When you are done processing the message you can call the following to compute the message tag.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1507
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1508 \index{omac\_done()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1509 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1510 int omac_done(omac_state *state,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1511 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1512 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1513 Which will terminate the OMAC and output the \textit{tag} (MAC) to ``out''. Note that unlike the HMAC and other code
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1514 ``outlen'' can be smaller than the default MAC size (for instance AES would make a 16-byte tag). Part of the OMAC
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1515 specification states that the output may be truncated. So if you pass in $outlen = 5$ and use AES as your cipher than
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1516 the output MAC code will only be five bytes long. If ``outlen'' is larger than the default size it is set to the default
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1517 size to show how many bytes were actually used.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1518
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1519 Similar to the HMAC code the file and memory functions are also provided. To OMAC a buffer of memory in one shot use the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1520 following function.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1521
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1522 \index{omac\_memory()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1523 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1524 int omac_memory(int cipher,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1525 const unsigned char *key, unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1526 const unsigned char *msg, unsigned long msglen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1527 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1528 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1529 This will compute the OMAC of ``msglen'' bytes of ``msg'' using the key ``key'' of length ``keylen'' bytes and the cipher
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1530 specified by the ``cipher'''th entry in the cipher\_descriptor table. It will store the MAC in ``out'' with the same
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1531 rules as omac\_done.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1532
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1533 To OMAC a file use
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1534 \index{omac\_file()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1535 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1536 int omac_file(int cipher,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1537 const unsigned char *key, unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1538 const char *filename,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1539 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1540 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1541
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1542 Which will OMAC the entire contents of the file specified by ``filename'' using the key ``key'' of length ``keylen'' bytes
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1543 and the cipher specified by the ``cipher'''th entry in the cipher\_descriptor table. It will store the MAC in ``out'' with
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1544 the same rules as omac\_done.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1545
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1546 To test if the OMAC code is working there is the following function:
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1547 \index{omac\_test()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1548 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1549 int omac_test(void);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1550 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1551 Which returns {\bf CRYPT\_OK} if the code passes otherwise it returns an error code. Some example code for using the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1552 OMAC system is given below.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1553
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1554 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1555 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1556 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1557 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1558 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1559 int idx, err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1560 omac_state omac;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1561 unsigned char key[16], dst[MAXBLOCKSIZE];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1562 unsigned long dstlen;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1563
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1564 /* register Rijndael */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1565 if (register_cipher(&rijndael_desc) == -1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1566 printf("Error registering Rijndael\n");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1567 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1568 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1569
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1570 /* get index of Rijndael in cipher descriptor table */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1571 idx = find_cipher("rijndael");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1572
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1573 /* we would make up our symmetric key in "key[]" here */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1574
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1575 /* start the OMAC */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1576 if ((err = omac_init(&omac, idx, key, 16)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1577 printf("Error setting up omac: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1578 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1579 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1580
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1581 /* process a few octets */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1582 if((err = omac_process(&omac, "hello", 5) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1583 printf("Error processing omac: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1584 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1585 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1586
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1587 /* get result (presumably to use it somehow...) */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1588 dstlen = sizeof(dst);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1589 if ((err = omac_done(&omac, dst, &dstlen)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1590 printf("Error finishing omac: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1591 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1592 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1593 printf("The omac is %lu bytes long\n", dstlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1594
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1595 /* return */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1596 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1597 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1598 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1599 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1600
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1601 \section{PMAC Support}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1602 The PMAC\footnote{J.Black, P.Rogaway, ``A Block--Cipher Mode of Operation for Parallelizable Message Authentication''}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1603 protocol is another MAC algorithm that relies solely on a symmetric-key block cipher. It uses essentially the same
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1604 API as the provided OMAC code.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1605
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1606 A PMAC state is initialized with the following.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1607
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1608 \index{pmac\_init()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1609 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1610 int pmac_init(pmac_state *pmac, int cipher,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1611 const unsigned char *key, unsigned long keylen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1612 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1613 Which initializes the ``pmac'' state with the given ``cipher'' and ``key'' of length ``keylen'' bytes. The chosen cipher
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1614 must have a 64 or 128 bit block size (e.x. AES).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1615
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1616 To MAC data simply send it through the process function.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1617
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1618 \index{pmac\_process()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1619 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1620 int pmac_process(pmac_state *state,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1621 const unsigned char *buf, unsigned long len);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1622 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1623 This will process ``len'' bytes of ``buf'' in the given ``state''. The function is not sensitive to the granularity of the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1624 data. For example,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1625
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1626 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1627 pmac_process(&mystate, "hello", 5);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1628 pmac_process(&mystate, " world", 6);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1629 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1630
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1631 Would produce the same result as,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1632
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1633 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1634 pmac_process(&mystate, "hello world", 11);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1635 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1636
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1637 When a complete message has been processed the following function can be called to compute the message tag.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1638
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1639 \index{pmac\_done()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1640 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1641 int pmac_done(pmac_state *state,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1642 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1643 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1644 This will store upto ``outlen'' bytes of the tag for the given ``state'' into ``out''. Note that if ``outlen'' is larger
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1645 than the size of the tag it is set to the amount of bytes stored in ``out''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1646
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1647 Similar to the PMAC code the file and memory functions are also provided. To PMAC a buffer of memory in one shot use the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1648 following function.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1649
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1650 \index{pmac\_memory()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1651 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1652 int pmac_memory(int cipher,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1653 const unsigned char *key, unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1654 const unsigned char *msg, unsigned long msglen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1655 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1656 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1657 This will compute the PMAC of ``msglen'' bytes of ``msg'' using the key ``key'' of length ``keylen'' bytes and the cipher
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1658 specified by the ``cipher'''th entry in the cipher\_descriptor table. It will store the MAC in ``out'' with the same
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1659 rules as omac\_done.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1660
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1661 To PMAC a file use
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1662 \index{pmac\_file()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1663 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1664 int pmac_file(int cipher,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1665 const unsigned char *key, unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1666 const char *filename,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1667 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1668 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1669
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1670 Which will PMAC the entire contents of the file specified by ``filename'' using the key ``key'' of length ``keylen'' bytes
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1671 and the cipher specified by the ``cipher'''th entry in the cipher\_descriptor table. It will store the MAC in ``out'' with
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1672 the same rules as omac\_done.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1673
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1674 To test if the PMAC code is working there is the following function:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1675 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1676 int pmac_test(void);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1677 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1678 Which returns {\bf CRYPT\_OK} if the code passes otherwise it returns an error code.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1679
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1680
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1681 \chapter{Pseudo-Random Number Generators}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1682 \section{Core Functions}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1683
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1684 The library provides an array of core functions for Pseudo-Random Number Generators (PRNGs) as well. A cryptographic PRNG is
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1685 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)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1686 key generation. There is a universal structure called ``prng\_state''. To initialize a PRNG call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1687 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1688 int XXX_start(prng_state *prng);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1689 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1690
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1691 This will setup the PRNG for future use and not seed it. In order
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1692 for the PRNG to be cryptographically useful you must give it entropy. Ideally you'd have some OS level source to tap
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1693 like in UNIX (see section 5.3). To add entropy to the PRNG call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1694 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1695 int XXX_add_entropy(const unsigned char *in, unsigned long len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1696 prng_state *prng);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1697 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1698
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1699 Which returns {\bf CRYPTO\_OK} if the entropy was accepted. Once you think you have enough entropy you call another
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1700 function to put the entropy into action.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1701 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1702 int XXX_ready(prng_state *prng);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1703 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1704
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1705 Which returns {\bf CRYPTO\_OK} if it is ready. Finally to actually read bytes call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1706 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1707 unsigned long XXX_read(unsigned char *out, unsigned long len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1708 prng_state *prng);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1709 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1710
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1711 Which returns the number of bytes read from the PRNG.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1712
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1713 \subsection{Remarks}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1714
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1715 It is possible to be adding entropy and reading from a PRNG at the same time. For example, if you first seed the PRNG
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1716 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1717 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1718 checking is guaranteed to see if the entropy is sufficient or if the PRNG is even in a ready state before reading.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1719
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1720 \subsection{Example}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1721
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1722 Below is a simple snippet to read 10 bytes from yarrow. Its important to note that this snippet is {\bf NOT} secure since
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1723 the entropy added is not random.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1724
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1725 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1726 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1727 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1728 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1729 prng_state prng;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1730 unsigned char buf[10];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1731 int err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1732
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1733 /* start it */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1734 if ((err = yarrow_start(&prng)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1735 printf("Start error: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1736 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1737 /* add entropy */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1738 if ((err = yarrow_add_entropy("hello world", 11, &prng)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1739 printf("Add_entropy error: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1740 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1741 /* ready and read */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1742 if ((err = yarrow_ready(&prng)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1743 printf("Ready error: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1744 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1745 printf("Read %lu bytes from yarrow\n", yarrow_read(buf, 10, &prng));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1746 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1747 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1748 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1749
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1750 \section{PRNG Descriptors}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1751 \index{PRNG Descriptor}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1752 PRNGs have descriptors too (surprised?). Stored in the structure ``prng\_descriptor''. The format of an element is:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1753 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1754 struct _prng_descriptor {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1755 char *name;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1756 int (*start) (prng_state *);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1757 int (*add_entropy)(const unsigned char *, unsigned long, prng_state *);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1758 int (*ready) (prng_state *);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1759 unsigned long (*read)(unsigned char *, unsigned long len, prng_state *);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1760 };
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1761 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1762
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1763 There is a ``int find\_prng(char *name)'' function as well. Returns -1 if the PRNG is not found, otherwise it returns
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1764 the position in the prng\_descriptor array.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1765
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1766 Just like the ciphers and hashes you must register your prng before you can use it. The two functions provided work
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1767 exactly as those for the cipher registry functions. They are:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1768 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1769 int register_prng(const struct _prng_descriptor *prng);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1770 int unregister_prng(const struct _prng_descriptor *prng);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1771 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1772
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1773 \subsubsection{PRNGs Provided}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1774 Currently Yarrow (yarrow\_desc), RC4 (rc4\_desc) and the secure RNG (sprng\_desc) are provided as PRNGs within the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1775 library.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1776
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1777 RC4 is provided with a PRNG interface because it is a stream cipher and not well suited for the symmetric block cipher
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1778 interface. You provide the key for RC4 via the rc4\_add\_entropy() function. By calling rc4\_ready() the key will be used
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1779 to setup the RC4 state for encryption or decryption. The rc4\_read() function has been modified from RC4 since it will
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1780 XOR the output of the RC4 keystream generator against the input buffer you provide. The following snippet will demonstrate
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1781 how to encrypt a buffer with RC4:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1782
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1783 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1784 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1785 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1786 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1787 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1788 prng_state prng;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1789 unsigned char buf[32];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1790 int err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1791
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1792 if ((err = rc4_start(&prng)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1793 printf("RC4 init error: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1794 exit(-1);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1795 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1796
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1797 /* use ``key'' as the key */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1798 if ((err = rc4_add_entropy("key", 3, &prng)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1799 printf("RC4 add entropy error: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1800 exit(-1);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1801 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1802
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1803 /* setup RC4 for use */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1804 if ((err = rc4_ready(&prng)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1805 printf("RC4 ready error: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1806 exit(-1);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1807 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1808
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1809 /* encrypt buffer */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1810 strcpy(buf,"hello world");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1811 if (rc4_read(buf, 11, &prng) != 11) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1812 printf("RC4 read error\n");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1813 exit(-1);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1814 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1815 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1816 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1817 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1818 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1819 To decrypt you have to do the exact same steps.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1820
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1821 \section{The Secure RNG}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1822 \index{Secure RNG}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1823 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1824 by performing some computation on fresh input bits. Possibly the hardest thing to get correctly in a cryptosystem is the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1825 PRNG. Computers are deterministic beasts that try hard not to stray from pre-determined paths. That makes gathering
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1826 entropy needed to seed the PRNG a hard task.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1827
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1828 There is one small function that may help on certain platforms:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1829 \index{rng\_get\_bytes()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1830 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1831 unsigned long rng_get_bytes(unsigned char *buf, unsigned long len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1832 void (*callback)(void));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1833 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1834
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1835 Which will try one of three methods of getting random data. The first is to open the popular ``/dev/random'' device which
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1836 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.}.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1837 The second method is to try the Microsoft Cryptographic Service Provider and read the RNG. The third method is an ANSI C
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1838 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1839 used so the calling application can still work. This is useful since the ANSI C RNG has a throughput of three
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1840 bytes a second. The callback pointer may be set to {\bf NULL} to avoid using it if you don't want to. The function
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1841 returns the number of bytes actually read from any RNG source. There is a function to help setup a PRNG as well:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1842 \index{rng\_make\_prng()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1843 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1844 int rng_make_prng(int bits, int wprng, prng_state *prng,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1845 void (*callback)(void));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1846 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1847 This will try to setup the prng with a state of at least ``bits'' of entropy. The ``callback'' parameter works much like
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1848 the callback in ``rng\_get\_bytes()''. It is highly recommended that you use this function to setup your PRNGs unless you have a
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1849 platform where the RNG doesn't work well. Example usage of this function is given below.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1850
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1851 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1852 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1853 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1854 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1855 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1856 ecc_key mykey;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1857 prng_state prng;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1858 int err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1859
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1860 /* register yarrow */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1861 if (register_prng(&yarrow_desc) == -1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1862 printf("Error registering Yarrow\n");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1863 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1864 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1865
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1866 /* setup the PRNG */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1867 if ((err = rng_make_prng(128, find_prng("yarrow"), &prng, NULL)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1868 printf("Error setting up PRNG, %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1869 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1870 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1871
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1872 /* make a 192-bit ECC key */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1873 if ((err = ecc_make_key(&prng, find_prng("yarrow"), 24, &mykey)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1874 printf("Error making key: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1875 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1876 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1877 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1878 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1879 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1880 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1881
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1882 \subsection{The Secure PRNG Interface}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1883 It is possible to access the secure RNG through the PRNG interface and in turn use it within dependent functions such
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1884 as the PK API. This simplifies the cryptosystem on platforms where the secure RNG is fast. The secure PRNG never
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1885 requires to be started, that is you need not call the start, add\_entropy or ready functions. For example, consider
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1886 the previous example using this PRNG.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1887
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1888 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1889 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1890 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1891 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1892 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1893 ecc_key mykey;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1894 int err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1895
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1896 /* register SPRNG */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1897 if (register_prng(&sprng_desc) == -1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1898 printf("Error registering SPRNG\n");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1899 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1900 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1901
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1902 /* make a 192-bit ECC key */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1903 if ((err = ecc_make_key(NULL, find_prng("sprng"), 24, &mykey)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1904 printf("Error making key: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1905 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1906 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1907 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1908 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1909 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1910 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1911
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1912 \chapter{RSA Public Key Cryptography}
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1913
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1914 \section{Introduction}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1915 RSA wrote the PKCS \#1 specifications which detail RSA Public Key Cryptography. In the specifications are
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1916 padding algorithms for encryption and signatures. The standard includes ``v1.5'' and ``v2.0'' algorithms.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1917 To simplify matters a little the v2.0 encryption and signature padding algorithms are called OAEP and PSS
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1918 respectively.
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1919
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1920 \section{PKCS \#1 Encryption}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1921
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1922 PKCS \#1 RSA Encryption amounts to OAEP padding of the input message followed by the modular exponentiation. As far as this portion of
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1923 the library is concerned we are only dealing with th OAEP padding of the message.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1924
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1925 \subsection{OAEP Encoding}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1926
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1927 \index{pkcs\_1\_oaep\_encode()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1928 \begin{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1929 int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1930 const unsigned char *lparam, unsigned long lparamlen,
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1931 unsigned long modulus_bitlen, prng_state *prng,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1932 int prng_idx, int hash_idx,
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1933 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1934 \end{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1935
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1936 This accepts ``msg'' as input of length ``msglen'' which will be OAEP padded. The ``lparam'' variable is an additional system specific
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1937 tag that can be applied to the encoding. This is useful to identify which system encoded the message. If no variance is desired then
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1938 ``lparam'' can be set to \textbf{NULL}.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1939
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1940 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1941 ``modulus\_bitlen''. ``hash\_idx'' is the index into the hash descriptor table of the hash desired. PKCS \#1 allows any hash to be
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1942 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1943 sized input message. ``prng\_idx'' and ``prng'' are the random number generator arguments required to randomize the padding process.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1944 The padded message is stored in ``out'' along with the length in ``outlen''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1945
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1946 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1947 $m - 2h - 2$. For example, with a $1024$--bit RSA key and SHA--1 as the hash the maximum payload is $86$ bytes.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1948
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1949 Note that when the message is padded it still has not been RSA encrypted. You must pass the output of this function to
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1950 rsa\_exptmod() to encrypt it.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1951
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1952 \subsection{OAEP Decoding}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1953
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1954 \index{pkcs\_1\_oaep\_decode()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1955 \begin{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1956 int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1957 const unsigned char *lparam, unsigned long lparamlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1958 unsigned long modulus_bitlen, int hash_idx,
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1959 unsigned char *out, unsigned long *outlen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1960 int *res);
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1961 \end{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1962
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1963 This function decodes an OAEP encoded message and outputs the original message that was passed to the OAEP encoder. ``msg'' is the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1964 output of pkcs\_1\_oaep\_encode() of length ``msglen''. ``lparam'' is the same system variable passed to the OAEP encoder. If it does not
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1965 match what was used during encoding this function will not decode the packet. ``modulus\_bitlen'' is the size of the RSA modulus in bits
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1966 and must match what was used during encoding. Similarly the ``hash\_idx'' index into the hash descriptor table must match what was used
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1967 during encoding.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1968
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1969 If the function succeeds it decodes the OAEP encoded message into ``out'' of length ``outlen'' and stores a
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1970 $1$ in ``res''. If the packet is invalid it stores $0$ in ``res'' and if the function fails for another reason
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1971 it returns an error code.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1972
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1973 \subsection{PKCS \#1 v1.5 Encoding}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1974
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1975 \index{pkcs\_1\_v15\_es\_encode()}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1976 \begin{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1977 int pkcs_1_v15_es_encode(const unsigned char *msg, unsigned long msglen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1978 unsigned long modulus_bitlen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1979 prng_state *prng, int prng_idx,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1980 unsigned char *out, unsigned long *outlen);
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1981 \end{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1982
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1983 This will PKCS v1.5 encode the data in ``msg'' of length ``msglen''. Pass the length (in bits) of your
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1984 RSA modulus in ``modulus\_bitlen''. The encoded data will be stored in ``out'' of length ``outlen''.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1985
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1986 \subsection{PKCS \#1 v1.5 Decoding}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1987 \index{pkcs\_1\_v15\_es\_decode()}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1988 \begin{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1989 int pkcs_1_v15_es_decode(const unsigned char *msg, unsigned long msglen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1990 unsigned long modulus_bitlen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1991 unsigned char *out, unsigned long outlen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1992 int *res);
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1993 \end{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1994
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1995 This will PKCS v1.5 decode the message in ``msg'' of length ``msglen''. It will store the output in ``out''. Note
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1996 that the length of the output ``outlen'' is a constant. This decoder cannot determine the original message
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1997 length. If the data in ``msg'' is a valid packet then a $1$ is stored in ``res'', otherwise a $0$ is
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
1998 stored.
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1999
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2000 \section{PKCS \#1 Digital Signatures}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2001
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2002 \subsection{PSS Encoding}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2003 PSS encoding is the second half of the PKCS \#1 standard which is padding to be applied to messages that are signed.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2004
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2005 \index{pkcs\_1\_pss\_encode()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2006 \begin{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2007 int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen,
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2008 unsigned long saltlen, prng_state *prng,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2009 int prng_idx, int hash_idx,
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2010 unsigned long modulus_bitlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2011 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2012 \end{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2013
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2014 This function assumes the message to be PSS encoded has previously been hashed. The input hash ``msghash'' is of length
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2015 ``msghashlen''. PSS allows a variable length random salt (it can be zero length) to be introduced in the signature process.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2016 ``hash\_idx'' is the index into the hash descriptor table of the hash to use. ``prng\_idx'' and ``prng'' are the random
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2017 number generator information required for the salt.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2018
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2019 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
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2020 of the modulus $h$ the length of the hash output (in octets) then there can be $m - h - 2$ bytes of salt.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2021
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2022 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().
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2023
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2024 \subsection{PSS Decoding}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2025
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2026 To decode a PSS encoded signature block you have to use the following.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2027
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2028 \index{pkcs\_1\_pss\_decode()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2029 \begin{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2030 int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2031 const unsigned char *sig, unsigned long siglen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2032 unsigned long saltlen, int hash_idx,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2033 unsigned long modulus_bitlen, int *res);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2034 \end{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2035 This will decode the PSS encoded message in ``sig'' of length ``siglen'' and compare it to values in ``msghash'' of length
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2036 ``msghashlen''. If the block is a valid PSS block and the decoded hash equals the hash supplied ``res'' is set to non--zero. Otherwise,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2037 it is set to zero. The rest of the parameters are as in the PSS encode call.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2038
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2039 It's important to use the same ``saltlen'' and hash for both encoding and decoding as otherwise the procedure will not work.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2040
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2041 \subsection{PKCS \#1 v1.5 Encoding}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2042
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2043 \index{pkcs\_1\_v15\_sa\_encode()}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2044 \begin{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2045 int pkcs_1_v15_sa_encode(const unsigned char *msghash, unsigned long msghashlen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2046 int hash_idx, unsigned long modulus_bitlen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2047 unsigned char *out, unsigned long *outlen);
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2048 \end{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2049
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2050 This will PKCS \#1 v1.5 signature encode the message hash ``msghash'' of length ``msghashlen''. You have
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2051 to tell this routine which hash produced the message hash in ``hash\_idx''. The encoded hash is stored
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2052 in ``out'' of length ``outlen''.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2053
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2054 \subsection{PKCS \#1 v1.5 Decoding}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2055
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2056 \index{pkcs\_1\_v15\_sa\_decode()}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2057 \begin{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2058 int pkcs_1_v15_sa_decode(const unsigned char *msghash, unsigned long msghashlen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2059 const unsigned char *sig, unsigned long siglen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2060 int hash_idx, unsigned long modulus_bitlen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2061 int *res);
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2062 \end{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2063
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2064 This will PKCS \#1 v1.5 signature decode the data in ``sig'' of length ``siglen'' and compare the extracted
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2065 hash against ``msghash'' of length ``msghashlen''. You have to tell this routine which hash produced the
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2066 message digest in ``hash\_idx''. If the packet is valid and the hashes match ``res'' is set to $1$. Otherwise,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2067 it is set to $0$.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2068
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2069 \section{RSA Operations}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2070 \subsection{Background}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2071
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2072 RSA is a public key algorithm that is based on the inability to find the ``e-th'' root modulo a composite of unknown
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2073 factorization. Normally the difficulty of breaking RSA is associated with the integer factoring problem but they are
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2074 not strictly equivalent.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2075
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2076 The system begins with with two primes $p$ and $q$ and their product $N = pq$. The order or ``Euler totient'' of the
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2077 multiplicative sub-group formed modulo $N$ is given as $\phi(N) = (p - 1)(q - 1)$ which can be reduced to
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2078 $\mbox{lcm}(p - 1, q - 1)$. The public key consists of the composite $N$ and some integer $e$ such that
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2079 $\mbox{gcd}(e, \phi(N)) = 1$. The private key consists of the composite $N$ and the inverse of $e$ modulo $\phi(N)$
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2080 often simply denoted as $de \equiv 1\mbox{ }(\mbox{mod }\phi(N))$.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2081
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2082 A person who wants to encrypt with your public key simply forms an integer (the plaintext) $M$ such that
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2083 $1 < M < N-2$ and computes the ciphertext $C = M^e\mbox{ }(\mbox{mod }N)$. Since finding the inverse exponent $d$
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2084 given only $N$ and $e$ appears to be intractable only the owner of the private key can decrypt the ciphertext and compute
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2085 $C^d \equiv \left (M^e \right)^d \equiv M^1 \equiv M\mbox{ }(\mbox{mod }N)$. Similarly the owner of the private key
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2086 can sign a message by ``decrypting'' it. Others can verify it by ``encrypting'' it.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2087
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2088 Currently RSA is a difficult system to cryptanalyze provided that both primes are large and not close to each other.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2089 Ideally $e$ should be larger than $100$ to prevent direct analysis. For example, if $e$ is three and you do not pad
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2090 the plaintext to be encrypted than it is possible that $M^3 < N$ in which case finding the cube-root would be trivial.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2091 The most often suggested value for $e$ is $65537$ since it is large enough to make such attacks impossible and also well
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2092 designed for fast exponentiation (requires 16 squarings and one multiplication).
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2093
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2094 It is important to pad the input to RSA since it has particular mathematical structure. For instance
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2095 $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
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2096 to have a forged signature for. Simply get the signatures for $M_1$ and $M_2$ on their own and multiply the result
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2097 together. Similar tricks can be used to deduce plaintexts from ciphertexts. It is important not only to sign
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2098 the hash of documents only but also to pad the inputs with data to remove such structure.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2099
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2100 \subsection{RSA Key Generation}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2101
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2102 For RSA routines a single ``rsa\_key'' structure is used. To make a new RSA key call:
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2103 \index{rsa\_make\_key()}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2104 \begin{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2105 int rsa_make_key(prng_state *prng,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2106 int wprng, int size,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2107 long e, rsa_key *key);
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2108 \end{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2109
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2110 Where ``wprng'' is the index into the PRNG descriptor array. ``size'' is the size in bytes of the RSA modulus desired.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2111 ``e'' is the encryption exponent desired, typical values are 3, 17, 257 and 65537. I suggest you stick with 65537 since its big
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2112 enough to prevent trivial math attacks and not super slow. ``key'' is where the key is placed. All keys must be at
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2113 least 128 bytes and no more than 512 bytes in size (\textit{that is from 1024 to 4096 bits}).
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2114
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2115 Note that the ``rsa\_make\_key()'' function allocates memory at runtime when you make the key. Make sure to call
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2116 ``rsa\_free()'' (see below) when you are finished with the key. If ``rsa\_make\_key()'' fails it will automatically
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2117 free the ram allocated itself.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2118
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2119 There are three types of RSA keys. The types are {\bf PK\_PRIVATE\_OPTIMIZED}, {\bf PK\_PRIVATE} and {\bf PK\_PUBLIC}. The first
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2120 two are private keys where the ``optimized'' type uses the Chinese Remainder Theorem to speed up decryption/signatures. By
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2121 default all new keys are of the ``optimized'' type. The non-optimized private type is provided for backwards compatibility
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2122 as well as to save space since the optimized key requires about four times as much memory.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2123
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2124 \subsection{RSA Exponentiation}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2125
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2126 To do raw work with the RSA function call:
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2127 \index{rsa\_exptmod()}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2128 \begin{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2129 int rsa_exptmod(const unsigned char *in, unsigned long inlen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2130 unsigned char *out, unsigned long *outlen, int which,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2131 prng_state *prng, int prng_idx,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2132 rsa_key *key);
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2133 \end{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2134 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
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2135 in ``out'' and the size of the result in ``outlen''. ``which'' is set to {\bf PK\_PUBLIC} to use ``e''
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2136 (i.e. for encryption/verifying) and set to {\bf PK\_PRIVATE} to use ``d'' as the exponent (i.e. for decrypting/signing).
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2137
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2138 Note that the output of his function is zero-padded as per PKCS \#1 specifications. This allows this routine to
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2139 interoprate with PKCS \#1 padding functions properly.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2140
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2141 \subsection{RSA Key Encryption}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2142 Normally RSA is used to encrypt short symmetric keys which are then used in block ciphers to encrypt a message.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2143 To facilitate encrypting short keys the following functions have been provided.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2144
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2145 \index{rsa\_encrypt\_key()}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2146 \begin{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2147 int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2148 unsigned char *outkey, unsigned long *outlen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2149 const unsigned char *lparam, unsigned long lparamlen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2150 prng_state *prng, int prng_idx, int hash_idx, rsa_key *key);
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2151 \end{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2152 This function will OAEP pad ``inkey'' of length inlen bytes then RSA encrypt it and store the ciphertext
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2153 in ``outkey'' of length ``outlen''. The ``lparam'' and ``lparamlen'' are the same parameters you would pass
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2154 to pkcs\_1\_oaep\_encode().
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2155
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2156 \index{rsa\_decrypt\_key()}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2157 \begin{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2158 int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2159 unsigned char *outkey, unsigned long *keylen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2160 const unsigned char *lparam, unsigned long lparamlen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2161 prng_state *prng, int prng_idx,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2162 int hash_idx, int *res,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2163 rsa_key *key);
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2164 \end{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2165 This function will RSA decrypt ``in'' of length ``inlen'' then OAEP depad the resulting data and store it in
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2166 ``outkey'' of length ``outlen''. The ``lparam'' and ``lparamlen'' are the same parameters you would pass
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2167 to pkcs\_1\_oaep\_decode().
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2168
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2169 If the RSA decrypted data isn't a valid OAEP packet then ``res'' is set to $0$. Otherwise, it is set to $1$.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2170
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2171 \subsection{RSA Hash Signatures}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2172 Similar to RSA key encryption RSA is also used to ``digitally sign'' message digests (hashes). To facilitate this
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2173 process the following functions have been provided.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2174
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2175 \index{rsa\_sign\_hash()}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2176 \begin{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2177 int rsa_sign_hash(const unsigned char *msghash, unsigned long msghashlen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2178 unsigned char *sig, unsigned long *siglen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2179 prng_state *prng, int prng_idx,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2180 int hash_idx, unsigned long saltlen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2181 rsa_key *key);
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2182 \end{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2183
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2184 This will PSS encode the message hash ``msghash'' of length ``msghashlen''. Next the PSS encoded message is
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2185 RSA ``signed'' and the output is stored in ``sig'' of length ``siglen''.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2186
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2187
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2188 \index{rsa\_verify\_hash()}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2189 \begin{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2190 int rsa_verify_hash(const unsigned char *sig, unsigned long siglen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2191 const unsigned char *msghash, unsigned long msghashlen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2192 prng_state *prng, int prng_idx,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2193 int hash_idx, unsigned long saltlen,
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2194 int *stat, rsa_key *key);
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2195 \end{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2196
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2197 This will RSA ``verify'' the signature in ``sig'' of length ``siglen''. Next the RSA decoded data is PSS decoded
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2198 and the extracted hash is compared against the message hash ``msghash'' of length ``msghashlen''.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2199
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2200 If the RSA decoded data is not a valid PSS message or if the PSS decoded hash does not match the ``msghash''
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2201 the value ``res'' is set to $0$. Otherwise, if the function succeeds and signature is valid ``res'' is set
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2202 to $1$.
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2203
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2204 \begin{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2205 #include <mycrypt.h>
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2206 int main(void)
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2207 {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2208 int err, hash_idx, prng_idx, res;
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2209 unsigned long l1, l2;
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2210 unsigned char pt[16], pt2[16], out[1024];
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2211 rsa_key key;
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2212
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2213 /* register prng/hash */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2214 if (register_prng(&sprng_desc) == -1) {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2215 printf("Error registering sprng");
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2216 return EXIT_FAILURE;
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2217 }
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2218
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2219 if (register_hash(&sha1_desc) == -1) {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2220 printf("Error registering sha1");
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2221 return EXIT_FAILURE;
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2222 }
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2223 hash_idx = find_hash("sha1");
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2224 prng_idx = find_prng("sprng");
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2225
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2226 /* make an RSA-1024 key */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2227 if ((err = rsa_make_key(NULL, /* PRNG state */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2228 prng_idx, /* PRNG idx */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2229 1024/8, /* 1024-bit key */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2230 65537, /* we like e=65537 */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2231 &key) /* where to store the key */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2232 ) != CRYPT_OK) {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2233 printf("rsa_make_key %s", error_to_string(err));
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2234 return EXIT_FAILURE;
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2235 }
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2236
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2237 /* fill in pt[] with a key we want to send ... */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2238 l1 = sizeof(out);
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2239 if ((err = rsa_encrypt_key(pt, /* data we wish to encrypt */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2240 16, /* data is 16 bytes long */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2241 out, /* where to store ciphertext */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2242 &l1, /* length of ciphertext */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2243 "TestApp", /* our lparam for this program */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2244 7, /* lparam is 7 bytes long */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2245 NULL, /* PRNG state */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2246 prng_idx, /* prng idx */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2247 hash_idx, /* hash idx */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2248 &key) /* our RSA key */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2249 ) != CRYPT_OK) {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2250 printf("rsa_encrypt_key %s", error_to_string(err));
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2251 return EXIT_FAILURE;
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2252 }
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2253
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2254 /* now let's decrypt the encrypted key */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2255 l2 = sizeof(pt2);
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2256 if ((err = rsa_decrypt_key(out, /* encrypted data */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2257 l1, /* length of ciphertext */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2258 pt2, /* where to put plaintext */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2259 &l2, /* plaintext length */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2260 "TestApp", /* lparam for this program */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2261 7, /* lparam is 7 bytes long */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2262 NULL, /* PRNG state */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2263 prng_idx, /* prng idx */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2264 hash_idx, /* hash idx */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2265 &res, /* validity of data */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2266 &key) /* our RSA key */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2267 ) != CRYPT_OK) {
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2268 printf("rsa_decrypt_key %s", error_to_string(err));
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2269 return EXIT_FAILURE;
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2270 }
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2271 /* if all went well pt == pt2, l2 == 16, res == 1 */
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2272 }
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2273 \end{verbatim}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2274
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2275 \chapter{Password Based Cryptography}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2276 \section{PKCS \#5}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2277 In order to securely handle user passwords for the purposes of creating session keys and chaining IVs the PKCS \#5 was drafted. PKCS \#5
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2278 is made up of two algorithms, Algorithm One and Algorithm Two. Algorithm One is the older fairly limited algorithm which has been implemented
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2279 for completeness. Algorithm Two is a bit more modern and more flexible to work with.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2280
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2281 \section{Algorithm One}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2282 Algorithm One accepts as input a password, an 8--byte salt and an iteration counter. The iteration counter is meant to act as delay for
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2283 people trying to brute force guess the password. The higher the iteration counter the longer the delay. This algorithm also requires a hash
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2284 algorithm and produces an output no longer than the output of the hash.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2285
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2286 \index{pkcs\_5\_alg1()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2287 \begin{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2288 int pkcs_5_alg1(const unsigned char *password, unsigned long password_len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2289 const unsigned char *salt,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2290 int iteration_count, int hash_idx,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2291 unsigned char *out, unsigned long *outlen)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2292 \end{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2293 Where ``password'' is the users password. Since the algorithm allows binary passwords you must also specify the length in ``password\_len''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2294 The ``salt'' is a fixed size 8--byte array which should be random for each user and session. The ``iteration\_count'' is the delay desired
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2295 on the password. The ``hash\_idx'' is the index of the hash you wish to use in the descriptor table.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2296
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2297 The output of length upto ``outlen'' is stored in ``out''. If ``outlen'' is initially larger than the size of the hash functions output
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2298 it is set to the number of bytes stored. If it is smaller than not all of the hash output is stored in ``out''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2299
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2300 \section{Algorithm Two}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2301
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2302 Algorithm Two is the recommended algorithm for this task. It allows variable length salts and can produce outputs larger than the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2303 hash functions output. As such it can easily be used to derive session keys for ciphers and MACs as well initial vectors as required
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2304 from a single password and invokation of this algorithm.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2305
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2306 \index{pkcs\_5\_alg2()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2307 \begin{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2308 int pkcs_5_alg2(const unsigned char *password, unsigned long password_len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2309 const unsigned char *salt, unsigned long salt_len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2310 int iteration_count, int hash_idx,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2311 unsigned char *out, unsigned long *outlen)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2312 \end{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2313 Where ``password'' is the users password. Since the algorithm allows binary passwords you must also specify the length in ``password\_len''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2314 The ``salt'' is an array of size ``salt\_len''. It should be random for each user and session. The ``iteration\_count'' is the delay desired
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2315 on the password. The ``hash\_idx'' is the index of the hash you wish to use in the descriptor table. The output of length upto
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2316 ``outlen'' is stored in ``out''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2317
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2318 \begin{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2319 /* demo to show how to make session state material from a password */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2320 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2321 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2322 \{
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2323 unsigned char password[100], salt[100],
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2324 cipher_key[16], cipher_iv[16],
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2325 mac_key[16], outbuf[48];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2326 int err, hash_idx;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2327 unsigned long outlen, password_len, salt_len;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2328
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2329 /* register hash and get it's idx .... */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2330
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2331 /* get users password and make up a salt ... */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2332
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2333 /* create the material (100 iterations in algorithm) */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2334 outlen = sizeof(outbuf);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2335 if ((err = pkcs_5_alg2(password, password_len, salt, salt_len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2336 100, hash_idx, outbuf, &outlen)) != CRYPT_OK) \{
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2337 /* error handle */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2338 \}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2339
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2340 /* now extract it */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2341 memcpy(cipher_key, outbuf, 16);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2342 memcpy(cipher_iv, outbuf+16, 16);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2343 memcpy(mac_key, outbuf+32, 16);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2344
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2345 /* use material (recall to store the salt in the output) */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2346 \}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2347 \end{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2348
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2349 \chapter{Diffie-Hellman Key Exchange}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2350
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2351 \section{Background}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2352
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2353 Diffie-Hellman was the original public key system proposed. The system is based upon the group structure
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2354 of finite fields. For Diffie-Hellman a prime $p$ is chosen and a ``base'' $b$ such that $b^x\mbox{ }(\mbox{mod }p)$
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2355 generates a large sub-group of prime order (for unique values of $x$).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2356
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2357 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2358 ``discrete logarithm'' denotes the action of finding $x$ given only $y$, $g$ and $p$. The key exchange part of
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2359 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2360 a shared key $K \equiv B_y^{A_x} \equiv A_y^{B_x} \equiv g^{A_xB_x}\mbox{ }(\mbox{mod }p)$.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2361
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2362 From this public encryption and signatures can be developed. The trivial way to encrypt (for example) using a public key
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2363 $y$ is to perform the key exchange offline. The sender invents a key $k$ and its public copy
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2364 $k' \equiv g^k\mbox{ }(\mbox{mod }p)$ and uses $K \equiv k'^{A_x}\mbox{ }(\mbox{mod }p)$ as a key to encrypt
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2365 the message with. Typically $K$ would be sent to a one-way hash and the message digested used as a key in a
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2366 symmetric cipher.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2367
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2368 It is important that the order of the sub-group that $g$ generates not only be large but also prime. There are
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2369 discrete logarithm algorithms that take $\sqrt r$ time given the order $r$. The discrete logarithm can be computed
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2370 modulo each prime factor of $r$ and the results combined using the Chinese Remainder Theorem. In the cases where
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2371 $r$ is ``B-Smooth'' (e.g. all small factors or powers of small prime factors) the solution is trivial to find.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2372
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2373 To thwart such attacks the primes and bases in the library have been designed and fixed. Given a prime $p$ the order of
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2374 the sub-group generated is a large prime namely ${p - 1} \over 2$. Such primes are known as ``strong primes'' and the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2375 smaller prime (e.g. the order of the base) are known as Sophie-Germaine primes.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2376
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2377 \section{Core Functions}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2378
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2379 This library also provides core Diffie-Hellman functions so you can negotiate keys over insecure mediums. The routines
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2380 provided are relatively easy to use and only take two function calls to negotiate a shared key. There is a structure
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2381 called ``dh\_key'' which stores the Diffie-Hellman key in a format these routines can use. The first routine is to
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2382 make a Diffie-Hellman private key pair:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2383 \index{dh\_make\_key()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2384 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2385 int dh_make_key(prng_state *prng, int wprng,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2386 int keysize, dh_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2387 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2388 The ``keysize'' is the size of the modulus you want in bytes. Currently support sizes are 96 to 512 bytes which correspond
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2389 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2390 specifying a size not explicitly supported by the library it will round {\em up} to the next key size. If the size is
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2391 above 512 it will return an error. So if you pass ``keysize == 32'' it will use a 768 bit key but if you pass
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2392 ``keysize == 20000'' it will return an error. The primes and generators used are built-into the library and were designed
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2393 to meet very specific goals. The primes are strong primes which means that if $p$ is the prime then
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2394 $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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2395 leaking a bit of the key. This means the bases generate a very large prime order group which is good to make cryptanalysis
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2396 hard.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2397
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2398 The next two routines are for exporting/importing Diffie-Hellman keys in a binary format. This is useful for transport
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2399 over communication mediums.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2400
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2401 \index{dh\_export()} \index{dh\_import()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2402 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2403 int dh_export(unsigned char *out, unsigned long *outlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2404 int type, dh_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2405
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2406 int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2407 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2408
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2409 These two functions work just like the ``rsa\_export()'' and ``rsa\_import()'' functions except these work with
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2410 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2411 ``dh\_key'' using:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2412 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2413 void dh_free(dh_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2414 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2415 After you have exported a copy of your public key (using {\bf PK\_PUBLIC} as ``type'') you can now create a shared secret
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2416 with the other user using:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2417 \index{dh\_shared\_secret()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2418 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2419 int dh_shared_secret(dh_key *private_key,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2420 dh_key *public_key,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2421 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2422 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2423
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2424 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2425 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2426 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2427 key:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2428 \index{dh\_get\_size()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2429 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2430 int dh_get_size(dh_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2431 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2432 This returns the size in bytes of the modulus chosen for that key.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2433
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2434 \subsection{Remarks on Usage}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2435 Its important that you hash the shared key before trying to use it as a key for a symmetric cipher or something. An
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2436 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.}:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2437 \newpage
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2438 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2439 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2440 int establish_secure_socket(int sock, int mode, unsigned char *key,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2441 prng_state *prng, int wprng)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2442 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2443 unsigned char buf[4096], buf2[4096];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2444 unsigned long x, len;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2445 int res, err, inlen;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2446 dh_key mykey, theirkey;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2447
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2448 /* make up our private key */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2449 if ((err = dh_make_key(prng, wprng, 128, &mykey)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2450 return err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2451 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2452
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2453 /* export our key as public */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2454 x = sizeof(buf);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2455 if ((err = dh_export(buf, &x, PK_PUBLIC, &mykey)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2456 res = err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2457 goto done2;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2458 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2459
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2460 if (mode == 0) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2461 /* mode 0 so we send first */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2462 if (send(sock, buf, x, 0) != x) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2463 res = CRYPT_ERROR;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2464 goto done2;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2465 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2466
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2467 /* get their key */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2468 if ((inlen = recv(sock, buf2, sizeof(buf2), 0)) <= 0) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2469 res = CRYPT_ERROR;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2470 goto done2;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2471 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2472 } else {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2473 /* mode >0 so we send second */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2474 if ((inlen = recv(sock, buf2, sizeof(buf2), 0)) <= 0) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2475 res = CRYPT_ERROR;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2476 goto done2;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2477 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2478
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2479 if (send(sock, buf, x, 0) != x) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2480 res = CRYPT_ERROR;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2481 goto done2;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2482 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2483 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2484
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2485 if ((err = dh_import(buf2, inlen, &theirkey)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2486 res = err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2487 goto done2;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2488 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2489
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2490 /* make shared secret */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2491 x = sizeof(buf);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2492 if ((err = dh_shared_secret(&mykey, &theirkey, buf, &x)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2493 res = err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2494 goto done;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2495 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2496
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2497 /* hash it */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2498 len = 16; /* default is MD5 so "key" must be at least 16 bytes long */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2499 if ((err = hash_memory(find_hash("md5"), buf, x, key, &len)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2500 res = err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2501 goto done;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2502 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2503
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2504 /* clean up and return */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2505 res = CRYPT_OK;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2506 done:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2507 dh_free(&theirkey);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2508 done2:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2509 dh_free(&mykey);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2510 zeromem(buf, sizeof(buf));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2511 zeromem(buf2, sizeof(buf2));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2512 return res;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2513 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2514 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2515 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2516 \newpage
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2517 \subsection{Remarks on The Snippet}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2518 When the above code snippet is done (assuming all went well) their will be a shared 128-bit key in the ``key'' array
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2519 passed to ``establish\_secure\_socket()''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2520
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2521 \section{Other Diffie-Hellman Functions}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2522 In order to test the Diffie-Hellman function internal workings (e.g. the primes and bases) their is a test function made
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2523 available:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2524 \index{dh\_test()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2525 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2526 int dh_test(void);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2527 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2528
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2529 This function returns {\bf CRYPT\_OK} if the bases and primes in the library are correct. There is one last helper
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2530 function:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2531 \index{dh\_sizes()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2532 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2533 void dh_sizes(int *low, int *high);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2534 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2535 Which stores the smallest and largest key sizes support into the two variables.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2536
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2537 \section{DH Packet}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2538 Similar to the RSA related functions there are functions to encrypt or decrypt symmetric keys using the DH public key
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2539 algorithms.
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2540 \index{dh\_encrypt\_key()} \index{dh\_decrypt\_key()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2541 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2542 int dh_encrypt_key(const unsigned char *inkey, unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2543 unsigned char *out, unsigned long *len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2544 prng_state *prng, int wprng, int hash,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2545 dh_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2546
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2547 int dh_decrypt_key(const unsigned char *in, unsigned long inlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2548 unsigned char *outkey, unsigned long *keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2549 dh_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2550 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2551 Where ``inkey'' is an input symmetric key of no more than 32 bytes. Essentially these routines created a random public key
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2552 and find the hash of the shared secret. The message digest is than XOR'ed against the symmetric key. All of the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2553 required data is placed in ``out'' by ``dh\_encrypt\_key()''. The hash must produce a message digest at least as large
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2554 as the symmetric key you are trying to share.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2555
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2556 Similar to the RSA system you can sign and verify a hash of a message.
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2557 \index{dh\_sign\_hash()} \index{dh\_verify\_hash()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2558 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2559 int dh_sign_hash(const unsigned char *in, unsigned long inlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2560 unsigned char *out, unsigned long *outlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2561 prng_state *prng, int wprng, dh_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2562
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2563 int dh_verify_hash(const unsigned char *sig, unsigned long siglen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2564 const unsigned char *hash, unsigned long hashlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2565 int *stat, dh_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2566 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2567
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2568 The ``dh\_sign\_hash'' function signs the message hash in ``in'' of length ``inlen'' and forms a DH packet in ``out''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2569 The ``dh\_verify\_hash'' function verifies the DH signature in ``sig'' against the hash in ``hash''. It sets ``stat''
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2570 to non-zero if the signature passes or zero if it fails.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2571
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2572 \chapter{Elliptic Curve Cryptography}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2573
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2574 \section{Background}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2575 The library provides a set of core ECC functions as well that are designed to be the Elliptic Curve analogy of all of the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2576 Diffie-Hellman routines in the previous chapter. Elliptic curves (of certain forms) have the benefit that they are harder
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2577 to attack (no sub-exponential attacks exist unlike normal DH crypto) in fact the fastest attack requires the square root
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2578 of the order of the base point in time. That means if you use a base point of order $2^{192}$ (which would represent a
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2579 192-bit key) then the work factor is $2^{96}$ in order to find the secret key.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2580
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2581 The curves in this library are taken from the following website:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2582 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2583 http://csrc.nist.gov/cryptval/dss.htm
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2584 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2585
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2586 They are all curves over the integers modulo a prime. The curves have the basic equation that is:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2587 \begin{equation}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2588 y^2 = x^3 - 3x + b\mbox{ }(\mbox{mod }p)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2589 \end{equation}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2590
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2591 The variable $b$ is chosen such that the number of points is nearly maximal. In fact the order of the base points $\beta$
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2592 provided are very close to $p$ that is $\vert \vert \phi(\beta) \vert \vert \approx \vert \vert p \vert \vert$. The curves
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2593 range in order from $\approx 2^{192}$ points to $\approx 2^{521}$. According to the source document any key size greater
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2594 than or equal to 256-bits is sufficient for long term security.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2595
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2596 \section{Core Functions}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2597
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2598 Like the DH routines there is a key structure ``ecc\_key'' used by the functions. There is a function to make a key:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2599 \index{ecc\_make\_key()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2600 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2601 int ecc_make_key(prng_state *prng, int wprng,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2602 int keysize, ecc_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2603 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2604
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2605 The ``keysize'' is the size of the modulus in bytes desired. Currently directly supported values are 20, 24, 28, 32, 48 and 65 bytes which
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2606 correspond to key sizes of 160, 192, 224, 256, 384 and 521 bits respectively. If you pass a key size that is between any key size
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2607 it will round the keysize up to the next available one. The rest of the parameters work like they do in the ``dh\_make\_key()'' function.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2608 To free the ram allocated by a key call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2609 \index{ecc\_free()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2610 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2611 void ecc_free(ecc_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2612 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2613
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2614 To import and export a key there are:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2615 \index{ecc\_export()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2616 \index{ecc\_import()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2617 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2618 int ecc_export(unsigned char *out, unsigned long *outlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2619 int type, ecc_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2620
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2621 int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2622 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2623 These two work exactly like there DH counterparts. Finally when you share your public key you can make a shared secret
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2624 with:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2625 \index{ecc\_shared\_secret()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2626 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2627 int ecc_shared_secret(ecc_key *private_key,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2628 ecc_key *public_key,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2629 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2630 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2631 Which works exactly like the DH counterpart, the ``private\_key'' is your own key and ``public\_key'' is the key the other
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2632 user sent you. Note that this function stores both $x$ and $y$ co-ordinates of the shared
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2633 elliptic point. You should hash the output to get a shared key in a more compact and useful form (most of the entropy is
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2634 in $x$ anyways). Both keys have to be the same size for this to work, to help there is a function to get the size in bytes
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2635 of a key.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2636 \index{ecc\_get\_size()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2637 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2638 int ecc_get_size(ecc_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2639 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2640
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2641 To test the ECC routines and to get the minimum and maximum key sizes there are these two functions:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2642 \index{ecc\_test()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2643 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2644 int ecc_test(void);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2645 void ecc_sizes(int *low, int *high);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2646 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2647 Which both work like their DH counterparts.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2648
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2649 \section{ECC Packet}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2650 Similar to the RSA API there are two functions which encrypt and decrypt symmetric keys using the ECC public key
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2651 algorithms.
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2652
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2653 \index{ecc\_encrypt\_key()} \index{ecc\_decrypt\_key()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2654 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2655 int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2656 unsigned char *out, unsigned long *len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2657 prng_state *prng, int wprng, int hash,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2658 ecc_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2659
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2660 int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2661 unsigned char *outkey, unsigned long *keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2662 ecc_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2663 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2664
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2665 Where ``inkey'' is an input symmetric key of no more than 32 bytes. Essentially these routines created a random public key
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2666 and find the hash of the shared secret. The message digest is than XOR'ed against the symmetric key. All of the required
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2667 data is placed in ``out'' by ``ecc\_encrypt\_key()''. The hash chosen must produce a message digest at least as large
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2668 as the symmetric key you are trying to share.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2669
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2670 There are also functions to sign and verify the hash of a message.
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2671 \index{ecc\_sign\_hash()} \index{ecc\_verify\_hash()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2672 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2673 int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2674 unsigned char *out, unsigned long *outlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2675 prng_state *prng, int wprng, ecc_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2676
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2677 int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2678 const unsigned char *hash, unsigned long hashlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2679 int *stat, ecc_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2680 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2681
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2682 The ``ecc\_sign\_hash'' function signs the message hash in ``in'' of length ``inlen'' and forms a ECC packet in ``out''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2683 The ``ecc\_verify\_hash'' function verifies the ECC signature in ``sig'' against the hash in ``hash''. It sets ``stat''
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2684 to non-zero if the signature passes or zero if it fails.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2685
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2686
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2687 \section{ECC Keysizes}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2688 With ECC if you try and sign a hash that is bigger than your ECC key you can run into problems. The math will still work
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2689 and in effect the signature will still work. With ECC keys the strength of the signature is limited by the size of
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2690 the hash or the size of they key, whichever is smaller. For example, if you sign with SHA256 and a ECC-160 key in effect
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2691 you have 160-bits of security (e.g. as if you signed with SHA-1).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2692
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2693 The library will not warn you if you make this mistake so it is important to check yourself before using the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2694 signatures.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2695
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2696 \chapter{Digital Signature Algorithm}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2697 \section{Introduction}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2698 The Digital Signature Algorithm (or DSA) is a variant of the ElGamal Signature scheme which has been modified to
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2699 reduce the bandwidth of a signature. For example, to have ``80-bits of security'' with ElGamal you need a group of
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2700 order at least 1024-bits. With DSA you need a group of order at least 160-bits. By comparison the ElGamal signature
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2701 would require at least 256 bytes where as the DSA signature would require only at least 40 bytes.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2702
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2703 The API for the DSA is essentially the same as the other PK algorithms. Except in the case of DSA no encryption or
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2704 decryption routines are provided.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2705
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2706 \section{Key Generation}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2707 To make a DSA key you must call the following function
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2708 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2709 int dsa_make_key(prng_state *prng, int wprng,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2710 int group_size, int modulus_size,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2711 dsa_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2712 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2713 The variable ``prng'' is an active PRNG state and ``wprng'' the index to the descriptor. ``group\_size'' and
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2714 ``modulus\_size'' control the difficulty of forging a signature. Both parameters are in bytes. The larger the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2715 ``group\_size'' the more difficult a forgery becomes upto a limit. The value of $group\_size$ is limited by
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2716 $15 < group\_size < 1024$ and $modulus\_size - group\_size < 512$. Suggested values for the pairs are as follows.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2717
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2718 \begin{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2719 \begin{tabular}{|c|c|c|}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2720 \hline \textbf{Bits of Security} & \textbf{group\_size} & \textbf{modulus\_size} \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2721 \hline 80 & 20 & 128 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2722 \hline 120 & 30 & 256 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2723 \hline 140 & 35 & 384 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2724 \hline 160 & 40 & 512 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2725 \hline
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2726 \end{tabular}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2727 \end{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2728
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2729 When you are finished with a DSA key you can call the following function to free the memory used.
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2730 \index{dsa\_free()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2731 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2732 void dsa_free(dsa_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2733 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2734
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2735 \section{Key Verification}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2736 Each DSA key is composed of the following variables.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2737
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2738 \begin{enumerate}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2739 \item $q$ a small prime of magnitude $256^{group\_size}$.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2740 \item $p = qr + 1$ a large prime of magnitude $256^{modulus\_size}$ where $r$ is a random even integer.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2741 \item $g = h^r \mbox{ (mod }p\mbox{)}$ a generator of order $q$ modulo $p$. $h$ can be any non-trivial random
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2742 value. For this library they start at $h = 2$ and step until $g$ is not $1$.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2743 \item $x$ a random secret (the secret key) in the range $1 < x < q$
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2744 \item $y = g^x \mbox{ (mod }p\mbox{)}$ the public key.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2745 \end{enumerate}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2746
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2747 A DSA key is considered valid if it passes all of the following tests.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2748
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2749 \begin{enumerate}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2750 \item $q$ must be prime.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2751 \item $p$ must be prime.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2752 \item $g$ cannot be one of $\lbrace -1, 0, 1 \rbrace$ (modulo $p$).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2753 \item $g$ must be less than $p$.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2754 \item $(p-1) \equiv 0 \mbox{ (mod }q\mbox{)}$.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2755 \item $g^q \equiv 1 \mbox{ (mod }p\mbox{)}$.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2756 \item $1 < y < p - 1$
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2757 \item $y^q \equiv 1 \mbox{ (mod }p\mbox{)}$.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2758 \end{enumerate}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2759
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2760 Tests one and two ensure that the values will at least form a field which is required for the signatures to
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2761 function. Tests three and four ensure that the generator $g$ is not set to a trivial value which would make signature
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2762 forgery easier. Test five ensures that $q$ divides the order of multiplicative sub-group of $\Z/p\Z$. Test six
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2763 ensures that the generator actually generates a prime order group. Tests seven and eight ensure that the public key
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2764 is within range and belongs to a group of prime order. Note that test eight does not prove that $g$ generated $y$ only
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2765 that $y$ belongs to a multiplicative sub-group of order $q$.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2766
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2767 The following function will perform these tests.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2768
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2769 \index{dsa\_verify\_key()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2770 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2771 int dsa_verify_key(dsa_key *key, int *stat);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2772 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2773
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2774 This will test ``key'' and store the result in ``stat''. If the result is $stat = 0$ the DSA key failed one of the tests
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2775 and should not be used at all. If the result is $stat = 1$ the DSA key is valid (as far as valid mathematics are concerned).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2776
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2777
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2778
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2779 \section{Signatures}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2780 To generate a DSA signature call the following function
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2781
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2782 \index{dsa\_sign\_hash()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2783 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2784 int dsa_sign_hash(const unsigned char *in, unsigned long inlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2785 unsigned char *out, unsigned long *outlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2786 prng_state *prng, int wprng, dsa_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2787 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2788
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2789 Which will sign the data in ``in'' of length ``inlen'' bytes. The signature is stored in ``out'' and the size
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2790 of the signature in ``outlen''. If the signature is longer than the size you initially specify in ``outlen'' nothing
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2791 is stored and the function returns an error code. The DSA ``key'' must be of the \textbf{PK\_PRIVATE} persuasion.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2792
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2793 To verify a hash created with that function use the following function
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2794
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2795 \index{dsa\_verify\_hash()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2796 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2797 int dsa_verify_hash(const unsigned char *sig, unsigned long siglen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2798 const unsigned char *hash, unsigned long inlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2799 int *stat, dsa_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2800 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2801 Which will verify the data in ``hash'' of length ``inlen'' against the signature stored in ``sig'' of length ``siglen''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2802 It will set ``stat'' to $1$ if the signature is valid, otherwise it sets ``stat'' to $0$.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2803
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2804 \section{Import and Export}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2805
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2806 To export a DSA key so that it can be transported use the following function
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2807 \index{dsa\_export()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2808 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2809 int dsa_export(unsigned char *out, unsigned long *outlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2810 int type,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2811 dsa_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2812 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2813 This will export the DSA ``key'' to the buffer ``out'' and set the length in ``outlen'' (which must have been previously
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2814 initialized to the maximum buffer size). The ``type`` variable may be either \textbf{PK\_PRIVATE} or \textbf{PK\_PUBLIC}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2815 depending on whether you want to export a private or public copy of the DSA key.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2816
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2817 To import an exported DSA key use the following function
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2818
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
2819 \index{dsa\_import()}
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2820 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2821 int dsa_import(const unsigned char *in, unsigned long inlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2822 dsa_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2823 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2824
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2825 This will import the DSA key from the buffer ``in'' of length ``inlen'' to the ``key''. If the process fails the function
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2826 will automatically free all of the heap allocated in the process (you don't have to call dsa\_free()).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2827
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2828 \chapter{Miscellaneous}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2829 \section{Base64 Encoding and Decoding}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2830 The library provides functions to encode and decode a RFC1521 base64 coding scheme. This means that it can decode what it
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2831 encodes but the format used does not comply to any known standard. The characters used in the mappings are:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2832 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2833 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2834 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2835 Those characters should are supported in virtually any 7-bit ASCII system which means they can be used for transport over
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2836 common e-mail, usenet and HTTP mediums. The format of an encoded stream is just a literal sequence of ASCII characters
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2837 where a group of four represent 24-bits of input. The first four chars of the encoders output is the length of the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2838 original input. After the first four characters is the rest of the message.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2839
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2840 Often it is desirable to line wrap the output to fit nicely in an e-mail or usenet posting. The decoder allows you to
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2841 put any character (that is not in the above sequence) in between any character of the encoders output. You may not however,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2842 break up the first four characters.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2843
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2844 To encode a binary string in base64 call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2845 \index{base64\_encode()} \index{base64\_decode()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2846 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2847 int base64_encode(const unsigned char *in, unsigned long len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2848 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2849 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2850 Where ``in'' is the binary string and ``out'' is where the ASCII output is placed. You must set the value of ``outlen'' prior
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2851 to calling this function and it sets the length of the base64 output in ``outlen'' when it is done. To decode a base64
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2852 string call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2853 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2854 int base64_decode(const unsigned char *in, unsigned long len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2855 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2856 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2857
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2858 \section{The Multiple Precision Integer Library (MPI)}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2859 The library comes with a copy of LibTomMath which is a multiple precision integer library written by the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2860 author of LibTomCrypt. LibTomMath is a trivial to use ANSI C compatible large integer library which is free
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2861 for all uses and is distributed freely.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2862
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2863 At the heart of all the functions is the data type ``mp\_int'' (defined in tommath.h). This data type is what
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2864 will hold all large integers. In order to use an mp\_int one must initialize it first, for example:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2865 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2866 #include <mycrypt.h> /* mycrypt.h includes mpi.h automatically */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2867 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2868 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2869 mp_int bignum;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2870
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2871 /* initialize it */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2872 mp_init(&bignum);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2873
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2874 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2875 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2876 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2877 If you are unfamiliar with the syntax of C the \& symbol is used to pass the address of ``bignum'' to the function. All
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2878 LibTomMath functions require the address of the parameters. To free the memory of a mp\_int use (for example):
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2879 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2880 mp_clear(&bignum);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2881 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2882
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2883 The functions also have the basic form of one of the following:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2884 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2885 mp_XXX(mp_int *a);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2886 mp_XXX(mp_int *a, mp_int *b, mp_int *c);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2887 mp_XXX(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2888 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2889
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2890 Where they perform some operation and store the result in the mp\_int variable passed on the far right.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2891 For example, to compute $c = a + b \mbox{ }(\mbox{mod }m)$ you would call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2892 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2893 mp_addmod(&a, &b, &m, &c);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2894 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2895
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2896 \subsection{Binary Forms of ``mp\_int'' Variables}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2897
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2898 Often it is required to store a ``mp\_int'' in binary form for transport (e.g. exporting a key, packet
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2899 encryption, etc.). LibTomMath includes two functions to help when exporting numbers:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2900 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2901 int mp_raw_size(mp_int *num);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2902 mp_toraw(&num, buf);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2903 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2904
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2905 The former function gives the size in bytes of the raw format and the latter function actually stores the raw data. All
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2906 ``mp\_int'' numbers are stored in big endian form (like PKCS demands) with the first byte being the sign of the number. The
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2907 ``rsa\_exptmod()'' function differs slightly since it will take the input in the form exactly as PKCS demands (without the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2908 leading sign byte). All other functions include the sign byte (since its much simpler just to include it). The sign byte
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2909 must be zero for positive numbers and non-zero for negative numbers. For example,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2910 the sequence:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2911 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2912 00 FF 30 04
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2913 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2914 Represents the integer $255 \cdot 256^2 + 48 \cdot 256^1 + 4 \cdot 256^0$ or 16,723,972.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2915
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2916 To read a binary string back into a ``mp\_int'' call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2917 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2918 mp_read_raw(mp_int *num, unsigned char *str, int len);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2919 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2920 Where ``num'' is where to store it, ``str'' is the binary string (including the leading sign byte) and ``len'' is the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2921 length of the binary string.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2922
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2923 \subsection{Primality Testing}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2924 \index{Primality Testing}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2925 The library includes primality testing and random prime functions as well. The primality tester will perform the test in
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2926 two phases. First it will perform trial division by the first few primes. Second it will perform eight rounds of the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2927 Rabin-Miller primality testing algorithm. If the candidate passes both phases it is declared prime otherwise it is declared
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2928 composite. No prime number will fail the two phases but composites can. Each round of the Rabin-Miller algorithm reduces
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2929 the probability of a pseudo-prime by $1 \over 4$ therefore after sixteen rounds the probability is no more than
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2930 $\left ( { 1 \over 4 } \right )^{8} = 2^{-16}$. In practice the probability of error is in fact much lower than that.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2931
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2932 When making random primes the trial division step is in fact an optimized implementation of ``Implementation of Fast RSA Key Generation on Smart Cards''\footnote{Chenghuai Lu, Andre L. M. dos Santos and Francisco R. Pimentel}.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2933 In essence a table of machine-word sized residues are kept of a candidate modulo a set of primes. When the candiate
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2934 is rejected and ultimately incremented to test the next number the residues are updated without using multi-word precision
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2935 math operations. As a result the routine can scan ahead to the next number required for testing with very little work
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2936 involved.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2937
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2938 In the event that a composite did make it through it would most likely cause the the algorithm trying to use it to fail. For
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2939 instance, in RSA two primes $p$ and $q$ are required. The order of the multiplicative sub-group (modulo $pq$) is given
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2940 as $\phi(pq)$ or $(p - 1)(q - 1)$. The decryption exponent $d$ is found as $de \equiv 1\mbox{ }(\mbox{mod } \phi(pq))$. If either $p$ or $q$ is composite the value of $d$ will be incorrect and the user
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2941 will not be able to sign or decrypt messages at all. Suppose $p$ was prime and $q$ was composite this is just a variation of
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2942 the multi-prime RSA. Suppose $q = rs$ for two primes $r$ and $s$ then $\phi(pq) = (p - 1)(r - 1)(s - 1)$ which clearly is
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2943 not equal to $(p - 1)(rs - 1)$.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2944
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2945 These are not technically part of the LibTomMath library but this is the best place to document them.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2946 To test if a ``mp\_int'' is prime call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2947 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2948 int is_prime(mp_int *N, int *result);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2949 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2950 This puts a one in ``result'' if the number is probably prime, otherwise it places a zero in it. It is assumed that if
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2951 it returns an error that the value in ``result'' is undefined. To make
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2952 a random prime call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2953 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2954 int rand_prime(mp_int *N, unsigned long len, prng_state *prng, int wprng);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2955 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2956 Where ``len'' is the size of the prime in bytes ($2 \le len \le 256$). You can set ``len'' to the negative size you want
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2957 to get a prime of the form $p \equiv 3\mbox{ }(\mbox{mod } 4)$. So if you want a 1024-bit prime of this sort pass
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2958 ``len = -128'' to the function. Upon success it will return {\bf CRYPT\_OK} and ``N'' will contain an integer which
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2959 is very likely prime.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2960
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2961 \chapter{Programming Guidelines}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2962
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2963 \section{Secure Pseudo Random Number Generators}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2964 Probably the singal most vulnerable point of any cryptosystem is the PRNG. Without one generating and protecting secrets
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2965 would be impossible. The requirement that one be setup correctly is vitally important and to address this point the library
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2966 does provide two RNG sources that will address the largest amount of end users as possible. The ``sprng'' PRNG provided
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2967 provides and easy to access source of entropy for any application on a *NIX or Windows computer.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2968
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2969 However, when the end user is not on one of these platforms the application developer must address the issue of finding
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2970 entropy. This manual is not designed to be a text on cryptography. I would just like to highlight that when you design
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2971 a cryptosystem make sure the first problem you solve is getting a fresh source of entropy.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2972
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2973 \section{Preventing Trivial Errors}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2974 Two simple ways to prevent trivial errors is to prevent overflows and to check the return values. All of the functions
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2975 which output variable length strings will require you to pass the length of the destination. If the size of your output
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2976 buffer is smaller than the output it will report an error. Therefore, make sure the size you pass is correct!
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2977
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2978 Also virtually all of the functions return an error code or {\bf CRYPT\_OK}. You should detect all errors as simple
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2979 typos or such can cause algorithms to fail to work as desired.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2980
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2981 \section{Registering Your Algorithms}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2982 To avoid linking and other runtime errors it is important to register the ciphers, hashes and PRNGs you intend to use
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2983 before you try to use them. This includes any function which would use an algorithm indirectly through a descriptor table.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2984
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2985 A neat bonus to the registry system is that you can add external algorithms that are not part of the library without
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2986 having to hack the library. For example, suppose you have a hardware specific PRNG on your system. You could easily
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2987 write the few functions required plus a descriptor. After registering your PRNG all of the library functions that
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2988 need a PRNG can instantly take advantage of it.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2989
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2990 \section{Key Sizes}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2991
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2992 \subsection{Symmetric Ciphers}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2993 For symmetric ciphers use as large as of a key as possible. For the most part ``bits are cheap'' so using a 256-bit key
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2994 is not a hard thing todo.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2995
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2996 \subsection{Assymetric Ciphers}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2997 The following chart gives the work factor for solving a DH/RSA public key using the NFS. The work factor for a key of order
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2998 $n$ is estimated to be
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2999 \begin{equation}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3000 e^{1.923 \cdot ln(n)^{1 \over 3} \cdot ln(ln(n))^{2 \over 3}}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3001 \end{equation}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3002
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3003 Note that $n$ is not the bit-length but the magnitude. For example, for a 1024-bit key $n = 2^{1024}$. The work required
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3004 is:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3005 \begin{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3006 \begin{tabular}{|c|c|}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3007 \hline RSA/DH Key Size (bits) & Work Factor ($log_2$) \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3008 \hline 512 & 63.92 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3009 \hline 768 & 76.50 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3010 \hline 1024 & 86.76 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3011 \hline 1536 & 103.37 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3012 \hline 2048 & 116.88 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3013 \hline 2560 & 128.47 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3014 \hline 3072 & 138.73 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3015 \hline 4096 & 156.49 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3016 \hline
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3017 \end{tabular}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3018 \end{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3019
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3020 The work factor for ECC keys is much higher since the best attack is still fully exponentional. Given a key of magnitude
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3021 $n$ it requires $\sqrt n$ work. The following table sumarizes the work required:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3022 \begin{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3023 \begin{tabular}{|c|c|}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3024 \hline ECC Key Size (bits) & Work Factor ($log_2$) \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3025 \hline 160 & 80 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3026 \hline 192 & 96 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3027 \hline 224 & 112 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3028 \hline 256 & 128 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3029 \hline 384 & 192 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3030 \hline 521 & 260.5 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3031 \hline
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3032 \end{tabular}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3033 \end{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3034
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3035 Using the above tables the following suggestions for key sizes seems appropriate:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3036 \begin{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3037 \begin{tabular}{|c|c|c|}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3038 \hline Security Goal & RSA/DH Key Size (bits) & ECC Key Size (bits) \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3039 \hline Short term (less than a year) & 1024 & 160 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3040 \hline Short term (less than five years) & 1536 & 192 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3041 \hline Long Term (less than ten years) & 2560 & 256 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3042 \hline
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3043 \end{tabular}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3044 \end{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3045
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3046 \section{Thread Safety}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3047 The library is not thread safe but several simple precautions can be taken to avoid any problems. The registry functions
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3048 such as register\_cipher() are not thread safe no matter what you do. Its best to call them from your programs initializtion
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3049 code before threads are initiated.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3050
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3051 The rest of the code uses state variables you must pass it such as hash\_state, hmac\_state, etc. This means that if each
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3052 thread has its own state variables then they will not affect each other. This is fairly simple with symmetric ciphers
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3053 and hashes. However, the keyring and PRNG support is something the threads will want to share. The simplest workaround
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3054 is create semaphores or mutexes around calls to those functions.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3055
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3056 Since C does not have standard semaphores this support is not native to Libtomcrypt. Even a C based semaphore is not entire
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3057 possible as some compilers may ignore the ``volatile'' keyword or have multiple processors. Provide your host application
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3058 is modular enough putting the locks in the right place should not bloat the code significantly and will solve all thread
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3059 safety issues within the library.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3060
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3061 \chapter{Configuring the Library}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3062 \section{Introduction}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3063 The library is fairly flexible about how it can be built, used and generally distributed. Additions are being made with
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3064 each new release that will make the library even more flexible. Most options are placed in the makefile and others
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3065 are in ``mycrypt\_cfg.h''. All are used when the library is built from scratch.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3066
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3067 For GCC platforms the file ``makefile'' is the makefile to be used. On MSVC platforms ``makefile.vc'' and on PS2 platforms
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3068 ``makefile.ps2''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3069
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3070 \section{mycrypt\_cfg.h}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3071 The file ``mycrypt\_cfg.h'' is what lets you control what functionality you want to remove from the library. By default,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3072 everything the library has to offer it built.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3073
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3074 \subsubsection{ARGTYPE}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3075 This lets you control how the \_ARGCHK macro will behave. The macro is used to check pointers inside the functions against
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3076 NULL. There are three settings for ARGTYPE. When set to 0 it will have the default behaviour of printing a message to
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3077 stderr and raising a SIGABRT signal. This is provided so all platforms that use libtomcrypt can have an error that functions
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3078 similarly. When set to 1 it will simply pass on to the assert() macro. When set to 2 it will resolve to a empty macro
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3079 and no error checking will be performed.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3080
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3081 \subsubsection{Endianess}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3082 There are five macros related to endianess issues. For little endian platforms define, ENDIAN\_LITTLE. For big endian
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3083 platforms define ENDIAN\_BIG. Similarly when the default word size of an ``unsigned long'' is 32-bits define ENDIAN\_32BITWORD
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3084 or define ENDIAN\_64BITWORD when its 64-bits. If you do not define any of them the library will automatically use ENDIAN\_NEUTRAL
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3085 which will work on all platforms. Currently the system will automatically detect GCC or MSVC on a windows platform as well
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3086 as GCC on a PS2 platform.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3087
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3088 \section{The Configure Script}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3089 There are also options you can specify from the configure script or ``mycrypt\_config.h''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3090
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3091 \subsubsection{X memory routines}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3092 The makefiles must define three macros denoted as XMALLOC, XCALLOC and XFREE which resolve to the name of the respective
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3093 functions. This lets you substitute in your own memory routines. If you substitute in your own functions they must behave
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3094 like the standard C library functions in terms of what they expect as input and output. By default the library uses the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3095 standard C routines.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3096
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3097 \subsubsection{X clock routines}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3098 The rng\_get\_bytes() function can call a function that requires the clock() function. These macros let you override
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3099 the default clock() used with a replacement. By default the standard C library clock() function is used.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3100
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3101 \subsubsection{NO\_FILE}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3102 During the build if NO\_FILE is defined then any function in the library that uses file I/O will not call the file I/O
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3103 functions and instead simply return CRYPT\_ERROR. This should help resolve any linker errors stemming from a lack of
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3104 file I/O on embedded platforms.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3105
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3106 \subsubsection{CLEAN\_STACK}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3107 When this functions is defined the functions that store key material on the stack will clean up afterwards. Assumes that
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3108 you have no memory paging with the stack.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3109
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3110 \subsubsection{Symmetric Ciphers, One-way Hashes, PRNGS and Public Key Functions}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3111 There are a plethora of macros for the ciphers, hashes, PRNGs and public key functions which are fairly self-explanatory.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3112 When they are defined the functionality is included otherwise it is not. There are some dependency issues which are
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3113 noted in the file. For instance, Yarrow requires CTR chaining mode, a block cipher and a hash function.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3114
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3115 \subsubsection{TWOFISH\_SMALL and TWOFISH\_TABLES}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3116 Twofish is a 128-bit symmetric block cipher that is provided within the library. The cipher itself is flexible enough
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3117 to allow some tradeoffs in the implementation. When TWOFISH\_SMALL is defined the scheduled symmetric key for Twofish
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3118 requires only 200 bytes of memory. This is achieved by not pre-computing the substitution boxes. Having this
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3119 defined will also greatly slow down the cipher. When this macro is not defined Twofish will pre-compute the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3120 tables at a cost of 4KB of memory. The cipher will be much faster as a result.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3121
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3122 When TWOFISH\_TABLES is defined the cipher will use pre-computed (and fixed in code) tables required to work. This is
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3123 useful when TWOFISH\_SMALL is defined as the table values are computed on the fly. When this is defined the code size
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3124 will increase by approximately 500 bytes. If this is defined but TWOFISH\_SMALL is not the cipher will still work but
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3125 it will not speed up the encryption or decryption functions.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3126
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3127 \subsubsection{SMALL\_CODE}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3128 When this is defined some of the code such as the Rijndael and SAFER+ ciphers are replaced with smaller code variants.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3129 These variants are slower but can save quite a bit of code space.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3130
15
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
3131 \input{crypt.ind}
6362d3854bb4 0.96 release of LibTomCrypt
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
3132
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3133 \end{document}