Merge pull request #54 from libtom/feature/doc

Feature/doc (only crypt.tex + changes)
This commit is contained in:
Steffen Jaeckel 2017-04-26 00:23:34 +02:00 committed by GitHub
commit 93317a1d6a
6 changed files with 3493 additions and 1897 deletions

2
.gitignore vendored
View File

@ -14,6 +14,8 @@ test_*.txt
tv.txt
*_tv.txt
doxygen/
doc/crypt.pdf
doc/refman.pdf
# *nix/windows test executables
constants

2374
Doxyfile

File diff suppressed because it is too large Load Diff

31
changes
View File

@ -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
v1.17 -- Cryptography Research Inc. contributed another small volley of patches, one to fix __WCHAR_DEFINED__ for BSD platforms,
another to silence MSVC warnings.

621
crypt.tex
View File

@ -277,15 +277,15 @@ There are a few helper macros to make the coding process a bit easier. The firs
\begin{small}
\begin{center}
\begin{tabular}{|c|c|c|}
\hline STORE32L(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $x \to y[0 \ldots 3]$ \\
\hline STORE64L(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $x \to y[0 \ldots 7]$ \\
\hline LOAD32L(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $y[0 \ldots 3] \to x$ \\
\hline LOAD64L(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $y[0 \ldots 7] \to x$ \\
\hline STORE32H(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $x \to y[3 \ldots 0]$ \\
\hline STORE64H(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $x \to y[7 \ldots 0]$ \\
\hline LOAD32H(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $y[3 \ldots 0] \to x$ \\
\hline LOAD64H(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $y[7 \ldots 0] \to x$ \\
\hline BSWAP(x) & {\bf unsigned long} x & Swap bytes \\
\hline STORE32L(x, y) & {\bf ulong32} x, {\bf unsigned char} *y & $x \to y[0 \ldots 3]$ \\
\hline STORE64L(x, y) & {\bf ulong64} x, {\bf unsigned char} *y & $x \to y[0 \ldots 7]$ \\
\hline LOAD32L(x, y) & {\bf ulong32} x, {\bf unsigned char} *y & $y[0 \ldots 3] \to x$ \\
\hline LOAD64L(x, y) & {\bf ulong64} x, {\bf unsigned char} *y & $y[0 \ldots 7] \to x$ \\
\hline STORE32H(x, y) & {\bf ulong32} x, {\bf unsigned char} *y & $x \to y[3 \ldots 0]$ \\
\hline STORE64H(x, y) & {\bf ulong64} x, {\bf unsigned char} *y & $x \to y[7 \ldots 0]$ \\
\hline LOAD32H(x, y) & {\bf ulong32} x, {\bf unsigned char} *y & $y[3 \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 ulong32} x & Swap bytes \\
\hline
\end{tabular}
\caption{Load And Store Macros}
@ -299,15 +299,15 @@ There are 32 and 64-bit cyclic rotations as well:
\begin{small}
\begin{center}
\begin{tabular}{|c|c|c|}
\hline ROL(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x << y, 0 \le y \le 31$ \\
\hline ROLc(x, y) & {\bf unsigned long} x, {\bf const unsigned long} y & $x << y, 0 \le y \le 31$ \\
\hline ROR(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x >> y, 0 \le y \le 31$ \\
\hline RORc(x, y) & {\bf unsigned long} x, {\bf const unsigned long} y & $x >> y, 0 \le y \le 31$ \\
\hline ROL(x, y) & {\bf ulong32} x, {\bf ulong32} 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 ulong32} x, {\bf ulong32} 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 ROL64(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x << y, 0 \le y \le 63$ \\
\hline ROL64c(x, y) & {\bf unsigned long} x, {\bf const unsigned long} y & $x << y, 0 \le y \le 63$ \\
\hline ROR64(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x >> y, 0 \le y \le 63$ \\
\hline ROR64c(x, y) & {\bf unsigned long} x, {\bf const unsigned long} y & $x >> y, 0 \le y \le 63$ \\
\hline ROL64(x, y) & {\bf ulong64} x, {\bf ulong64} 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 ulong64} x, {\bf ulong64} 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
\end{tabular}
\caption{Rotate Macros}
@ -601,7 +601,7 @@ As of this release the current cipher\_descriptors elements are the following:
\vfil
\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{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{small}
\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 SEED & kseed\_desc & 16 & 16 & 16 \\
\hline KASUMI & kasumi\_desc & 8 & 16 & 8 \\
\hline Camellia & camellia\_desc & 16 & 16, 24, 32 & 18, 24 \\
\hline
\end{tabular}
\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
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
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
@ -1508,9 +1511,91 @@ Similarly, this will OCB decrypt, and compare the internally computed tag agains
appropriately.
\subsection{CCM Mode}
CCM is a NIST proposal for encrypt + authenticate that is centered around using AES (or any 16--byte cipher) as a primitive. Unlike EAX and OCB mode,
it is only meant for \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.
CCM is a NIST proposal for encrypt + authenticate that is centered around using AES (or any 16--byte cipher) as a primitive.
\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()}
\begin{verbatim}
@ -1526,86 +1611,107 @@ int ccm_memory(
int direction);
\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
16--byte block size for CCM.
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
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,
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).
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.
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
encrypted, it is stored in \textit{header} of length \textit{headerlen} octets. The header can be zero octets long (if $headerlen = 0$ then
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.
\subsubsection{Example Usage}
The following is an example usage of how to use CCM over multiple packets with a shared secret key.
\begin{small}
\begin{verbatim}
#include <tomcrypt.h>
int send_packet(const unsigned char *pt, unsigned long ptlen,
const unsigned char *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)
{
unsigned char key[16], nonce[12], pt[32], ct[32],
tag[16], tagcp[16];
unsigned long taglen;
int err;
ccm_state ccm;
unsigned char key[16], NONCE[12], pt[PACKET_SIZE];
int err, x;
unsigned long ptlen;
/* register cipher */
/* somehow fill key/NONCE with random values */
/* register AES */
register_cipher(&aes_desc);
/* somehow fill key, nonce, pt */
/* encrypt it */
taglen = sizeof(tag);
/* init the CCM state */
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, /* [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;
ccm_init(&ccm, find_cipher("aes"), key, 16, PACKET_SIZE, 16, size(NONCE))) != CRYPT_OK) {
whine_and_pout(err);
}
/* now pt[0..31] should hold the original plaintext,
tagcp[0..15] and tag[0..15] should have the same contents */
/* handle us some packets */
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{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:
\index{Hash descriptor table}
\begin{figure}[here]
\begin{figure}[h]
\begin{center}
\begin{tabular}{|c|c|c|}
\hline \textbf{Name} & \textbf{Descriptor Name} & \textbf{Size of Message Digest (bytes)} \\
\hline WHIRLPOOL & whirlpool\_desc & 64 \\
\hline SHA3-512 & sha3\_512\_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 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 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 BLAKE2S-224 & blake2s\_224\_desc & 28 \\
\hline BLAKE2B-384 & blake2b\_384\_desc & 48 \\
\hline TIGER-192 & tiger\_desc & 24 \\
\hline SHA-1 & sha1\_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 MD5 & md5\_desc & 16 \\
\hline MD4 & md4\_desc & 16 \\
\hline MD2 & md2\_desc & 16 \\
\hline BLAKE2S-128 & blake2s\_128\_desc & 16 \\
\hline
\end{tabular}
\end{center}
@ -2137,11 +2257,11 @@ int main(void)
\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
(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.
\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}.
\subsection{PRNGs Provided}
\begin{figure}[here]
\begin{figure}[h]
\begin{center}
\begin{small}
\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.
\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}
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.
@ -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}
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}
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$.
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}
\begin{small}
@ -3643,7 +3788,7 @@ int main(void)
\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
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}
To export a RSA key use the following function.
@ -3655,8 +3800,17 @@ int rsa_export(unsigned char *out,
int type,
rsa_key *key);
\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}
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.
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
there is no function provided to export in this format.
import the key, strip off the additional data and fill in the rsa\_key structure.
\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
$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{tabular}{|c|c|c|}
\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{small}
\begin{figure}[here]
\begin{figure}[h]
\begin{center}
\begin{small}
\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\_OBJECT\_IDENTIFIER & OBJECT IDENTIFIER \\
\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\_UTF8\_STRING & UTF8 STRING (one wchar\_t per char) \\
\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\_SET & SET \\
\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
\end{tabular}
\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
with the following function.
\index{der\_encode\_sequence()}
\index{der\_encode\_sequence()}\index{LTC\_ASN1\_EOL}
\begin{verbatim}
int der_encode_sequence(ltc_asn1_list *list,
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}.
\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.
@ -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
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}
\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
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}
\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).
\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}
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
@ -4963,7 +5216,7 @@ will have the \textit{used} flag set to non--zero to reflect it was the data typ
\subsection{ASN.1 Flexi Decoder}
The ASN.1 \textit{flexi} decoder allows the developer to decode arbitrary ASN.1 DER packets (provided they use data types LibTomCrypt supports) without first knowing
the structure of the data. Where der\_decode \_sequence() requires the developer to specify the data types to decode in advance the flexi decoder is entirely
the structure of the data. Where der\_decode\_sequence() requires the developer to specify the data types to decode in advance the flexi decoder is entirely
free form.
The flexi decoder uses the same \textit{ltc\_asn1\_list} but instead of being stored in an array it uses the linked list pointers \textit{prev}, \textit{next}, \textit{parent}
@ -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.
\index{der\_decode\_sequence\_flexi()}
\index{LTC\_ASN1\_CONSTRUCTED}
\index{LTC\_ASN1\_CONTEXT\_SPECIFIC}
\begin{verbatim}
int der_decode_sequence_flexi(const unsigned char *in,
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.
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
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.
@ -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
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}
\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
is:
\begin{figure}[here]
\begin{figure}[h]
\begin{center}
\begin{tabular}{|c|c|}
\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
$n$ it requires $\sqrt n$ work. The following table summarizes the work required:
\begin{figure}[here]
\begin{figure}[h]
\begin{center}
\begin{tabular}{|c|c|}
\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.
\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}
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.
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.
\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.
\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
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.
\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
data type you can perform integer operations with. Ideally it should be four or eight bytes since it must properly divide the size
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 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
use this mode. So sad.

Binary file not shown.

View File

@ -12,8 +12,10 @@ PLATFORM := $(shell uname | sed -e 's/_.*//')
ifeq ($V,1)
silent=
silent_stdout=
else
silent=@
silent_stdout= > /dev/null
endif
%.o: %.c
@ -359,10 +361,12 @@ clean:
cd testprof ; $(MAKE) clean
#build the doxy files (requires Doxygen, tetex and patience)
doxy:
doxygen
cd doc/doxygen/latex ; ${MAKE} ; mv -f refman.pdf ../../.
echo The huge doxygen PDF should be available as doc/refman.pdf
doxygen:
doxygen $(silent_stdout)
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
#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
touch --reference=crypt.bak crypt.tex
echo "hello" > crypt.ind
latex crypt > /dev/null
latex crypt > /dev/null
makeindex crypt.idx > /dev/null
latex crypt $(silent_stdout)
latex crypt $(silent_stdout)
makeindex crypt.idx $(silent_stdout)
perl fixupind.pl
pdflatex crypt > /dev/null
pdflatex crypt $(silent_stdout)
sed -b -i 's,^/ID \[.*\]$$,/ID [<0> <0>],g' crypt.pdf
mv -ivf crypt.pdf doc/crypt.pdf
mv crypt.bak crypt.tex
@ -392,12 +396,12 @@ docs: crypt.tex
docdvi: crypt.tex
echo hello > crypt.ind
latex crypt > /dev/null
latex crypt > /dev/null
latex crypt $(silent_stdout)
latex crypt $(silent_stdout)
makeindex crypt.idx
perl fixupind.pl
latex crypt > /dev/null
latex crypt > /dev/null
latex crypt $(silent_stdout)
latex crypt $(silent_stdout)
#zipup the project (take that!)
no_oops: clean