annotate crypt.tex @ 3:7faae8f46238 libtomcrypt-orig

Branch renaming
author Matt Johnston <matt@ucc.asn.au>
date Mon, 31 May 2004 18:25:41 +0000
parents
children 6362d3854bb4
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}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
50 \title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.95}
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.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
106 These routines are fully portable but are not conformant to any known set of standards. They are all based on established
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
107 number theory and cryptography.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
108
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
109 \subsection{What the library IS NOT for?}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
110
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
111 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
112 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
113 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
114 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
115 well as non-standard higher level functions.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
116
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
117 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
118 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
119 of the code has been reviewed by a growing community of developers.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
120
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
121 \subsubsection{Why not?}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
122 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
123 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
124 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
125 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
126 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
127 supposed to support these standards they had better make them more accessible.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
128
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
129 \section{Why did I write it?}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
130 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
131 two categories:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
132 \begin{enumerate}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
133 \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
134 \item It was (still is) good coding practice.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
135 \end{enumerate}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
136
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
137 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
138 {\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
139
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
140 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
141 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
142 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
143 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
144 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
145 application can support all ciphers/hashes/prngs without changing the source code.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
146
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
147 \subsection{Modular}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
148 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
149 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
150 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
151 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
152 usage of the library.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
153
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
154 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
155 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
156 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
157 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
158 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
159 end applications provided they are written properly.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
160
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
161 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
162 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
163 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
164 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
165 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
166 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
167 can make use of the cipher right away.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
168
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 \section{License}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
171
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
172 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
173 under a public domain license:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
174
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
175 \begin{enumerate}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
176 \item rc2.c
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
177 \item safer.c
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
178 \end{enumerate}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
179
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
180 `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
181 library.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
182
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
183 ``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
184 was written by Richard De Moliner ([email protected]) and is public domain.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
185
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
186 The project is hereby released as public domain.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
187
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
188 \section{Patent Disclosure}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
189
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
190 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
191 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
192 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
193 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
194
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
195 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
196 the ciphers you just can't advertise that you are doing so.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
197
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
198 \section{Building the library}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
199
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
200 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
201 file ``libtomcrypt.a''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
202
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
203 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
204 your library path.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
205
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
206 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
207 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
208 under where VC98 is installed).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
209
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
210 \section{Building against the library}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
211
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
212 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
213 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
214 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
215 if you want one (the provided ``makefile'' will work with custom configs).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
216
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
217 \section{Thanks}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
218 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
219 \begin{enumerate}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
220 \item Richard van de Laarschot
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
221 \item Richard Heathfield
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
222 \item Ajay K. Agrawal
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
223 \item Brian Gladman
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
224 \item Svante Seleborg
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
225 \item Clay Culver
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
226 \item Jason Klapste
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
227 \item Dobes Vandermeer
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
228 \item Daniel Richards
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
229 \item Wayne Scott
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
230 \item Andrew Tyler
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
231 \item Sky Schulz
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
232 \item Christopher Imes
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
233 \end{enumerate}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
234
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
235 \chapter{The Application Programming Interface (API)}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
236 \section{Introduction}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
237 \index{CRYPT\_ERROR} \index{CRYPT\_OK}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
238
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
239 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
240 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
241 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
242 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
243
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
244 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
245 const char *error_to_string(int errno);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
246 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
247
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
248 An example of handling an error is:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
249 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
250 void somefunc(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
251 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
252 int errno;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
253
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
254 /* call a cryptographic function */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
255 if ((errno = some_crypto_function(...)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
256 printf("A crypto error occured, %s\n", error_to_string(errno));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
257 /* perform error handling */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
258 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
259 /* continue on if no error occured */
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 \end{verbatim}
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 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
264 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
265 that is not an issue.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
266
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
267 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
268 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
269 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
270 int main(void) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
271 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
272 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
273 \end{verbatim}
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 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
276 (the bignum library routines).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
277
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
278 \section{Macros}
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 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
281 32/64-bit words in little/big endian format. The macros are:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
282
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
283 \index{STORE32L} \index{STORE64L} \index{LOAD32L} \index{LOAD64L}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
284 \index{STORE32H} \index{STORE64H} \index{LOAD32H} \index{LOAD64H} \index{BSWAP}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
285 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
286 \begin{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
287 \begin{tabular}{|c|c|c|}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
288 \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
289 \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
290 \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
291 \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
292 \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
293 \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
294 \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
295 \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
296 \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
297 \hline
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
298 \end{tabular}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
299 \end{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
300 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
301
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
302 There are 32-bit cyclic rotations as well:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
303 \index{ROL} \index{ROR}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
304 \begin{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
305 \begin{tabular}{|c|c|c|}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
306 \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
307 \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
308 \hline
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
309 \end{tabular}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
310 \end{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
311
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
312 \section{Functions with Variable Length Output}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
313 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
314 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
315 the output will be stored. For example:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
316 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
317 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
318 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
319 int main(void) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
320 rsa_key key;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
321 unsigned char buffer[1024];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
322 unsigned long x;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
323 int errno;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
324
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
325 /* ... Make up the RSA key somehow */
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 /* 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
328 x = sizeof(buffer);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
329 if ((errno = rsa_export(buffer, &x, PK_PUBLIC, &key)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
330 printf("Export error: %s\n", error_to_string(errno));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
331 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
332 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
333
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
334 /* 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
335 printf("RSA exported key takes %d bytes\n", x);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
336
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
337 /* ... do something with the buffer */
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 return 0;
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 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
342 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
343 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
344 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
345 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
346
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
347 \section{Functions that need a PRNG}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
348 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
349 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
350
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
351 \section{Functions that use Arrays of Octets}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
352 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
353 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
354 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
355 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
356 (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
357
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
358 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
359 type ``byte'' will be synonymous with an array of type ``unsigned char''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
360
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
361 \chapter{Symmetric Block Ciphers}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
362 \section{Core Functions}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
363
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
364 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
365 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
366 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
367 the API to grow in a modular fashion.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
368
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
369 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
370 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
371 are (given that XXX is the name of the cipher):
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
372 \index{Cipher Setup}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
373 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
374 int XXX_setup(const unsigned char *key, int keylen, int rounds,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
375 symmetric_key *skey);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
376 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
377
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
378 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
379 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
380
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
381 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
382 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
383 ``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
384 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
385
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
386 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
387 \index{Cipher Encrypt} \index{Cipher Decrypt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
388 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
389 void XXX_ecb_encrypt(const unsigned char *pt, unsigned char *ct,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
390 symmetric_key *skey);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
391
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
392 void XXX_ecb_decrypt(const unsigned char *ct, unsigned char *pt,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
393 symmetric_key *skey);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
394 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
395 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
396 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
397 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
398 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
399 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
400 int XXX_test(void);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
401 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
402 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
403 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
404 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
405 int XXX_keysize(int *keysize);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
406 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
407 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
408 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
409 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
410 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
411 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
412 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
413 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
414 int keysize, errno;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
415
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
416 /* 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
417 keysize = 20;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
418 if ((errno = twofish_keysize(&keysize)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
419 printf("Error getting key size: %s\n", error_to_string(errno));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
420 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
421 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
422 printf("Twofish suggested a key size of %d\n", keysize);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
423 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
424 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
425 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
426 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
427 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
428 Blowfish in ECB mode is below.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
429
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
430 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
431 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
432 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
433 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
434 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
435 unsigned char pt[8], ct[8], key[8];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
436 symmetric_key skey;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
437 int errno;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
438
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
439 /* ... key is loaded appropriately in ``key'' ... */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
440 /* ... load a block of plaintext in ``pt'' ... */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
441
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
442 /* schedule the key */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
443 if ((errno = blowfish_setup(key, 8, 0, &skey)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
444 printf("Setup error: %s\n", error_to_string(errno));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
445 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
446 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
447
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
448 /* encrypt the block */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
449 blowfish_ecb_encrypt(pt, ct, &skey);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
450
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
451 /* decrypt the block */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
452 blowfish_ecb_decrypt(ct, pt, &skey);
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 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
455 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
456 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
457 \end{small}
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 \section{Key Sizes and Number of Rounds}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
460 \index{Symmetric Keys}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
461 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
462 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
463 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
464 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
465 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
466 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
467 only 53 bits of entropy.
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 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
470 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
471 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
472
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
473 \section{The Cipher Descriptors}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
474 \index{Cipher Descriptor}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
475 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
476 of this array has the following format:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
477
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
478 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
479 struct _cipher_descriptor {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
480 char *name;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
481 unsigned long min_key_length, max_key_length,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
482 block_length, default_rounds;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
483 int (*setup) (const unsigned char *key, int keylength,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
484 int num_rounds, symmetric_key *skey);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
485 void (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
486 symmetric_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
487 void (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
488 symmetric_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
489 int (*test) (void);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
490 int (*keysize) (int *desired_keysize);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
491 };
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
492 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
493
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
494 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
495 ``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
496 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
497 of rounds that will be used.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
498
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
499 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
500 marked when ``name'' equals {\bf NULL}.
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 As of this release the current cipher\_descriptors elements are
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 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
505 \begin{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
506 \begin{tabular}{|c|c|c|c|c|c|}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
507 \hline Name & Descriptor Name & Block Size & Key Range & Rounds \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
508 \hline Blowfish & blowfish\_desc & 8 & 8 $\ldots$ 56 & 16 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
509 \hline X-Tea & xtea\_desc & 8 & 16 & 32 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
510 \hline RC2 & rc2\_desc & 8 & 8 $\ldots$ 128 & 16 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
511 \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
512 \hline RC6-32/20/b & rc6\_desc & 16 & 8 $\ldots$ 128 & 20 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
513 \hline SAFER+ & saferp\_desc &16 & 16, 24, 32 & 8, 12, 16 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
514 \hline Safer K64 & safer\_k64\_desc & 8 & 8 & 6 $\ldots$ 13 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
515 \hline Safer SK64 & safer\_sk64\_desc & 8 & 8 & 6 $\ldots$ 13 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
516 \hline Safer K128 & safer\_k128\_desc & 8 & 16 & 6 $\ldots$ 13 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
517 \hline Safer SK128 & safer\_sk128\_desc & 8 & 16 & 6 $\ldots$ 13 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
518 \hline AES & aes\_desc & 16 & 16, 24, 32 & 10, 12, 14 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
519 \hline Twofish & twofish\_desc & 16 & 16, 24, 32 & 16 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
520 \hline DES & des\_desc & 8 & 7 & 16 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
521 \hline 3DES (EDE mode) & des3\_desc & 8 & 21 & 16 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
522 \hline CAST5 (CAST-128) & cast5\_desc & 8 & 5 $\ldots$ 16 & 12, 16 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
523 \hline Noekeon & noekeon\_desc & 16 & 16 & 16 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
524 \hline Skipjack & skipjack\_desc & 8 & 10 & 32 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
525 \hline
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
526 \end{tabular}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
527 \end{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
528 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
529
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
530 \subsection{Notes}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
531 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
532 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
533 or safer\_ecb\_decrypt() respectively.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
534
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
535 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
536 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
537 byte string from the real 7/21 byte key.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
538
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
539 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
540 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
541 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
542 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
543 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
544 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
545 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
546 Twofish round function.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
547
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
548 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
549 \begin{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
550 \begin{tabular}{|l|l|l|}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
551 \hline TWOFISH\_SMALL & TWOFISH\_TABLES & Speed and Memory (per key) \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
552 \hline undefined & undefined & Very fast, 4.2KB of ram. \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
553 \hline undefined & defined & As above, faster keysetup, larger code (1KB more). \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
554 \hline defined & undefined & Very slow, 0.2KB of ram. \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
555 \hline defined & defined & Somewhat faster, 0.2KB of ram, larger code. \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
556 \hline
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
557 \end{tabular}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
558 \end{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
559 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
560
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
561 To work with the cipher\_descriptor array there is a function:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
562 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
563 int find_cipher(char *name)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
564 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
565 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
566 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
567 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
568 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
569 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
570 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
571 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
572 unsigned char key[8];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
573 symmetric_key skey;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
574 int errno;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
575
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
576 /* you must register a cipher before you use it */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
577 if (register_cipher(&blowfish_desc)) == -1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
578 printf("Unable to register Blowfish cipher.");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
579 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
580 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
581
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
582 /* generic call to function (assuming the key in key[] was already setup) */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
583 if ((errno = cipher_descriptor[find_cipher("blowfish")].setup(key, 8, 0, &skey)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
584 printf("Error setting up Blowfish: %s\n", error_to_string(errno));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
585 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
586 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
587
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
588 /* ... use cipher ... */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
589 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
590 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
591 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
592
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
593 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
594 to use a cipher with the descriptor table you must register it first using:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
595 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
596 int register_cipher(const struct _cipher_descriptor *cipher);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
597 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
598 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
599 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
600 than once it will just return the index of the first copy. To remove a cipher call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
601 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
602 int unregister_cipher(const struct _cipher_descriptor *cipher);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
603 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
604 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
605 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
606 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
607 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
608 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
609 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
610 int errno;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
611
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
612 /* register the cipher */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
613 if (register_cipher(&rijndael_desc) == -1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
614 printf("Error registering Rijndael\n");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
615 return -1;
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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
618 /* use Rijndael */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
619
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
620 /* remove it */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
621 if ((errno = unregister_cipher(&rijndael_desc)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
622 printf("Error removing Rijndael: %s\n", error_to_string(errno));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
623 return -1;
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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
626 return 0;
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 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
629 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
630 This snippet is a small program that registers only Rijndael only.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
631
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
632 \section{Symmetric Modes of Operations}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
633 \subsection{Background}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
634 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
635 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
636 $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
637
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
638 \subsubsection{ECB Mode}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
639 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
640 \begin{equation}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
641 C_i = E_k(P_i)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
642 \end{equation}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
643 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
644 than once.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
645
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
646 \subsubsection{CBC Mode}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
647 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
648 It is given as:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
649 \begin{equation}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
650 C_i = E_k(P_i \oplus C_{i - 1})
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
651 \end{equation}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
652 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
653
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
654 \subsubsection{CTR Mode}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
655 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
656 treated as a large binary counter the CTR mode is given as:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
657 \begin{eqnarray}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
658 C_{-1} = C_{-1} + 1\mbox{ }(\mbox{mod }2^W) \nonumber \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
659 C_i = P_i \oplus E_k(C_{-1})
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
660 \end{eqnarray}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
661 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
662 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
663 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
664
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
665 \subsubsection{CFB Mode}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
666 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
667 \begin{eqnarray}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
668 C_i = P_i \oplus C_{-1} \nonumber \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
669 C_{-1} = E_k(C_i)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
670 \end{eqnarray}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
671 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
672 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
673 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
674
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
675 \subsubsection{OFB Mode}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
676 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
677 \begin{eqnarray}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
678 C_{-1} = E_k(C_{-1}) \nonumber \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
679 C_i = P_i \oplus C_{-1}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
680 \end{eqnarray}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
681 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
682 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
683
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
684 \subsection{Choice of Mode}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
685 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
686 \begin{enumerate}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
687 \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
688 \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
689 \item Technically does not require the decryption routine of the cipher.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
690 \item Allows random access to the plaintext.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
691 \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
692 \end{enumerate}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
693 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
694 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
695 block of memory with either of the three modes.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
696
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
697 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
698 other modes.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
699
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
700 \subsection{Implementation}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
701 \index{CBC Mode} \index{CTR Mode}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
702 \index{OFB Mode} \index{CFB Mode}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
703 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
704 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
705 use that mode. They have identical setup routines (except ECB mode for obvious reasons):
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
706 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
707 int XXX_start(int cipher, const unsigned char *IV,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
708 const unsigned char *key, int keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
709 int num_rounds, symmetric_XXX *XXX);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
710
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
711 int ecb_start(int cipher, const unsigned char *key, int keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
712 int num_rounds, symmetric_ECB *ecb);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
713 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
714
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
715 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
716 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
717 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
718 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
719 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
720 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
721
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
722 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
723 actually encrypt or decrypt the following routines are provided:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
724 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
725 int XXX_encrypt(const unsigned char *pt, unsigned char *ct,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
726 symmetric_XXX *XXX);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
727 int XXX_decrypt(const unsigned char *ct, unsigned char *pt,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
728 symmetric_XXX *XXX);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
729
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
730 int YYY_encrypt(const unsigned char *pt, unsigned char *ct,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
731 unsigned long len, symmetric_YYY *YYY);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
732 int YYY_decrypt(const unsigned char *ct, unsigned char *pt,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
733 unsigned long len, symmetric_YYY *YYY);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
734 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
735 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
736 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
737 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
738 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
739 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
740
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
741 To decrypt in either mode you simply perform the setup like before (recall you have to fetch the IV value you used)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
742 and use the decrypt routine on all of the blocks. When you are done working with either mode you should wipe the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
743 memory (using ``zeromem()'') to help prevent the key from leaking. For example:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
744 \newpage
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
745 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
746 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
747 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
748 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
749 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
750 unsigned char key[16], IV[16], buffer[512];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
751 symmetric_CTR ctr;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
752 int x, errno;
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 /* register twofish first */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
755 if (register_cipher(&twofish_desc) == -1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
756 printf("Error registering cipher.\n");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
757 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
758 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
759
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
760 /* somehow fill out key and IV */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
761
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
762 /* start up CTR mode */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
763 if ((errno = ctr_start(find_cipher("twofish"), IV, key, 16, 0, &ctr)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
764 printf("ctr_start error: %s\n", error_to_string(errno));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
765 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
766 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
767
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
768 /* somehow fill buffer than encrypt it */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
769 if ((errno = ctr_encrypt(buffer, buffer, sizeof(buffer), &ctr)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
770 printf("ctr_encrypt error: %s\n", error_to_string(errno));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
771 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
772 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
773
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
774 /* make use of ciphertext... */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
775
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
776 /* clear up and return */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
777 zeromem(key, sizeof(key));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
778 zeromem(&ctr, sizeof(ctr));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
779
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
780 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
781 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
782 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
783 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
784
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
785 \section{Encrypt and Authenticate Modes}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
786
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
787 \subsection{EAX Mode}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
788 LibTomCrypt provides support for a mode called EAX\footnote{See
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
789 M. Bellare, P. Rogaway, D. Wagner, A Conventional Authenticated-Encryption Mode.} in a manner similar to the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
790 way it was intended to be used.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
791
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
792 First a short description of what EAX mode is before I explain how to use it. EAX is a mode that requires a cipher,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
793 CTR and OMAC support and provides encryption and authentication. It is initialized with a random ``nonce'' that can
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
794 be shared publicly as well as a ``header'' which can be fixed and public as well as a random secret symmetric key.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
795
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
796 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
797 be added at anytime during an EAX stream and is part of the authentication tag. That is, changes in the meta-data can
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
798 be detected by an invalid output tag.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
799
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
800 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
801 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
802 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
803 of operation.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
804
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
805 The mode is initialized with the following function.
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 int eax_init(eax_state *eax, int cipher,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
808 const unsigned char *key, unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
809 const unsigned char *nonce, unsigned long noncelen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
810 const unsigned char *header, unsigned long headerlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
811 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
812
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
813 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
814 ``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
815 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
816 ``headerlen''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
817
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
818 When this function completes ``eax'' will be initialized such that you can now either have data decrypted or
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
819 encrypted in EAX mode. Note that if ``headerlen'' is zero you may pass ``header'' as \textbf{NULL}. It will still
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
820 initialize the EAX ``H'' value to the correct value.
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 To encrypt or decrypt data in a streaming mode use the following.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
823 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
824 int eax_encrypt(eax_state *eax, const unsigned char *pt,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
825 unsigned char *ct, unsigned long length);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
826
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
827 int eax_decrypt(eax_state *eax, const unsigned char *ct,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
828 unsigned char *pt, unsigned long length);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
829 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
830 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
831 ``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
832 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
833 ``pt'' and ``ct'' to be the same region in memory.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
834
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
835 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
836 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
837 EAX stream with the following.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
838
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
839 Also note that you cannot both encrypt or decrypt with the same ``eax'' context. For bi-directional communication you
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
840 will need to initialize two EAX contexts (preferably with different headers and nonces).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
841
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
842 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
843 int eax_addheader(eax_state *eax,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
844 const unsigned char *header, unsigned long length);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
845 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
846
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
847 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
848 ``tag'' (checksum) may be computed with the following function.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
849
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
850 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
851 int eax_done(eax_state *eax,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
852 unsigned char *tag, unsigned long *taglen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
853 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
854 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
855 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
856
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
857 The EAX mode code can be tested to ensure it matches the test vectors by calling the following function.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
858 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
859 int eax_test(void);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
860 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
861 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
862
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
863 \subsection{OCB Mode}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
864 LibTomCrypt provides support for a mode called OCB\footnote{See
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
865 P. Rogaway, M. Bellare, J. Black, T. Krovetz, ``OCB: A Block Cipher Mode of Operation for Efficient Authenticated Encryption''.}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
866 in a mode somewhat similar to as it was meant to be used.
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 OCB is an encryption protocol that simultaneously provides authentication. It is slightly faster to use than EAX mode
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
869 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
870
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
871 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
872 int ocb_init(ocb_state *ocb, int cipher,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
873 const unsigned char *key, unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
874 const unsigned char *nonce);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
875 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
876
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
877 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
878 and the random ``nonce''. Note that ``nonce'' must be a random (public) string the same length as the block ciphers
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
879 block size (e.g. 16 for AES).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
880
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
881 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
882 To encrypt or decrypt data use the following.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
883
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
884 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
885 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
886 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
887 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
888
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
889 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
890 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
891 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
892 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
893
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
894 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
895
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
896 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
897 int ocb_done_encrypt(ocb_state *ocb,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
898 const unsigned char *pt, unsigned long ptlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
899 unsigned char *ct,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
900 unsigned char *tag, unsigned long *taglen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
901 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
902
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
903 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
904 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
905 store upto ``taglen'' bytes of the tag into ``tag''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
906
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
907 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
908 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
909
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
910 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
911
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 ocb_done_decrypt(ocb_state *ocb,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
914 const unsigned char *ct, unsigned long ctlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
915 unsigned char *pt,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
916 const unsigned char *tag, unsigned long taglen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
917 int *res);
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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
920 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
921 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
922 ``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
923 message).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
924
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
925 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
926
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
927 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
928 int ocb_encrypt_authenticate_memory(int cipher,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
929 const unsigned char *key, unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
930 const unsigned char *nonce,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
931 const unsigned char *pt, unsigned long ptlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
932 unsigned char *ct,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
933 unsigned char *tag, unsigned long *taglen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
934 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
935
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
936 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
937 can be any arbitrary length.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
938
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
939 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
940 int ocb_decrypt_verify_memory(int cipher,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
941 const unsigned char *key, unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
942 const unsigned char *nonce,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
943 const unsigned char *ct, unsigned long ctlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
944 unsigned char *pt,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
945 const unsigned char *tag, unsigned long taglen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
946 int *res);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
947 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
948
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
949 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
950 appropriately.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
951
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
952
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
953
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
954 \chapter{One-Way Cryptographic Hash Functions}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
955 \section{Core Functions}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
956
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
957 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
958 To initialize hash XXX (where XXX is the name) call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
959 \index{Hash Functions}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
960 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
961 void XXX_init(hash_state *md);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
962 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
963
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
964 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
965 message being hashed call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
966 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
967 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
968 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
969
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
970 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
971 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
972 (hash output) will be the same. For example, this means that:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
973 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
974 md5_process(&md, "hello ", 6);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
975 md5_process(&md, "world", 5);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
976 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
977 Will produce the same message digest as the single call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
978 \index{Message Digest}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
979 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
980 md5_process(&md, "hello world", 11);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
981 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
982
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
983 To finally get the message digest (the hash) call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
984 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
985 int XXX_done(hash_state *md,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
986 unsigned char *out);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
987 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
988
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
989 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
990 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
991 will wipe the ``md'' variable before returning automatically.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
992
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
993 To test a hash function call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
994 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
995 int XXX_test(void);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
996 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
997
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
998 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
999 example snippet that hashes a message with md5 is given below.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1000 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1001 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1002 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1003 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1004 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1005 hash_state md;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1006 unsigned char *in = "hello world", out[16];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1007
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1008 /* setup the hash */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1009 md5_init(&md);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1010
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1011 /* add the message */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1012 md5_process(&md, in, strlen(in));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1013
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1014 /* get the hash in out[0..15] */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1015 md5_done(&md, out);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1016
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1017 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1018 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1019 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1020 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1021
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1022 \section{Hash Descriptors}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1023 \index{Hash Descriptors}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1024 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
1025 are defined by:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1026 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1027 struct _hash_descriptor {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1028 char *name;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1029 unsigned long hashsize; /* digest output size in bytes */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1030 unsigned long blocksize; /* the block size the hash uses */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1031 void (*init) (hash_state *);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1032 int (*process)(hash_state *, const unsigned char *, unsigned long);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1033 int (*done) (hash_state *, unsigned char *);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1034 int (*test) (void);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1035 };
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1036 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1037
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1038 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
1039 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
1040 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
1041 position in the descriptor table of the hash.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1042
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1043 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
1044 \begin{small}
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 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1047 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1048 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1049 unsigned char buffer[100], hash[MAXBLOCKSIZE];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1050 int idx, x;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1051 hash_state md;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1052
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1053 /* register hashes .... */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1054 if (register_hash(&md5_desc) == -1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1055 printf("Error registering MD5.\n");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1056 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1057 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1058
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1059 /* register other hashes ... */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1060
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1061 /* prompt for name and strip newline */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1062 printf("Enter hash name: \n");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1063 fgets(buffer, sizeof(buffer), stdin);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1064 buffer[strlen(buffer) - 1] = 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1065
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1066 /* get hash index */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1067 idx = find_hash(buffer);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1068 if (idx == -1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1069 printf("Invalid hash name!\n");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1070 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1071 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1072
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1073 /* hash input until blank line */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1074 hash_descriptor[idx].init(&md);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1075 while (fgets(buffer, sizeof(buffer), stdin) != NULL)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1076 hash_descriptor[idx].process(&md, buffer, strlen(buffer));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1077 hash_descriptor[idx].done(&md, hash);
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 /* dump to screen */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1080 for (x = 0; x < hash_descriptor[idx].hashsize; x++)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1081 printf("%02x ", hash[x]);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1082 printf("\n");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1083 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1084 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1085 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1086 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1087
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1088 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
1089 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
1090
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1091 There are three helper functions as well:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1092 \index{hash\_memory()} \index{hash\_file()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1093 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1094 int hash_memory(int hash, const unsigned char *data,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1095 unsigned long len, unsigned char *dst,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1096 unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1097
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1098 int hash_file(int hash, const char *fname,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1099 unsigned char *dst,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1100 unsigned long *outlen);
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 int hash_filehandle(int hash, FILE *in,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1103 unsigned char *dst, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1104 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1105
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1106 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
1107 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
1108 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
1109 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
1110 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
1111 the file position when finished.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1112
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1113 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
1114 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1115 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1116 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1117 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1118 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1119 int idx, errno;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1120 unsigned long len;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1121 unsigned char out[MAXBLOCKSIZE];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1122
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1123 /* register the hash */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1124 if (register_hash(&md5_desc) == -1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1125 printf("Error registering MD5.\n");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1126 return -1;
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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1129 /* get the index of the hash */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1130 idx = find_hash("md5");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1131
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1132 /* call the hash */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1133 len = sizeof(out);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1134 if ((errno = hash_memory(idx, "hello world", 11, out, &len)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1135 printf("Error hashing data: %s\n", error_to_string(errno));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1136 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1137 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1138 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1139 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1140 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1141 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1142
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1143 The following hashes are provided as of this release:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1144 \begin{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1145 \begin{tabular}{|c|c|c|}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1146 \hline Name & Descriptor Name & Size of Message Digest (bytes) \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1147 \hline WHIRLPOOL & whirlpool\_desc & 64 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1148 \hline SHA-512 & sha512\_desc & 64 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1149 \hline SHA-384 & sha384\_desc & 48 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1150 \hline SHA-256 & sha256\_desc & 32 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1151 \hline SHA-224 & sha224\_desc & 28 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1152 \hline TIGER-192 & tiger\_desc & 24 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1153 \hline SHA-1 & sha1\_desc & 20 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1154 \hline RIPEMD-160 & rmd160\_desc & 20 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1155 \hline RIPEMD-128 & rmd128\_desc & 16 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1156 \hline MD5 & md5\_desc & 16 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1157 \hline MD4 & md4\_desc & 16 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1158 \hline MD2 & md2\_desc & 16 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1159 \hline
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1160 \end{tabular}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1161 \end{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1162
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1163 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
1164 work exactly like those of the cipher registration code. The functions are:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1165 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1166 int register_hash(const struct _hash_descriptor *hash);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1167 int unregister_hash(const struct _hash_descriptor *hash);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1168 \end{verbatim}
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 \subsection{Notice}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1171 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
1172 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
1173 (e.g. Yarrow).
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 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
1176 for all purposes you would normally use a hash for.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1177
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1178 \chapter{Message Authentication Codes}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1179 \section{HMAC Protocol}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1180 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
1181 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
1182 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
1183 eavesdropper will not be able to verify the authenticity of a message.
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 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
1186 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
1187 chars. The initialization routine is:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1188 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1189 int hmac_init(hmac_state *hmac, int hash,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1190 const unsigned char *key, unsigned long keylen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1191 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1192 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
1193 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
1194 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:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1195 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1196 int hmac_process(hmac_state *hmac, const unsigned char *buf,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1197 unsigned long len);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1198 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1199 ``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
1200 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
1201 are finished with the HMAC process you must call the following function to get the HMAC code:
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 int hmac_done(hmac_state *hmac, unsigned char *hashOut,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1204 unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1205 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1206 ``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
1207 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
1208 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
1209 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
1210
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1211 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
1212 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
1213 calling the three step process yourself.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1214
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1215 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1216 int hmac_memory(int hash, const unsigned char *key, unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1217 const unsigned char *data, unsigned long len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1218 unsigned char *dst, unsigned long *dstlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1219 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1220 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
1221 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
1222 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
1223 to the size of the destination buffer before calling this function. Similarly for files there is the following function:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1224 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1225 int hmac_file(int hash, const char *fname, const unsigned char *key,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1226 unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1227 unsigned char *dst, unsigned long *dstlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1228 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1229 ``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
1230 ``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
1231 result should be stored.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1232
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1233 To test if the HMAC code is working there is the following function:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1234 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1235 int hmac_test(void);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1236 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1237 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
1238 HMAC system is given below.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1239
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1240 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1241 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1242 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1243 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1244 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1245 int idx, errno;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1246 hmac_state hmac;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1247 unsigned char key[16], dst[MAXBLOCKSIZE];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1248 unsigned long dstlen;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1249
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1250 /* register SHA-1 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1251 if (register_hash(&sha1_desc) == -1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1252 printf("Error registering SHA1\n");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1253 return -1;
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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1256 /* get index of SHA1 in hash descriptor table */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1257 idx = find_hash("sha1");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1258
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1259 /* we would make up our symmetric key in "key[]" here */
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 /* start the HMAC */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1262 if ((errno = hmac_init(&hmac, idx, key, 16)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1263 printf("Error setting up hmac: %s\n", error_to_string(errno));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1264 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1265 }
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 /* process a few octets */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1268 if((errno = hmac_process(&hmac, "hello", 5) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1269 printf("Error processing hmac: %s\n", error_to_string(errno));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1270 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1271 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1272
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1273 /* get result (presumably to use it somehow...) */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1274 dstlen = sizeof(dst);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1275 if ((errno = hmac_done(&hmac, dst, &dstlen)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1276 printf("Error finishing hmac: %s\n", error_to_string(errno));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1277 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1278 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1279 printf("The hmac is %lu bytes long\n", dstlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1280
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1281 /* return */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1282 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1283 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1284 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1285 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1286
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1287 \section{OMAC Support}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1288 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
1289 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
1290 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
1291
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1292 To start an OMAC state you call
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1293
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1294 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1295 int omac_init(omac_state *omac, int cipher,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1296 const unsigned char *key, unsigned long keylen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1297 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1298 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
1299 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
1300 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
1301
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1302 To send data through the algorithm call
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1303 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1304 int omac_process(omac_state *state,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1305 const unsigned char *buf, unsigned long len);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1306 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1307 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
1308 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
1309
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1310 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1311 omac_process(&mystate, "hello", 5);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1312 omac_process(&mystate, " world", 6);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1313 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1314
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1315 Would produce the same result as,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1316
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1317 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1318 omac_process(&mystate, "hello world", 11);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1319 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1320
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1321 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
1322
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1323 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1324 int omac_done(omac_state *state,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1325 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1326 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1327 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
1328 ``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
1329 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
1330 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
1331 size to show how many bytes were actually used.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1332
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1333 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
1334 following function.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1335
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1336 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1337 int omac_memory(int cipher,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1338 const unsigned char *key, unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1339 const unsigned char *msg, unsigned long msglen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1340 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1341 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1342 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
1343 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
1344 rules as omac\_done.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1345
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1346 To OMAC a file use
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1347 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1348 int omac_file(int cipher,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1349 const unsigned char *key, unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1350 const char *filename,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1351 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1352 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1353
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1354 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
1355 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
1356 the same rules as omac\_done.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1357
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1358 To test if the OMAC code is working there is the following function:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1359 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1360 int omac_test(void);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1361 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1362 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
1363 OMAC system is given below.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1364
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1365 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1366 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1367 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1368 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1369 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1370 int idx, err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1371 omac_state omac;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1372 unsigned char key[16], dst[MAXBLOCKSIZE];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1373 unsigned long dstlen;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1374
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1375 /* register Rijndael */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1376 if (register_cipher(&rijndael_desc) == -1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1377 printf("Error registering Rijndael\n");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1378 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1379 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1380
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1381 /* get index of Rijndael in cipher descriptor table */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1382 idx = find_cipher("rijndael");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1383
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1384 /* we would make up our symmetric key in "key[]" here */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1385
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1386 /* start the OMAC */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1387 if ((err = omac_init(&omac, idx, key, 16)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1388 printf("Error setting up omac: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1389 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1390 }
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 /* process a few octets */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1393 if((err = omac_process(&omac, "hello", 5) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1394 printf("Error processing omac: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1395 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1396 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1397
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1398 /* get result (presumably to use it somehow...) */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1399 dstlen = sizeof(dst);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1400 if ((err = omac_done(&omac, dst, &dstlen)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1401 printf("Error finishing omac: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1402 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1403 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1404 printf("The omac is %lu bytes long\n", dstlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1405
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1406 /* return */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1407 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1408 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1409 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1410 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1411
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1412 \section{PMAC Support}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1413 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
1414 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
1415 API as the provided OMAC code.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1416
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1417 A PMAC state is initialized with the following.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1418
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1419 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1420 int pmac_init(pmac_state *pmac, int cipher,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1421 const unsigned char *key, unsigned long keylen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1422 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1423 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
1424 must have a 64 or 128 bit block size (e.x. AES).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1425
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1426 To MAC data simply send it through the process function.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1427
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1428 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1429 int pmac_process(pmac_state *state,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1430 const unsigned char *buf, unsigned long len);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1431 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1432 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
1433 data. For example,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1434
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1435 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1436 pmac_process(&mystate, "hello", 5);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1437 pmac_process(&mystate, " world", 6);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1438 \end{verbatim}
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 Would produce the same result as,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1441
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1442 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1443 pmac_process(&mystate, "hello world", 11);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1444 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1445
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1446 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
1447
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1448 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1449 int pmac_done(pmac_state *state,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1450 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1451 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1452 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
1453 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
1454
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1455 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
1456 following function.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1457
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1458 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1459 int pmac_memory(int cipher,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1460 const unsigned char *key, unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1461 const unsigned char *msg, unsigned long msglen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1462 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1463 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1464 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
1465 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
1466 rules as omac\_done.
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 To PMAC a file use
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1469 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1470 int pmac_file(int cipher,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1471 const unsigned char *key, unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1472 const char *filename,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1473 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1474 \end{verbatim}
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 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
1477 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
1478 the same rules as omac\_done.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1479
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1480 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
1481 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1482 int pmac_test(void);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1483 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1484 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
1485
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1486
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1487 \chapter{Pseudo-Random Number Generators}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1488 \section{Core Functions}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1489
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1490 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
1491 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
1492 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
1493 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1494 int XXX_start(prng_state *prng);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1495 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1496
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1497 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
1498 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
1499 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
1500 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1501 int XXX_add_entropy(const unsigned char *in, unsigned long len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1502 prng_state *prng);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1503 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1504
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1505 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
1506 function to put the entropy into action.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1507 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1508 int XXX_ready(prng_state *prng);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1509 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1510
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1511 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
1512 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1513 unsigned long XXX_read(unsigned char *out, unsigned long len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1514 prng_state *prng);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1515 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1516
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1517 Which returns the number of bytes read from the PRNG.
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 \subsection{Remarks}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1520
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1521 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
1522 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
1523 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
1524 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
1525
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1526 \subsection{Example}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1527
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1528 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
1529 the entropy added is not random.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1530
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1531 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1532 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1533 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1534 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1535 prng_state prng;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1536 unsigned char buf[10];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1537 int err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1538
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1539 /* start it */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1540 if ((err = yarrow_start(&prng)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1541 printf("Start error: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1542 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1543 /* add entropy */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1544 if ((err = yarrow_add_entropy("hello world", 11, &prng)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1545 printf("Add_entropy error: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1546 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1547 /* ready and read */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1548 if ((err = yarrow_ready(&prng)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1549 printf("Ready error: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1550 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1551 printf("Read %lu bytes from yarrow\n", yarrow_read(buf, 10, &prng));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1552 return 0;
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 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1555
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1556 \section{PRNG Descriptors}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1557 \index{PRNG Descriptor}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1558 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
1559 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1560 struct _prng_descriptor {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1561 char *name;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1562 int (*start) (prng_state *);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1563 int (*add_entropy)(const unsigned char *, unsigned long, prng_state *);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1564 int (*ready) (prng_state *);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1565 unsigned long (*read)(unsigned char *, unsigned long len, prng_state *);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1566 };
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1567 \end{verbatim}
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 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
1570 the position in the prng\_descriptor array.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1571
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1572 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
1573 exactly as those for the cipher registry functions. They are:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1574 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1575 int register_prng(const struct _prng_descriptor *prng);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1576 int unregister_prng(const struct _prng_descriptor *prng);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1577 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1578
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1579 \subsubsection{PRNGs Provided}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1580 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
1581 library.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1582
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1583 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
1584 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
1585 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
1586 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
1587 how to encrypt a buffer with RC4:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1588
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1589 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1590 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1591 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1592 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1593 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1594 prng_state prng;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1595 unsigned char buf[32];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1596 int err;
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 if ((err = rc4_start(&prng)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1599 printf("RC4 init error: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1600 exit(-1);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1601 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1602
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1603 /* use ``key'' as the key */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1604 if ((err = rc4_add_entropy("key", 3, &prng)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1605 printf("RC4 add entropy error: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1606 exit(-1);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1607 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1608
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1609 /* setup RC4 for use */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1610 if ((err = rc4_ready(&prng)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1611 printf("RC4 ready error: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1612 exit(-1);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1613 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1614
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1615 /* encrypt buffer */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1616 strcpy(buf,"hello world");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1617 if (rc4_read(buf, 11, &prng) != 11) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1618 printf("RC4 read error\n");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1619 exit(-1);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1620 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1621 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1622 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1623 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1624 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1625 To decrypt you have to do the exact same steps.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1626
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1627 \section{The Secure RNG}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1628 \index{Secure RNG}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1629 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
1630 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
1631 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
1632 entropy needed to seed the PRNG a hard task.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1633
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1634 There is one small function that may help on certain platforms:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1635 \index{rng\_get\_bytes()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1636 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1637 unsigned long rng_get_bytes(unsigned char *buf, unsigned long len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1638 void (*callback)(void));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1639 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1640
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1641 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
1642 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
1643 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
1644 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
1645 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
1646 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
1647 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
1648 \index{rng\_make\_prng()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1649 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1650 int rng_make_prng(int bits, int wprng, prng_state *prng,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1651 void (*callback)(void));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1652 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1653 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
1654 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
1655 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
1656
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1657 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1658 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1659 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1660 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1661 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1662 ecc_key mykey;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1663 prng_state prng;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1664 int err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1665
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1666 /* register yarrow */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1667 if (register_prng(&yarrow_desc) == -1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1668 printf("Error registering Yarrow\n");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1669 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1670 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1671
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1672 /* setup the PRNG */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1673 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
1674 printf("Error setting up PRNG, %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1675 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1676 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1677
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1678 /* make a 192-bit ECC key */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1679 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
1680 printf("Error making key: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1681 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1682 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1683 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1684 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1685 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1686 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1687
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1688 \subsection{The Secure PRNG Interface}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1689 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
1690 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
1691 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
1692 the previous example using this PRNG.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1693
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1694 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1695 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1696 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1697 int main(void)
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 ecc_key mykey;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1700 int err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1701
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1702 /* register SPRNG */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1703 if (register_prng(&sprng_desc) == -1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1704 printf("Error registering SPRNG\n");
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1705 return -1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1706 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1707
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1708 /* make a 192-bit ECC key */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1709 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
1710 printf("Error making key: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1711 return -1;
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 return 0;
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 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1716 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1717
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1718 \chapter{RSA Public Key Cryptography}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1719 \textbf{Note: } \textit{This chapter on PKCS \#1 RSA will replace the older chapter on RSA (The current chapter nine) in subsequent
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1720 releases of the library. Users are encouraged to stop using the LibTomCrypt style padding functions.}
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 \section{PKCS \#1 Encryption}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1723
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1724 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
1725 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
1726
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1727 \subsection{OAEP Encoding}
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 \begin{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1730 int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1731 const unsigned char *lparam, unsigned long lparamlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1732 unsigned long modulus_bitlen, int hash_idx,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1733 int prng_idx, prng_state *prng,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1734 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1735 \end{alltt}
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 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
1738 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
1739 ``lparam'' can be set to \textbf{NULL}.
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 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
1742 ``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
1743 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
1744 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
1745 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
1746
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1747 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
1748 $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
1749
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1750 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
1751 rsa\_exptmod() to encrypt it.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1752
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1753 \subsection{OAEP Decoding}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1754
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1755 \begin{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1756 int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1757 const unsigned char *lparam, unsigned long lparamlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1758 unsigned long modulus_bitlen, int hash_idx,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1759 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1760 \end{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1761
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1762 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
1763 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
1764 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
1765 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
1766 during encoding.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1767
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1768 If the function succeeds it decodes the OAEP encoded message into ``out'' of length ``outlen''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1769
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1770 \section{PKCS \#1 Digital Signatures}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1771
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1772 \subsection{PSS Encoding}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1773 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
1774
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1775 \begin{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1776 int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1777 unsigned long saltlen, int hash_idx,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1778 int prng_idx, prng_state *prng,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1779 unsigned long modulus_bitlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1780 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1781 \end{alltt}
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 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
1784 ``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
1785 ``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
1786 number generator information required for the salt.
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 Similar to OAEP encoding ``modulus\_bitlen'' is the size of the RSA modulus. It limits the size of the salt. If $m$ is the length
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1789 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
1790
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1791 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
1792
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1793 \subsection{PSS Decoding}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1794
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1795 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
1796
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1797 \begin{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1798 int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1799 const unsigned char *sig, unsigned long siglen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1800 unsigned long saltlen, int hash_idx,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1801 unsigned long modulus_bitlen, int *res);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1802 \end{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1803 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
1804 ``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
1805 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
1806
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1807 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
1808
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1809 \chapter{Password Based Cryptography}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1810 \section{PKCS \#5}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1811 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
1812 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
1813 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
1814
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1815 \section{Algorithm One}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1816 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
1817 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
1818 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
1819
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1820 \begin{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1821 int pkcs_5_alg1(const unsigned char *password, unsigned long password_len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1822 const unsigned char *salt,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1823 int iteration_count, int hash_idx,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1824 unsigned char *out, unsigned long *outlen)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1825 \end{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1826 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
1827 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
1828 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
1829
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1830 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
1831 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
1832
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1833 \section{Algorithm Two}
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 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
1836 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
1837 from a single password and invokation of this algorithm.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1838
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1839 \begin{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1840 int pkcs_5_alg2(const unsigned char *password, unsigned long password_len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1841 const unsigned char *salt, unsigned long salt_len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1842 int iteration_count, int hash_idx,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1843 unsigned char *out, unsigned long *outlen)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1844 \end{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1845 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
1846 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
1847 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
1848 ``outlen'' is stored in ``out''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1849
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1850 \begin{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1851 /* demo to show how to make session state material from a password */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1852 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1853 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1854 \{
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1855 unsigned char password[100], salt[100],
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1856 cipher_key[16], cipher_iv[16],
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1857 mac_key[16], outbuf[48];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1858 int err, hash_idx;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1859 unsigned long outlen, password_len, salt_len;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1860
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1861 /* register hash and get it's idx .... */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1862
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1863 /* get users password and make up a salt ... */
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 /* create the material (100 iterations in algorithm) */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1866 outlen = sizeof(outbuf);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1867 if ((err = pkcs_5_alg2(password, password_len, salt, salt_len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1868 100, hash_idx, outbuf, &outlen)) != CRYPT_OK) \{
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1869 /* error handle */
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 /* now extract it */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1873 memcpy(cipher_key, outbuf, 16);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1874 memcpy(cipher_iv, outbuf+16, 16);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1875 memcpy(mac_key, outbuf+32, 16);
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 /* use material (recall to store the salt in the output) */
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{alltt}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1880
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1881 \chapter{RSA Routines}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1882
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1883 \textbf{Note: } \textit{This chapter has been marked for removal. In particular any function that uses the LibTomCrypt style
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1884 RSA padding (e.g. rsa\_pad() rsa\_signpad()) will be removed in the v0.96 release cycle. The functions like rsa\_make\_key() and
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1885 rsa\_exptmod() will stay but may be slightly modified. }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1886
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1887 \section{Background}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1888
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1889 RSA is a public key algorithm that is based on the inability to find the ``e-th'' root modulo a composite of unknown
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1890 factorization. Normally the difficulty of breaking RSA is associated with the integer factoring problem but they are
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1891 not strictly equivalent.
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 The system begins with with two primes $p$ and $q$ and their product $N = pq$. The order or ``Euler totient'' of the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1894 multiplicative sub-group formed modulo $N$ is given as $\phi(N) = (p - 1)(q - 1)$ which can be reduced to
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1895 $\mbox{lcm}(p - 1, q - 1)$. The public key consists of the composite $N$ and some integer $e$ such that
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1896 $\mbox{gcd}(e, \phi(N)) = 1$. The private key consists of the composite $N$ and the inverse of $e$ modulo $\phi(N)$
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1897 often simply denoted as $de \equiv 1\mbox{ }(\mbox{mod }\phi(N))$.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1898
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1899 A person who wants to encrypt with your public key simply forms an integer (the plaintext) $M$ such that
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1900 $1 < M < N-2$ and computes the ciphertext $C = M^e\mbox{ }(\mbox{mod }N)$. Since finding the inverse exponent $d$
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1901 given only $N$ and $e$ appears to be intractable only the owner of the private key can decrypt the ciphertext and compute
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1902 $C^d \equiv \left (M^e \right)^d \equiv M^1 \equiv M\mbox{ }(\mbox{mod }N)$. Similarly the owner of the private key
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1903 can sign a message by ``decrypting'' it. Others can verify it by ``encrypting'' it.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1904
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1905 Currently RSA is a difficult system to cryptanalyze provided that both primes are large and not close to each other.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1906 Ideally $e$ should be larger than $100$ to prevent direct analysis. For example, if $e$ is three and you do not pad
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1907 the plaintext to be encrypted than it is possible that $M^3 < N$ in which case finding the cube-root would be trivial.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1908 The most often suggested value for $e$ is $65537$ since it is large enough to make such attacks impossible and also well
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1909 designed for fast exponentiation (requires 16 squarings and one multiplication).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1910
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1911 It is important to pad the input to RSA since it has particular mathematical structure. For instance
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1912 $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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1913 to have a forged signature for. Simply get the signatures for $M_1$ and $M_2$ on their own and multiply the result
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1914 together. Similar tricks can be used to deduce plaintexts from ciphertexts. It is important not only to sign
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1915 the hash of documents only but also to pad the inputs with data to remove such structure.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1916
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1917 \section{Core Functions}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1918
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1919 For RSA routines a single ``rsa\_key'' structure is used. To make a new RSA key call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1920 \index{rsa\_make\_key()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1921 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1922 int rsa_make_key(prng_state *prng,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1923 int wprng, int size,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1924 long e, rsa_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1925 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1926
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1927 Where ``wprng'' is the index into the PRNG descriptor array. ``size'' is the size in bytes of the RSA modulus desired.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1928 ``e'' is the encryption exponent desired, typical values are 3, 17, 257 and 65537. I suggest you stick with 65537 since its big
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1929 enough to prevent trivial math attacks and not super slow. ``key'' is where the key is placed. All keys must be at
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1930 least 128 bytes and no more than 512 bytes in size (\textit{that is from 1024 to 4096 bits}).
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1931
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1932 Note that the ``rsa\_make\_key()'' function allocates memory at runtime when you make the key. Make sure to call
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1933 ``rsa\_free()'' (see below) when you are finished with the key. If ``rsa\_make\_key()'' fails it will automatically
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1934 free the ram allocated itself.
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 There are three types of RSA keys. The types are {\bf PK\_PRIVATE\_OPTIMIZED}, {\bf PK\_PRIVATE} and {\bf PK\_PUBLIC}. The first
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1937 two are private keys where the ``optimized'' type uses the Chinese Remainder Theorem to speed up decryption/signatures. By
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1938 default all new keys are of the ``optimized'' type. The non-optimized private type is provided for backwards compatibility
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1939 as well as to save space since the optimized key requires about four times as much memory.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1940
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1941 To do raw work with the RSA function call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1942 \index{rsa\_exptmod()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1943 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1944 int rsa_exptmod(const unsigned char *in, unsigned long inlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1945 unsigned char *out, unsigned long *outlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1946 int which, rsa_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1947 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1948 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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1949 in ``out'' and the size of the result in ``outlen''. ``which'' is set to {\bf PK\_PUBLIC} to use ``e''
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1950 (i.e. for encryption/verifying) and set to {\bf PK\_PRIVATE} to use ``d'' as the exponent (i.e. for decrypting/signing).
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 Note that this function does not perform padding on the input (as per PKCS). So if you send in ``0000001'' you will
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1953 get ``01'' back (when you do the opposite operation). Make sure you pad properly which usually involves setting the msb to
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1954 a non-zero value.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1955
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1956 \section{Packet Routines}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1957 To encrypt or decrypt a symmetric key using RSA the following functions are provided. The idea is that you make up
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1958 a random symmetric key and use that to encode your message. By RSA encrypting the symmetric key you can send it to a
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1959 recipient who can RSA decrypt it and symmetrically decrypt the message.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1960 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1961 int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1962 unsigned char *outkey, unsigned long *outlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1963 prng_state *prng, int wprng, rsa_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1964 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1965 This function is used to RSA encrypt a symmetric to share with another user. The symmetric key and its length are
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1966 passed as ``inkey'' and ``inlen'' respectively. The symmetric key is limited to a range of 8 to 32 bytes
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1967 (\textit{64 to 256 bits}). The RSA encrypted packet is stored in ``outkey'' and will be of length ``outlen'' bytes. The
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1968 value of ``outlen'' must be originally set to the size of the output buffer.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1969
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1970 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1971 int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1972 unsigned char *outkey, unsigned long *keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1973 rsa_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1974 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1975
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1976 This function will decrypt an RSA packet to retrieve the original symmetric key encrypted with rsa\_encrypt\_key().
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1977 Similarly to sign or verify a hash of a message the following two messages are provided. The idea is to hash your message
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1978 then use these functions to RSA sign the hash.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1979 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1980 int rsa_sign_hash(const unsigned char *in, unsigned long inlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1981 unsigned char *out, unsigned long *outlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1982 rsa_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1983
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1984 int rsa_verify_hash(const unsigned char *sig, unsigned long siglen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1985 const unsigned char *hash, int *stat, rsa_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1986 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1987 For ``rsa\_sign\_hash'' the input is intended to be the hash of a message the user wants to sign. The output is the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1988 RSA signed packet which ``rsa\_verify\_hash'' can verify. For the verification function ``sig'' is the RSA signature
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1989 and ``hash'' is the hash of the message. The integer ``stat'' is set to non-zero if the signature is valid or zero
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1990 otherwise.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1991
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1992 To import/export RSA keys as a memory buffer (e.g. to store them to disk) call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1993 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1994 int rsa_export(unsigned char *out, unsigned long *outlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1995 int type, rsa_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1996
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1997 int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1998 \end{verbatim}
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 The ``type'' parameter is {\bf PK\_PUBLIC}, {\bf PK\_PRIVATE} or {\bf PK\_PRIVATE\_OPTIMIZED} to export either a public or
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2001 private key. The latter type will export a key with the optimized parameters. To free the memory used by an RSA key call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2002 \index{rsa\_free()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2003 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2004 void rsa_free(rsa_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2005 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2006
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2007 Note that if the key fails to ``rsa\_import()'' you do not have to free the memory allocated for it.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2008
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2009 \section{Remarks}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2010 It is important that you match your RSA key size with the function you are performing. The internal padding for both
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2011 signatures and encryption triple the size of the plaintext. This means to encrypt or sign
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2012 a message of N bytes you must have a modulus of 1+3N bytes. Note that this doesn't affect the length of the plaintext
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2013 you pass into functions like rsa\_encrypt(). This restriction applies only to data that is passed through the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2014 internal RSA routines directly directly.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2015
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2016 The following table gives the size requirements for various hashes.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2017 \begin{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2018 \begin{tabular}{|c|c|c|}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2019 \hline Name & Size of Message Digest (bytes) & RSA Key Size (bits)\\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2020 \hline SHA-512 & 64 & 1544\\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2021 \hline SHA-384 & 48 & 1160 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2022 \hline SHA-256 & 32 & 776\\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2023 \hline TIGER-192 & 24 & 584\\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2024 \hline SHA-1 & 20 & 488\\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2025 \hline MD5 & 16 & 392\\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2026 \hline MD4 & 16 & 392\\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2027 \hline
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2028 \end{tabular}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2029 \end{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2030
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2031 The symmetric ciphers will use at a maximum a 256-bit key which means at the least a 776-bit RSA key is
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2032 required to use all of the symmetric ciphers with the RSA routines. If you want to use any of the large size
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2033 message digests (SHA-512 or SHA-384) you will have to use a larger key. Or to be simple just make 2048-bit or larger
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2034 keys. None of the hashes will have problems with such key sizes.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2035
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2036 \chapter{Diffie-Hellman Key Exchange}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2037
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2038 \section{Background}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2039
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2040 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
2041 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
2042 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
2043
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2044 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
2045 ``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
2046 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
2047 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
2048
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2049 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
2050 $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
2051 $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
2052 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
2053 symmetric cipher.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2054
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2055 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
2056 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
2057 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
2058 $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
2059
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2060 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
2061 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
2062 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
2063
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2064 \section{Core Functions}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2065
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2066 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
2067 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
2068 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
2069 make a Diffie-Hellman private key pair:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2070 \index{dh\_make\_key()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2071 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2072 int dh_make_key(prng_state *prng, int wprng,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2073 int keysize, dh_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2074 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2075 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
2076 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
2077 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
2078 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
2079 ``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
2080 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
2081 $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
2082 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
2083 hard.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2084
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2085 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
2086 over communication mediums.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2087
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2088 \index{dh\_export()} \index{dh\_import()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2089 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2090 int dh_export(unsigned char *out, unsigned long *outlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2091 int type, dh_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2092
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2093 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
2094 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2095
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2096 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
2097 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
2098 ``dh\_key'' using:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2099 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2100 void dh_free(dh_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2101 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2102 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
2103 with the other user using:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2104 \index{dh\_shared\_secret()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2105 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2106 int dh_shared_secret(dh_key *private_key,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2107 dh_key *public_key,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2108 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2109 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2110
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2111 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
2112 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
2113 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
2114 key:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2115 \index{dh\_get\_size()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2116 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2117 int dh_get_size(dh_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2118 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2119 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
2120
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2121 \subsection{Remarks on Usage}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2122 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
2123 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
2124 \newpage
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2125 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2126 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2127 int establish_secure_socket(int sock, int mode, unsigned char *key,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2128 prng_state *prng, int wprng)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2129 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2130 unsigned char buf[4096], buf2[4096];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2131 unsigned long x, len;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2132 int res, err, inlen;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2133 dh_key mykey, theirkey;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2134
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2135 /* make up our private key */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2136 if ((err = dh_make_key(prng, wprng, 128, &mykey)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2137 return err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2138 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2139
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2140 /* export our key as public */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2141 x = sizeof(buf);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2142 if ((err = dh_export(buf, &x, PK_PUBLIC, &mykey)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2143 res = err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2144 goto done2;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2145 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2146
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2147 if (mode == 0) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2148 /* mode 0 so we send first */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2149 if (send(sock, buf, x, 0) != x) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2150 res = CRYPT_ERROR;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2151 goto done2;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2152 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2153
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2154 /* get their key */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2155 if ((inlen = recv(sock, buf2, sizeof(buf2), 0)) <= 0) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2156 res = CRYPT_ERROR;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2157 goto done2;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2158 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2159 } else {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2160 /* mode >0 so we send second */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2161 if ((inlen = recv(sock, buf2, sizeof(buf2), 0)) <= 0) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2162 res = CRYPT_ERROR;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2163 goto done2;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2164 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2165
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2166 if (send(sock, buf, x, 0) != x) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2167 res = CRYPT_ERROR;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2168 goto done2;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2169 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2170 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2171
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2172 if ((err = dh_import(buf2, inlen, &theirkey)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2173 res = err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2174 goto done2;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2175 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2176
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2177 /* make shared secret */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2178 x = sizeof(buf);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2179 if ((err = dh_shared_secret(&mykey, &theirkey, buf, &x)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2180 res = err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2181 goto done;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2182 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2183
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2184 /* hash it */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2185 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
2186 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
2187 res = err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2188 goto done;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2189 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2190
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2191 /* clean up and return */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2192 res = CRYPT_OK;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2193 done:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2194 dh_free(&theirkey);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2195 done2:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2196 dh_free(&mykey);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2197 zeromem(buf, sizeof(buf));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2198 zeromem(buf2, sizeof(buf2));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2199 return res;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2200 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2201 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2202 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2203 \newpage
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2204 \subsection{Remarks on The Snippet}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2205 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
2206 passed to ``establish\_secure\_socket()''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2207
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2208 \section{Other Diffie-Hellman Functions}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2209 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
2210 available:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2211 \index{dh\_test()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2212 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2213 int dh_test(void);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2214 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2215
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2216 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
2217 function:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2218 \index{dh\_sizes()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2219 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2220 void dh_sizes(int *low, int *high);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2221 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2222 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
2223
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2224 \section{DH Packet}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2225 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
2226 algorithms.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2227 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2228 int dh_encrypt_key(const unsigned char *inkey, unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2229 unsigned char *out, unsigned long *len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2230 prng_state *prng, int wprng, int hash,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2231 dh_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2232
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2233 int dh_decrypt_key(const unsigned char *in, unsigned long inlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2234 unsigned char *outkey, unsigned long *keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2235 dh_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2236 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2237 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
2238 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
2239 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
2240 as the symmetric key you are trying to share.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2241
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2242 Similar to the RSA system you can sign and verify a hash of a message.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2243 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2244 int dh_sign_hash(const unsigned char *in, unsigned long inlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2245 unsigned char *out, unsigned long *outlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2246 prng_state *prng, int wprng, dh_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2247
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2248 int dh_verify_hash(const unsigned char *sig, unsigned long siglen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2249 const unsigned char *hash, unsigned long hashlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2250 int *stat, dh_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2251 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2252
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2253 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
2254 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
2255 to non-zero if the signature passes or zero if it fails.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2256
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2257 \chapter{Elliptic Curve Cryptography}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2258
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2259 \section{Background}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2260 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
2261 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
2262 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
2263 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
2264 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
2265
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2266 The curves in this library are taken from the following website:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2267 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2268 http://csrc.nist.gov/cryptval/dss.htm
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2269 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2270
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2271 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
2272 \begin{equation}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2273 y^2 = x^3 - 3x + b\mbox{ }(\mbox{mod }p)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2274 \end{equation}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2275
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2276 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
2277 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
2278 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
2279 than or equal to 256-bits is sufficient for long term security.
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{Core Functions}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2282
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2283 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
2284 \index{ecc\_make\_key()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2285 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2286 int ecc_make_key(prng_state *prng, int wprng,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2287 int keysize, ecc_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2288 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2289
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2290 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
2291 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
2292 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
2293 To free the ram allocated by a key call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2294 \index{ecc\_free()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2295 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2296 void ecc_free(ecc_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2297 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2298
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2299 To import and export a key there are:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2300 \index{ecc\_export()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2301 \index{ecc\_import()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2302 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2303 int ecc_export(unsigned char *out, unsigned long *outlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2304 int type, ecc_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2305
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2306 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
2307 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2308 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
2309 with:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2310 \index{ecc\_shared\_secret()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2311 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2312 int ecc_shared_secret(ecc_key *private_key,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2313 ecc_key *public_key,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2314 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2315 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2316 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
2317 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
2318 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
2319 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
2320 of a key.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2321 \index{ecc\_get\_size()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2322 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2323 int ecc_get_size(ecc_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2324 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2325
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2326 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
2327 \index{ecc\_test()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2328 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2329 int ecc_test(void);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2330 void ecc_sizes(int *low, int *high);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2331 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2332 Which both work like their DH counterparts.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2333
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2334 \section{ECC Packet}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2335 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
2336 algorithms.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2337 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2338 int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2339 unsigned char *out, unsigned long *len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2340 prng_state *prng, int wprng, int hash,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2341 ecc_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2342
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2343 int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2344 unsigned char *outkey, unsigned long *keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2345 ecc_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2346 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2347
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2348 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
2349 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
2350 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
2351 as the symmetric key you are trying to share.
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 There are also functions to sign and verify the hash of a message.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2354 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2355 int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2356 unsigned char *out, unsigned long *outlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2357 prng_state *prng, int wprng, ecc_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2358
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2359 int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2360 const unsigned char *hash, unsigned long hashlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2361 int *stat, ecc_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2362 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2363
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2364 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
2365 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
2366 to non-zero if the signature passes or zero if it fails.
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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2369 \section{ECC Keysizes}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2370 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
2371 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
2372 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
2373 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
2374
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2375 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
2376 signatures.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2377
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2378 \chapter{Digital Signature Algorithm}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2379 \section{Introduction}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2380 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
2381 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
2382 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
2383 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
2384
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2385 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
2386 decryption routines are provided.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2387
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2388 \section{Key Generation}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2389 To make a DSA key you must call the following function
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2390 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2391 int dsa_make_key(prng_state *prng, int wprng,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2392 int group_size, int modulus_size,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2393 dsa_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2394 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2395 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
2396 ``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
2397 ``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
2398 $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
2399
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2400 \begin{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2401 \begin{tabular}{|c|c|c|}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2402 \hline \textbf{Bits of Security} & \textbf{group\_size} & \textbf{modulus\_size} \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2403 \hline 80 & 20 & 128 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2404 \hline 120 & 30 & 256 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2405 \hline 140 & 35 & 384 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2406 \hline 160 & 40 & 512 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2407 \hline
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2408 \end{tabular}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2409 \end{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2410
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2411 When you are finished with a DSA key you can call the following function to free the memory used.
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 dsa_free(dsa_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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2416 \section{Key Verification}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2417 Each DSA key is composed of the following variables.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2418
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2419 \begin{enumerate}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2420 \item $q$ a small prime of magnitude $256^{group\_size}$.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2421 \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
2422 \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
2423 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
2424 \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
2425 \item $y = g^x \mbox{ (mod }p\mbox{)}$ the public key.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2426 \end{enumerate}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2427
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2428 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
2429
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2430 \begin{enumerate}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2431 \item $q$ must be prime.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2432 \item $p$ must be prime.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2433 \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
2434 \item $g$ must be less than $p$.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2435 \item $(p-1) \equiv 0 \mbox{ (mod }q\mbox{)}$.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2436 \item $g^q \equiv 1 \mbox{ (mod }p\mbox{)}$.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2437 \item $1 < y < p - 1$
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2438 \item $y^q \equiv 1 \mbox{ (mod }p\mbox{)}$.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2439 \end{enumerate}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2440
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2441 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
2442 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
2443 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
2444 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
2445 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
2446 that $y$ belongs to a multiplicative sub-group of order $q$.
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 The following function will perform these tests.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2449
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2450 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2451 int dsa_verify_key(dsa_key *key, int *stat);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2452 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2453
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2454 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
2455 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
2456
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2457
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 \section{Signatures}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2460 To generate a DSA signature call the following function
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2461
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2462 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2463 int dsa_sign_hash(const unsigned char *in, unsigned long inlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2464 unsigned char *out, unsigned long *outlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2465 prng_state *prng, int wprng, dsa_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2466 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2467
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2468 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
2469 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
2470 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
2471
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2472 To verify a hash created with that function use the following function
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2473
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2474 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2475 int dsa_verify_hash(const unsigned char *sig, unsigned long siglen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2476 const unsigned char *hash, unsigned long inlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2477 int *stat, dsa_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2478 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2479 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
2480 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
2481
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2482 \section{Import and Export}
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 To export a DSA key so that it can be transported use the following function
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2485 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2486 int dsa_export(unsigned char *out, unsigned long *outlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2487 int type,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2488 dsa_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2489 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2490 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
2491 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
2492 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
2493
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2494 To import an exported DSA key use the following function
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 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2497 int dsa_import(const unsigned char *in, unsigned long inlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2498 dsa_key *key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2499 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2500
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2501 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
2502 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
2503
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2504 \chapter{Public Keyrings}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2505 \section{Introduction}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2506 In order to simplify the usage of the public key algorithms a set of keyring routines have been developed. They let the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2507 developer manage asymmetric keys by providing load, save, export, import routines as well as encrypt, decrypt, sign, verify
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2508 routines in a unified API. That is all three types of PK systems can be used within the same keyring with the same API.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2509
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2510 To define types of keys there are four enumerations used globaly:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2511 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2512 enum {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2513 NON_KEY=0,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2514 RSA_KEY,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2515 DH_KEY,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2516 ECC_KEY
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2517 };
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2518 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2519
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2520 To make use of the system the developer has to know how link-lists work. The main structure that the keyring routines use
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2521 is the ``pk\_key'' defined as:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2522 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2523 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2524 typedef struct Pk_key {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2525 int key_type, /* PUBLIC, PRIVATE, PRIVATE_OPTIMIZED */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2526 system; /* RSA, ECC or DH ? */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2527
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2528 char name[MAXLEN], /* various info's about this key */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2529 email[MAXLEN],
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2530 description[MAXLEN];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2531
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2532 unsigned long ID; /* CRC32 of the name/email/description together */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2533
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2534 _pk_key key;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2535
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2536 struct Pk_key *next; /* linked list chain */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2537 } pk_key;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2538 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2539 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2540
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2541 The list is chained via the ``next'' member and terminated with the node of the list that has ``system'' equal to
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2542 {\bf NON\_KEY}.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2543
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2544 \section{The Keyring API}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2545 To initialize a blank keyring the function ``kr\_init()'' is used.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2546 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2547 int kr_init(pk_key **pk);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2548 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2549 You pass it a pointer to a pointer of type ``pk\_key'' where it will allocate ram for one node of the keyring and sets the
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2550 pointer.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2551
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2552 Now instead of calling the PK specific ``make\_key'' functions there is one function that can make all three types of keys.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2553 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2554 int kr_make_key(pk_key *pk, prng_state *prng, int wprng,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2555 int system, int keysize, const char *name,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2556 const char *email, const char *description);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2557 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2558 The ``name'', ``email'' and ``description'' parameters are simply little pieces of information that you can tag along with a
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2559 key. They can each be either blank or any string less than 256 bytes. ``system'' is one of the enumeration elements, that
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2560 is {\bf RSA\_KEY}, {\bf DH\_KEY} or {\bf ECC\_KEY}. ``keysize'' is the size of the key you desire which is regulated by
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2561 the individual systems, for example, RSA keys are limited in keysize from 128 to 512 bytes.
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 To find keys along a keyring there are two functions provided:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2564 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2565 pk_key *kr_find(pk_key *pk, unsigned long ID);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2566
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2567 pk_key *kr_find_name(pk_key *pk, const char *name);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2568 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2569 The first searches by the 32-bit ID provided and the latter checks the name against the keyring. They both return a pointer
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2570 to the node in the ring of a match or {\bf NULL} if no match is found.
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 To export or import a single node of a keyring the two functions are provided:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2573 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2574 int kr_export(pk_key *pk, unsigned long ID, int key_type,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2575 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2576
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2577 int kr_import(pk_key *pk, const unsigned char *in);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2578 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2579 The export function exports the key with an ID provided and of a specific type much like the normal PK export routines. The
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2580 ``key\_type'' is one of {\bf PK\_PUBLIC} or {\bf PK\_PRIVATE}. In this function with RSA keys the type
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2581 {\bf PK\_PRIVATE\_OPTIMIZED} is the same as the {\bf PK\_PRIVATE} type. The import function will read in a packet and
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2582 add it to the keyring.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2583
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2584 To load and save whole keyrings from disk:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2585 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2586 int kr_load(pk_key **pk, FILE *in, symmetric_CTR *ctr);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2587
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2588 int kr_save(pk_key *pk, FILE *out, symmetric_CTR *ctr);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2589 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2590 Both take file pointers to allow the user to pre-append data to the stream. The ``ctr'' parameter should be setup with
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2591 ``ctr\_start'' or set to NULL. This parameter lets the user encrypt the keyring as its written to disk, if it is set
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2592 to NULL the data is written without being encrypted. The load function assumes the list has not been initialized yet
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2593 and will reset the pointer given to it.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2594
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2595 There are the four encrypt, decrypt, sign and verify functions as well
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2596 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2597 int kr_encrypt_key(pk_key *pk, unsigned long ID,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2598 const unsigned char *in, unsigned long inlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2599 unsigned char *out, unsigned long *outlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2600 prng_state *prng, int wprng, int hash);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2601
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2602 int kr_decrypt_key(pk_key *pk, const unsigned char *in,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2603 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2604 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2605
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2606 The kr\_encrypt\_key() routine is designed to encrypt a symmetric key with a specified users public key. The symmetric
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2607 key is then used with a block cipher to encode the message. The recipient can call kr\_decrypt\_key() to get the original
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2608 symmetric key back and decode the message. The hash specified must produce a message digest longer than symmetric key
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2609 provided.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2610
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2611 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2612 int kr_sign_hash(pk_key *pk, unsigned long ID,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2613 const unsigned char *in, unsigned long inlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2614 unsigned char *out, unsigned long *outlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2615 prng_state *prng, int wprng);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2616
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2617 int kr_verify_hash(pk_key *pk, const unsigned char *in,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2618 const unsigned char *hash, unsigned long hashlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2619 int *stat);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2620 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2621
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2622 Similar to the two previous these are used to sign a message digest or verify one. This requires hashing the message
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2623 first then passing the output in.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2624
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2625 To delete keys and clear rings there are:
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 kr_del(pk_key **_pk, unsigned long ID);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2628 int kr_clear(pk_key **pk);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2629 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2630 ``kr\_del'' will try to remove a key with a given ID from the ring and ``kr\_clear'' will completely empty a list and free
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2631 the memory associated with it. Below is small example using the keyring API:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2632
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2633 \begin{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2634 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2635 #include <mycrypt.h>
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2636 int main(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2637 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2638 pk_key *kr;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2639 unsigned char buf[4096], buf2[4096];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2640 unsigned long len;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2641 int err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2642
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2643 /* make a new list */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2644 if ((err = kr_init(&kr)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2645 printf("kr_init: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2646 exit(-1);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2647 }
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 /* add a key to it */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2650 register_prng(&sprng_desc);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2651 if ((err = kr_make_key(kr, NULL, find_prng("sprng"), RSA_KEY, 128,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2652 "TomBot", "[email protected]", "test key")) == CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2653 printf("kr_make_key: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2654 exit(-1);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2655 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2656
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2657 /* export the first key */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2658 len = sizeof(buf);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2659 if ((err = kr_export(kr, kr->ID, PK_PRIVATE, buf, &len)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2660 printf("kr_export: %s\n", error_to_string(err));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2661 exit(-1);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2662 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2663
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 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2666 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2667 \end{small}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2668
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2669 \chapter{$GF(2^w)$ Math Routines}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2670
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2671 The library provides a set of polynomial-basis $GF(2^w)$ routines to help facilitate algorithms such as ECC over such
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2672 fields. Note that the current implementation of ECC in the library is strictly over the integers only. The routines
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2673 are simple enough to use for other purposes outside of ECC.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2674
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2675 At the heart of all of the GF routines is the data type ``gf\_int'. It is simply a type definition for an array of
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2676 $L$ 32-bit words. You can configure the maximum size $L$ of the ``gf\_int'' type by opening the file ``mycrypt.h'' and
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2677 changing ``LSIZE''. Note that if you set it to $n$ then you can only multiply upto two $n \over 2$ bit polynomials without
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2678 an overflow. The type ``gf\_intp'' is associated with a pointer to an ``unsigned long'' as required in the algorithms.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2679
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2680 There are no initialization routines for ``gf\_int'' variables and you can simply use them after declaration. There are five
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2681 low level functions:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2682 \index{gf\_copy()} \index{gf\_zero()} \index{gf\_iszero()} \index{gf\_isone()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2683 \index{gf\_deg()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2684 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2685 void gf_copy(gf_intp a, gf_intp b);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2686 void gf_zero(gf_intp a);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2687 int gf_iszero(gf_intp a);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2688 int gf_isone(gf_intp a);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2689 int gf_deg(gf_intp a);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2690 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2691 There are all fairly self-explanatory. ``gf\_copy(a, b)'' copies the contents of ``a'' into ``b''. ``gf\_zero()'' simply
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2692 zeroes the entire polynomial. ``gf\_iszero()'' tests to see if the polynomial is all zero and ``gf\_isone()'' tests to see
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2693 if the polynomial is equal to the multiplicative identity. ``gf\_deg()'' returns the degree of the polynomial or $-1$ if its
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2694 a zero polynomial.
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 There are five core math routines as well:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2697 \index{gf\_shl()} \index{gf\_shr()} \index{gf\_add()} \index{gf\_mul()} \index{gf\_div()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2698 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2699 void gf_shl(gf_intp a, gf_intp b);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2700 void gf_shr(gf_intp a, gf_intp b);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2701 void gf_add(gf_intp a, gf_intp b, gf_intp c);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2702 void gf_mul(gf_intp a, gf_intp b, gf_intp c);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2703 void gf_div(gf_intp a, gf_intp b, gf_intp q, gf_intp r);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2704 \end{verbatim}
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 Which are all fairly obvious. ``gf\_shl(a,b)'' multiplies the polynomial ``a'' by $x$ and stores it in ``b''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2707 ``gf\_shl(a,b)'' divides the polynomial ``a'' by $x$ and stores it in ``b''. ``gf\_add(a,b,c)'' adds the polynomial
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2708 ``a'' to ``b'' and stores the sum in ``c''. Similarly for ``gf\_mul(a,b,c)''. The ``gf\_div(a,b,q,r)'' function divides
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2709 ``a'' by ``b'' and stores the quotient in ``q'' and the remainder in ``r''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2710
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2711 There are six number theoretic functions as well:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2712 \index{gf\_mod()} \index{gf\_mulmod()} \index{gf\_invmod()} \index{gf\_gcd()} \index{gf\_is\_prime()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2713 \index{gf\_sqrt()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2714 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2715 void gf_mod(gf_intp a, gf_intp m, gf_intp b);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2716 void gf_mulmod(gf_intp a, gf_intp b, gf_intp m, gf_intp c);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2717 void gf_invmod(gf_intp A, gf_intp M, gf_intp B);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2718 void gf_sqrt(gf_intp a, gf_intp m, gf_intp b);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2719 void gf_gcd(gf_intp A, gf_intp B, gf_intp c);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2720 int gf_is_prime(gf_intp a);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2721 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2722
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2723 Which all work similarly except for ``gf\_mulmod(a,b,m,c)'' which computes $c = ab\mbox{ }(\mbox{mod }m)$. The
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2724 ``gf\_is\_prime()'' function returns one if the polynomial is primitive, otherwise it returns zero.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2725
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2726 Finally to read/store a ``gf\_int'' in a binary string use:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2727 \index{gf\_size()} \index{gf\_toraw()} \index{gf\_readraw()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2728 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2729 int gf_size(gf_intp a);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2730 void gf_toraw(gf_intp a, unsigned char *dst);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2731 void gf_readraw(gf_intp a, unsigned char *str, int len);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2732 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2733 Where ``gf\_size()'' returns the size in bytes required for the data. ``gf\_toraw(a,b)'' stores the polynomial in ``b''
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2734 in binary format (endian neutral). ``gf\_readraw(a,b,c)'' reads the binary string in ``b'' back. Note that the length
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2735 you pass it must be the same as returned by ``gf\_size()'' or it will not load correctly.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2736
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2737 \chapter{Miscellaneous}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2738 \section{Base64 Encoding and Decoding}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2739 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
2740 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
2741 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2742 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2743 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2744 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
2745 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
2746 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
2747 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
2748
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2749 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
2750 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
2751 break up the first four characters.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2752
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2753 To encode a binary string in base64 call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2754 \index{base64\_encode()} \index{base64\_decode()}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2755 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2756 int base64_encode(const unsigned char *in, unsigned long len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2757 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2758 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2759 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
2760 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
2761 string call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2762 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2763 int base64_decode(const unsigned char *in, unsigned long len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2764 unsigned char *out, unsigned long *outlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2765 \end{verbatim}
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 \section{The Multiple Precision Integer Library (MPI)}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2768 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
2769 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
2770 for all uses and is distributed freely.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2771
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2772 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
2773 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
2774 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2775 #include <mycrypt.h> /* mycrypt.h includes mpi.h automatically */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2776 int main(void)
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 mp_int bignum;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2779
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2780 /* initialize it */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2781 mp_init(&bignum);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2782
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2783 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2784 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2785 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2786 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
2787 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
2788 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2789 mp_clear(&bignum);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2790 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2791
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2792 The functions also have the basic form of one of the following:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2793 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2794 mp_XXX(mp_int *a);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2795 mp_XXX(mp_int *a, mp_int *b, mp_int *c);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2796 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
2797 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2798
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2799 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
2800 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
2801 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2802 mp_addmod(&a, &b, &m, &c);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2803 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2804
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2805 \subsection{Binary Forms of ``mp\_int'' Variables}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2806
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2807 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
2808 encryption, etc.). LibTomMath includes two functions to help when exporting numbers:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2809 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2810 int mp_raw_size(mp_int *num);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2811 mp_toraw(&num, buf);
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
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2814 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
2815 ``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
2816 ``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
2817 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
2818 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
2819 the sequence:
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 00 FF 30 04
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2822 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2823 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
2824
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2825 To read a binary string back into a ``mp\_int'' call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2826 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2827 mp_read_raw(mp_int *num, unsigned char *str, int len);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2828 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2829 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
2830 length of the binary string.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2831
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2832 \subsection{Primality Testing}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2833 \index{Primality Testing}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2834 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
2835 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
2836 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
2837 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
2838 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
2839 $\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
2840
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2841 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
2842 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
2843 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
2844 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
2845 involved.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2846
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2847 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
2848 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
2849 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
2850 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
2851 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
2852 not equal to $(p - 1)(rs - 1)$.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2853
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2854 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
2855 To test if a ``mp\_int'' is prime call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2856 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2857 int is_prime(mp_int *N, int *result);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2858 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2859 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
2860 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
2861 a random prime call:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2862 \begin{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2863 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
2864 \end{verbatim}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2865 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
2866 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
2867 ``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
2868 is very likely prime.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2869
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2870 \chapter{Programming Guidelines}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2871
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2872 \section{Secure Pseudo Random Number Generators}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2873 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
2874 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
2875 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
2876 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
2877
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2878 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
2879 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
2880 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
2881
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2882 \section{Preventing Trivial Errors}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2883 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
2884 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
2885 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
2886
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2887 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
2888 typos or such can cause algorithms to fail to work as desired.
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 \section{Registering Your Algorithms}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2891 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
2892 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
2893
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2894 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
2895 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
2896 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
2897 need a PRNG can instantly take advantage of it.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2898
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2899 \section{Key Sizes}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2900
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2901 \subsection{Symmetric Ciphers}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2902 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
2903 is not a hard thing todo.
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 \subsection{Assymetric Ciphers}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2906 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
2907 $n$ is estimated to be
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2908 \begin{equation}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2909 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
2910 \end{equation}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2911
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2912 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
2913 is:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2914 \begin{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2915 \begin{tabular}{|c|c|}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2916 \hline RSA/DH Key Size (bits) & Work Factor ($log_2$) \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2917 \hline 512 & 63.92 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2918 \hline 768 & 76.50 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2919 \hline 1024 & 86.76 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2920 \hline 1536 & 103.37 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2921 \hline 2048 & 116.88 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2922 \hline 2560 & 128.47 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2923 \hline 3072 & 138.73 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2924 \hline 4096 & 156.49 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2925 \hline
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2926 \end{tabular}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2927 \end{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2928
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2929 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
2930 $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
2931 \begin{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2932 \begin{tabular}{|c|c|}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2933 \hline ECC Key Size (bits) & Work Factor ($log_2$) \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2934 \hline 160 & 80 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2935 \hline 192 & 96 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2936 \hline 224 & 112 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2937 \hline 256 & 128 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2938 \hline 384 & 192 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2939 \hline 521 & 260.5 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2940 \hline
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2941 \end{tabular}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2942 \end{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2943
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2944 Using the above tables the following suggestions for key sizes seems appropriate:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2945 \begin{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2946 \begin{tabular}{|c|c|c|}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2947 \hline Security Goal & RSA/DH Key Size (bits) & ECC Key Size (bits) \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2948 \hline Short term (less than a year) & 1024 & 160 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2949 \hline Short term (less than five years) & 1536 & 192 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2950 \hline Long Term (less than ten years) & 2560 & 256 \\
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2951 \hline
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2952 \end{tabular}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2953 \end{center}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2954
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2955 \section{Thread Safety}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2956 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
2957 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
2958 code before threads are initiated.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2959
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2960 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
2961 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
2962 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
2963 is create semaphores or mutexes around calls to those functions.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2964
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2965 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
2966 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
2967 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
2968 safety issues within the library.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2969
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2970 \chapter{Configuring the Library}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2971 \section{Introduction}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2972 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
2973 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
2974 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
2975
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2976 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
2977 ``makefile.ps2''.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2978
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2979 \section{mycrypt\_cfg.h}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2980 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
2981 everything the library has to offer it built.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2982
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2983 \subsubsection{ARGTYPE}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2984 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
2985 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
2986 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
2987 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
2988 and no error checking will be performed.
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 \subsubsection{Endianess}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2991 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
2992 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
2993 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
2994 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
2995 as GCC on a PS2 platform.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2996
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2997 \section{The Configure Script}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2998 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
2999
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3000 \subsubsection{X memory routines}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3001 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
3002 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
3003 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
3004 standard C routines.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3005
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3006 \subsubsection{X clock routines}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3007 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
3008 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
3009
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3010 \subsubsection{NO\_FILE}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3011 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
3012 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
3013 file I/O on embedded platforms.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3014
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3015 \subsubsection{CLEAN\_STACK}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3016 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
3017 you have no memory paging with the stack.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3018
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3019 \subsubsection{Symmetric Ciphers, One-way Hashes, PRNGS and Public Key Functions}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3020 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
3021 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
3022 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
3023
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3024 \subsubsection{TWOFISH\_SMALL and TWOFISH\_TABLES}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3025 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
3026 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
3027 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
3028 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
3029 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
3030
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3031 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
3032 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
3033 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
3034 it will not speed up the encryption or decryption functions.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3035
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3036 \subsubsection{SMALL\_CODE}
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3037 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
3038 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
3039
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3040 \end{document}