Merge pull request #54 from libtom/feature/doc
Feature/doc (only crypt.tex + changes)
This commit is contained in:
commit
93317a1d6a
2
.gitignore
vendored
2
.gitignore
vendored
@ -14,6 +14,8 @@ test_*.txt
|
|||||||
tv.txt
|
tv.txt
|
||||||
*_tv.txt
|
*_tv.txt
|
||||||
doxygen/
|
doxygen/
|
||||||
|
doc/crypt.pdf
|
||||||
|
doc/refman.pdf
|
||||||
|
|
||||||
# *nix/windows test executables
|
# *nix/windows test executables
|
||||||
constants
|
constants
|
||||||
|
31
changes
31
changes
@ -1,3 +1,34 @@
|
|||||||
|
XXX, 2014
|
||||||
|
v1.18.0
|
||||||
|
-- Added Camellia block cipher
|
||||||
|
-- Thanks to Karel Miko for cotributing a bunchload of patches and additions, namely
|
||||||
|
OCBv3, DSA and ECC key generation FIPS-186-4 compliance, BASE64-URL encoding,
|
||||||
|
a bugfix in Camellia,
|
||||||
|
-- Larry Bugbee contributed the necessary stuff to more easily call libtomcrypt
|
||||||
|
from a dynamic language like Python, as shown in his pyTomCrypt
|
||||||
|
-- Nikos Mavrogiannopoulos contributed RSA blinding and export of RSA and DSA keys
|
||||||
|
in OpenSSL/GnuTLS compatible format
|
||||||
|
-- Patrick Pelletier contributed a smart volley of patches
|
||||||
|
-- RyanC contributed HKDF including documentation (yippie)
|
||||||
|
-- Added 2-key Triple-DES mode, thanks to Paul Howarth
|
||||||
|
-- Christopher Brown contributed some patches and additions to ASN.1/DER
|
||||||
|
-- Pascal Brand of STMicroelectronics contributed patches regarding the
|
||||||
|
XTS mode and RSA private key operations with keys without CRT parameters
|
||||||
|
-- Applied some patches from the OLPC project regarding PKCS#1 and preventing
|
||||||
|
the hash algorithms from overflowing
|
||||||
|
-- Fixed the Bleichbacher Signature attack in PKCS#1 v1.5 EMSA, thanks to Alex Dent
|
||||||
|
-- Add PKCS#1 testvectors from RSA
|
||||||
|
-- Brought back Diffie-Hellman
|
||||||
|
-- Enabled timing resistant calculations of ECC and RSA operations per default
|
||||||
|
-- Fixed several build issues on FreeBSD, NetBSD, Linux x32 ABI, x86_64 Windows ...
|
||||||
|
-- Documentation (crypt.pdf) is now built deterministically, thanks to Michael Stapelberg
|
||||||
|
-- Removed all compiler warnings
|
||||||
|
-- Improved/extended several tests
|
||||||
|
-- Add SHA512/256 and SHA512/224
|
||||||
|
-- Bugfix multi2
|
||||||
|
-- Bugfix Noekeon
|
||||||
|
-- Bugfix XTEA
|
||||||
|
|
||||||
May 12th, 2007
|
May 12th, 2007
|
||||||
v1.17 -- Cryptography Research Inc. contributed another small volley of patches, one to fix __WCHAR_DEFINED__ for BSD platforms,
|
v1.17 -- Cryptography Research Inc. contributed another small volley of patches, one to fix __WCHAR_DEFINED__ for BSD platforms,
|
||||||
another to silence MSVC warnings.
|
another to silence MSVC warnings.
|
||||||
|
619
crypt.tex
619
crypt.tex
@ -277,15 +277,15 @@ There are a few helper macros to make the coding process a bit easier. The firs
|
|||||||
\begin{small}
|
\begin{small}
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tabular}{|c|c|c|}
|
\begin{tabular}{|c|c|c|}
|
||||||
\hline STORE32L(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $x \to y[0 \ldots 3]$ \\
|
\hline STORE32L(x, y) & {\bf ulong32} x, {\bf unsigned char} *y & $x \to y[0 \ldots 3]$ \\
|
||||||
\hline STORE64L(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $x \to y[0 \ldots 7]$ \\
|
\hline STORE64L(x, y) & {\bf ulong64} x, {\bf unsigned char} *y & $x \to y[0 \ldots 7]$ \\
|
||||||
\hline LOAD32L(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $y[0 \ldots 3] \to x$ \\
|
\hline LOAD32L(x, y) & {\bf ulong32} x, {\bf unsigned char} *y & $y[0 \ldots 3] \to x$ \\
|
||||||
\hline LOAD64L(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $y[0 \ldots 7] \to x$ \\
|
\hline LOAD64L(x, y) & {\bf ulong64} x, {\bf unsigned char} *y & $y[0 \ldots 7] \to x$ \\
|
||||||
\hline STORE32H(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $x \to y[3 \ldots 0]$ \\
|
\hline STORE32H(x, y) & {\bf ulong32} x, {\bf unsigned char} *y & $x \to y[3 \ldots 0]$ \\
|
||||||
\hline STORE64H(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $x \to y[7 \ldots 0]$ \\
|
\hline STORE64H(x, y) & {\bf ulong64} x, {\bf unsigned char} *y & $x \to y[7 \ldots 0]$ \\
|
||||||
\hline LOAD32H(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $y[3 \ldots 0] \to x$ \\
|
\hline LOAD32H(x, y) & {\bf ulong32} x, {\bf unsigned char} *y & $y[3 \ldots 0] \to x$ \\
|
||||||
\hline LOAD64H(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $y[7 \ldots 0] \to x$ \\
|
\hline LOAD64H(x, y) & {\bf ulong64} x, {\bf unsigned char} *y & $y[7 \ldots 0] \to x$ \\
|
||||||
\hline BSWAP(x) & {\bf unsigned long} x & Swap bytes \\
|
\hline BSWAP(x) & {\bf ulong32} x & Swap bytes \\
|
||||||
\hline
|
\hline
|
||||||
\end{tabular}
|
\end{tabular}
|
||||||
\caption{Load And Store Macros}
|
\caption{Load And Store Macros}
|
||||||
@ -299,15 +299,15 @@ There are 32 and 64-bit cyclic rotations as well:
|
|||||||
\begin{small}
|
\begin{small}
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tabular}{|c|c|c|}
|
\begin{tabular}{|c|c|c|}
|
||||||
\hline ROL(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x << y, 0 \le y \le 31$ \\
|
\hline ROL(x, y) & {\bf ulong32} x, {\bf ulong32} y & $x << y, 0 \le y \le 31$ \\
|
||||||
\hline ROLc(x, y) & {\bf unsigned long} x, {\bf const unsigned long} y & $x << y, 0 \le y \le 31$ \\
|
\hline ROLc(x, y) & {\bf ulong32} x, {\bf const ulong32} y & $x << y, 0 \le y \le 31$ \\
|
||||||
\hline ROR(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x >> y, 0 \le y \le 31$ \\
|
\hline ROR(x, y) & {\bf ulong32} x, {\bf ulong32} y & $x >> y, 0 \le y \le 31$ \\
|
||||||
\hline RORc(x, y) & {\bf unsigned long} x, {\bf const unsigned long} y & $x >> y, 0 \le y \le 31$ \\
|
\hline RORc(x, y) & {\bf ulong32} x, {\bf const ulong32} y & $x >> y, 0 \le y \le 31$ \\
|
||||||
\hline && \\
|
\hline && \\
|
||||||
\hline ROL64(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x << y, 0 \le y \le 63$ \\
|
\hline ROL64(x, y) & {\bf ulong64} x, {\bf ulong64} y & $x << y, 0 \le y \le 63$ \\
|
||||||
\hline ROL64c(x, y) & {\bf unsigned long} x, {\bf const unsigned long} y & $x << y, 0 \le y \le 63$ \\
|
\hline ROL64c(x, y) & {\bf ulong64} x, {\bf const ulong64} y & $x << y, 0 \le y \le 63$ \\
|
||||||
\hline ROR64(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x >> y, 0 \le y \le 63$ \\
|
\hline ROR64(x, y) & {\bf ulong64} x, {\bf ulong64} y & $x >> y, 0 \le y \le 63$ \\
|
||||||
\hline ROR64c(x, y) & {\bf unsigned long} x, {\bf const unsigned long} y & $x >> y, 0 \le y \le 63$ \\
|
\hline ROR64c(x, y) & {\bf ulong64} x, {\bf const ulong64} y & $x >> y, 0 \le y \le 63$ \\
|
||||||
\hline
|
\hline
|
||||||
\end{tabular}
|
\end{tabular}
|
||||||
\caption{Rotate Macros}
|
\caption{Rotate Macros}
|
||||||
@ -601,7 +601,7 @@ As of this release the current cipher\_descriptors elements are the following:
|
|||||||
\vfil
|
\vfil
|
||||||
\index{Cipher descriptor table}
|
\index{Cipher descriptor table}
|
||||||
\index{blowfish\_desc} \index{xtea\_desc} \index{rc2\_desc} \index{rc5\_desc} \index{rc6\_desc} \index{saferp\_desc} \index{aes\_desc} \index{twofish\_desc}
|
\index{blowfish\_desc} \index{xtea\_desc} \index{rc2\_desc} \index{rc5\_desc} \index{rc6\_desc} \index{saferp\_desc} \index{aes\_desc} \index{twofish\_desc}
|
||||||
\index{des\_desc} \index{des3\_desc} \index{noekeon\_desc} \index{skipjack\_desc} \index{anubis\_desc} \index{khazad\_desc} \index{kseed\_desc} \index{kasumi\_desc}
|
\index{des\_desc} \index{des3\_desc} \index{noekeon\_desc} \index{skipjack\_desc} \index{anubis\_desc} \index{khazad\_desc} \index{kseed\_desc} \index{kasumi\_desc} \index{camellia\_desc} \index{aes\_enc\_desc}
|
||||||
\begin{figure}[hpbt]
|
\begin{figure}[hpbt]
|
||||||
\begin{small}
|
\begin{small}
|
||||||
\begin{center}
|
\begin{center}
|
||||||
@ -625,6 +625,7 @@ As of this release the current cipher\_descriptors elements are the following:
|
|||||||
\hline Khazad & khazad\_desc & 8 & 16 & 8 \\
|
\hline Khazad & khazad\_desc & 8 & 16 & 8 \\
|
||||||
\hline SEED & kseed\_desc & 16 & 16 & 16 \\
|
\hline SEED & kseed\_desc & 16 & 16 & 16 \\
|
||||||
\hline KASUMI & kasumi\_desc & 8 & 16 & 8 \\
|
\hline KASUMI & kasumi\_desc & 8 & 16 & 8 \\
|
||||||
|
\hline Camellia & camellia\_desc & 16 & 16, 24, 32 & 18, 24 \\
|
||||||
\hline
|
\hline
|
||||||
\end{tabular}
|
\end{tabular}
|
||||||
\end{center}
|
\end{center}
|
||||||
@ -653,6 +654,8 @@ Note that for \textit{DES} and \textit{3DES} they use 8 and 24 byte keys but onl
|
|||||||
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
|
fact used for the purposes of encryption. My suggestion is just to use random 8/24 byte keys instead of trying to make a 8/24
|
||||||
byte string from the real 7/21 byte key.
|
byte string from the real 7/21 byte key.
|
||||||
|
|
||||||
|
For \textit{3DES} exists a two-key mode, that can be initialized by calling the setup function with a \textit{keylen} of 16. This results in the re-usage of key \textit{K1} as key \textit{K3}. This mode has been specified as \textit{Keying Option 2} in FIPS 46-3.
|
||||||
|
|
||||||
\item
|
\item
|
||||||
Note that \textit{Twofish} has additional configuration options (Figure \ref{fig:twofishopts}) that take place at build time. These options are found in
|
Note that \textit{Twofish} has additional configuration options (Figure \ref{fig:twofishopts}) that take place at build time. These options are found in
|
||||||
the file \textit{tomcrypt\_cfg.h}. The first option is \textit{TWOFISH\_SMALL} which when defined will force the Twofish code
|
the file \textit{tomcrypt\_cfg.h}. The first option is \textit{TWOFISH\_SMALL} which when defined will force the Twofish code
|
||||||
@ -1508,9 +1511,91 @@ Similarly, this will OCB decrypt, and compare the internally computed tag agains
|
|||||||
appropriately.
|
appropriately.
|
||||||
|
|
||||||
\subsection{CCM Mode}
|
\subsection{CCM Mode}
|
||||||
CCM is a NIST proposal for encrypt + authenticate that is centered around using AES (or any 16--byte cipher) as a primitive. Unlike EAX and OCB mode,
|
CCM is a NIST proposal for encrypt + authenticate that is centered around using AES (or any 16--byte cipher) as a primitive.
|
||||||
it is only meant for \textit{packet} mode where the length of the input is known in advance. Since it is a packet mode function, CCM only has one
|
|
||||||
function that performs the protocol.
|
\subsubsection{Initialization}
|
||||||
|
To initialize the CCM context with a secret key call the following function.
|
||||||
|
|
||||||
|
\index{ccm\_init()}
|
||||||
|
\begin{verbatim}
|
||||||
|
int ccm_init( ccm_state *ccm,
|
||||||
|
int cipher,
|
||||||
|
const unsigned char *key,
|
||||||
|
int keylen,
|
||||||
|
int ptlen,
|
||||||
|
int taglen,
|
||||||
|
int aadlen);
|
||||||
|
\end{verbatim}
|
||||||
|
This initializes the CCM state \textit{ccm} for the given cipher indexed by \textit{cipher}, with a secret key \textit{key} of length \textit{keylen} octets. The cipher
|
||||||
|
chosen must have a 16--byte block size (e.g., AES).
|
||||||
|
Unlike EAX and OCB mode, CCM is only meant for \textit{packet} mode where the length of the input is known in advance. This is why the length of the stream
|
||||||
|
to authenticate is given as \textit{ptlen}.
|
||||||
|
With CCM, a header is meta--data you want to send with the message but not have encrypted. The header len is given in the init
|
||||||
|
as \textit{aadlen}.
|
||||||
|
|
||||||
|
\subsubsection{Nonce Vector}
|
||||||
|
After the state has been initialized (or reset) the next step is to add the session (or packet) initial vector. It should be unique per packet encrypted.
|
||||||
|
|
||||||
|
\index{ccm\_add\_nonce()}
|
||||||
|
\begin{verbatim}
|
||||||
|
int ccm_add_nonce( ccm_state *ccm,
|
||||||
|
const unsigned char *nonce,
|
||||||
|
unsigned long noncelen);
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
This adds the nonce (a.k.a. salt) \textit{nonce} of length \textit{noncelen} octets to the CCM state \textit{ccm}. Note that this function must be called
|
||||||
|
once and only once.
|
||||||
|
|
||||||
|
\subsubsection{Additional Authentication Data}
|
||||||
|
The header is meta--data you want to send with the message but not have encrypted, it must be stored in \textit{adata} of length \textit{adatalen} octets.
|
||||||
|
|
||||||
|
\index{ccm\_add\_aad()}
|
||||||
|
\begin{verbatim}
|
||||||
|
int ccm_add_aad( ccm_state *ccm,
|
||||||
|
const unsigned char *adata,
|
||||||
|
unsigned long adatalen);
|
||||||
|
\end{verbatim}
|
||||||
|
This adds the additional authentication data \textit{adata} of length \textit{adatalen} to the CCM state \textit{ccm}.
|
||||||
|
|
||||||
|
\subsubsection{Plaintext Processing}
|
||||||
|
After the AAD has been processed, the plaintext (or ciphertext depending on the direction) can be processed.
|
||||||
|
|
||||||
|
\index{ccm\_process()}
|
||||||
|
\begin{verbatim}
|
||||||
|
int ccm_process(ccm_state *ccm,
|
||||||
|
unsigned char *pt,
|
||||||
|
unsigned long ptlen,
|
||||||
|
unsigned char *ct,
|
||||||
|
int direction);
|
||||||
|
\end{verbatim}
|
||||||
|
This processes message data where \textit{pt} is the plaintext and \textit{ct} is the ciphertext. The length of both are equal and stored in \textit{ptlen}. Depending on
|
||||||
|
the mode \textit{pt} is the input and \textit{ct} is the output (or vice versa). When \textit{direction} equals \textbf{CCM\_ENCRYPT} the plaintext is read,
|
||||||
|
encrypted and stored in the ciphertext buffer. When \textit{direction} equals \textbf{CCM\_DECRYPT} the opposite occurs.
|
||||||
|
|
||||||
|
\subsubsection{State Termination}
|
||||||
|
To terminate a CCM state and retrieve the message authentication tag call the following function.
|
||||||
|
|
||||||
|
\index{ccm\_done()}
|
||||||
|
\begin{verbatim}
|
||||||
|
int ccm_done( ccm_state *ccm,
|
||||||
|
unsigned char *tag,
|
||||||
|
unsigned long *taglen);
|
||||||
|
\end{verbatim}
|
||||||
|
This terminates the CCM state \textit{ccm} and stores the tag in \textit{tag} of length \textit{taglen} octets.
|
||||||
|
|
||||||
|
\subsubsection{State Reset}
|
||||||
|
The call to ccm\_init() will perform considerable pre--computation and if you're going to be dealing with a lot of packets
|
||||||
|
it is very costly to have to call it repeatedly. To aid in this endeavour, the reset function is provided.
|
||||||
|
|
||||||
|
\index{ccm\_reset()}
|
||||||
|
\begin{verbatim}
|
||||||
|
int ccm_reset(ccm_state *ccm);
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
This will reset the CCM state \textit{ccm} to the state that ccm\_init() left it. The user would then call ccm\_add\_nonce(), ccm\_add\_aad(), etc.
|
||||||
|
|
||||||
|
\subsubsection{One--Shot Packet}
|
||||||
|
To process a single packet under any given key the following helper function can be used.
|
||||||
|
|
||||||
\index{ccm\_memory()}
|
\index{ccm\_memory()}
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
@ -1526,86 +1611,107 @@ int ccm_memory(
|
|||||||
int direction);
|
int direction);
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
||||||
This performs the \textit{CCM} operation on the data. The \textit{cipher} variable indicates which cipher in the descriptor table to use. It must have a
|
This will initialize the CCM state with the given key, nonce and AAD value then proceed to encrypt or decrypt the message text and store the final
|
||||||
16--byte block size for CCM.
|
message tag. The definition of the variables is the same as it is for all the manual functions.
|
||||||
|
|
||||||
The key can be specified in one of two fashions. First, it can be passed as an array of octets in \textit{key} of length \textit{keylen}. Alternatively,
|
If you are processing many packets under the same key you shouldn't use this function as it invokes the pre--computation with each call.
|
||||||
it can be passed in as a previously scheduled key in \textit{uskey}. The latter fashion saves time when the same key is used for multiple packets. If
|
|
||||||
\textit{uskey} is not \textbf{NULL}, then \textit{key} may be \textbf{NULL} (and vice-versa).
|
|
||||||
|
|
||||||
The nonce or salt is \textit{nonce} of length \textit{noncelen} octets. The header is meta--data you want to send with the message but not have
|
\subsubsection{Example Usage}
|
||||||
encrypted, it is stored in \textit{header} of length \textit{headerlen} octets. The header can be zero octets long (if $headerlen = 0$ then
|
The following is an example usage of how to use CCM over multiple packets with a shared secret key.
|
||||||
you can pass \textit{header} as \textbf{NULL}).
|
|
||||||
|
|
||||||
The plaintext is stored in \textit{pt}, and the ciphertext in \textit{ct}. The length of both are expected to be equal and is passed in as \textit{ptlen}. It is
|
|
||||||
allowable that $pt = ct$. The \textit{direction} variable indicates whether encryption (direction $=$ \textbf{CCM\_ENCRYPT}) or
|
|
||||||
decryption (direction $=$ \textbf{CCM\_DECRYPT}) is to be performed.
|
|
||||||
|
|
||||||
As implemented, this version of CCM cannot handle header or plaintext data longer than $2^{32} - 1$ octets long.
|
|
||||||
|
|
||||||
You can test the implementation of CCM with the following function.
|
|
||||||
|
|
||||||
\index{ccm\_test()}
|
|
||||||
\begin{verbatim}
|
|
||||||
int ccm_test(void);
|
|
||||||
\end{verbatim}
|
|
||||||
|
|
||||||
This will return \textbf{CRYPT\_OK} if the CCM routine passes known test vectors. It requires AES or Rijndael to be registered previously, otherwise it will
|
|
||||||
return \textbf{CRYPT\_NOP}.
|
|
||||||
|
|
||||||
\subsubsection{CCM Example}
|
|
||||||
The following is a sample of how to call CCM.
|
|
||||||
|
|
||||||
\begin{small}
|
\begin{small}
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
#include <tomcrypt.h>
|
#include <tomcrypt.h>
|
||||||
|
|
||||||
|
int send_packet(const unsigned char *pt, unsigned long ptlen,
|
||||||
|
const unsigned char *nonce, unsigned long noncelen,
|
||||||
|
const unsigned char *aad, unsigned long aadlen,
|
||||||
|
ccm_state *ccm)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
unsigned long taglen;
|
||||||
|
unsigned char tag[16];
|
||||||
|
|
||||||
|
/* reset the state */
|
||||||
|
if ((err = ccm_reset(ccm)) != CRYPT_OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the nonce */
|
||||||
|
if ((err = ccm_add_nonce(ccm, nonce, noncelen)) != CRYPT_OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the AAD (note: aad can be NULL if aadlen == 0) */
|
||||||
|
if ((err = ccm_add_aad(ccm, aad, aadlen)) != CRYPT_OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* process the plaintext */
|
||||||
|
if ((err =
|
||||||
|
ccm_process(ccm, pt, ptlen, pt, CCM_ENCRYPT)) != CRYPT_OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finish up and get the MAC tag */
|
||||||
|
taglen = sizeof(tag);
|
||||||
|
if ((err = ccm_done(ccm, tag, &taglen)) != CRYPT_OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ... send a header describing the lengths ... */
|
||||||
|
|
||||||
|
/* depending on the protocol and how nonce is
|
||||||
|
* generated you may have to send it too... */
|
||||||
|
send(socket, nonce, noncelen, 0);
|
||||||
|
|
||||||
|
/* send the aad */
|
||||||
|
send(socket, aad, aadlen, 0);
|
||||||
|
|
||||||
|
/* send the ciphertext */
|
||||||
|
send(socket, pt, ptlen, 0);
|
||||||
|
|
||||||
|
/* send the tag */
|
||||||
|
send(socket, tag, taglen, 0);
|
||||||
|
|
||||||
|
return CRYPT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
unsigned char key[16], nonce[12], pt[32], ct[32],
|
ccm_state ccm;
|
||||||
tag[16], tagcp[16];
|
unsigned char key[16], NONCE[12], pt[PACKET_SIZE];
|
||||||
unsigned long taglen;
|
int err, x;
|
||||||
int err;
|
unsigned long ptlen;
|
||||||
|
|
||||||
/* register cipher */
|
/* somehow fill key/NONCE with random values */
|
||||||
|
|
||||||
|
/* register AES */
|
||||||
register_cipher(&aes_desc);
|
register_cipher(&aes_desc);
|
||||||
|
|
||||||
/* somehow fill key, nonce, pt */
|
/* init the CCM state */
|
||||||
|
|
||||||
/* encrypt it */
|
|
||||||
taglen = sizeof(tag);
|
|
||||||
if ((err =
|
if ((err =
|
||||||
ccm_memory(find_cipher("aes"),
|
ccm_init(&ccm, find_cipher("aes"), key, 16, PACKET_SIZE, 16, size(NONCE))) != CRYPT_OK) {
|
||||||
key, 16, /* 128-bit key */
|
whine_and_pout(err);
|
||||||
NULL, /* not prescheduled */
|
|
||||||
nonce, 12, /* 96-bit nonce */
|
|
||||||
NULL, 0, /* no header */
|
|
||||||
pt, 32, /* [in] 32-byte plaintext */
|
|
||||||
ct, /* [out] ciphertext */
|
|
||||||
tag, &taglen,
|
|
||||||
CCM_ENCRYPT)) != CRYPT_OK) {
|
|
||||||
printf("ccm_memory error %s\n", error_to_string(err));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
/* ct[0..31] and tag[0..15] now hold the output */
|
|
||||||
|
|
||||||
/* decrypt it */
|
|
||||||
taglen = sizeof(tagcp);
|
|
||||||
if ((err =
|
|
||||||
ccm_memory(find_cipher("aes"),
|
|
||||||
key, 16, /* 128-bit key */
|
|
||||||
NULL, /* not prescheduled */
|
|
||||||
nonce, 12, /* 96-bit nonce */
|
|
||||||
NULL, 0, /* no header */
|
|
||||||
pt, 32, /* [out] 32-byte plaintext */
|
|
||||||
ct, /* [in] ciphertext */
|
|
||||||
tagcp, &taglen,
|
|
||||||
CCM_DECRYPT)) != CRYPT_OK) {
|
|
||||||
printf("ccm_memory error %s\n", error_to_string(err));
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now pt[0..31] should hold the original plaintext,
|
/* handle us some packets */
|
||||||
tagcp[0..15] and tag[0..15] should have the same contents */
|
for (;;) {
|
||||||
|
ptlen = make_packet_we_want_to_send(pt);
|
||||||
|
|
||||||
|
/* use NONCE as counter (12 byte counter) */
|
||||||
|
for (x = 11; x >= 0; x--) {
|
||||||
|
if (++NONCE[x]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((err = send_packet(pt, ptlen, NONCE, 12, NULL, 0, &ccm))
|
||||||
|
!= CRYPT_OK) {
|
||||||
|
whine_and_pout(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
\end{small}
|
\end{small}
|
||||||
@ -2056,24 +2162,38 @@ int unregister_hash(const struct _hash_descriptor *hash);
|
|||||||
The following hashes are provided as of this release within the LibTomCrypt library:
|
The following hashes are provided as of this release within the LibTomCrypt library:
|
||||||
\index{Hash descriptor table}
|
\index{Hash descriptor table}
|
||||||
|
|
||||||
\begin{figure}[here]
|
\begin{figure}[h]
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tabular}{|c|c|c|}
|
\begin{tabular}{|c|c|c|}
|
||||||
\hline \textbf{Name} & \textbf{Descriptor Name} & \textbf{Size of Message Digest (bytes)} \\
|
\hline \textbf{Name} & \textbf{Descriptor Name} & \textbf{Size of Message Digest (bytes)} \\
|
||||||
\hline WHIRLPOOL & whirlpool\_desc & 64 \\
|
\hline WHIRLPOOL & whirlpool\_desc & 64 \\
|
||||||
|
\hline SHA3-512 & sha3\_512\_desc & 64 \\
|
||||||
\hline SHA-512 & sha512\_desc & 64 \\
|
\hline SHA-512 & sha512\_desc & 64 \\
|
||||||
|
\hline BLAKE2B-512 & blake2b\_512\_desc & 64 \\
|
||||||
|
\hline SHA3-384 & sha3\_384\_desc & 48 \\
|
||||||
\hline SHA-384 & sha384\_desc & 48 \\
|
\hline SHA-384 & sha384\_desc & 48 \\
|
||||||
\hline RIPEMD-320 & rmd160\_desc & 40 \\
|
\hline RIPEMD-320 & rmd160\_desc & 40 \\
|
||||||
|
\hline SHA-512/256 & sha512\_256\_desc & 32 \\
|
||||||
|
\hline SHA3-256 & sha3\_256\_desc & 32 \\
|
||||||
\hline SHA-256 & sha256\_desc & 32 \\
|
\hline SHA-256 & sha256\_desc & 32 \\
|
||||||
\hline RIPEMD-256 & rmd160\_desc & 32 \\
|
\hline RIPEMD-256 & rmd160\_desc & 32 \\
|
||||||
|
\hline BLAKE2S-256 & blake2s\_256\_desc & 32 \\
|
||||||
|
\hline BLAKE2B-256 & blake2b\_256\_desc & 32 \\
|
||||||
|
\hline SHA-512/224 & sha512\_224\_desc & 28 \\
|
||||||
|
\hline SHA3-224 & sha3\_224\_desc & 28 \\
|
||||||
\hline SHA-224 & sha224\_desc & 28 \\
|
\hline SHA-224 & sha224\_desc & 28 \\
|
||||||
|
\hline BLAKE2S-224 & blake2s\_224\_desc & 28 \\
|
||||||
|
\hline BLAKE2B-384 & blake2b\_384\_desc & 48 \\
|
||||||
\hline TIGER-192 & tiger\_desc & 24 \\
|
\hline TIGER-192 & tiger\_desc & 24 \\
|
||||||
\hline SHA-1 & sha1\_desc & 20 \\
|
\hline SHA-1 & sha1\_desc & 20 \\
|
||||||
\hline RIPEMD-160 & rmd160\_desc & 20 \\
|
\hline RIPEMD-160 & rmd160\_desc & 20 \\
|
||||||
|
\hline BLAKE2S-160 & blake2s\_160\_desc & 20 \\
|
||||||
|
\hline BLAKE2B-160 & blake2b\_160\_desc & 20 \\
|
||||||
\hline RIPEMD-128 & rmd128\_desc & 16 \\
|
\hline RIPEMD-128 & rmd128\_desc & 16 \\
|
||||||
\hline MD5 & md5\_desc & 16 \\
|
\hline MD5 & md5\_desc & 16 \\
|
||||||
\hline MD4 & md4\_desc & 16 \\
|
\hline MD4 & md4\_desc & 16 \\
|
||||||
\hline MD2 & md2\_desc & 16 \\
|
\hline MD2 & md2\_desc & 16 \\
|
||||||
|
\hline BLAKE2S-128 & blake2s\_128\_desc & 16 \\
|
||||||
\hline
|
\hline
|
||||||
\end{tabular}
|
\end{tabular}
|
||||||
\end{center}
|
\end{center}
|
||||||
@ -2137,11 +2257,11 @@ int main(void)
|
|||||||
|
|
||||||
|
|
||||||
\mysection{Notice}
|
\mysection{Notice}
|
||||||
It is highly recommended that you \textbf{not} use the MD4 or MD5 hashes for the purposes of digital signatures or authentication codes.
|
It is highly recommended that you \textbf{not} use the MD2, MD4, MD5, or SHA-1 hashes for the purposes of digital signatures or authentication codes.
|
||||||
These hashes are provided for completeness and they still can be used for the purposes of password hashing or one-way accumulators
|
These hashes are provided for completeness and they still can be used for the purposes of password hashing or one-way accumulators
|
||||||
(e.g. Yarrow).
|
(e.g. Yarrow).
|
||||||
|
|
||||||
The other hashes such as the SHA-1, SHA-2 (that includes SHA-512, SHA-384 and SHA-256) and TIGER-192 are still considered secure
|
The other hashes such as the SHA-2 (that includes SHA-512, SHA-512/384, SHA-384, SHA-512/256, SHA-256 and SHA-224) and TIGER-192 are still considered secure
|
||||||
for all purposes you would normally use a hash for.
|
for all purposes you would normally use a hash for.
|
||||||
|
|
||||||
\chapter{Message Authentication Codes}
|
\chapter{Message Authentication Codes}
|
||||||
@ -2920,7 +3040,7 @@ descriptor twice, and will return the index of the current placement in the tabl
|
|||||||
will return \textbf{CRYPT\_OK} if the PRNG was found and removed. Otherwise, it returns \textbf{CRYPT\_ERROR}.
|
will return \textbf{CRYPT\_OK} if the PRNG was found and removed. Otherwise, it returns \textbf{CRYPT\_ERROR}.
|
||||||
|
|
||||||
\subsection{PRNGs Provided}
|
\subsection{PRNGs Provided}
|
||||||
\begin{figure}[here]
|
\begin{figure}[h]
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{small}
|
\begin{small}
|
||||||
\begin{tabular}{|c|c|l|}
|
\begin{tabular}{|c|c|l|}
|
||||||
@ -3374,6 +3494,14 @@ in \textit{out} and the size of the result in \textit{outlen}. \textit{which} is
|
|||||||
|
|
||||||
Note: the output of this function is zero--padded as per PKCS \#1 specification. This allows this routine to work with PKCS \#1 padding functions properly.
|
Note: the output of this function is zero--padded as per PKCS \#1 specification. This allows this routine to work with PKCS \#1 padding functions properly.
|
||||||
|
|
||||||
|
\subsection{RSA Key Size}
|
||||||
|
To fetch the key size of an RSA key, use the following function:
|
||||||
|
\index{rsa\_get\_size()}
|
||||||
|
\begin{verbatim}
|
||||||
|
int rsa_get_size(rsa_key *key);
|
||||||
|
\end{verbatim}
|
||||||
|
This can be used to determine the modulus size of an RSA key.
|
||||||
|
|
||||||
\mysection{RSA Key Encryption}
|
\mysection{RSA Key Encryption}
|
||||||
Normally RSA is used to encrypt short symmetric keys which are then used in block ciphers to encrypt a message.
|
Normally RSA is used to encrypt short symmetric keys which are then used in block ciphers to encrypt a message.
|
||||||
To facilitate encrypting short keys the following functions have been provided.
|
To facilitate encrypting short keys the following functions have been provided.
|
||||||
@ -3538,6 +3666,22 @@ and the extracted hash is compared against the message digest pointed to by \tex
|
|||||||
If the RSA decoded data is not a valid PSS message, or if the PSS decoded hash does not match the \textit{msghash}
|
If the RSA decoded data is not a valid PSS message, or if the PSS decoded hash does not match the \textit{msghash}
|
||||||
value, \textit{res} is set to $0$. Otherwise, if the function succeeds, and signature is valid \textit{res} is set to $1$.
|
value, \textit{res} is set to $0$. Otherwise, if the function succeeds, and signature is valid \textit{res} is set to $1$.
|
||||||
|
|
||||||
|
\subsection{RSA Signature Salt Length}
|
||||||
|
|
||||||
|
The v2.1 signature algorithm requires a salt length to be able to properly
|
||||||
|
encode resp. decode. To fetch the maximum possible salt length this function
|
||||||
|
is provided:
|
||||||
|
|
||||||
|
\index{rsa\_sign\_saltlen\_get\_max()}
|
||||||
|
\begin{verbatim}
|
||||||
|
int rsa_sign_saltlen_get_max(int hash_idx, rsa_key *key);
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
As stated in the PKCS\#1 RFC3447 "Typical salt lengths in octets are hLen
|
||||||
|
(the length of the output of the hash function Hash) and 0".
|
||||||
|
This function is provided to be able to use other lengths as well and to make
|
||||||
|
sure at runtime that the RSA key can handle the desired salt length.
|
||||||
|
|
||||||
\subsection{Extended Verification}
|
\subsection{Extended Verification}
|
||||||
|
|
||||||
As of v1.15, the library supports both v1.5 and v2.1 signature verification. The extended signature verification function has the following prototype:
|
As of v1.15, the library supports both v1.5 and v2.1 signature verification. The extended signature verification function has the following prototype:
|
||||||
@ -3563,7 +3707,8 @@ If the RSA decoded data is not a valid PSS message, or if the PKCS decoded hash
|
|||||||
value, \textit{res} is set to $0$. Otherwise, if the function succeeds, and signature is valid \textit{res} is set to $1$.
|
value, \textit{res} is set to $0$. Otherwise, if the function succeeds, and signature is valid \textit{res} is set to $1$.
|
||||||
|
|
||||||
The \textit{padding} parameter must be set to \textbf{LTC\_PKCS\_1\_V1\_5} to perform a v1.5 verification. Otherwise, it must be set to
|
The \textit{padding} parameter must be set to \textbf{LTC\_PKCS\_1\_V1\_5} to perform a v1.5 verification. Otherwise, it must be set to
|
||||||
\textbf{LTC\_PKCS\_1\_PSS} to perform a v2.1 verification. When performing a v1.5 verification the \textit{hash\_idx} parameter is ignored.
|
\textbf{LTC\_PKCS\_1\_PSS} to perform a v2.1 verification. When performing a v1.5 verification the \textit{hash\_idx} and \textit{saltlen} parameters are ignored.
|
||||||
|
|
||||||
|
|
||||||
\mysection{RSA Encryption Example}
|
\mysection{RSA Encryption Example}
|
||||||
\begin{small}
|
\begin{small}
|
||||||
@ -3643,7 +3788,7 @@ int main(void)
|
|||||||
\mysection{RSA Key Format}
|
\mysection{RSA Key Format}
|
||||||
|
|
||||||
The RSA key format adopted for exporting and importing keys is the PKCS \#1 format defined by the ASN.1 constructs known as
|
The RSA key format adopted for exporting and importing keys is the PKCS \#1 format defined by the ASN.1 constructs known as
|
||||||
RSAPublicKey and RSAPrivateKey. Additionally, the OpenSSL key format is supported by the import function only.
|
RSAPublicKey and RSAPrivateKey. Additionally, the OpenSSL key format is supported as well.
|
||||||
|
|
||||||
\subsection{RSA Key Export}
|
\subsection{RSA Key Export}
|
||||||
To export a RSA key use the following function.
|
To export a RSA key use the following function.
|
||||||
@ -3655,8 +3800,17 @@ int rsa_export(unsigned char *out,
|
|||||||
int type,
|
int type,
|
||||||
rsa_key *key);
|
rsa_key *key);
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
This will export the RSA key in either a RSAPublicKey or RSAPrivateKey (PKCS \#1 types) depending on the value of \textit{type}. When it is
|
|
||||||
set to \textbf{PK\_PRIVATE} the export format will be RSAPrivateKey and otherwise it will be RSAPublicKey.
|
This will export the RSA key depending on the value of \textit{type}.
|
||||||
|
|
||||||
|
The RSAPublicKey (PKCS \#1 type) format will be used for the public key,
|
||||||
|
indicated by \textbf{PK\_PUBLIC}.
|
||||||
|
The RSAPrivateKey (PKCS \#1 type) format will be used for the private key,
|
||||||
|
indicated by \textbf{PK\_PRIVATE}.
|
||||||
|
|
||||||
|
As of v1.18 this function can also export OpenSSL-compatible formatted public RSA keys.
|
||||||
|
By OR'ing \textbf{PK\_STD} and \textbf{PK\_PUBLIC} the public key will be exported
|
||||||
|
in the SubjectPublicKeyInfo (X.509 type) format.
|
||||||
|
|
||||||
\subsection{RSA Key Import}
|
\subsection{RSA Key Import}
|
||||||
To import a RSA key use the following function.
|
To import a RSA key use the following function.
|
||||||
@ -3672,8 +3826,7 @@ This will import the key stored in \textit{inlen} and import it to \textit{key}.
|
|||||||
function can import both RSAPublicKey and RSAPrivateKey formats.
|
function can import both RSAPublicKey and RSAPrivateKey formats.
|
||||||
|
|
||||||
As of v1.06 this function can also import OpenSSL DER formatted public RSA keys. They are essentially encapsulated RSAPublicKeys. LibTomCrypt will
|
As of v1.06 this function can also import OpenSSL DER formatted public RSA keys. They are essentially encapsulated RSAPublicKeys. LibTomCrypt will
|
||||||
import the key, strip off the additional data (it's the preferred hash) and fill in the rsa\_key structure as if it were a native RSAPublicKey. Note that
|
import the key, strip off the additional data and fill in the rsa\_key structure.
|
||||||
there is no function provided to export in this format.
|
|
||||||
|
|
||||||
|
|
||||||
\chapter{Diffie-Hellman Key Exchange}
|
\chapter{Diffie-Hellman Key Exchange}
|
||||||
@ -4309,7 +4462,7 @@ The variable \textit{prng} is an active PRNG state and \textit{wprng} the index
|
|||||||
\textit{group\_size} the more difficult a forgery becomes upto a limit. The value of $group\_size$ is limited by
|
\textit{group\_size} the more difficult a forgery becomes upto a limit. The value of $group\_size$ is limited by
|
||||||
$15 < group\_size < 1024$ and $modulus\_size - group\_size < 512$. Suggested values for the pairs are as follows.
|
$15 < group\_size < 1024$ and $modulus\_size - group\_size < 512$. Suggested values for the pairs are as follows.
|
||||||
|
|
||||||
\begin{figure}[here]
|
\begin{figure}[h]
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tabular}{|c|c|c|}
|
\begin{tabular}{|c|c|c|}
|
||||||
\hline \textbf{Bits of Security} & \textbf{group\_size} & \textbf{modulus\_size} \\
|
\hline \textbf{Bits of Security} & \textbf{group\_size} & \textbf{modulus\_size} \\
|
||||||
@ -4525,7 +4678,7 @@ LTC_SET_ASN1(sequence, x++, LTC_ASN1_NULL, NULL, 0);
|
|||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
\end{small}
|
\end{small}
|
||||||
|
|
||||||
\begin{figure}[here]
|
\begin{figure}[h]
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{small}
|
\begin{small}
|
||||||
\begin{tabular}{|l|l|}
|
\begin{tabular}{|l|l|}
|
||||||
@ -4539,13 +4692,18 @@ LTC_SET_ASN1(sequence, x++, LTC_ASN1_NULL, NULL, 0);
|
|||||||
\hline LTC\_ASN1\_NULL & NULL \\
|
\hline LTC\_ASN1\_NULL & NULL \\
|
||||||
\hline LTC\_ASN1\_OBJECT\_IDENTIFIER & OBJECT IDENTIFIER \\
|
\hline LTC\_ASN1\_OBJECT\_IDENTIFIER & OBJECT IDENTIFIER \\
|
||||||
\hline LTC\_ASN1\_IA5\_STRING & IA5 STRING (one octet per char) \\
|
\hline LTC\_ASN1\_IA5\_STRING & IA5 STRING (one octet per char) \\
|
||||||
\hline LTC\_ASN1\_UTF8\_STRING & UTF8 STRING (one wchar\_t per char) \\
|
|
||||||
\hline LTC\_ASN1\_PRINTABLE\_STRING & PRINTABLE STRING (one octet per char) \\
|
\hline LTC\_ASN1\_PRINTABLE\_STRING & PRINTABLE STRING (one octet per char) \\
|
||||||
|
\hline LTC\_ASN1\_UTF8\_STRING & UTF8 STRING (one wchar\_t per char) \\
|
||||||
\hline LTC\_ASN1\_UTCTIME & UTCTIME (see ltc\_utctime structure) \\
|
\hline LTC\_ASN1\_UTCTIME & UTCTIME (see ltc\_utctime structure) \\
|
||||||
|
\hline LTC\_ASN1\_CHOICE & CHOICE \\
|
||||||
\hline LTC\_ASN1\_SEQUENCE & SEQUENCE (and SEQUENCE OF) \\
|
\hline LTC\_ASN1\_SEQUENCE & SEQUENCE (and SEQUENCE OF) \\
|
||||||
\hline LTC\_ASN1\_SET & SET \\
|
\hline LTC\_ASN1\_SET & SET \\
|
||||||
\hline LTC\_ASN1\_SETOF & SET OF \\
|
\hline LTC\_ASN1\_SETOF & SET OF \\
|
||||||
\hline LTC\_ASN1\_CHOICE & CHOICE \\
|
\hline LTC\_ASN1\_RAW\_BIT\_STRING & BIT STRING (one octet per char) \\
|
||||||
|
\hline LTC\_ASN1\_TELETEX\_STRING & TELETEX STRING (one octet per char) \\
|
||||||
|
\hline LTC\_ASN1\_CONSTRUCTED & A constructed type that is not SEQUENCE or SET \\
|
||||||
|
\hline LTC\_ASN1\_CONTEXT\_SPECIFIC & A context-specific type \\
|
||||||
|
\hline LTC\_ASN1\_GENERALIZEDTIME & GeneralizedTime (see ltc\_generalizedtime structure) \\
|
||||||
\hline
|
\hline
|
||||||
\end{tabular}
|
\end{tabular}
|
||||||
\caption{List of ASN.1 Supported Types}
|
\caption{List of ASN.1 Supported Types}
|
||||||
@ -4560,7 +4718,7 @@ The SEQUENCE data type is a collection of other ASN.1 data types encapsulated wi
|
|||||||
To encode a sequence a \textbf{ltc\_asn1\_list} array must be initialized with the members of the sequence and their respective pointers. The encoding is performed
|
To encode a sequence a \textbf{ltc\_asn1\_list} array must be initialized with the members of the sequence and their respective pointers. The encoding is performed
|
||||||
with the following function.
|
with the following function.
|
||||||
|
|
||||||
\index{der\_encode\_sequence()}
|
\index{der\_encode\_sequence()}\index{LTC\_ASN1\_EOL}
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
int der_encode_sequence(ltc_asn1_list *list,
|
int der_encode_sequence(ltc_asn1_list *list,
|
||||||
unsigned long inlen,
|
unsigned long inlen,
|
||||||
@ -4614,7 +4772,7 @@ int der_length_sequence(ltc_asn1_list *list,
|
|||||||
|
|
||||||
This will get the encoding size for the given \textit{list} of length \textit{inlen} and store it in \textit{outlen}.
|
This will get the encoding size for the given \textit{list} of length \textit{inlen} and store it in \textit{outlen}.
|
||||||
|
|
||||||
\subsubsection{SEQUENCE Multiple Argument Lists}
|
\subsubsection{SEQUENCE Multiple Argument Lists}\index{LTC\_ASN1\_EOL}
|
||||||
|
|
||||||
For small or simple sequences an encoding or decoding can be performed with one of the following two functions.
|
For small or simple sequences an encoding or decoding can be performed with one of the following two functions.
|
||||||
|
|
||||||
@ -4784,6 +4942,30 @@ int der_length_bit_string(unsigned long nbits,
|
|||||||
These will encode or decode a BIT STRING data type. The bits are passed in (or read out) using one \textbf{char} per bit. A non--zero value will be interpreted
|
These will encode or decode a BIT STRING data type. The bits are passed in (or read out) using one \textbf{char} per bit. A non--zero value will be interpreted
|
||||||
as a one bit, and a zero value a zero bit.
|
as a one bit, and a zero value a zero bit.
|
||||||
|
|
||||||
|
\subsection{ASN.1 RAW BIT STRING}
|
||||||
|
|
||||||
|
\index{der\_encode\_raw\_bit\_string()}\index{der\_decode\_raw\_bit\_string()}
|
||||||
|
\begin{verbatim}
|
||||||
|
int der_encode_raw_bit_string(const unsigned char *in,
|
||||||
|
unsigned long inlen,
|
||||||
|
unsigned char *out,
|
||||||
|
unsigned long *outlen);
|
||||||
|
|
||||||
|
int der_decode_raw_bit_string(const unsigned char *in,
|
||||||
|
unsigned long inlen,
|
||||||
|
unsigned char *out,
|
||||||
|
unsigned long *outlen);
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
These will encode or decode a BIT STRING data type.
|
||||||
|
The bits are passed in (or read out) using one \textbf{unsigned char} per 8 bit.
|
||||||
|
|
||||||
|
This function differs from the normal BIT STRING, as it can be used to directly
|
||||||
|
process raw binary data and store it to resp. read it from an ASN.1 BIT STRING
|
||||||
|
data type.
|
||||||
|
|
||||||
|
The length function is the same as for the normal BIT STRING \textit{der\_length\_bit\_string()}.
|
||||||
|
|
||||||
\subsection{ASN.1 OCTET STRING}
|
\subsection{ASN.1 OCTET STRING}
|
||||||
|
|
||||||
\index{der\_encode\_octet\_string()}\index{der\_decode\_octet\_string()}\index{der\_length\_octet\_string()}
|
\index{der\_encode\_octet\_string()}\index{der\_decode\_octet\_string()}\index{der\_length\_octet\_string()}
|
||||||
@ -4850,6 +5032,26 @@ to numerical conversions based on the conventions of the compiler being used. F
|
|||||||
say a SPARC machine. Internally, these functions have a table of literal characters and their numerical ASCII values. This provides a stable conversion provided
|
say a SPARC machine. Internally, these functions have a table of literal characters and their numerical ASCII values. This provides a stable conversion provided
|
||||||
that the build platform honours the run--time platforms character conventions.
|
that the build platform honours the run--time platforms character conventions.
|
||||||
|
|
||||||
|
\subsection{ASN.1 TELETEX STRING}
|
||||||
|
|
||||||
|
\index{der\_decode\_teletex\_string()}\index{der\_length\_teletex\_string()}
|
||||||
|
\begin{verbatim}
|
||||||
|
int der_decode_teletex_string(const unsigned char *in,
|
||||||
|
unsigned long inlen,
|
||||||
|
unsigned char *out,
|
||||||
|
unsigned long *outlen);
|
||||||
|
|
||||||
|
int der_length_teletex_string(const unsigned char *octets,
|
||||||
|
unsigned long noctets,
|
||||||
|
unsigned long *outlen);
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
These will decode a TELETEX STRING.
|
||||||
|
The characters are read in individual \textbf{char} elements.
|
||||||
|
The internal structure is similar to that of the IA5 STRING implementation, to
|
||||||
|
be able to provide a stable conversion independent of the build-- and run--time
|
||||||
|
platform.
|
||||||
|
|
||||||
\subsection{ASN.1 PRINTABLE STRING}
|
\subsection{ASN.1 PRINTABLE STRING}
|
||||||
|
|
||||||
\index{der\_encode\_printable\_string()}\index{der\_decode\_printable\_string()}\index{der\_length\_printable\_string()}
|
\index{der\_encode\_printable\_string()}\index{der\_decode\_printable\_string()}\index{der\_length\_printable\_string()}
|
||||||
@ -4941,6 +5143,57 @@ input. The decoder will read all valid ASN.1 formats and perform range checking
|
|||||||
|
|
||||||
It is suggested that decoded data be further scrutinized (e.g. days of month in particular).
|
It is suggested that decoded data be further scrutinized (e.g. days of month in particular).
|
||||||
|
|
||||||
|
\subsection{ASN.1 GeneralizedTime}
|
||||||
|
|
||||||
|
The GeneralizedTime type is to store a date and time in ASN.1 format. It uses the following structure to organize the time.
|
||||||
|
|
||||||
|
\index{ltc\_utctime structure}
|
||||||
|
\begin{verbatim}
|
||||||
|
typedef struct {
|
||||||
|
unsigned YYYY, /* year 0--9999 */
|
||||||
|
MM, /* month 1--12 */
|
||||||
|
DD, /* day 1--31 */
|
||||||
|
hh, /* hour 0--23 */
|
||||||
|
mm, /* minute 0--59 */
|
||||||
|
ss, /* second 0--59 */
|
||||||
|
fs, /* fractional seconds 1--UINT_MAX */
|
||||||
|
off_dir, /* timezone offset direction 0 == +, 1 == - */
|
||||||
|
off_hh, /* timezone offset hours */
|
||||||
|
off_mm; /* timezone offset minutes */
|
||||||
|
} ltc_generalizedtime;
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
The time can be offset plus or minus a set amount of hours (off\_hh) and minutes (off\_mm). When \textit{off\_dir} is zero, the time will be added otherwise it
|
||||||
|
will be subtracted. For instance, the array $\lbrace 2005, 6, 20, 22, 4, 0, 122, 0, 5, 0 \rbrace$ represents the current time of
|
||||||
|
\textit{2005, June 20th, 22:04:00.122} with a time offset of +05h00.
|
||||||
|
|
||||||
|
\index{der\_encode\_utctime()}\index{der\_decode\_utctime()}\index{der\_length\_utctime()}
|
||||||
|
\begin{verbatim}
|
||||||
|
int der_encode_generalizedtime(ltc_generalizedtime *gtime,
|
||||||
|
unsigned char *out,
|
||||||
|
unsigned long *outlen);
|
||||||
|
|
||||||
|
int der_decode_generalizedtime(const unsigned char *in,
|
||||||
|
unsigned long *inlen,
|
||||||
|
ltc_generalizedtime *out);
|
||||||
|
|
||||||
|
int der_length_generalizedtime(ltc_generalizedtime *gtime,
|
||||||
|
unsigned long *outlen);
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
The encoder will store time in one of the following ASN.1 formats, either \textit{YYYYMMDDhhmmssZ} or
|
||||||
|
\textit{YYYYMMDDhhmmss$\pm$hhmm} or\textit{YYYYMMDDhhmmss.fsZ} or \textit{YYYYMMDDhhmmss.fs$\pm$hhmm},
|
||||||
|
and perform minimal error checking on the input.
|
||||||
|
The decoder will read all valid ASN.1 formats and perform range checking on the values (not complete but
|
||||||
|
rational) useful for catching packet errors.
|
||||||
|
|
||||||
|
The fractional seconds are always added in case they are not $0$.
|
||||||
|
The implementation of fractional seconds is currently unreliable and you can't detect decoded
|
||||||
|
resp. encode leading $0$'s (e.g. \textit{20170424232717.005Z} would be decoded as
|
||||||
|
\textit{22. April 2017, 23:27:17.5}).
|
||||||
|
|
||||||
|
It is suggested that decoded data be further scrutinized (e.g. days of month in particular).
|
||||||
|
|
||||||
\subsection{ASN.1 CHOICE}
|
\subsection{ASN.1 CHOICE}
|
||||||
|
|
||||||
The CHOICE ASN.1 type represents a union of ASN.1 types all of which are stored in a \textit{ltc\_asn1\_list}. There is no encoder for the CHOICE type, only a
|
The CHOICE ASN.1 type represents a union of ASN.1 types all of which are stored in a \textit{ltc\_asn1\_list}. There is no encoder for the CHOICE type, only a
|
||||||
@ -4974,6 +5227,8 @@ When a SEQUENCE or SET has been encountered a SEQUENCE (or SET resp.) item will
|
|||||||
pointer points to a new list of items contained within the object.
|
pointer points to a new list of items contained within the object.
|
||||||
|
|
||||||
\index{der\_decode\_sequence\_flexi()}
|
\index{der\_decode\_sequence\_flexi()}
|
||||||
|
\index{LTC\_ASN1\_CONSTRUCTED}
|
||||||
|
\index{LTC\_ASN1\_CONTEXT\_SPECIFIC}
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
int der_decode_sequence_flexi(const unsigned char *in,
|
int der_decode_sequence_flexi(const unsigned char *in,
|
||||||
unsigned long *inlen,
|
unsigned long *inlen,
|
||||||
@ -4988,6 +5243,26 @@ normally. The decoded list \textit{out} will point to the very first element of
|
|||||||
|
|
||||||
An invalid decoding will terminate the process, and free the allocated memory automatically.
|
An invalid decoding will terminate the process, and free the allocated memory automatically.
|
||||||
|
|
||||||
|
The flexi decoder calls itself when decoding a constructed type. This leads to
|
||||||
|
a 'child process' that will terminate when it decodes an unkown/invalid
|
||||||
|
identifier and leaves an allocated but uninitialized child element.
|
||||||
|
However the parent processing will continue with a "soft-error".
|
||||||
|
This can be detected by checking for \textit{child} elements with
|
||||||
|
type \textbf{LTC\_ASN1\_EOL} after decoding.
|
||||||
|
|
||||||
|
As of v1.18 the flexi decoder will also decode arbitrary constructed types
|
||||||
|
other than SEQUENCE and SET. The \textit{type} field will be set to
|
||||||
|
\textbf{LTC\_ASN1\_CONSTRUCTED} and the plain identifier that was indicated in the ASN.1
|
||||||
|
encoding is stored in the \textit{used} field. Further decoding is done in the
|
||||||
|
same way as if it were a SEQUENCE or SET.
|
||||||
|
|
||||||
|
Also as of v1.18 the flexi decoder is capable to handle
|
||||||
|
\textit{context-specific} encodings. The \textit{type} field will be set to
|
||||||
|
\textbf{LTC\_ASN1\_CONTEXT\_SPECIFIC} and the plain identifier that was indicated
|
||||||
|
in the ASN.1 encoding is stored in the \textit{used} field. Encapsulated data
|
||||||
|
in the \textit{context-specific} encoding is copied to newly allocated memory
|
||||||
|
and is accessible through the \textit{data} field.
|
||||||
|
|
||||||
\textbf{Note:} the list decoded by this function is \textbf{NOT} in the correct form for der\_encode\_sequence() to use directly. You will first
|
\textbf{Note:} the list decoded by this function is \textbf{NOT} in the correct form for der\_encode\_sequence() to use directly. You will first
|
||||||
have to convert the list by first storing all of the siblings in an array then storing all the children as sub-lists of a sequence using the \textit{.data}
|
have to convert the list by first storing all of the siblings in an array then storing all the children as sub-lists of a sequence using the \textit{.data}
|
||||||
pointer. Currently no function in LibTomCrypt provides this ability.
|
pointer. Currently no function in LibTomCrypt provides this ability.
|
||||||
@ -5311,6 +5586,130 @@ to get a prime of the form $p \equiv 3\mbox{ }(\mbox{mod } 4)$. So if you want
|
|||||||
\textit{len = -128} to the function. Upon success it will return {\bf CRYPT\_OK} and \textit{N} will contain an integer which
|
\textit{len = -128} to the function. Upon success it will return {\bf CRYPT\_OK} and \textit{N} will contain an integer which
|
||||||
is very likely prime.
|
is very likely prime.
|
||||||
|
|
||||||
|
\mysection{Dynamic Language Support}
|
||||||
|
\index{Dynamic Language Support}
|
||||||
|
Various LibTomCrypt functions require that their callers define a struct
|
||||||
|
(or a union) and provide a pointer to it, or allocate sufficient memory and
|
||||||
|
provide its pointer. Programs written in C or C++ can obtain the necessary
|
||||||
|
information by simply including the appropriate header files, but dynamic
|
||||||
|
languages like Python don't understand C header files, and without assistance,
|
||||||
|
have no way to know how much memory to allocate. A similar story can be told
|
||||||
|
for certain LTC constant values.
|
||||||
|
|
||||||
|
LTC's Dynamic Language Support provides functions that return the size of
|
||||||
|
a named struct or union, the value of a named constant, a list of all sizes
|
||||||
|
supported, and a list of all named constants supported. Two additional
|
||||||
|
functions can initialize LTM and TFM.
|
||||||
|
|
||||||
|
To get the size of a named struct or union:
|
||||||
|
\begin{verbatim}
|
||||||
|
int crypt_get_size( const char *namein,
|
||||||
|
unsigned int *sizeout);
|
||||||
|
\end{verbatim}
|
||||||
|
$namein$ is spelled exactly as found in the C header files. This function will
|
||||||
|
return -1 if $namein$ is not found.
|
||||||
|
|
||||||
|
To get the value of a named constant:
|
||||||
|
\begin{verbatim}
|
||||||
|
int crypt_get_constant(const char *namein,
|
||||||
|
int *valueout);
|
||||||
|
\end{verbatim}
|
||||||
|
$namein$ is spelled exactly as found in the C header files. Again, -1 is
|
||||||
|
returned if $namein$ is not found.
|
||||||
|
|
||||||
|
To get the names of all the supported structs, unions and constants:
|
||||||
|
\begin{verbatim}
|
||||||
|
int crypt_list_all_sizes( char *names_list,
|
||||||
|
unsigned int *names_list_size);
|
||||||
|
|
||||||
|
int crypt_list_all_constants( char *names_list,
|
||||||
|
unsigned int *names_list_size);
|
||||||
|
\end{verbatim}
|
||||||
|
You may want to call these functions twice, first to get the amount
|
||||||
|
of memory to be allocated for the $names_list$, and a final time to
|
||||||
|
actually populate $names_list$. If $names_list$ is NULL,
|
||||||
|
$names_list_size$ will be the minimum size needed to receive the
|
||||||
|
complete $names_list$. If $names_list$ is NOT NULL, $names_list$ must
|
||||||
|
be a pointer to sufficient memory into which the $names_list$ will be
|
||||||
|
written. Also, the value in $names_list_size$ sets the upper bound of
|
||||||
|
the number of characters to be written. A -1 return value signifies
|
||||||
|
insufficient space.
|
||||||
|
|
||||||
|
The format of the $names_list$ string is a series of $name,value$ pairs
|
||||||
|
where each name and value is separated by a comma, the pairs are separated
|
||||||
|
by newlines, and the list is null terminated.
|
||||||
|
|
||||||
|
Calling either of these functions will initialize the respective
|
||||||
|
math library.
|
||||||
|
\begin{verbatim}
|
||||||
|
void init_LTM(void);
|
||||||
|
void init_TFM(void);
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
Here is a Python program demonstrating how to call various LTC dynamic
|
||||||
|
language support functions.
|
||||||
|
\begin{verbatim}
|
||||||
|
from ctypes import *
|
||||||
|
|
||||||
|
# load the OSX shared/dynamic library
|
||||||
|
LIB = CDLL('libtomcrypt.dylib')
|
||||||
|
|
||||||
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
# print info about this library
|
||||||
|
|
||||||
|
little = c_int() # assume False is big
|
||||||
|
word32 = c_int() # assume False is 64-bit
|
||||||
|
|
||||||
|
LIB.crypt_get_constant('ENDIAN_LITTLE', byref(little))
|
||||||
|
LIB.crypt_get_constant('ENDIAN_32BITWORD', byref(word32))
|
||||||
|
|
||||||
|
print('this lib was compiled for a %s endian %d-bit processor'
|
||||||
|
% ('little' if little else 'big', 32 if word32 else 64))
|
||||||
|
|
||||||
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
# print the size of the struct named "sha256_state"
|
||||||
|
|
||||||
|
struct_size = c_int()
|
||||||
|
|
||||||
|
# don't forget to add the '_struct' or '_union' suffix
|
||||||
|
LIB.crypt_get_size('sha256_state_struct', byref(struct_size))
|
||||||
|
|
||||||
|
print('allocate %d bytes for sha256_state' % struct_size.value)
|
||||||
|
|
||||||
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
# print a list of all supported named constants
|
||||||
|
|
||||||
|
list_size = c_int()
|
||||||
|
|
||||||
|
# call with NULL to calc the min size needed for the list
|
||||||
|
LIB.crypt_list_all_constants(None, byref(list_size))
|
||||||
|
|
||||||
|
# allocate required space
|
||||||
|
names_list = c_buffer(list_size.value)
|
||||||
|
|
||||||
|
# call again providing a pointer to where to write the list
|
||||||
|
LIB.crypt_list_all_constants(names_list, byref(list_size))
|
||||||
|
|
||||||
|
print(names_list.value)
|
||||||
|
|
||||||
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
# print a list of all supported named structs and unions
|
||||||
|
|
||||||
|
list_size = c_int()
|
||||||
|
|
||||||
|
# call with NULL to calc the min size needed for the list
|
||||||
|
LIB.crypt_list_all_sizes(None, byref(list_size))
|
||||||
|
|
||||||
|
# allocate required space
|
||||||
|
names_list = c_buffer(list_size.value)
|
||||||
|
|
||||||
|
# call again providing a pointer to where to write the list
|
||||||
|
LIB.crypt_list_all_sizes(names_list, byref(list_size))
|
||||||
|
|
||||||
|
print(names_list.value)
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
|
||||||
\chapter{Programming Guidelines}
|
\chapter{Programming Guidelines}
|
||||||
|
|
||||||
\mysection{Secure Pseudo Random Number Generators}
|
\mysection{Secure Pseudo Random Number Generators}
|
||||||
@ -5355,7 +5754,7 @@ e^{1.923 \cdot ln(n)^{1 \over 3} \cdot ln(ln(n))^{2 \over 3}}
|
|||||||
|
|
||||||
Note that $n$ is not the bit-length but the magnitude. For example, for a 1024-bit key $n = 2^{1024}$. The work required
|
Note that $n$ is not the bit-length but the magnitude. For example, for a 1024-bit key $n = 2^{1024}$. The work required
|
||||||
is:
|
is:
|
||||||
\begin{figure}[here]
|
\begin{figure}[h]
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tabular}{|c|c|}
|
\begin{tabular}{|c|c|}
|
||||||
\hline RSA/DH Key Size (bits) & Work Factor ($log_2$) \\
|
\hline RSA/DH Key Size (bits) & Work Factor ($log_2$) \\
|
||||||
@ -5375,7 +5774,7 @@ is:
|
|||||||
|
|
||||||
The work factor for ECC keys is much higher since the best attack is still fully exponential. Given a key of magnitude
|
The work factor for ECC keys is much higher since the best attack is still fully exponential. Given a key of magnitude
|
||||||
$n$ it requires $\sqrt n$ work. The following table summarizes the work required:
|
$n$ it requires $\sqrt n$ work. The following table summarizes the work required:
|
||||||
\begin{figure}[here]
|
\begin{figure}[h]
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tabular}{|c|c|}
|
\begin{tabular}{|c|c|}
|
||||||
\hline ECC Key Size (bits) & Work Factor ($log_2$) \\
|
\hline ECC Key Size (bits) & Work Factor ($log_2$) \\
|
||||||
@ -5594,14 +5993,14 @@ if you handle signals on your own. When set to 3, it will resolve to a empty ma
|
|||||||
to 4, it will return CRYPT\_INVALID\_ARG to the caller.
|
to 4, it will return CRYPT\_INVALID\_ARG to the caller.
|
||||||
|
|
||||||
\subsubsection{Endianness}
|
\subsubsection{Endianness}
|
||||||
There are five macros related to endianess issues. For little endian platforms define, \textbf{ENDIAN\_LITTLE}. For big endian
|
There are five macros related to endianness issues. For little endian platforms define, \textbf{ENDIAN\_LITTLE}. For big endian
|
||||||
platforms define \textbf{ENDIAN\_BIG}. Similarly when the default word size of an \textit{unsigned long} is 32-bits define \textbf{ENDIAN\_32BITWORD}
|
platforms define \textbf{ENDIAN\_BIG}. Similarly when the default word size of an \textit{unsigned long} is 32-bits define \textbf{ENDIAN\_32BITWORD}
|
||||||
or define \textbf{ENDIAN\_64BITWORD} when its 64-bits. If you do not define any of them the library will automatically use \textbf{ENDIAN\_NEUTRAL}
|
or define \textbf{ENDIAN\_64BITWORD} when its 64-bits. If you do not define any of them the library will automatically use \textbf{ENDIAN\_NEUTRAL}
|
||||||
which will work on all platforms.
|
which will work on all platforms.
|
||||||
|
|
||||||
Currently LibTomCrypt will detect x86-32, x86-64, MIPS R5900, SPARC and SPARC64 running GCC as well as x86-32 running MSVC.
|
Currently LibTomCrypt will detect x86-32, x86-64, MIPS R5900, SPARC and SPARC64 running GCC as well as x86-32 running MSVC.
|
||||||
|
|
||||||
\mysection{The Configure Script}
|
\mysection{Customisation}
|
||||||
There are also options you can specify from the \textit{tomcrypt\_custom.h} header file.
|
There are also options you can specify from the \textit{tomcrypt\_custom.h} header file.
|
||||||
|
|
||||||
\subsection{X memory routines}
|
\subsection{X memory routines}
|
||||||
@ -5636,7 +6035,7 @@ When this has been defined the library will not use faster word oriented operati
|
|||||||
which can be auto-detected. This macro ensures that they are never enabled.
|
which can be auto-detected. This macro ensures that they are never enabled.
|
||||||
|
|
||||||
\subsection{LTC\_FAST}
|
\subsection{LTC\_FAST}
|
||||||
This mode (auto-detected with x86\_32,x86\_64 platforms with GCC or MSVC) configures various routines such as ctr\_encrypt() or
|
This mode (auto-detected with x86\_32, x86\_64 platforms with GCC or CLANG) configures various routines such as ctr\_encrypt() or
|
||||||
cbc\_encrypt() that it can safely XOR multiple octets in one step by using a larger data type. This has the benefit of
|
cbc\_encrypt() that it can safely XOR multiple octets in one step by using a larger data type. This has the benefit of
|
||||||
cutting down the overhead of the respective functions.
|
cutting down the overhead of the respective functions.
|
||||||
|
|
||||||
@ -5656,8 +6055,8 @@ The simplest precaution is to make sure you process all data in power of two blo
|
|||||||
CTR'ing a long stream process it in blocks of (say) four kilobytes and handle any remaining incomplete blocks at the end of the stream.
|
CTR'ing a long stream process it in blocks of (say) four kilobytes and handle any remaining incomplete blocks at the end of the stream.
|
||||||
|
|
||||||
\index{LTC\_FAST\_TYPE}
|
\index{LTC\_FAST\_TYPE}
|
||||||
If you do plan on using the \textit{LTC\_FAST} mode you have to also define a \textit{LTC\_FAST\_TYPE} macro which resolves to an optimal sized
|
If you do plan on using the \textit{LTC\_FAST} mode, a \textit{LTC\_FAST\_TYPE} type which resolves to an optimal sized
|
||||||
data type you can perform integer operations with. Ideally it should be four or eight bytes since it must properly divide the size
|
data type you can perform integer operations with is required. For the auto-detected platforms this type will be defined automatically. Ideally it should be four or eight bytes since it must properly divide the size
|
||||||
of your block cipher (e.g. 16 bytes for AES). This means sadly if you're on a platform with 57--bit words (or something) you can't
|
of your block cipher (e.g. 16 bytes for AES). This means sadly if you're on a platform with 57--bit words (or something) you can't
|
||||||
use this mode. So sad.
|
use this mode. So sad.
|
||||||
|
|
||||||
|
BIN
doc/crypt.pdf
BIN
doc/crypt.pdf
Binary file not shown.
28
makefile
28
makefile
@ -12,8 +12,10 @@ PLATFORM := $(shell uname | sed -e 's/_.*//')
|
|||||||
|
|
||||||
ifeq ($V,1)
|
ifeq ($V,1)
|
||||||
silent=
|
silent=
|
||||||
|
silent_stdout=
|
||||||
else
|
else
|
||||||
silent=@
|
silent=@
|
||||||
|
silent_stdout= > /dev/null
|
||||||
endif
|
endif
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
@ -359,10 +361,12 @@ clean:
|
|||||||
cd testprof ; $(MAKE) clean
|
cd testprof ; $(MAKE) clean
|
||||||
|
|
||||||
#build the doxy files (requires Doxygen, tetex and patience)
|
#build the doxy files (requires Doxygen, tetex and patience)
|
||||||
doxy:
|
doxygen:
|
||||||
doxygen
|
doxygen $(silent_stdout)
|
||||||
cd doc/doxygen/latex ; ${MAKE} ; mv -f refman.pdf ../../.
|
|
||||||
echo The huge doxygen PDF should be available as doc/refman.pdf
|
doxy: doxygen
|
||||||
|
cd doc/doxygen/latex ; ${MAKE} $(silent_stdout) ; mv -f refman.pdf ../../.
|
||||||
|
@echo The huge doxygen PDF should be available as doc/refman.pdf
|
||||||
|
|
||||||
#This builds the crypt.pdf file. Note that the rm -f *.pdf has been removed
|
#This builds the crypt.pdf file. Note that the rm -f *.pdf has been removed
|
||||||
#from the clean command! This is because most people would like to keep the
|
#from the clean command! This is because most people would like to keep the
|
||||||
@ -380,11 +384,11 @@ docs: crypt.tex
|
|||||||
mv crypt-deterministic.tex crypt.tex
|
mv crypt-deterministic.tex crypt.tex
|
||||||
touch --reference=crypt.bak crypt.tex
|
touch --reference=crypt.bak crypt.tex
|
||||||
echo "hello" > crypt.ind
|
echo "hello" > crypt.ind
|
||||||
latex crypt > /dev/null
|
latex crypt $(silent_stdout)
|
||||||
latex crypt > /dev/null
|
latex crypt $(silent_stdout)
|
||||||
makeindex crypt.idx > /dev/null
|
makeindex crypt.idx $(silent_stdout)
|
||||||
perl fixupind.pl
|
perl fixupind.pl
|
||||||
pdflatex crypt > /dev/null
|
pdflatex crypt $(silent_stdout)
|
||||||
sed -b -i 's,^/ID \[.*\]$$,/ID [<0> <0>],g' crypt.pdf
|
sed -b -i 's,^/ID \[.*\]$$,/ID [<0> <0>],g' crypt.pdf
|
||||||
mv -ivf crypt.pdf doc/crypt.pdf
|
mv -ivf crypt.pdf doc/crypt.pdf
|
||||||
mv crypt.bak crypt.tex
|
mv crypt.bak crypt.tex
|
||||||
@ -392,12 +396,12 @@ docs: crypt.tex
|
|||||||
|
|
||||||
docdvi: crypt.tex
|
docdvi: crypt.tex
|
||||||
echo hello > crypt.ind
|
echo hello > crypt.ind
|
||||||
latex crypt > /dev/null
|
latex crypt $(silent_stdout)
|
||||||
latex crypt > /dev/null
|
latex crypt $(silent_stdout)
|
||||||
makeindex crypt.idx
|
makeindex crypt.idx
|
||||||
perl fixupind.pl
|
perl fixupind.pl
|
||||||
latex crypt > /dev/null
|
latex crypt $(silent_stdout)
|
||||||
latex crypt > /dev/null
|
latex crypt $(silent_stdout)
|
||||||
|
|
||||||
#zipup the project (take that!)
|
#zipup the project (take that!)
|
||||||
no_oops: clean
|
no_oops: clean
|
||||||
|
Loading…
Reference in New Issue
Block a user