added libtomcrypt-0.98
This commit is contained in:
		
							parent
							
								
									a21f63bbd8
								
							
						
					
					
						commit
						69f289d6dc
					
				
							
								
								
									
										44
									
								
								changes
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								changes
									
									
									
									
									
								
							@ -1,3 +1,45 @@
 | 
			
		||||
August 6th, 2004
 | 
			
		||||
v0.98  -- Update to hmac_init to free all allocated memory on error
 | 
			
		||||
       -- Update to PRNG API to fix import/export functions of Fortuna and Yarrow
 | 
			
		||||
       -- Added test functions to PRNG api, RC4 now conforms ;-) [was a minor issue]
 | 
			
		||||
       -- Added the SOBER-128 PRNG based off of code donated by Greg Rose.
 | 
			
		||||
       -- Added Tech Note #4 [notes/tech0004.txt] 
 | 
			
		||||
       -- Changed RC4 back [due to request].  It will now XOR the output so you can use it like 
 | 
			
		||||
          a stream cipher easily.
 | 
			
		||||
       -- Update Fortuna's export() to emit a hash of each pool.  This means that the accumulated 
 | 
			
		||||
          entropy that was spread over all the pools isn't entirely lost when you export/import.
 | 
			
		||||
       -- Zhi Chen suggested a comment for rsa_encrypt_key() to let users know [easily] that it was
 | 
			
		||||
          PKCS #1 v2.0 padding.  (updated other rsa_* functions)
 | 
			
		||||
       -- Cleaned up Noekeon to remove unrolling [wasn't required, was messy and actually slower with GCC/ICC]
 | 
			
		||||
       -- Updated RC4 so that when you feed it >256 bytes of entropy it quietly ignores additional
 | 
			
		||||
          bytes.  Also removed the % from the key setup to speed it up a bit.
 | 
			
		||||
       -- Added cipher/hash/prng tests to x86_prof to help catch bugs while testing
 | 
			
		||||
       -- Made the PRNG "done" return int, fixed sprng_done to not require prng* to be non-null
 | 
			
		||||
       -- Spruced up mycrypt_custom.h to trap more errors and also help prevent LTMSSE from being defined
 | 
			
		||||
          on non-i386 platforms by accident.
 | 
			
		||||
       -- Added RSA/ECC/DH speed tests to x86_prof and cleaned it up to build with zero warnings
 | 
			
		||||
       -- Changed Fortuna to count only entropy [not the 2 byte header] added to pool[0] into the 
 | 
			
		||||
          reseed mechanism.  
 | 
			
		||||
       -- Added "export_size" member to prng_descriptor tables so you can know in advance the size of 
 | 
			
		||||
          the exported state for any given PRNG.  
 | 
			
		||||
       -- Ported over patch on LTM 0.30 [not ready to release LTM 0.31] that fixes bug in mp_mul()/mp_div()
 | 
			
		||||
          that used to result in negative zeroes when you multiplied zero by a negative integer.  
 | 
			
		||||
          (patch due to "Wolfgang Ehrhardt" <Wolfgang.Ehrhardt@munich.netsurf.de>)
 | 
			
		||||
       -- Fixed rsa_*decrypt_key() and rsa_*verify_hash() to default to invalid "stat" or "res".  This way
 | 
			
		||||
          if any of the higher level functions fail [before you get to the padding] the result will be in
 | 
			
		||||
          a known state].  Applied to both v2 and v1.5 padding helpers.
 | 
			
		||||
       -- Added MACs to x86_prof
 | 
			
		||||
       -- Fixed up "warnings" in x86_prof and tv_gen
 | 
			
		||||
       -- Added a "profiled" target back [for GCC 3.4 and ICC v8].  Doesn't seem to help but might be worth
 | 
			
		||||
          tinkering with.
 | 
			
		||||
       -- Beefed up load/store test in demos/test
 | 
			
		||||
 | 
			
		||||
       ++ New note, in order to use the optimized LOAD/STORE macros your platform
 | 
			
		||||
          must support unaligned 32/64 bit load/stores.  The x86s support this
 | 
			
		||||
          but some [ARM for instance] do not.  If your platform cannot perform
 | 
			
		||||
          unaligned operations you must use the endian neutral code which is safe for 
 | 
			
		||||
          any sort of platform.
 | 
			
		||||
 | 
			
		||||
July 23rd, 2004
 | 
			
		||||
v0.97b -- Added PKCS #1 v1.5 RSA encrypt/sign helpers (like rsa_sign_hash, etc...)
 | 
			
		||||
       -- Added missing prng check to rsa_decrypt_key() [not critical as I don't use 
 | 
			
		||||
@ -62,7 +104,7 @@ v0.96  -- Removed GF and Keyring code
 | 
			
		||||
       -- Changed PSS/OAEP API slightly to be more consistent with other PK functions (order of arguments)
 | 
			
		||||
       -- rsa_exptmod() now pads with leading zeroes as per I2OSP.
 | 
			
		||||
       -- added error checking to yarrow code
 | 
			
		||||
       -- Mike Frysinger pointed out that tommath.h from this distro will overwrite tommath.h
 | 
			
		||||
       --  pointed out that tommath.h from this distro will overwrite tommath.h
 | 
			
		||||
          from libtommath.  I changed this to ltc_tommath.h to avoid any such problems.
 | 
			
		||||
       -- Fixed bug in PSS encoder/decoder that didn't handle the MSB properly
 | 
			
		||||
       -- refactored AES, now sports an "encrypt only" descriptor which uses half as much code space.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										44
									
								
								crypt.c
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								crypt.c
									
									
									
									
									
								
							@ -141,6 +141,26 @@ const char *crypt_build_settings =
 | 
			
		||||
    "   CTR\n"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    "\nMACs:\n"
 | 
			
		||||
#if defined(HMAC)
 | 
			
		||||
    "   HMAC\n"
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(OMAC)
 | 
			
		||||
    "   OMAC\n"
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(PMAC)
 | 
			
		||||
    "   PMAC\n"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    "\nENC + AUTH modes:\n"
 | 
			
		||||
#if defined(EAX_MODE)
 | 
			
		||||
    "   EAX_MODE\n"
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(OCB_MODE)
 | 
			
		||||
    "   OCB_MODE\n"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    "\nPRNG:\n"
 | 
			
		||||
#if defined(YARROW)
 | 
			
		||||
    "   Yarrow\n"
 | 
			
		||||
@ -151,6 +171,12 @@ const char *crypt_build_settings =
 | 
			
		||||
#if defined(RC4)
 | 
			
		||||
    "   RC4\n"
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(FORTUNA)
 | 
			
		||||
    "   Fortuna\n"
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(SOBER128)
 | 
			
		||||
    "   SOBER128\n"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    "\nPK Algs:\n"
 | 
			
		||||
#if defined(MRSA)
 | 
			
		||||
@ -197,21 +223,6 @@ const char *crypt_build_settings =
 | 
			
		||||
#if defined(MPI)
 | 
			
		||||
    " MPI "
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(HMAC)
 | 
			
		||||
    " HMAC "
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(OMAC)
 | 
			
		||||
    " OMAC "
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(PMAC)
 | 
			
		||||
    " PMAC "
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(EAX_MODE)
 | 
			
		||||
    " EAX_MODE "
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(OCB_MODE)
 | 
			
		||||
    " OCB_MODE "
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(TRY_UNRANDOM_FIRST)
 | 
			
		||||
    " TRY_UNRANDOM_FIRST "
 | 
			
		||||
#endif
 | 
			
		||||
@ -229,6 +240,9 @@ const char *crypt_build_settings =
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(NO_FILE)
 | 
			
		||||
    " NO_FILE "
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(LTMSSE)
 | 
			
		||||
    " LTMSSE "
 | 
			
		||||
#endif
 | 
			
		||||
    "\n"
 | 
			
		||||
    "\n\n\n"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										161
									
								
								crypt.tex
									
									
									
									
									
								
							
							
						
						
									
										161
									
								
								crypt.tex
									
									
									
									
									
								
							@ -47,7 +47,7 @@
 | 
			
		||||
\def\gap{\vspace{0.5ex}}
 | 
			
		||||
\makeindex
 | 
			
		||||
\begin{document}
 | 
			
		||||
\title{LibTomCrypt \\ Version 0.97b}
 | 
			
		||||
\title{LibTomCrypt \\ Version 0.98}
 | 
			
		||||
\author{Tom St Denis \\
 | 
			
		||||
\\
 | 
			
		||||
tomstdenis@iahu.ca \\
 | 
			
		||||
@ -1687,12 +1687,15 @@ int pmac_test(void);
 | 
			
		||||
Which returns {\bf CRYPT\_OK} if the code passes otherwise it returns an error code.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
\chapter{Pseudo-Random Number Generators}
 | 
			
		||||
\section{Core Functions}
 | 
			
		||||
 | 
			
		||||
The library provides an array of core functions for Pseudo-Random Number Generators (PRNGs) as well.  A cryptographic PRNG is
 | 
			
		||||
used to expand a shorter bit string into a longer bit string.  PRNGs are used wherever random data is required such as Public Key (PK)
 | 
			
		||||
key generation.  There is a universal structure called ``prng\_state''.  To initialize a PRNG call:
 | 
			
		||||
\index{PRNG start}
 | 
			
		||||
\begin{verbatim}
 | 
			
		||||
int XXX_start(prng_state *prng);
 | 
			
		||||
\end{verbatim}
 | 
			
		||||
@ -1700,6 +1703,7 @@ int XXX_start(prng_state *prng);
 | 
			
		||||
This will setup the PRNG for future use and not seed it.  In order 
 | 
			
		||||
for the PRNG to be cryptographically useful you must give it entropy.  Ideally you'd have some OS level source to tap 
 | 
			
		||||
like in UNIX (see section 5.3).  To add entropy to the PRNG call:
 | 
			
		||||
\index{PRNG add\_entropy}
 | 
			
		||||
\begin{verbatim}
 | 
			
		||||
int XXX_add_entropy(const unsigned char *in, unsigned long len, 
 | 
			
		||||
                    prng_state *prng);
 | 
			
		||||
@ -1707,17 +1711,77 @@ int XXX_add_entropy(const unsigned char *in, unsigned long len,
 | 
			
		||||
 | 
			
		||||
Which returns {\bf CRYPTO\_OK} if the entropy was accepted.  Once you think you have enough entropy you call another
 | 
			
		||||
function to put the entropy into action.
 | 
			
		||||
\index{PRNG ready}
 | 
			
		||||
\begin{verbatim}
 | 
			
		||||
int XXX_ready(prng_state *prng);
 | 
			
		||||
\end{verbatim}
 | 
			
		||||
 | 
			
		||||
Which returns {\bf CRYPTO\_OK} if it is ready.  Finally to actually read bytes call:
 | 
			
		||||
\index{PRNG read}
 | 
			
		||||
\begin{verbatim}
 | 
			
		||||
unsigned long XXX_read(unsigned char *out, unsigned long len,
 | 
			
		||||
                       prng_state *prng);
 | 
			
		||||
\end{verbatim}
 | 
			
		||||
 | 
			
		||||
Which returns the number of bytes read from the PRNG.
 | 
			
		||||
Which returns the number of bytes read from the PRNG.  When you are finished with a PRNG state you call
 | 
			
		||||
the following.
 | 
			
		||||
 | 
			
		||||
\index{PRNG done}
 | 
			
		||||
\begin{verbatim}
 | 
			
		||||
void XXX_done(prng_state *prng);
 | 
			
		||||
\end{verbatim}
 | 
			
		||||
 | 
			
		||||
This will terminate a PRNG state and free any memory (if any) allocated.  To export a PRNG state
 | 
			
		||||
so that you can later resume the PRNG call the following.
 | 
			
		||||
 | 
			
		||||
\index{PRNG export}
 | 
			
		||||
\begin{verbatim}
 | 
			
		||||
int XXX_export(unsigned char *out, unsigned long *outlen, 
 | 
			
		||||
               prng_state    *prng);
 | 
			
		||||
\end{verbatim}
 | 
			
		||||
 | 
			
		||||
This will write a ``PRNG state'' to the buffer ``out'' of length ``outlen'' bytes.  The idea of 
 | 
			
		||||
the export is meant to be used as a ``seed file''.  That is, when the program starts up there will not likely
 | 
			
		||||
be that much entropy available.   To import a state to seed a PRNG call the following function.
 | 
			
		||||
 | 
			
		||||
\index{PRNG import}
 | 
			
		||||
\begin{verbatim}
 | 
			
		||||
int XXX_import(const unsigned char *in, unsigned long inlen, 
 | 
			
		||||
                     prng_state     *prng);
 | 
			
		||||
\end{verbatim}
 | 
			
		||||
 | 
			
		||||
This will call the start and add\_entropy functions of the given PRNG.  It will use the state in
 | 
			
		||||
``in'' of length ``inlen'' as the initial seed.  You must pass the same seed length as was exported
 | 
			
		||||
by the corresponding export function.
 | 
			
		||||
 | 
			
		||||
Note that importing a state will not ``resume'' the PRNG from where it left off.  That is, if you export
 | 
			
		||||
a state, emit (say) 8 bytes and then import the previously exported state the next 8 bytes will not 
 | 
			
		||||
specifically equal the 8 bytes you generated previously.
 | 
			
		||||
 | 
			
		||||
When a program is first executed the normal course of operation is 
 | 
			
		||||
 | 
			
		||||
\begin{enumerate}
 | 
			
		||||
   \item Gather entropy from your sources for a given period of time or number of events.
 | 
			
		||||
   \item Start, use your entropy via add\_entropy and ready the PRNG yourself.
 | 
			
		||||
\end{enumerate}
 | 
			
		||||
 | 
			
		||||
When your program is finished you simply call the export function and save the state to a medium (disk,
 | 
			
		||||
flash memory, etc).  The next time your application starts up you can detect the state, feed it to the 
 | 
			
		||||
import function and go on your way.  It is ideal that (as soon as possible) after startup you export a
 | 
			
		||||
fresh state.  This helps in the case that the program aborts or the machine is powered down without
 | 
			
		||||
being given a chance to exit properly.  
 | 
			
		||||
 | 
			
		||||
Note that even if you have a state to import it is important to add new entropy to the state.  However,
 | 
			
		||||
there is less pressure to do so.  
 | 
			
		||||
 | 
			
		||||
To test a PRNG for operational conformity call the following functions.
 | 
			
		||||
 | 
			
		||||
\index{PRNG test}
 | 
			
		||||
\begin{verbatim}
 | 
			
		||||
int XXX_test(void);
 | 
			
		||||
\end{verbatim}
 | 
			
		||||
 | 
			
		||||
This will return \textbf{CRYPT\_OK} if PRNG is operating properly.
 | 
			
		||||
 | 
			
		||||
\subsection{Remarks}
 | 
			
		||||
 | 
			
		||||
@ -1728,8 +1792,8 @@ checking is guaranteed to see if the entropy is sufficient or if the PRNG is eve
 | 
			
		||||
 | 
			
		||||
\subsection{Example}
 | 
			
		||||
 | 
			
		||||
Below is a simple snippet to read 10 bytes from yarrow.  Its important to note that this snippet is {\bf NOT} secure since
 | 
			
		||||
the entropy added is not random.
 | 
			
		||||
Below is a simple snippet to read 10 bytes from yarrow.  Its important to note that this snippet is 
 | 
			
		||||
{\bf NOT} secure since the entropy added is not random.
 | 
			
		||||
 | 
			
		||||
\begin{verbatim}
 | 
			
		||||
#include <mycrypt.h>
 | 
			
		||||
@ -1762,10 +1826,15 @@ PRNGs have descriptors too (surprised?). Stored in the structure ``prng\_descrip
 | 
			
		||||
\begin{verbatim}
 | 
			
		||||
struct _prng_descriptor {
 | 
			
		||||
    char *name;
 | 
			
		||||
    int  export_size;    /* size in bytes of exported state */
 | 
			
		||||
    int (*start)      (prng_state *);
 | 
			
		||||
    int (*add_entropy)(const unsigned char *, unsigned long, prng_state *);
 | 
			
		||||
    int (*ready)      (prng_state *);
 | 
			
		||||
    unsigned long (*read)(unsigned char *, unsigned long len, prng_state *);
 | 
			
		||||
    void (*done)(prng_state *);
 | 
			
		||||
    int (*export)(unsigned char *, unsigned long *, prng_state *);
 | 
			
		||||
    int (*import)(const unsigned char *, unsigned long, prng_state *);
 | 
			
		||||
    int (*test)(void);
 | 
			
		||||
};
 | 
			
		||||
\end{verbatim}
 | 
			
		||||
 | 
			
		||||
@ -1779,16 +1848,82 @@ int register_prng(const struct _prng_descriptor *prng);
 | 
			
		||||
int unregister_prng(const struct _prng_descriptor *prng);
 | 
			
		||||
\end{verbatim}
 | 
			
		||||
 | 
			
		||||
\subsubsection{PRNGs Provided}
 | 
			
		||||
Currently Yarrow (yarrow\_desc), RC4 (rc4\_desc) and the secure RNG (sprng\_desc) are provided as PRNGs within the 
 | 
			
		||||
library.  
 | 
			
		||||
\subsection{PRNGs Provided}
 | 
			
		||||
\begin{figure}[here]
 | 
			
		||||
\begin{center}
 | 
			
		||||
\begin{small}
 | 
			
		||||
\begin{tabular}{|c|c|l|}
 | 
			
		||||
\hline \textbf{Name} & \textbf{Descriptor} & \textbf{Usage} \\
 | 
			
		||||
\hline Yarrow & yarrow\_desc & Fast short-term PRNG \\
 | 
			
		||||
\hline Fortuna & fortuna\_desc & Fast long-term PRNG (recommended) \\
 | 
			
		||||
\hline RC4 & rc4\_desc & Stream Cipher \\
 | 
			
		||||
\hline SOBER-128 & sober128\_desc & Stream Cipher (also very fast PRNG) \\
 | 
			
		||||
\hline
 | 
			
		||||
\end{tabular}
 | 
			
		||||
\end{small}
 | 
			
		||||
\end{center}
 | 
			
		||||
\caption{List of Provided PRNGs}
 | 
			
		||||
\end{figure}
 | 
			
		||||
 | 
			
		||||
RC4 is provided with a PRNG interface because it is a stream cipher and not well suited for the symmetric block cipher
 | 
			
		||||
interface.  You provide the key for RC4 via the rc4\_add\_entropy() function.  By calling rc4\_ready() the key will be used
 | 
			
		||||
to setup the RC4 state for encryption or decryption.  The rc4\_read() function has been modified from RC4 since it will 
 | 
			
		||||
XOR the output of the RC4 keystream generator against the input buffer you provide.  The following snippet will demonstrate
 | 
			
		||||
how to encrypt a buffer with RC4:
 | 
			
		||||
\subsubsection{Yarrow}
 | 
			
		||||
Yarrow is fast PRNG meant to collect an unspecified amount of entropy from sources 
 | 
			
		||||
(keyboard, mouse, interrupts, etc) and produce an unbounded string of random bytes.  
 | 
			
		||||
 | 
			
		||||
\textit{Note:} This PRNG is still secure for most taskings but is no longer recommended.  Users
 | 
			
		||||
should use Fortuna instead.
 | 
			
		||||
 | 
			
		||||
\subsubsection{Fortuna}
 | 
			
		||||
 | 
			
		||||
Fortuna is a fast attack tolerant and more thoroughly designed PRNG suitable for long term
 | 
			
		||||
usage.  It is faster than the default implementation of Yarrow\footnote{Yarrow has been implemented
 | 
			
		||||
to work with most cipher and hash combos based on which you have chosen to build into the library.} while
 | 
			
		||||
providing more security.  
 | 
			
		||||
 | 
			
		||||
Fortuna is slightly less flexible than Yarrow in the sense that it only works with the AES block cipher 
 | 
			
		||||
and SHA--256 hash function.  Technically Fortuna will work with any block cipher that accepts a 256--bit
 | 
			
		||||
key and any hash that produces at least a 256--bit output.  However, to make the implementation simpler
 | 
			
		||||
it has been fixed to those choices.
 | 
			
		||||
 | 
			
		||||
Fortuna is more secure than Yarrow in the sense that attackers who learn parts of the entropy being 
 | 
			
		||||
added to the PRNG learn far less about the state than that of Yarrow.  Without getting into to many
 | 
			
		||||
details Fortuna has the ability to recover from state determination attacks where the attacker starts
 | 
			
		||||
to learn information from the PRNGs output about the internal state.  Yarrow on the other hand cannot 
 | 
			
		||||
recover from that problem until new entropy is added to the pool and put to use through the ready() function.
 | 
			
		||||
 | 
			
		||||
\subsubsection{RC4}
 | 
			
		||||
 | 
			
		||||
RC4 is an old stream cipher that can also double duty as a PRNG in a pinch.  You ``key'' it by
 | 
			
		||||
calling add\_entropy() and setup the key by calling ready().  You can only add upto 256 bytes via
 | 
			
		||||
add\_entropy().  
 | 
			
		||||
 | 
			
		||||
When you read from RC4 the output of the RC4 algorithm is XOR'd against your buffer you provide.  In this
 | 
			
		||||
manner you can use rc4\_read() as an encrypt (and decrypt) function.  
 | 
			
		||||
 | 
			
		||||
You really shouldn't use RC4 anymore.  This isn't because RC4 is weak (though biases are known to exist) just
 | 
			
		||||
simply that faster alternatives exist.
 | 
			
		||||
 | 
			
		||||
\subsubsection{SOBER-128}
 | 
			
		||||
 | 
			
		||||
SOBER-128 is a stream cipher designed by the QUALCOMM Australia team.  Like RC4 you ``key'' it by 
 | 
			
		||||
calling add\_entropy().  There is no need to call ready() for this PRNG as it does not do anything.  
 | 
			
		||||
 | 
			
		||||
Note that this cipher has several oddities about how it operates.  The first time you call 
 | 
			
		||||
add\_entropy() that sets the cipher's key.  Every other time you call the same function it sets
 | 
			
		||||
the cipher's IV variable.  The IV mechanism allows you to encrypt several messages with the same
 | 
			
		||||
key and not re--use the same key material.
 | 
			
		||||
 | 
			
		||||
Unlike Yarrow and Fortuna all of the entropy (and hence security) of this algorithm rests in the data
 | 
			
		||||
you pass it on the first call to add\_entropy().  All buffers sent to add\_entropy() must have a length
 | 
			
		||||
that is a multiple of four bytes.
 | 
			
		||||
 | 
			
		||||
Like RC4 the output of SOBER--128 is XOR'ed against the buffer you provide it.  In this manner you can use
 | 
			
		||||
sober128\_read() as an encrypt (and decrypt) function.
 | 
			
		||||
 | 
			
		||||
Since SOBER-128 has a fixed keying scheme and is very fast (faster than RC4) the ideal usage of SOBER-128 is to 
 | 
			
		||||
key it from the output of Fortuna (or Yarrow) and use it to encrypt messages.  It is also ideal for
 | 
			
		||||
simulations which need a high quality (and fast) stream of bytes.  
 | 
			
		||||
 | 
			
		||||
\subsubsection{Example Usage}
 | 
			
		||||
\begin{small}
 | 
			
		||||
\begin{verbatim}
 | 
			
		||||
#include <mycrypt.h>
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,10 @@
 | 
			
		||||
 | 
			
		||||
int cipher_hash_test(void)
 | 
			
		||||
{
 | 
			
		||||
   int x;
 | 
			
		||||
   int           x;
 | 
			
		||||
   unsigned char buf[4096];
 | 
			
		||||
   unsigned long n;
 | 
			
		||||
   prng_state    nprng;
 | 
			
		||||
   
 | 
			
		||||
   /* test ciphers */
 | 
			
		||||
   for (x = 0; cipher_descriptor[x].name != NULL; x++) {
 | 
			
		||||
@ -15,6 +18,24 @@ int cipher_hash_test(void)
 | 
			
		||||
   for (x = 0; hash_descriptor[x].name != NULL; x++) {
 | 
			
		||||
      DO(hash_descriptor[x].test());
 | 
			
		||||
   }
 | 
			
		||||
 
 | 
			
		||||
   /* test prngs (test, import/export */
 | 
			
		||||
   for (x = 0; prng_descriptor[x].name != NULL; x++) {
 | 
			
		||||
      DO(prng_descriptor[x].test());
 | 
			
		||||
      DO(prng_descriptor[x].start(&nprng));
 | 
			
		||||
      DO(prng_descriptor[x].add_entropy("helloworld12", 12, &nprng));
 | 
			
		||||
      DO(prng_descriptor[x].ready(&nprng));
 | 
			
		||||
      n = sizeof(buf);
 | 
			
		||||
      DO(prng_descriptor[x].export(buf, &n, &nprng));
 | 
			
		||||
      prng_descriptor[x].done(&nprng);
 | 
			
		||||
      DO(prng_descriptor[x].import(buf, n, &nprng));
 | 
			
		||||
      DO(prng_descriptor[x].ready(&nprng));
 | 
			
		||||
      if (prng_descriptor[x].read(buf, 100, &nprng) != 100) {
 | 
			
		||||
         fprintf(stderr, "Error reading from imported PRNG!\n");
 | 
			
		||||
         exit(EXIT_FAILURE);
 | 
			
		||||
      }
 | 
			
		||||
      prng_descriptor[x].done(&nprng);
 | 
			
		||||
   }
 | 
			
		||||
   
 | 
			
		||||
   return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,43 +1,44 @@
 | 
			
		||||
#include "test.h"
 | 
			
		||||
 | 
			
		||||
/* Test store/load macros with offsets */
 | 
			
		||||
int store_test(void)
 | 
			
		||||
{
 | 
			
		||||
  unsigned char buf[8];
 | 
			
		||||
  unsigned long L;
 | 
			
		||||
  ulong64 LL;
 | 
			
		||||
  unsigned char buf[24];
 | 
			
		||||
  unsigned long L, L1;
 | 
			
		||||
  int y;
 | 
			
		||||
  ulong64 LL, LL1;
 | 
			
		||||
 | 
			
		||||
  L = 0x12345678UL;
 | 
			
		||||
  STORE32L (L, &buf[0]);
 | 
			
		||||
  L = 0;
 | 
			
		||||
  LOAD32L (L, &buf[0]);
 | 
			
		||||
  if (L != 0x12345678UL) {
 | 
			
		||||
    printf ("LOAD/STORE32 Little don't work");
 | 
			
		||||
    return 1;
 | 
			
		||||
  }
 | 
			
		||||
  LL = CONST64 (0x01020304050607);
 | 
			
		||||
  STORE64L (LL, &buf[0]);
 | 
			
		||||
  LL = 0;
 | 
			
		||||
  LOAD64L (LL, &buf[0])
 | 
			
		||||
    if (LL != CONST64 (0x01020304050607)) {
 | 
			
		||||
    printf ("LOAD/STORE64 Little don't work");
 | 
			
		||||
    return 1;
 | 
			
		||||
  for (y = 0; y < 4; y++) {
 | 
			
		||||
      STORE32L(L, buf + y);
 | 
			
		||||
      LOAD32L(L1, buf + y);
 | 
			
		||||
      if (L1 != L) {
 | 
			
		||||
         fprintf(stderr, "\n32L failed at offset %d\n", y);
 | 
			
		||||
         return 1;
 | 
			
		||||
      }
 | 
			
		||||
      STORE32H(L, buf + y);
 | 
			
		||||
      LOAD32H(L1, buf + y);
 | 
			
		||||
      if (L1 != L) {
 | 
			
		||||
         fprintf(stderr, "\n32H failed at offset %d\n", y);
 | 
			
		||||
         return 1;
 | 
			
		||||
      }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  L = 0x12345678UL;
 | 
			
		||||
  STORE32H (L, &buf[0]);
 | 
			
		||||
  L = 0;
 | 
			
		||||
  LOAD32H (L, &buf[0]);
 | 
			
		||||
  if (L != 0x12345678UL) {
 | 
			
		||||
    printf ("LOAD/STORE32 High don't work, %08lx", L);
 | 
			
		||||
    return 1;
 | 
			
		||||
  }
 | 
			
		||||
  LL = CONST64 (0x01020304050607);
 | 
			
		||||
  STORE64H (LL, &buf[0]);
 | 
			
		||||
  LL = 0;
 | 
			
		||||
  LOAD64H (LL, &buf[0])
 | 
			
		||||
    if (LL != CONST64 (0x01020304050607)) {
 | 
			
		||||
    printf ("LOAD/STORE64 High don't work");
 | 
			
		||||
    return 1;
 | 
			
		||||
  for (y = 0; y < 8; y++) {
 | 
			
		||||
      STORE64L(LL, buf + y);
 | 
			
		||||
      LOAD64L(LL1, buf + y);
 | 
			
		||||
      if (LL1 != LL) {
 | 
			
		||||
         fprintf(stderr, "\n64L failed at offset %d\n", y);
 | 
			
		||||
         return 1;
 | 
			
		||||
      }
 | 
			
		||||
      STORE64H(LL, buf + y);
 | 
			
		||||
      LOAD64H(LL1, buf + y);
 | 
			
		||||
      if (LL1 != LL) {
 | 
			
		||||
         fprintf(stderr, "\n64H failed at offset %d\n", y);
 | 
			
		||||
         return 1;
 | 
			
		||||
      }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -112,15 +112,21 @@ void register_algs(void)
 | 
			
		||||
  register_hash (&whirlpool_desc);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
   if (register_prng(&yarrow_desc) == -1) {
 | 
			
		||||
      printf("Error registering yarrow PRNG\n");
 | 
			
		||||
      exit(-1);
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   if (register_prng(&sprng_desc) == -1) {
 | 
			
		||||
      printf("Error registering sprng PRNG\n");
 | 
			
		||||
      exit(-1);
 | 
			
		||||
   }
 | 
			
		||||
#ifdef YARROW
 | 
			
		||||
   register_prng(&yarrow_desc);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef FORTUNA
 | 
			
		||||
   register_prng(&fortuna_desc);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef RC4
 | 
			
		||||
   register_prng(&rc4_desc);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef SPRNG
 | 
			
		||||
   register_prng(&sprng_desc);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef SOBER128
 | 
			
		||||
   register_prng(&sober128_desc);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* sort tests based on their requirement/services.  Helps make sure dependencies are tested first */
 | 
			
		||||
 | 
			
		||||
@ -203,7 +203,7 @@ void cipher_gen(void)
 | 
			
		||||
void hmac_gen(void)
 | 
			
		||||
{
 | 
			
		||||
   unsigned char key[MAXBLOCKSIZE], output[MAXBLOCKSIZE], *input;
 | 
			
		||||
   int x, y, z, kl, err;
 | 
			
		||||
   int x, y, z, err;
 | 
			
		||||
   FILE *out;
 | 
			
		||||
   unsigned long len;
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										303
									
								
								demos/x86_prof.c
									
									
									
									
									
								
							
							
						
						
									
										303
									
								
								demos/x86_prof.c
									
									
									
									
									
								
							@ -191,16 +191,26 @@ void reg_algs(void)
 | 
			
		||||
  register_hash (&whirlpool_desc);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef YARROW 
 | 
			
		||||
   #error This demo requires Yarrow.
 | 
			
		||||
#endif
 | 
			
		||||
register_prng(&yarrow_desc);
 | 
			
		||||
#ifdef FORTUNA
 | 
			
		||||
register_prng(&fortuna_desc);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef RC4
 | 
			
		||||
register_prng(&rc4_desc);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef SOBER128
 | 
			
		||||
register_prng(&sober128_desc);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
rng_make_prng(128, find_prng("yarrow"), &prng, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int time_keysched(void)
 | 
			
		||||
{
 | 
			
		||||
  unsigned long x, i, y1;
 | 
			
		||||
  unsigned long x, y1;
 | 
			
		||||
  ulong64 t1, c1;
 | 
			
		||||
  symmetric_key skey;
 | 
			
		||||
  int kl;
 | 
			
		||||
@ -241,7 +251,7 @@ int time_cipher(void)
 | 
			
		||||
  symmetric_key skey;
 | 
			
		||||
  void    (*func) (const unsigned char *, unsigned char *, symmetric_key *);
 | 
			
		||||
  unsigned char key[MAXBLOCKSIZE], pt[MAXBLOCKSIZE];
 | 
			
		||||
 | 
			
		||||
  int err;
 | 
			
		||||
 | 
			
		||||
  printf ("\n\nECB Time Trials for the Symmetric Ciphers:\n");
 | 
			
		||||
  no_results = 0;
 | 
			
		||||
@ -249,6 +259,12 @@ int time_cipher(void)
 | 
			
		||||
    cipher_descriptor[x].setup (key, cipher_descriptor[x].min_key_length, 0,
 | 
			
		||||
                &skey);
 | 
			
		||||
 | 
			
		||||
    /* sanity check on cipher */
 | 
			
		||||
    if ((err = cipher_descriptor[x].test()) != CRYPT_OK) {
 | 
			
		||||
       fprintf(stderr, "\n\nERROR: Cipher %s failed self-test %s\n", cipher_descriptor[x].name, error_to_string(err));
 | 
			
		||||
       exit(EXIT_FAILURE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#define DO1   func(pt,pt,&skey);
 | 
			
		||||
#define DO2   DO1 DO1
 | 
			
		||||
 | 
			
		||||
@ -303,13 +319,20 @@ int time_hash(void)
 | 
			
		||||
  unsigned long x, y1, len;
 | 
			
		||||
  ulong64 t1, t2, c1, c2;
 | 
			
		||||
  hash_state md;
 | 
			
		||||
  int    (*func)(hash_state *, const unsigned char *, unsigned long);
 | 
			
		||||
  int    (*func)(hash_state *, const unsigned char *, unsigned long), err;
 | 
			
		||||
  unsigned char pt[MAXBLOCKSIZE];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  printf ("\n\nHASH Time Trials for:\n");
 | 
			
		||||
  no_results = 0;
 | 
			
		||||
  for (x = 0; hash_descriptor[x].name != NULL; x++) {
 | 
			
		||||
 | 
			
		||||
    /* sanity check on hash */
 | 
			
		||||
    if ((err = hash_descriptor[x].test()) != CRYPT_OK) {
 | 
			
		||||
       fprintf(stderr, "\n\nERROR: Hash %s failed self-test %s\n", hash_descriptor[x].name, error_to_string(err));
 | 
			
		||||
       exit(EXIT_FAILURE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    hash_descriptor[x].init(&md);
 | 
			
		||||
 | 
			
		||||
#define DO1   func(&md,pt,len);
 | 
			
		||||
@ -365,7 +388,7 @@ void time_mult(void)
 | 
			
		||||
           t1 = (t_read() - t1)>>1;
 | 
			
		||||
           if (t1 < t2) t2 = t1;
 | 
			
		||||
       }
 | 
			
		||||
       printf("%3d digits: %9llu cycles\n", x, t2);
 | 
			
		||||
       printf("%3lu digits: %9llu cycles\n", x, t2);
 | 
			
		||||
   }
 | 
			
		||||
   mp_clear_multi(&a,&b,&c,NULL);
 | 
			
		||||
 | 
			
		||||
@ -395,7 +418,7 @@ void time_sqr(void)
 | 
			
		||||
           t1 = (t_read() - t1)>>1;
 | 
			
		||||
           if (t1 < t2) t2 = t1;
 | 
			
		||||
       }
 | 
			
		||||
       printf("%3d digits: %9llu cycles\n", x, t2);
 | 
			
		||||
       printf("%3lu digits: %9llu cycles\n", x, t2);
 | 
			
		||||
   }
 | 
			
		||||
   mp_clear_multi(&a,&b,NULL);
 | 
			
		||||
 | 
			
		||||
@ -407,20 +430,27 @@ void time_prng(void)
 | 
			
		||||
{
 | 
			
		||||
   ulong64 t1, t2;
 | 
			
		||||
   unsigned char buf[4096];
 | 
			
		||||
   prng_state prng;
 | 
			
		||||
   prng_state tprng;
 | 
			
		||||
   unsigned long x, y;
 | 
			
		||||
   int           err;
 | 
			
		||||
 | 
			
		||||
   printf("Timing PRNGs:\n");
 | 
			
		||||
   printf("Timing PRNGs (cycles/byte output, cycles add_entropy (32 bytes) :\n");
 | 
			
		||||
   for (x = 0; prng_descriptor[x].name != NULL; x++) {
 | 
			
		||||
      prng_descriptor[x].start(&prng);
 | 
			
		||||
 | 
			
		||||
      /* sanity check on prng */
 | 
			
		||||
      if ((err = prng_descriptor[x].test()) != CRYPT_OK) {
 | 
			
		||||
         fprintf(stderr, "\n\nERROR: PRNG %s failed self-test %s\n", prng_descriptor[x].name, error_to_string(err));
 | 
			
		||||
         exit(EXIT_FAILURE);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      prng_descriptor[x].start(&tprng);
 | 
			
		||||
      zeromem(buf, 256);
 | 
			
		||||
      prng_descriptor[x].add_entropy(buf, 256, &prng);
 | 
			
		||||
      prng_descriptor[x].ready(&prng);
 | 
			
		||||
      prng_descriptor[x].add_entropy(buf, 256, &tprng);
 | 
			
		||||
      prng_descriptor[x].ready(&tprng);
 | 
			
		||||
      t2 = -1;
 | 
			
		||||
 | 
			
		||||
#define DO1 prng_descriptor[x].read(buf, 4096, &prng);
 | 
			
		||||
#define DO1 if (prng_descriptor[x].read(buf, 4096, &tprng) != 4096) { printf("\n\nERROR READ != 4096\n\n"); exit(EXIT_FAILURE); }
 | 
			
		||||
#define DO2 DO1 DO1
 | 
			
		||||
 | 
			
		||||
      for (y = 0; y < 10000; y++) {
 | 
			
		||||
         t_start();
 | 
			
		||||
         t1 = t_read();
 | 
			
		||||
@ -428,14 +458,255 @@ void time_prng(void)
 | 
			
		||||
         t1 = (t_read() - t1)>>1;
 | 
			
		||||
         if (t1 < t2) t2 = t1;
 | 
			
		||||
      }
 | 
			
		||||
      printf("%20s: %llu\n", prng_descriptor[x].name, t2>>12);
 | 
			
		||||
   }
 | 
			
		||||
      printf("%20s: %5llu ", prng_descriptor[x].name, t2>>12);
 | 
			
		||||
#undef DO2
 | 
			
		||||
#undef DO1
 | 
			
		||||
 | 
			
		||||
#define DO1 prng_descriptor[x].start(&tprng); prng_descriptor[x].add_entropy(buf, 32, &tprng); prng_descriptor[x].ready(&tprng); prng_descriptor[x].done(&tprng);
 | 
			
		||||
#define DO2 DO1 DO1
 | 
			
		||||
      for (y = 0; y < 10000; y++) {
 | 
			
		||||
         t_start();
 | 
			
		||||
         t1 = t_read();
 | 
			
		||||
         DO2;
 | 
			
		||||
         t1 = (t_read() - t1)>>1;
 | 
			
		||||
         if (t1 < t2) t2 = t1;
 | 
			
		||||
      }
 | 
			
		||||
      printf("%5llu\n", t2);
 | 
			
		||||
#undef DO2
 | 
			
		||||
#undef DO1
 | 
			
		||||
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
      
 | 
			
		||||
/* time various RSA operations */
 | 
			
		||||
void time_rsa(void)
 | 
			
		||||
{
 | 
			
		||||
   rsa_key key;
 | 
			
		||||
   ulong64 t1, t2;
 | 
			
		||||
   unsigned char buf[2][4096];
 | 
			
		||||
   unsigned long x, y, z, zzz;
 | 
			
		||||
   int           err, zz;
 | 
			
		||||
 | 
			
		||||
   for (x = 1024; x <= 2048; x += 512) {
 | 
			
		||||
       t2 = 0;
 | 
			
		||||
       for (y = 0; y < 16; y++) {
 | 
			
		||||
           t_start();
 | 
			
		||||
           t1 = t_read();
 | 
			
		||||
           if ((err = rsa_make_key(&prng, find_prng("yarrow"), x/8, 65537, &key)) != CRYPT_OK) {
 | 
			
		||||
              fprintf(stderr, "\n\nrsa_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
 | 
			
		||||
              exit(EXIT_FAILURE);
 | 
			
		||||
           }
 | 
			
		||||
           t1 = t_read() - t1;
 | 
			
		||||
           t2 += t1;
 | 
			
		||||
 | 
			
		||||
           if (y < 15) {
 | 
			
		||||
              rsa_free(&key);
 | 
			
		||||
           }
 | 
			
		||||
       }
 | 
			
		||||
       t2 >>= 4;
 | 
			
		||||
       printf("RSA-%lu make_key    took %15llu cycles\n", x, t2);
 | 
			
		||||
 | 
			
		||||
       t2 = 0;
 | 
			
		||||
       for (y = 0; y < 16; y++) {
 | 
			
		||||
           t_start();
 | 
			
		||||
           t1 = t_read();
 | 
			
		||||
           z = sizeof(buf[1]);
 | 
			
		||||
           if ((err = rsa_encrypt_key(buf[0], 32, buf[1], &z, "testprog", 8, &prng,
 | 
			
		||||
                                      find_prng("yarrow"), find_hash("sha1"),
 | 
			
		||||
                                      &key)) != CRYPT_OK) {
 | 
			
		||||
              fprintf(stderr, "\n\nrsa_encrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
 | 
			
		||||
              exit(EXIT_FAILURE);
 | 
			
		||||
           }
 | 
			
		||||
           t1 = t_read() - t1;
 | 
			
		||||
           t2 += t1;
 | 
			
		||||
       }
 | 
			
		||||
       t2 >>= 4;
 | 
			
		||||
       printf("RSA-%lu encrypt_key took %15llu cycles\n", x, t2);
 | 
			
		||||
 | 
			
		||||
       t2 = 0;
 | 
			
		||||
       for (y = 0; y < 16; y++) {
 | 
			
		||||
           t_start();
 | 
			
		||||
           t1 = t_read();
 | 
			
		||||
           zzz = sizeof(buf[0]);
 | 
			
		||||
           if ((err = rsa_decrypt_key(buf[1], z, buf[0], &zzz, "testprog", 8, &prng,
 | 
			
		||||
                                      find_prng("yarrow"), find_hash("sha1"), 
 | 
			
		||||
                                      &zz, &key)) != CRYPT_OK) {
 | 
			
		||||
              fprintf(stderr, "\n\nrsa_decrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
 | 
			
		||||
              exit(EXIT_FAILURE);
 | 
			
		||||
           }
 | 
			
		||||
           t1 = t_read() - t1;
 | 
			
		||||
           t2 += t1;
 | 
			
		||||
       }
 | 
			
		||||
       t2 >>= 4;
 | 
			
		||||
       printf("RSA-%lu decrypt_key took %15llu cycles\n", x, t2);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
       rsa_free(&key);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* time various ECC operations */
 | 
			
		||||
void time_ecc(void)
 | 
			
		||||
{
 | 
			
		||||
   ecc_key key;
 | 
			
		||||
   ulong64 t1, t2;
 | 
			
		||||
   unsigned char buf[2][4096];
 | 
			
		||||
   unsigned long i, x, y, z;
 | 
			
		||||
   int           err;
 | 
			
		||||
   static unsigned long sizes[] = {160/8, 256/8, 521/8, 100000};
 | 
			
		||||
 | 
			
		||||
   for (x = sizes[i=0]; x < 100000; x = sizes[++i]) {
 | 
			
		||||
       t2 = 0;
 | 
			
		||||
       for (y = 0; y < 16; y++) {
 | 
			
		||||
           t_start();
 | 
			
		||||
           t1 = t_read();
 | 
			
		||||
           if ((err = ecc_make_key(&prng, find_prng("yarrow"), x, &key)) != CRYPT_OK) {
 | 
			
		||||
              fprintf(stderr, "\n\necc_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
 | 
			
		||||
              exit(EXIT_FAILURE);
 | 
			
		||||
           }
 | 
			
		||||
           t1 = t_read() - t1;
 | 
			
		||||
           t2 += t1;
 | 
			
		||||
 | 
			
		||||
           if (y < 15) {
 | 
			
		||||
              ecc_free(&key);
 | 
			
		||||
           }
 | 
			
		||||
       }
 | 
			
		||||
       t2 >>= 4;
 | 
			
		||||
       printf("ECC-%lu make_key    took %15llu cycles\n", x*8, t2);
 | 
			
		||||
 | 
			
		||||
       t2 = 0;
 | 
			
		||||
       for (y = 0; y < 16; y++) {
 | 
			
		||||
           t_start();
 | 
			
		||||
           t1 = t_read();
 | 
			
		||||
           z = sizeof(buf[1]);
 | 
			
		||||
           if ((err = ecc_encrypt_key(buf[0], 20, buf[1], &z, &prng, find_prng("yarrow"), find_hash("sha1"),
 | 
			
		||||
                                      &key)) != CRYPT_OK) {
 | 
			
		||||
              fprintf(stderr, "\n\necc_encrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
 | 
			
		||||
              exit(EXIT_FAILURE);
 | 
			
		||||
           }
 | 
			
		||||
           t1 = t_read() - t1;
 | 
			
		||||
           t2 += t1;
 | 
			
		||||
       }
 | 
			
		||||
       t2 >>= 4;
 | 
			
		||||
       printf("ECC-%lu encrypt_key took %15llu cycles\n", x*8, t2);
 | 
			
		||||
       ecc_free(&key);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* time various DH operations */
 | 
			
		||||
void time_dh(void)
 | 
			
		||||
{
 | 
			
		||||
   dh_key key;
 | 
			
		||||
   ulong64 t1, t2;
 | 
			
		||||
   unsigned char buf[2][4096];
 | 
			
		||||
   unsigned long i, x, y, z;
 | 
			
		||||
   int           err;
 | 
			
		||||
   static unsigned long sizes[] = {768/8, 1024/8, 1536/8, 2048/8, 3072/8, 4096/8, 100000};
 | 
			
		||||
 | 
			
		||||
   for (x = sizes[i=0]; x < 100000; x = sizes[++i]) {
 | 
			
		||||
       t2 = 0;
 | 
			
		||||
       for (y = 0; y < 16; y++) {
 | 
			
		||||
           t_start();
 | 
			
		||||
           t1 = t_read();
 | 
			
		||||
           if ((err = dh_make_key(&prng, find_prng("yarrow"), x, &key)) != CRYPT_OK) {
 | 
			
		||||
              fprintf(stderr, "\n\ndh_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
 | 
			
		||||
              exit(EXIT_FAILURE);
 | 
			
		||||
           }
 | 
			
		||||
           t1 = t_read() - t1;
 | 
			
		||||
           t2 += t1;
 | 
			
		||||
 | 
			
		||||
           if (y < 15) {
 | 
			
		||||
              dh_free(&key);
 | 
			
		||||
           }
 | 
			
		||||
       }
 | 
			
		||||
       t2 >>= 4;
 | 
			
		||||
       printf("DH-%4lu make_key    took %15llu cycles\n", x*8, t2);
 | 
			
		||||
 | 
			
		||||
       t2 = 0;
 | 
			
		||||
       for (y = 0; y < 16; y++) {
 | 
			
		||||
           t_start();
 | 
			
		||||
           t1 = t_read();
 | 
			
		||||
           z = sizeof(buf[1]);
 | 
			
		||||
           if ((err = dh_encrypt_key(buf[0], 20, buf[1], &z, &prng, find_prng("yarrow"), find_hash("sha1"),
 | 
			
		||||
                                      &key)) != CRYPT_OK) {
 | 
			
		||||
              fprintf(stderr, "\n\ndh_encrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
 | 
			
		||||
              exit(EXIT_FAILURE);
 | 
			
		||||
           }
 | 
			
		||||
           t1 = t_read() - t1;
 | 
			
		||||
           t2 += t1;
 | 
			
		||||
       }
 | 
			
		||||
       t2 >>= 4;
 | 
			
		||||
       printf("DH-%4lu encrypt_key took %15llu cycles\n", x*8, t2);
 | 
			
		||||
       dh_free(&key);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define MAC_SIZE 32
 | 
			
		||||
void time_macs(void)
 | 
			
		||||
{
 | 
			
		||||
   unsigned char *buf, key[16], tag[16];
 | 
			
		||||
   ulong64 t1, t2;
 | 
			
		||||
   unsigned long x, z;
 | 
			
		||||
   int err, cipher_idx, hash_idx;
 | 
			
		||||
 | 
			
		||||
   printf("\nMAC Timings (cycles/byte on %dKB blocks):\n", MAC_SIZE);
 | 
			
		||||
 | 
			
		||||
   buf = XMALLOC(MAC_SIZE*1024);
 | 
			
		||||
   if (buf == NULL) {
 | 
			
		||||
      fprintf(stderr, "\n\nout of heap yo\n\n");
 | 
			
		||||
      exit(EXIT_FAILURE);
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   cipher_idx = find_cipher("aes");
 | 
			
		||||
   hash_idx   = find_hash("md5");
 | 
			
		||||
 | 
			
		||||
   yarrow_read(buf, MAC_SIZE*1024, &prng);
 | 
			
		||||
   yarrow_read(key, 16, &prng);
 | 
			
		||||
 | 
			
		||||
   t2 = -1;
 | 
			
		||||
   for (x = 0; x < 10000; x++) {
 | 
			
		||||
        t_start();
 | 
			
		||||
        t1 = t_read();
 | 
			
		||||
        z = 16;
 | 
			
		||||
        if ((err = omac_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) {
 | 
			
		||||
           fprintf(stderr, "\n\nomac error... %s\n", error_to_string(err));
 | 
			
		||||
           exit(EXIT_FAILURE);
 | 
			
		||||
        }
 | 
			
		||||
        t1 = t_read() - t1;
 | 
			
		||||
        if (t1 < t2) t2 = t1;
 | 
			
		||||
   }
 | 
			
		||||
   printf("OMAC-AES\t\t%9llu\n", t2/(MAC_SIZE*1024));
 | 
			
		||||
 | 
			
		||||
   t2 = -1;
 | 
			
		||||
   for (x = 0; x < 10000; x++) {
 | 
			
		||||
        t_start();
 | 
			
		||||
        t1 = t_read();
 | 
			
		||||
        z = 16;
 | 
			
		||||
        if ((err = pmac_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) {
 | 
			
		||||
           fprintf(stderr, "\n\npmac error... %s\n", error_to_string(err));
 | 
			
		||||
           exit(EXIT_FAILURE);
 | 
			
		||||
        }
 | 
			
		||||
        t1 = t_read() - t1;
 | 
			
		||||
        if (t1 < t2) t2 = t1;
 | 
			
		||||
   }
 | 
			
		||||
   printf("PMAC-AES\t\t%9llu\n", t2/(MAC_SIZE*1024));
 | 
			
		||||
 | 
			
		||||
   t2 = -1;
 | 
			
		||||
   for (x = 0; x < 10000; x++) {
 | 
			
		||||
        t_start();
 | 
			
		||||
        t1 = t_read();
 | 
			
		||||
        z = 16;
 | 
			
		||||
        if ((err = hmac_memory(hash_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) {
 | 
			
		||||
           fprintf(stderr, "\n\nhmac error... %s\n", error_to_string(err));
 | 
			
		||||
           exit(EXIT_FAILURE);
 | 
			
		||||
        }
 | 
			
		||||
        t1 = t_read() - t1;
 | 
			
		||||
        if (t1 < t2) t2 = t1;
 | 
			
		||||
   }
 | 
			
		||||
   printf("HMAC-MD5\t\t%9llu\n", t2/(MAC_SIZE*1024));
 | 
			
		||||
 | 
			
		||||
   XFREE(buf);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(void)
 | 
			
		||||
{
 | 
			
		||||
@ -446,10 +717,14 @@ int main(void)
 | 
			
		||||
//  init_timer();
 | 
			
		||||
  time_mult();
 | 
			
		||||
  time_sqr();
 | 
			
		||||
  time_rsa();
 | 
			
		||||
  time_dh();
 | 
			
		||||
  time_ecc();
 | 
			
		||||
  time_prng();
 | 
			
		||||
  time_cipher();
 | 
			
		||||
  time_keysched();
 | 
			
		||||
  time_hash();
 | 
			
		||||
  time_macs();
 | 
			
		||||
 | 
			
		||||
  return EXIT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								doc/crypt.pdf
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								doc/crypt.pdf
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										147
									
								
								fortuna.c
									
									
									
									
									
								
							
							
						
						
									
										147
									
								
								fortuna.c
									
									
									
									
									
								
							@ -19,22 +19,36 @@ we reseed automatically when len(pool0) >= 64 or every FORTUNA_WD calls to the r
 | 
			
		||||
 | 
			
		||||
#ifdef FORTUNA 
 | 
			
		||||
 | 
			
		||||
/* requries SHA256 and AES  */
 | 
			
		||||
#if !(defined(RIJNDAEL) && defined(SHA256))
 | 
			
		||||
   #error FORTUNA requires SHA256 and RIJNDAEL (AES)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef FORTUNA_POOLS
 | 
			
		||||
   #warning FORTUNA_POOLS was not previously defined (old headers?)
 | 
			
		||||
   #define FORTUNA_POOLS 32
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if FORTUNA_POOLS < 4 || FORTUNA_POOLS > 32
 | 
			
		||||
   #error FORTUNA_POOLS must be in [4..32]
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
const struct _prng_descriptor fortuna_desc = {
 | 
			
		||||
    "fortuna",
 | 
			
		||||
    "fortuna", 1024,
 | 
			
		||||
    &fortuna_start,
 | 
			
		||||
    &fortuna_add_entropy,
 | 
			
		||||
    &fortuna_ready,
 | 
			
		||||
    &fortuna_read,
 | 
			
		||||
    &fortuna_done,
 | 
			
		||||
    &fortuna_export,
 | 
			
		||||
    &fortuna_import
 | 
			
		||||
 | 
			
		||||
    &fortuna_import,
 | 
			
		||||
    &fortuna_test
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* update the IV */
 | 
			
		||||
static void fortuna_update_iv(prng_state *prng)
 | 
			
		||||
{
 | 
			
		||||
   int x;
 | 
			
		||||
   int            x;
 | 
			
		||||
   unsigned char *IV;
 | 
			
		||||
   /* update IV */
 | 
			
		||||
   IV = prng->fortuna.IV;
 | 
			
		||||
@ -47,7 +61,7 @@ static void fortuna_update_iv(prng_state *prng)
 | 
			
		||||
/* reseed the PRNG */
 | 
			
		||||
static int fortuna_reseed(prng_state *prng)
 | 
			
		||||
{
 | 
			
		||||
   unsigned char tmp[32];
 | 
			
		||||
   unsigned char tmp[MAXBLOCKSIZE];
 | 
			
		||||
   hash_state    md;
 | 
			
		||||
   int           err, x;
 | 
			
		||||
 | 
			
		||||
@ -59,7 +73,7 @@ static int fortuna_reseed(prng_state *prng)
 | 
			
		||||
      return err;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   for (x = 0; x < 32; x++) {
 | 
			
		||||
   for (x = 0; x < FORTUNA_POOLS; x++) {
 | 
			
		||||
       if (x == 0 || ((prng->fortuna.reset_cnt >> (x-1)) & 1) == 0) { 
 | 
			
		||||
          /* terminate this hash */
 | 
			
		||||
          if ((err = sha256_done(&prng->fortuna.pool[x], tmp)) != CRYPT_OK) {
 | 
			
		||||
@ -105,7 +119,7 @@ int fortuna_start(prng_state *prng)
 | 
			
		||||
   _ARGCHK(prng != NULL);
 | 
			
		||||
   
 | 
			
		||||
   /* initialize the pools */
 | 
			
		||||
   for (x = 0; x < 32; x++) {
 | 
			
		||||
   for (x = 0; x < FORTUNA_POOLS; x++) {
 | 
			
		||||
       sha256_init(&prng->fortuna.pool[x]);
 | 
			
		||||
   }
 | 
			
		||||
   prng->fortuna.pool_idx = prng->fortuna.pool0_len = prng->fortuna.reset_cnt = 
 | 
			
		||||
@ -144,9 +158,11 @@ int fortuna_add_entropy(const unsigned char *buf, unsigned long len, prng_state
 | 
			
		||||
      return err;
 | 
			
		||||
   }
 | 
			
		||||
   if (prng->fortuna.pool_idx == 0) {
 | 
			
		||||
      prng->fortuna.pool0_len += len + 2;
 | 
			
		||||
      prng->fortuna.pool0_len += len;
 | 
			
		||||
   }
 | 
			
		||||
   if (++(prng->fortuna.pool_idx) == FORTUNA_POOLS) {
 | 
			
		||||
      prng->fortuna.pool_idx = 0;
 | 
			
		||||
   }
 | 
			
		||||
   prng->fortuna.pool_idx = (prng->fortuna.pool_idx + 1) & 31;
 | 
			
		||||
 | 
			
		||||
   return CRYPT_OK;
 | 
			
		||||
}
 | 
			
		||||
@ -160,7 +176,7 @@ unsigned long fortuna_read(unsigned char *dst, unsigned long len, prng_state *pr
 | 
			
		||||
{
 | 
			
		||||
   unsigned char tmp[16];
 | 
			
		||||
   int           err;
 | 
			
		||||
   unsigned long tlen, n;
 | 
			
		||||
   unsigned long tlen;
 | 
			
		||||
 | 
			
		||||
   _ARGCHK(dst  != NULL);
 | 
			
		||||
   _ARGCHK(prng != NULL);
 | 
			
		||||
@ -174,18 +190,21 @@ unsigned long fortuna_read(unsigned char *dst, unsigned long len, prng_state *pr
 | 
			
		||||
 | 
			
		||||
   /* now generate the blocks required */
 | 
			
		||||
   tlen = len;
 | 
			
		||||
   while (len > 0) {
 | 
			
		||||
       if (len >= 16) {
 | 
			
		||||
          /* encrypt the IV and store it */
 | 
			
		||||
          rijndael_ecb_encrypt(prng->fortuna.IV, dst, &prng->fortuna.skey);
 | 
			
		||||
          dst += 16;
 | 
			
		||||
          len -= 16;
 | 
			
		||||
       } else {
 | 
			
		||||
          rijndael_ecb_encrypt(prng->fortuna.IV, tmp, &prng->fortuna.skey);
 | 
			
		||||
          XMEMCPY(dst, tmp, len);
 | 
			
		||||
          len = 0;
 | 
			
		||||
       }
 | 
			
		||||
       fortuna_update_iv(prng);
 | 
			
		||||
 | 
			
		||||
   /* handle whole blocks without the extra memcpy */
 | 
			
		||||
   while (len >= 16) {
 | 
			
		||||
      /* encrypt the IV and store it */
 | 
			
		||||
      rijndael_ecb_encrypt(prng->fortuna.IV, dst, &prng->fortuna.skey);
 | 
			
		||||
      dst += 16;
 | 
			
		||||
      len -= 16;
 | 
			
		||||
      fortuna_update_iv(prng);
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   /* left over bytes? */
 | 
			
		||||
   if (len > 0) {
 | 
			
		||||
      rijndael_ecb_encrypt(prng->fortuna.IV, tmp, &prng->fortuna.skey);
 | 
			
		||||
      XMEMCPY(dst, tmp, len);
 | 
			
		||||
      fortuna_update_iv(prng);
 | 
			
		||||
   }
 | 
			
		||||
       
 | 
			
		||||
   /* generate new key */
 | 
			
		||||
@ -201,33 +220,77 @@ unsigned long fortuna_read(unsigned char *dst, unsigned long len, prng_state *pr
 | 
			
		||||
   return tlen;
 | 
			
		||||
}   
 | 
			
		||||
 | 
			
		||||
void fortuna_done(prng_state *prng)
 | 
			
		||||
int fortuna_done(prng_state *prng)
 | 
			
		||||
{
 | 
			
		||||
   int           err, x;
 | 
			
		||||
   unsigned char tmp[32];
 | 
			
		||||
 | 
			
		||||
   _ARGCHK(prng != NULL);
 | 
			
		||||
 | 
			
		||||
   /* terminate all the hashes */
 | 
			
		||||
   for (x = 0; x < FORTUNA_POOLS; x++) {
 | 
			
		||||
       if ((err = sha256_done(&(prng->fortuna.pool[x]), tmp)) != CRYPT_OK) {
 | 
			
		||||
          return err; 
 | 
			
		||||
       }
 | 
			
		||||
   }
 | 
			
		||||
   /* call cipher done when we invent one ;-) */
 | 
			
		||||
 | 
			
		||||
#ifdef CLEAN_STACK
 | 
			
		||||
   zeromem(tmp, sizeof(tmp));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
   return CRYPT_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
 | 
			
		||||
{
 | 
			
		||||
   int x;
 | 
			
		||||
   int         x, err;
 | 
			
		||||
   hash_state *md;
 | 
			
		||||
 | 
			
		||||
   _ARGCHK(out    != NULL);
 | 
			
		||||
   _ARGCHK(outlen != NULL);
 | 
			
		||||
   _ARGCHK(prng   != NULL);
 | 
			
		||||
 | 
			
		||||
   /* we'll write 2048 bytes for s&g's */
 | 
			
		||||
   if (*outlen < 2048) {
 | 
			
		||||
   /* we'll write bytes for s&g's */
 | 
			
		||||
   if (*outlen < 32*FORTUNA_POOLS) {
 | 
			
		||||
      return CRYPT_BUFFER_OVERFLOW;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   for (x = 0; x < 32; x++) {
 | 
			
		||||
      if (fortuna_read(out+x*64, 64, prng) != 64) {
 | 
			
		||||
         return CRYPT_ERROR_READPRNG;
 | 
			
		||||
   md = XMALLOC(sizeof(hash_state));
 | 
			
		||||
   if (md == NULL) {
 | 
			
		||||
      return CRYPT_MEM;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   /* to emit the state we copy each pool, terminate it then hash it again so 
 | 
			
		||||
    * an attacker who sees the state can't determine the current state of the PRNG 
 | 
			
		||||
    */   
 | 
			
		||||
   for (x = 0; x < FORTUNA_POOLS; x++) {
 | 
			
		||||
      /* copy the PRNG */
 | 
			
		||||
      XMEMCPY(md, &(prng->fortuna.pool[x]), sizeof(*md));
 | 
			
		||||
 | 
			
		||||
      /* terminate it */
 | 
			
		||||
      if ((err = sha256_done(md, out+x*32)) != CRYPT_OK) {
 | 
			
		||||
         goto __ERR;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /* now hash it */
 | 
			
		||||
      sha256_init(md);
 | 
			
		||||
      if ((err = sha256_process(md, out+x*32, 32)) != CRYPT_OK) {
 | 
			
		||||
         goto __ERR;
 | 
			
		||||
      }
 | 
			
		||||
      if ((err = sha256_done(md, out+x*32)) != CRYPT_OK) {
 | 
			
		||||
         goto __ERR;
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
   *outlen = 2048;
 | 
			
		||||
   *outlen = 32*FORTUNA_POOLS;
 | 
			
		||||
   err = CRYPT_OK;
 | 
			
		||||
 | 
			
		||||
   return CRYPT_OK;
 | 
			
		||||
__ERR:
 | 
			
		||||
#ifdef CLEAN_STACK
 | 
			
		||||
   zeromem(md, sizeof(*md));
 | 
			
		||||
#endif
 | 
			
		||||
   XFREE(md);
 | 
			
		||||
   return err;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
 | 
			
		||||
@ -237,19 +300,33 @@ int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prn
 | 
			
		||||
   _ARGCHK(in   != NULL);
 | 
			
		||||
   _ARGCHK(prng != NULL);
 | 
			
		||||
 | 
			
		||||
   if (inlen != 2048) {
 | 
			
		||||
   if (inlen != 32*FORTUNA_POOLS) {
 | 
			
		||||
      return CRYPT_INVALID_ARG;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   if ((err = fortuna_start(prng)) != CRYPT_OK) {
 | 
			
		||||
      return err;
 | 
			
		||||
   }
 | 
			
		||||
   for (x = 0; x < 32; x++) {
 | 
			
		||||
      if ((err = fortuna_add_entropy(in+x*64, 64, &prng)) != CRYPT_OK) {
 | 
			
		||||
   for (x = 0; x < FORTUNA_POOLS; x++) {
 | 
			
		||||
      if ((err = fortuna_add_entropy(in+x*32, 32, prng)) != CRYPT_OK) {
 | 
			
		||||
         return err;
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
   return fortuna_ready(&prng);
 | 
			
		||||
   return err;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int fortuna_test(void)
 | 
			
		||||
{
 | 
			
		||||
#ifndef LTC_TEST
 | 
			
		||||
   return CRYPT_NOP;
 | 
			
		||||
#else
 | 
			
		||||
   int err;
 | 
			
		||||
 | 
			
		||||
   if ((err = sha256_test()) != CRYPT_OK) {
 | 
			
		||||
      return err;
 | 
			
		||||
   }
 | 
			
		||||
   return rijndael_test();
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -64,17 +64,17 @@ int hmac_done(hmac_state *hmac, unsigned char *hashOut, unsigned long *outlen)
 | 
			
		||||
       return CRYPT_MEM;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Get the hash of the first HMAC vector plus the data
 | 
			
		||||
    /* Get the hash of the first HMAC vector plus the data */
 | 
			
		||||
    if ((err = hash_descriptor[hash].done(&hmac->md, isha)) != CRYPT_OK) {
 | 
			
		||||
       goto __ERR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Create the second HMAC vector vector for step (3)
 | 
			
		||||
    /* Create the second HMAC vector vector for step (3) */
 | 
			
		||||
    for(i=0; i < HMAC_BLOCKSIZE; i++) {
 | 
			
		||||
        buf[i] = hmac->key[i] ^ 0x5C;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Now calculate the "outer" hash for step (5), (6), and (7)
 | 
			
		||||
    /* Now calculate the "outer" hash for step (5), (6), and (7) */
 | 
			
		||||
    hash_descriptor[hash].init(&hmac->md);
 | 
			
		||||
    if ((err = hash_descriptor[hash].process(&hmac->md, buf, HMAC_BLOCKSIZE)) != CRYPT_OK) {
 | 
			
		||||
       goto __ERR;
 | 
			
		||||
@ -86,7 +86,7 @@ int hmac_done(hmac_state *hmac, unsigned char *hashOut, unsigned long *outlen)
 | 
			
		||||
       goto __ERR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // copy to output 
 | 
			
		||||
    /* copy to output  */
 | 
			
		||||
    for (i = 0; i < hashsize && i < *outlen; i++) {
 | 
			
		||||
        hashOut[i] = buf[i];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										16
									
								
								hmac_init.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								hmac_init.c
									
									
									
									
									
								
							@ -68,9 +68,9 @@ int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned lon
 | 
			
		||||
       return CRYPT_MEM;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // (1) make sure we have a large enough key
 | 
			
		||||
    /* (1) make sure we have a large enough key */
 | 
			
		||||
    if(keylen > HMAC_BLOCKSIZE) {
 | 
			
		||||
        z = (unsigned long)HMAC_BLOCKSIZE;
 | 
			
		||||
        z = HMAC_BLOCKSIZE;
 | 
			
		||||
        if ((err = hash_memory(hash, key, keylen, hmac->key, &z)) != CRYPT_OK) {
 | 
			
		||||
           goto __ERR;
 | 
			
		||||
        }
 | 
			
		||||
@ -85,15 +85,21 @@ int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned lon
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Create the initial vector for step (3)
 | 
			
		||||
    /* Create the initial vector for step (3) */
 | 
			
		||||
    for(i=0; i < HMAC_BLOCKSIZE;   i++) {
 | 
			
		||||
       buf[i] = hmac->key[i] ^ 0x36;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Pre-pend that to the hash data
 | 
			
		||||
    /* Pre-pend that to the hash data */
 | 
			
		||||
    hash_descriptor[hash].init(&hmac->md);
 | 
			
		||||
    err = hash_descriptor[hash].process(&hmac->md, buf, HMAC_BLOCKSIZE);
 | 
			
		||||
    if ((err = hash_descriptor[hash].process(&hmac->md, buf, HMAC_BLOCKSIZE)) != CRYPT_OK) {
 | 
			
		||||
       goto __ERR;
 | 
			
		||||
    }
 | 
			
		||||
    goto done;
 | 
			
		||||
__ERR:
 | 
			
		||||
    /* free the key since we failed */
 | 
			
		||||
    XFREE(hmac->key);
 | 
			
		||||
done:
 | 
			
		||||
#ifdef CLEAN_STACK
 | 
			
		||||
   zeromem(buf, HMAC_BLOCKSIZE);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -291,6 +291,7 @@ Key First"
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(memcmp(digest, cases[i].digest, (size_t)hash_descriptor[hash].hashsize) != 0)  {
 | 
			
		||||
            failed++;
 | 
			
		||||
#if 0
 | 
			
		||||
            unsigned int j;
 | 
			
		||||
            printf("\nHMAC-%s test #%d:\n", cases[i].algo, cases[i].num);
 | 
			
		||||
@ -303,9 +304,8 @@ Key First"
 | 
			
		||||
               printf("%2x ", cases[i].digest[j]);
 | 
			
		||||
            }
 | 
			
		||||
            printf("\n");
 | 
			
		||||
            return CRYPT_ERROR;
 | 
			
		||||
#endif
 | 
			
		||||
            failed++;
 | 
			
		||||
            //return CRYPT_ERROR;
 | 
			
		||||
        } else {
 | 
			
		||||
            /* printf("HMAC-%s test #%d: Passed\n", cases[i].algo, cases[i].num); */
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										18
									
								
								makefile
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								makefile
									
									
									
									
									
								
							@ -4,7 +4,7 @@
 | 
			
		||||
# Modified by Clay Culver
 | 
			
		||||
 | 
			
		||||
# The version
 | 
			
		||||
VERSION=0.97b
 | 
			
		||||
VERSION=0.98
 | 
			
		||||
 | 
			
		||||
# Compiler and Linker Names
 | 
			
		||||
#CC=gcc
 | 
			
		||||
@ -63,7 +63,7 @@ crypt_find_cipher_id.o     crypt_find_prng.o        crypt_prng_is_valid.o      \
 | 
			
		||||
crypt_unregister_cipher.o  crypt_cipher_is_valid.o  crypt_find_hash.o          \
 | 
			
		||||
crypt_hash_descriptor.o    crypt_register_cipher.o  crypt_unregister_hash.o    \
 | 
			
		||||
\
 | 
			
		||||
fortuna.o sprng.o yarrow.o rc4.o rng_get_bytes.o  rng_make_prng.o \
 | 
			
		||||
sober128.o fortuna.o sprng.o yarrow.o rc4.o rng_get_bytes.o  rng_make_prng.o \
 | 
			
		||||
\
 | 
			
		||||
rand_prime.o is_prime.o \
 | 
			
		||||
\
 | 
			
		||||
@ -171,10 +171,10 @@ small: library $(SMALLOBJECTS)
 | 
			
		||||
	$(CC) $(SMALLOBJECTS) $(LIBNAME) -o $(SMALL) $(WARN)
 | 
			
		||||
	
 | 
			
		||||
x86_prof: library $(PROFS)
 | 
			
		||||
	$(CC) $(PROFS) $(LIBNAME) -o $(PROF)
 | 
			
		||||
	$(CC) $(PROFS) $(LIBNAME) $(EXTRALIBS) -o $(PROF)
 | 
			
		||||
 | 
			
		||||
tv_gen: library $(TVS)
 | 
			
		||||
	$(CC) $(TVS) $(LIBNAME) -o $(TV)
 | 
			
		||||
	$(CC) $(TVS) $(LIBNAME) $(EXTRALIBS) -o $(TV)
 | 
			
		||||
 | 
			
		||||
#This rule installs the library and the header files. This must be run
 | 
			
		||||
#as root in order to have a high enough permission to write to the correct
 | 
			
		||||
@ -215,13 +215,21 @@ docdvi: crypt.tex
 | 
			
		||||
	echo hello > crypt.ind
 | 
			
		||||
	latex crypt > /dev/null
 | 
			
		||||
	latex crypt > /dev/null
 | 
			
		||||
	makeindex.idx crypt
 | 
			
		||||
	makeindex crypt.idx
 | 
			
		||||
	latex crypt > /dev/null
 | 
			
		||||
 | 
			
		||||
#pretty build
 | 
			
		||||
pretty:
 | 
			
		||||
	perl pretty.build
 | 
			
		||||
 | 
			
		||||
#for GCC 3.4+
 | 
			
		||||
profiled:
 | 
			
		||||
	make clean
 | 
			
		||||
	make CFLAGS="$(CFLAGS) -fprofile-generate" EXTRALIBS=-lgcov x86_prof
 | 
			
		||||
	./x86_prof
 | 
			
		||||
	rm *.o *.a x86_prof
 | 
			
		||||
	make CFLAGS="$(CFLAGS) -fprofile-use" EXTRALIBS=-lgcov x86_prof
 | 
			
		||||
 | 
			
		||||
#beta
 | 
			
		||||
beta: clean
 | 
			
		||||
	cd .. ; rm -rf crypt* libtomcrypt-$(VERSION)-beta ; mkdir libtomcrypt-$(VERSION)-beta ; \
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,7 @@ crypt_find_cipher_id.o     crypt_find_prng.o        crypt_prng_is_valid.o      \
 | 
			
		||||
crypt_unregister_cipher.o  crypt_cipher_is_valid.o  crypt_find_hash.o          \
 | 
			
		||||
crypt_hash_descriptor.o    crypt_register_cipher.o  crypt_unregister_hash.o    \
 | 
			
		||||
\
 | 
			
		||||
sprng.o fortuna.o yarrow.o rc4.o rng_get_bytes.o  rng_make_prng.o \
 | 
			
		||||
sprng.o fortuna.o sober128.o yarrow.o rc4.o rng_get_bytes.o  rng_make_prng.o \
 | 
			
		||||
\
 | 
			
		||||
rand_prime.o is_prime.o \
 | 
			
		||||
\
 | 
			
		||||
 | 
			
		||||
@ -79,7 +79,7 @@ crypt_find_cipher_id.o     crypt_find_prng.o        crypt_prng_is_valid.o      \
 | 
			
		||||
crypt_unregister_cipher.o  crypt_cipher_is_valid.o  crypt_find_hash.o          \
 | 
			
		||||
crypt_hash_descriptor.o    crypt_register_cipher.o  crypt_unregister_hash.o    \
 | 
			
		||||
\
 | 
			
		||||
sprng.o fortuna.o yarrow.o rc4.o rng_get_bytes.o  rng_make_prng.o \
 | 
			
		||||
sober128.o fortuna.o sprng.o yarrow.o rc4.o rng_get_bytes.o  rng_make_prng.o \
 | 
			
		||||
\
 | 
			
		||||
rand_prime.o is_prime.o \
 | 
			
		||||
\
 | 
			
		||||
@ -188,6 +188,13 @@ x86_prof: library $(PROFS)
 | 
			
		||||
tv_gen: library $(TVS)
 | 
			
		||||
	$(CC) $(TVS) $(LIBNAME) -o $(TV)
 | 
			
		||||
 | 
			
		||||
profiled:
 | 
			
		||||
	make clean
 | 
			
		||||
	make CFLAGS="$(CFLAGS) -prof_gen" x86_prof
 | 
			
		||||
	./x86_prof
 | 
			
		||||
	rm *.o *.a x86_prof
 | 
			
		||||
	make CFLAGS="$(CFLAGS) -prof_use" x86_prof
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
#This rule installs the library and the header files. This must be run
 | 
			
		||||
#as root in order to have a high enough permission to write to the correct
 | 
			
		||||
 | 
			
		||||
@ -18,7 +18,7 @@ crypt_find_cipher_id.obj     crypt_find_prng.obj        crypt_prng_is_valid.obj
 | 
			
		||||
crypt_unregister_cipher.obj  crypt_cipher_is_valid.obj  crypt_find_hash.obj          \
 | 
			
		||||
crypt_hash_descriptor.obj    crypt_register_cipher.obj  crypt_unregister_hash.obj    \
 | 
			
		||||
\
 | 
			
		||||
sprng.obj fortuna.obj yarrow.obj rc4.obj rng_get_bytes.obj  rng_make_prng.obj \
 | 
			
		||||
sprng.obj fortuna.obj sober128.obj yarrow.obj rc4.obj rng_get_bytes.obj  rng_make_prng.obj \
 | 
			
		||||
\
 | 
			
		||||
rand_prime.obj is_prime.obj \
 | 
			
		||||
\
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								mpi.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								mpi.c
									
									
									
									
									
								
							@ -4703,7 +4703,7 @@ int mp_mul (mp_int * a, mp_int * b, mp_int * c)
 | 
			
		||||
      res = s_mp_mul (a, b, c);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  c->sign = neg;
 | 
			
		||||
  c->sign = (c->used == 0) ? MP_ZPOS : neg;
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,4 @@
 | 
			
		||||
/* Defines the _ARGCHK macro used within the library */
 | 
			
		||||
 | 
			
		||||
/* ch1-01-1 */
 | 
			
		||||
/* ARGTYPE is defined in mycrypt_cfg.h */
 | 
			
		||||
#if ARGTYPE == 0
 | 
			
		||||
 | 
			
		||||
@ -20,5 +18,4 @@
 | 
			
		||||
#define _ARGCHK(x) 
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
/* ch1-01-1 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -20,12 +20,16 @@ void XFREE(void *p);
 | 
			
		||||
void *XMEMCPY(void *dest, const void *src, size_t n);
 | 
			
		||||
int   XMEMCMP(const void *s1, const void *s2, size_t n);
 | 
			
		||||
 | 
			
		||||
/* ch1-01-1 */
 | 
			
		||||
/* type of argument checking, 0=default, 1=fatal and 2=none */
 | 
			
		||||
#define ARGTYPE  0
 | 
			
		||||
/* ch1-01-1 */
 | 
			
		||||
 | 
			
		||||
/* Controls endianess and size of registers.  Leave uncommented to get platform neutral [slower] code */
 | 
			
		||||
/* Controls endianess and size of registers.  Leave uncommented to get platform neutral [slower] code 
 | 
			
		||||
 * 
 | 
			
		||||
 * Note: in order to use the optimized macros your platform must support unaligned 32 and 64 bit read/writes.
 | 
			
		||||
 * The x86 platforms allow this but some others [ARM for instance] do not.  On those platforms you **MUST**
 | 
			
		||||
 * use the portable [slower] macros.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* detect x86-32 machines somewhat */
 | 
			
		||||
#if defined(INTEL_CC) || (defined(_MSC_VER) && defined(WIN32)) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__)))
 | 
			
		||||
   #define ENDIAN_LITTLE
 | 
			
		||||
@ -52,12 +56,6 @@ int   XMEMCMP(const void *s1, const void *s2, size_t n);
 | 
			
		||||
   #define ENDIAN_NEUTRAL
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef YARROW
 | 
			
		||||
   #ifndef CTR
 | 
			
		||||
      #error YARROW requires CTR chaining mode to be defined!
 | 
			
		||||
   #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* packet code */
 | 
			
		||||
#if defined(MRSA) || defined(MDH) || defined(MECC)
 | 
			
		||||
    #define PACKET
 | 
			
		||||
 | 
			
		||||
@ -82,18 +82,29 @@
 | 
			
		||||
 | 
			
		||||
/* Various tidbits of modern neatoness */
 | 
			
		||||
#define BASE64
 | 
			
		||||
 | 
			
		||||
/* Yarrow */
 | 
			
		||||
#define YARROW
 | 
			
		||||
// which descriptor of AES to use? 
 | 
			
		||||
// 0 = rijndael_enc 1 = aes_enc, 2 = rijndael [full], 3 = aes [full]
 | 
			
		||||
#define YARROW_AES 0
 | 
			
		||||
 | 
			
		||||
#if defined(YARROW) && !defined(CTR)
 | 
			
		||||
   #error YARROW requires CTR chaining mode to be defined!
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define SPRNG
 | 
			
		||||
#define RC4
 | 
			
		||||
 | 
			
		||||
/* Fortuna */
 | 
			
		||||
/* Fortuna PRNG */
 | 
			
		||||
#define FORTUNA
 | 
			
		||||
/* reseed every N calls to the read function */
 | 
			
		||||
#define FORTUNA_WD    1024
 | 
			
		||||
#define FORTUNA_WD    10
 | 
			
		||||
/* number of pools (4..32) can save a bit of ram by lowering the count */
 | 
			
		||||
#define FORTUNA_POOLS 32
 | 
			
		||||
 | 
			
		||||
/* Greg's SOBER128 PRNG ;-0 */
 | 
			
		||||
#define SOBER128
 | 
			
		||||
 | 
			
		||||
#define DEVRANDOM
 | 
			
		||||
#define TRY_URANDOM_FIRST
 | 
			
		||||
@ -139,6 +150,12 @@
 | 
			
		||||
/* Use SSE2 optimizations in LTM?  Requires GCC or ICC and a P4 or K8 processor */
 | 
			
		||||
// #define LTMSSE
 | 
			
		||||
 | 
			
		||||
/* prevents the code from being "unportable" at least to non i386 platforms */
 | 
			
		||||
#if defined(LTMSSE) && !( (defined(__GNUC__) && defined(__i386__)) || defined(INTEL_CC)) 
 | 
			
		||||
   #warning LTMSSE is only available for GNU CC (i386) or Intel CC
 | 
			
		||||
   #undef LTMSSE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* PKCS #1 and #5 stuff */
 | 
			
		||||
#define PKCS_1
 | 
			
		||||
#define PKCS_5
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,7 @@ struct rc4_prng {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct fortuna_prng {
 | 
			
		||||
    hash_state pool[32];     /* the 32 pools */
 | 
			
		||||
    hash_state pool[FORTUNA_POOLS];     /* the  pools */
 | 
			
		||||
 | 
			
		||||
    symmetric_key skey;
 | 
			
		||||
 | 
			
		||||
@ -25,21 +25,44 @@ struct fortuna_prng {
 | 
			
		||||
    ulong64       reset_cnt;  /* number of times we have reset */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct sober128_prng {
 | 
			
		||||
    ulong32      R[17],          /* Working storage for the shift register */
 | 
			
		||||
                 initR[17],      /* saved register contents */ 
 | 
			
		||||
                 konst,          /* key dependent constant */
 | 
			
		||||
                 sbuf;           /* partial word encryption buffer */
 | 
			
		||||
 | 
			
		||||
    int          nbuf,           /* number of part-word stream bits buffered */
 | 
			
		||||
                 flag,           /* first add_entropy call or not? */
 | 
			
		||||
                 set;            /* did we call add_entropy to set key? */
 | 
			
		||||
    
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef union Prng_state {
 | 
			
		||||
#ifdef YARROW
 | 
			
		||||
    struct yarrow_prng    yarrow;
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef RC4
 | 
			
		||||
    struct rc4_prng       rc4;
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef FORTUNA
 | 
			
		||||
    struct fortuna_prng   fortuna;
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef SOBER128
 | 
			
		||||
    struct sober128_prng  sober128;
 | 
			
		||||
#endif
 | 
			
		||||
} prng_state;
 | 
			
		||||
 | 
			
		||||
extern struct _prng_descriptor {
 | 
			
		||||
    char *name;
 | 
			
		||||
    int  export_size;    /* size in bytes of exported state */
 | 
			
		||||
    int (*start)(prng_state *);
 | 
			
		||||
    int (*add_entropy)(const unsigned char *, unsigned long, prng_state *);
 | 
			
		||||
    int (*ready)(prng_state *);
 | 
			
		||||
    unsigned long (*read)(unsigned char *, unsigned long, prng_state *);
 | 
			
		||||
    void (*done)(prng_state *);
 | 
			
		||||
    int (*done)(prng_state *);
 | 
			
		||||
    int (*export)(unsigned char *, unsigned long *, prng_state *);
 | 
			
		||||
    int (*import)(const unsigned char *, unsigned long, prng_state *);
 | 
			
		||||
    int (*test)(void);
 | 
			
		||||
} prng_descriptor[];
 | 
			
		||||
 | 
			
		||||
#ifdef YARROW
 | 
			
		||||
@ -47,9 +70,10 @@ extern struct _prng_descriptor {
 | 
			
		||||
 int yarrow_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng);
 | 
			
		||||
 int yarrow_ready(prng_state *prng);
 | 
			
		||||
 unsigned long yarrow_read(unsigned char *buf, unsigned long len, prng_state *prng);
 | 
			
		||||
 void yarrow_done(prng_state *prng);
 | 
			
		||||
 int yarrow_done(prng_state *prng);
 | 
			
		||||
 int  yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
 | 
			
		||||
 int  yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
 | 
			
		||||
 int  yarrow_test(void);
 | 
			
		||||
 extern const struct _prng_descriptor yarrow_desc;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -58,9 +82,10 @@ extern struct _prng_descriptor {
 | 
			
		||||
 int fortuna_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng);
 | 
			
		||||
 int fortuna_ready(prng_state *prng);
 | 
			
		||||
 unsigned long fortuna_read(unsigned char *buf, unsigned long len, prng_state *prng);
 | 
			
		||||
 void fortuna_done(prng_state *prng);
 | 
			
		||||
 int fortuna_done(prng_state *prng);
 | 
			
		||||
 int  fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
 | 
			
		||||
 int  fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
 | 
			
		||||
 int  fortuna_test(void);
 | 
			
		||||
 extern const struct _prng_descriptor fortuna_desc;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -69,9 +94,10 @@ extern struct _prng_descriptor {
 | 
			
		||||
 int rc4_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng);
 | 
			
		||||
 int rc4_ready(prng_state *prng);
 | 
			
		||||
 unsigned long rc4_read(unsigned char *buf, unsigned long len, prng_state *prng);
 | 
			
		||||
 void rc4_done(prng_state *prng);
 | 
			
		||||
 int  rc4_done(prng_state *prng);
 | 
			
		||||
 int  rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
 | 
			
		||||
 int  rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
 | 
			
		||||
 int  rc4_test(void);
 | 
			
		||||
 extern const struct _prng_descriptor rc4_desc;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -80,26 +106,36 @@ extern struct _prng_descriptor {
 | 
			
		||||
 int sprng_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng);
 | 
			
		||||
 int sprng_ready(prng_state *prng);
 | 
			
		||||
 unsigned long sprng_read(unsigned char *buf, unsigned long len, prng_state *prng);
 | 
			
		||||
 void sprng_done(prng_state *prng);
 | 
			
		||||
 int sprng_done(prng_state *prng);
 | 
			
		||||
 int  sprng_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
 | 
			
		||||
 int  sprng_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
 | 
			
		||||
 int  sprng_test(void);
 | 
			
		||||
 extern const struct _prng_descriptor sprng_desc;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef SOBER128
 | 
			
		||||
 int sober128_start(prng_state *prng);
 | 
			
		||||
 int sober128_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng);
 | 
			
		||||
 int sober128_ready(prng_state *prng);
 | 
			
		||||
 unsigned long sober128_read(unsigned char *buf, unsigned long len, prng_state *prng);
 | 
			
		||||
 int sober128_done(prng_state *prng);
 | 
			
		||||
 int  sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
 | 
			
		||||
 int  sober128_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
 | 
			
		||||
 int  sober128_test(void);
 | 
			
		||||
 extern const struct _prng_descriptor sober128_desc;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 int find_prng(const char *name);
 | 
			
		||||
 int register_prng(const struct _prng_descriptor *prng);
 | 
			
		||||
 int unregister_prng(const struct _prng_descriptor *prng);
 | 
			
		||||
 int prng_is_valid(int idx);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Slow RNG you **might** be able to use to seed a PRNG with.  Be careful as this
 | 
			
		||||
 * might not work on all platforms as planned
 | 
			
		||||
 */
 | 
			
		||||
/* ch2-02-1 */ 
 | 
			
		||||
 unsigned long rng_get_bytes(unsigned char *buf, 
 | 
			
		||||
unsigned long rng_get_bytes(unsigned char *buf, 
 | 
			
		||||
                                   unsigned long len, 
 | 
			
		||||
                                   void (*callback)(void));
 | 
			
		||||
/* ch2-02-1 */
 | 
			
		||||
 | 
			
		||||
 int rng_make_prng(int bits, int wprng, prng_state *prng, void (*callback)(void));
 | 
			
		||||
int rng_make_prng(int bits, int wprng, prng_state *prng, void (*callback)(void));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										21
									
								
								noekeon.c
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								noekeon.c
									
									
									
									
									
								
							@ -33,7 +33,6 @@ static const ulong32 RC[] = {
 | 
			
		||||
   0x000000d4UL 
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define kTHETA(a, b, c, d)                                 \
 | 
			
		||||
    temp = a^c; temp = temp ^ ROL(temp, 8) ^ ROR(temp, 8); \
 | 
			
		||||
    b ^= temp; d ^= temp;                                  \
 | 
			
		||||
@ -97,9 +96,7 @@ void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
   ulong32 a,b,c,d,temp;
 | 
			
		||||
#ifdef SMALL_CODE
 | 
			
		||||
   int r;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
   _ARGCHK(key != NULL);
 | 
			
		||||
   _ARGCHK(pt != NULL);
 | 
			
		||||
@ -115,16 +112,9 @@ void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k
 | 
			
		||||
       GAMMA(a,b,c,d); \
 | 
			
		||||
       PI2(a,b,c,d);
 | 
			
		||||
 | 
			
		||||
#ifdef SMALL_CODE
 | 
			
		||||
   for (r = 0; r < 16; ++r) {
 | 
			
		||||
       ROUND(r);
 | 
			
		||||
   }
 | 
			
		||||
#else 
 | 
			
		||||
   ROUND( 0); ROUND( 1); ROUND( 2); ROUND( 3);
 | 
			
		||||
   ROUND( 4); ROUND( 5); ROUND( 6); ROUND( 7);
 | 
			
		||||
   ROUND( 8); ROUND( 9); ROUND(10); ROUND(11);
 | 
			
		||||
   ROUND(12); ROUND(13); ROUND(14); ROUND(15);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#undef ROUND
 | 
			
		||||
 | 
			
		||||
@ -150,9 +140,7 @@ void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_k
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
   ulong32 a,b,c,d, temp;
 | 
			
		||||
#ifdef SMALL_CODE
 | 
			
		||||
   int r;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
   _ARGCHK(key != NULL);
 | 
			
		||||
   _ARGCHK(pt != NULL);
 | 
			
		||||
@ -169,17 +157,10 @@ void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_k
 | 
			
		||||
       GAMMA(a,b,c,d); \
 | 
			
		||||
       PI2(a,b,c,d); 
 | 
			
		||||
 | 
			
		||||
#ifdef SMALL_CODE
 | 
			
		||||
   for (r = 16; r > 0; --r) {
 | 
			
		||||
       ROUND(r);
 | 
			
		||||
   }
 | 
			
		||||
#else
 | 
			
		||||
   ROUND(16); ROUND(15); ROUND(14); ROUND(13);
 | 
			
		||||
   ROUND(12); ROUND(11); ROUND(10); ROUND( 9);
 | 
			
		||||
   ROUND( 8); ROUND( 7); ROUND( 6); ROUND( 5);
 | 
			
		||||
   ROUND( 4); ROUND( 3); ROUND( 2); ROUND( 1);
 | 
			
		||||
#endif
 | 
			
		||||
   
 | 
			
		||||
 | 
			
		||||
#undef ROUND
 | 
			
		||||
 | 
			
		||||
   THETA(key->noekeon.dK, a,b,c,d);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										91
									
								
								notes/tech0004.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								notes/tech0004.txt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,91 @@
 | 
			
		||||
Tech Note 0004
 | 
			
		||||
Using Yarrow, Fortuna and SOBER-128
 | 
			
		||||
Tom St Denis
 | 
			
		||||
 | 
			
		||||
Introduction
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
This tech note explains how to use three of the more useful pseudo random number generators and their 
 | 
			
		||||
own little "issues".  While all of the PRNGs have the same API and are roughly used in the same 
 | 
			
		||||
manner their effectiveness really depends on the user knowing how they work.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Yarrow
 | 
			
		||||
------
 | 
			
		||||
 | 
			
		||||
Yarrow is by far the simplest of the PRNGs.  It gathers bits of entropy by hashing the pool state
 | 
			
		||||
plus the additional bits storing the message digest back in the pool.  E.g.
 | 
			
		||||
 | 
			
		||||
pool = hash(pool || newbits)
 | 
			
		||||
 | 
			
		||||
Simply dump bits into the PRNG via yarrow_add_entropy() and call yarrow_ready() when you want to 
 | 
			
		||||
put them to use.  This PRNG while simple is not entirely safe.  An attacker who learns the state
 | 
			
		||||
of the pool and can control future events can control the PRNG.  This requires an active attacker but 
 | 
			
		||||
isn't entire impossible.
 | 
			
		||||
 | 
			
		||||
The pool is then used as a key for a cipher that is used in CTR mode.  
 | 
			
		||||
 | 
			
		||||
Yarrow is mostly meant for short-term programs [e.g. like file utils].  This particular implementation
 | 
			
		||||
is not meant for long-term usage.
 | 
			
		||||
 | 
			
		||||
Fortuna
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
Fortuna was designed by Niels Fergusson and Bruce Schneier [Bruce is also the guy who invented Yarrow].  It
 | 
			
		||||
operates on a more defensive level than Yarrow.  Instead of 1 entropy pool it has 32 and the new entropy 
 | 
			
		||||
is spread [round robin] in all of the pools. 
 | 
			
		||||
 | 
			
		||||
That is, each call to fortuna_add_entropy() puts the bits in the next [in the sequenece] pool of entropy.  
 | 
			
		||||
Effective bits are added to the pool by sending them through a hash [but not terminating the hash].  
 | 
			
		||||
 | 
			
		||||
Here's the main catch though.  When the PRNG must be reseeded [so that you can extract bits from it] only
 | 
			
		||||
certain pools are used.  More precisely the i'th pool is used every 2**i'th reseeding.  For example, pool[0]
 | 
			
		||||
is always used.  pool[1] is used every second reseeding, pool[2] every fourth.
 | 
			
		||||
 | 
			
		||||
The pools are hashed together along with the current key and the result is the new key for a cipher which
 | 
			
		||||
operates in CTR mode [more about that in a sec].
 | 
			
		||||
 | 
			
		||||
Now this may seem odd at first however there is a good reason behind it.  An attacker who learns pool[0] won't
 | 
			
		||||
strictly know the other pools.  So the recovery rate of is not 0.  In fact pool[0] can be completely 
 | 
			
		||||
compromised and the PRNG will still eventually recover.  The value FORTUNA_WD is the "WatchDog" counter.
 | 
			
		||||
Every FORTUNA_WD calls to fortuna_read will invoke the reseed operation.  By default this is set to 10 which 
 | 
			
		||||
means after 10 calls the PRNG will reseed itself.  
 | 
			
		||||
 | 
			
		||||
The pools are combined with the running cipher key [256 bits] so that a cipher in CTR mode can produce 
 | 
			
		||||
the stream.  Unlike Yarrow the cipher is re-keyed after every call to fortuna_read() [so one big call 
 | 
			
		||||
would be faster than many smaller calls].  This prevents too much data being encrypted under the same
 | 
			
		||||
key [and mitigates a flaw in CTR mode that the same block can't be emitted twice under the same key].
 | 
			
		||||
 | 
			
		||||
Fortuna is really meant for a kernel-level PRNG.  The more sources [and often] you feed into it the 
 | 
			
		||||
healthier it will be.  It's also meant to be used for long term purposes.  Since it can recover from
 | 
			
		||||
compromises it is harder to control it.  
 | 
			
		||||
 | 
			
		||||
SOBER-128
 | 
			
		||||
------
 | 
			
		||||
 | 
			
		||||
SOBER-128 is actually a stream cipher but like most ciphers can easily be modelled in the context of a PRNG.
 | 
			
		||||
This PRNG is extremely fast [4 cycles/byte on a P4] and was designed by a well known cryptographer [Greg Rose].
 | 
			
		||||
 | 
			
		||||
SOBER-128 doesn't really "act" like the other two PRNGs.  It's meant to be seeded once and then read as 
 | 
			
		||||
required.  In such a sense it isn't a "system PRNG" but useful short term purposes.  In particular
 | 
			
		||||
the sober128_read() function actually XORs against the input buffer you specify.  This allows the 
 | 
			
		||||
read() function to be used as an "encrypt" function as well.  
 | 
			
		||||
 | 
			
		||||
You can only key SOBER-128 once [by calling sober128_add_entropy()].  Once it it is keyed subsequent
 | 
			
		||||
calls to add_entropy() will be considered a "re-IV" operation.  Changing the IV allows you to use same
 | 
			
		||||
initial key and not produce the same output stream.  It also lets you differentiate packets.  E.g. each
 | 
			
		||||
packet has it's own IV.
 | 
			
		||||
 | 
			
		||||
All inputs to sober128_add_entropy() must have a length that is a multiple of four.
 | 
			
		||||
 | 
			
		||||
Overall
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
Since SOBER-128 is *much* faster than the other two PRNGs a good setup would be to use Fortuna as your 
 | 
			
		||||
system-wide PRNG and use SOBER-128 [key'ed from Fortuna] for encrypting streams or as a PRNG for 
 | 
			
		||||
simulations.
 | 
			
		||||
 | 
			
		||||
Yarrow is still a good candidate but only for "short lived" programs.  However, since Fortuna is faster
 | 
			
		||||
[by about 10 cycles/byte on a P4] I'd use Fortuna anyways...
 | 
			
		||||
 | 
			
		||||
Tom
 | 
			
		||||
@ -21,8 +21,9 @@ foreach my $filename (glob "*.c") {
 | 
			
		||||
    if (!($filename =~ "sha384.c")) {
 | 
			
		||||
    if (!($filename =~ "dh_sys.c")) {
 | 
			
		||||
    if (!($filename =~ "ecc_sys.c")) {
 | 
			
		||||
    if (!($filename =~ "sober128tab.c")) {
 | 
			
		||||
       ++$count;
 | 
			
		||||
    }}}}}}}
 | 
			
		||||
    }}}}}}}}
 | 
			
		||||
}
 | 
			
		||||
print "Source files to build: $count\nBuilding...\n";
 | 
			
		||||
my $i = 0;
 | 
			
		||||
@ -36,6 +37,7 @@ foreach my $filename (glob "*.c") {
 | 
			
		||||
    if (!($filename =~ "sha384.c")) {
 | 
			
		||||
    if (!($filename =~ "dh_sys.c")) {
 | 
			
		||||
    if (!($filename =~ "ecc_sys.c")) {
 | 
			
		||||
    if (!($filename =~ "sober128tab.c")) {
 | 
			
		||||
       printf("Building %3.2f%%, ", (++$i/$count)*100.0);
 | 
			
		||||
       if ($i % 4 == 0) { print "/, "; }
 | 
			
		||||
       if ($i % 4 == 1) { print "-, "; }
 | 
			
		||||
@ -71,7 +73,7 @@ foreach my $filename (glob "*.c") {
 | 
			
		||||
          my $delay = time - $starttime;
 | 
			
		||||
          $rate = $i/$delay;
 | 
			
		||||
       }
 | 
			
		||||
    }}}}}}}
 | 
			
		||||
    }}}}}}}}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# finish building the library 
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										119
									
								
								rc4.c
									
									
									
									
									
								
							
							
						
						
									
										119
									
								
								rc4.c
									
									
									
									
									
								
							@ -14,14 +14,15 @@
 | 
			
		||||
 | 
			
		||||
const struct _prng_descriptor rc4_desc = 
 | 
			
		||||
{
 | 
			
		||||
   "rc4",
 | 
			
		||||
   "rc4", 32,
 | 
			
		||||
    &rc4_start,
 | 
			
		||||
    &rc4_add_entropy,
 | 
			
		||||
    &rc4_ready,
 | 
			
		||||
    &rc4_read,
 | 
			
		||||
    &rc4_done,
 | 
			
		||||
    &rc4_export,
 | 
			
		||||
    &rc4_import
 | 
			
		||||
    &rc4_import,
 | 
			
		||||
    &rc4_test
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int rc4_start(prng_state *prng)
 | 
			
		||||
@ -36,11 +37,18 @@ int rc4_start(prng_state *prng)
 | 
			
		||||
 | 
			
		||||
int rc4_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng)
 | 
			
		||||
{
 | 
			
		||||
    _ARGCHK(buf != NULL);
 | 
			
		||||
    _ARGCHK(buf  != NULL);
 | 
			
		||||
    _ARGCHK(prng != NULL);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
    /* trim as required */
 | 
			
		||||
    if (prng->rc4.x + len > 256) {
 | 
			
		||||
       return CRYPT_INVALID_KEYSIZE;
 | 
			
		||||
       if (prng->rc4.x == 256) {
 | 
			
		||||
          /* I can't possibly accept another byte, ok maybe a mint wafer... */
 | 
			
		||||
          return CRYPT_OK;
 | 
			
		||||
       } else {
 | 
			
		||||
          /* only accept part of it */
 | 
			
		||||
          len = 256 - prng->rc4.x;
 | 
			
		||||
       }       
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    while (len--) {
 | 
			
		||||
@ -53,26 +61,30 @@ int rc4_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prn
 | 
			
		||||
 | 
			
		||||
int rc4_ready(prng_state *prng)
 | 
			
		||||
{
 | 
			
		||||
    unsigned char key[256], tmp;
 | 
			
		||||
    int keylen, x, y;
 | 
			
		||||
    unsigned char key[256], tmp, *s;
 | 
			
		||||
    int keylen, x, y, j;
 | 
			
		||||
 | 
			
		||||
    _ARGCHK(prng != NULL);
 | 
			
		||||
 | 
			
		||||
    /* extract the key */
 | 
			
		||||
    XMEMCPY(key, prng->rc4.buf, 256);
 | 
			
		||||
    s = prng->rc4.buf;
 | 
			
		||||
    XMEMCPY(key, s, 256);
 | 
			
		||||
    keylen = prng->rc4.x;
 | 
			
		||||
 | 
			
		||||
    /* make RC4 perm and shuffle */
 | 
			
		||||
    for (x = 0; x < 256; x++) {
 | 
			
		||||
        prng->rc4.buf[x] = x;
 | 
			
		||||
        s[x] = x;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (x = y = 0; x < 256; x++) {
 | 
			
		||||
        y = (y + prng->rc4.buf[x] + key[x % keylen]) & 255;
 | 
			
		||||
        tmp = prng->rc4.buf[x]; prng->rc4.buf[x] = prng->rc4.buf[y]; prng->rc4.buf[y] = tmp;
 | 
			
		||||
    for (j = x = y = 0; x < 256; x++) {
 | 
			
		||||
        y = (y + prng->rc4.buf[x] + key[j++]) & 255;
 | 
			
		||||
        if (j == keylen) {
 | 
			
		||||
           j = 0; 
 | 
			
		||||
        }
 | 
			
		||||
        tmp = s[x]; s[x] = s[y]; s[y] = tmp;
 | 
			
		||||
    }
 | 
			
		||||
    prng->rc4.x = x;
 | 
			
		||||
    prng->rc4.y = y;
 | 
			
		||||
    prng->rc4.x = 0;
 | 
			
		||||
    prng->rc4.y = 0;
 | 
			
		||||
 | 
			
		||||
#ifdef CLEAN_STACK
 | 
			
		||||
    zeromem(key, sizeof(key));
 | 
			
		||||
@ -83,8 +95,7 @@ int rc4_ready(prng_state *prng)
 | 
			
		||||
 | 
			
		||||
unsigned long rc4_read(unsigned char *buf, unsigned long len, prng_state *prng)
 | 
			
		||||
{
 | 
			
		||||
   int x, y; 
 | 
			
		||||
   unsigned char *s, tmp;
 | 
			
		||||
   unsigned char x, y, *s, tmp;
 | 
			
		||||
   unsigned long n;
 | 
			
		||||
 | 
			
		||||
   _ARGCHK(buf != NULL);
 | 
			
		||||
@ -99,31 +110,99 @@ unsigned long rc4_read(unsigned char *buf, unsigned long len, prng_state *prng)
 | 
			
		||||
      y = (y + s[x]) & 255;
 | 
			
		||||
      tmp = s[x]; s[x] = s[y]; s[y] = tmp;
 | 
			
		||||
      tmp = (s[x] + s[y]) & 255;
 | 
			
		||||
      *buf++ = s[tmp];
 | 
			
		||||
      *buf++ ^= s[tmp];
 | 
			
		||||
   }
 | 
			
		||||
   prng->rc4.x = x;
 | 
			
		||||
   prng->rc4.y = y;
 | 
			
		||||
   return n;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void rc4_done(prng_state *prng)
 | 
			
		||||
int rc4_done(prng_state *prng)
 | 
			
		||||
{
 | 
			
		||||
   _ARGCHK(prng != NULL);
 | 
			
		||||
   return CRYPT_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
 | 
			
		||||
{
 | 
			
		||||
   _ARGCHK(outlen != NULL);
 | 
			
		||||
   _ARGCHK(out    != NULL);
 | 
			
		||||
   _ARGCHK(prng   != NULL);
 | 
			
		||||
 | 
			
		||||
   if (*outlen < 32) {
 | 
			
		||||
      return CRYPT_BUFFER_OVERFLOW;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   if (rc4_read(out, 32, prng) != 32) {
 | 
			
		||||
      return CRYPT_ERROR_READPRNG;
 | 
			
		||||
   }
 | 
			
		||||
   *outlen = 32;
 | 
			
		||||
 | 
			
		||||
   *outlen = 0;
 | 
			
		||||
   return CRYPT_OK;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
 | 
			
		||||
{
 | 
			
		||||
   return CRYPT_OK;
 | 
			
		||||
   int err;
 | 
			
		||||
   _ARGCHK(in   != NULL);
 | 
			
		||||
   _ARGCHK(prng != NULL);
 | 
			
		||||
 | 
			
		||||
   if (inlen != 32) {
 | 
			
		||||
      return CRYPT_INVALID_ARG;
 | 
			
		||||
   }
 | 
			
		||||
   
 | 
			
		||||
   if ((err = rc4_start(prng)) != CRYPT_OK) {
 | 
			
		||||
      return err;
 | 
			
		||||
   }
 | 
			
		||||
   return rc4_add_entropy(in, 32, prng);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int rc4_test(void)
 | 
			
		||||
{
 | 
			
		||||
#ifndef LTC_TEST
 | 
			
		||||
   return CRYPT_NOP;
 | 
			
		||||
#else
 | 
			
		||||
   static const struct {
 | 
			
		||||
      unsigned char key[8], pt[8], ct[8];
 | 
			
		||||
   } tests[] = {
 | 
			
		||||
{
 | 
			
		||||
   { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
 | 
			
		||||
   { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
 | 
			
		||||
   { 0x75, 0xb7, 0x87, 0x80, 0x99, 0xe0, 0xc5, 0x96 }
 | 
			
		||||
}
 | 
			
		||||
};
 | 
			
		||||
   prng_state prng;
 | 
			
		||||
   unsigned char dst[8];
 | 
			
		||||
   int err, x;
 | 
			
		||||
 | 
			
		||||
   for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
 | 
			
		||||
       if ((err = rc4_start(&prng)) != CRYPT_OK) {
 | 
			
		||||
          return err;
 | 
			
		||||
       }
 | 
			
		||||
       if ((err = rc4_add_entropy(tests[x].key, 8, &prng)) != CRYPT_OK) {
 | 
			
		||||
          return err;
 | 
			
		||||
       }
 | 
			
		||||
       if ((err = rc4_ready(&prng)) != CRYPT_OK) {
 | 
			
		||||
          return err;
 | 
			
		||||
       }
 | 
			
		||||
       XMEMCPY(dst, tests[x].pt, 8);
 | 
			
		||||
       if (rc4_read(dst, 8, &prng) != 8) {
 | 
			
		||||
          return CRYPT_ERROR_READPRNG;
 | 
			
		||||
       }
 | 
			
		||||
       rc4_done(&prng);
 | 
			
		||||
       if (memcmp(dst, tests[x].ct, 8)) {
 | 
			
		||||
#if 0
 | 
			
		||||
          int y;
 | 
			
		||||
          printf("\n\nRC4 failed, I got:\n"); 
 | 
			
		||||
          for (y = 0; y < 8; y++) printf("%02x ", dst[y]);
 | 
			
		||||
          printf("\n");
 | 
			
		||||
#endif
 | 
			
		||||
          return CRYPT_FAIL_TESTVECTOR;
 | 
			
		||||
       }
 | 
			
		||||
   }
 | 
			
		||||
   return CRYPT_OK;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
 | 
			
		||||
#ifdef MRSA
 | 
			
		||||
 | 
			
		||||
/* decrypt then OAEP depad  */
 | 
			
		||||
/* (PKCS #1 v2.0) decrypt then OAEP depad  */
 | 
			
		||||
int rsa_decrypt_key(const unsigned char *in,     unsigned long inlen,
 | 
			
		||||
                          unsigned char *outkey, unsigned long *keylen, 
 | 
			
		||||
                    const unsigned char *lparam, unsigned long lparamlen,
 | 
			
		||||
@ -30,6 +30,9 @@ int rsa_decrypt_key(const unsigned char *in,     unsigned long inlen,
 | 
			
		||||
  _ARGCHK(key    != NULL);
 | 
			
		||||
  _ARGCHK(res    != NULL);
 | 
			
		||||
 | 
			
		||||
  /* default to invalid */
 | 
			
		||||
  *res = 0;
 | 
			
		||||
 | 
			
		||||
  /* valid hash/prng ? */
 | 
			
		||||
  if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
 | 
			
		||||
     return err;
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
 | 
			
		||||
#ifdef MRSA
 | 
			
		||||
 | 
			
		||||
/* OAEP pad then encrypt */
 | 
			
		||||
/* (PKCS #1 v2.0) OAEP pad then encrypt */
 | 
			
		||||
int rsa_encrypt_key(const unsigned char *inkey,  unsigned long inlen,
 | 
			
		||||
                          unsigned char *outkey, unsigned long *outlen,
 | 
			
		||||
                    const unsigned char *lparam, unsigned long lparamlen,
 | 
			
		||||
 | 
			
		||||
@ -13,6 +13,7 @@
 | 
			
		||||
 | 
			
		||||
#ifdef MRSA
 | 
			
		||||
 | 
			
		||||
/* Export an RSA key */
 | 
			
		||||
int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key)
 | 
			
		||||
{
 | 
			
		||||
   unsigned long y, z; 
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,7 @@
 | 
			
		||||
 | 
			
		||||
#ifdef MRSA
 | 
			
		||||
 | 
			
		||||
/* compute an RSA modular exponentiation */
 | 
			
		||||
int rsa_exptmod(const unsigned char *in,   unsigned long inlen,
 | 
			
		||||
                      unsigned char *out,  unsigned long *outlen, int which,
 | 
			
		||||
                      prng_state    *prng, int           prng_idx,
 | 
			
		||||
 | 
			
		||||
@ -69,7 +69,7 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
 | 
			
		||||
   if ((err = mp_invmod(&key->e, &tmp1, &key->d)) != MP_OKAY)         { goto error2; } /* key->d = 1/e mod lcm(p-1,q-1) */
 | 
			
		||||
   if ((err = mp_mul(&p, &q, &key->N)) != MP_OKAY)                    { goto error2; } /* key->N = pq */
 | 
			
		||||
 | 
			
		||||
/* optimize for CRT now */
 | 
			
		||||
   /* optimize for CRT now */
 | 
			
		||||
   /* find d mod q-1 and d mod p-1 */
 | 
			
		||||
   if ((err = mp_sub_d(&p, 1, &tmp1)) != MP_OKAY)                     { goto error2; } /* tmp1 = q-1 */
 | 
			
		||||
   if ((err = mp_sub_d(&q, 1, &tmp2)) != MP_OKAY)                     { goto error2; } /* tmp2 = p-1 */
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
 | 
			
		||||
#ifdef MRSA
 | 
			
		||||
 | 
			
		||||
/* PSS pad then sign */
 | 
			
		||||
/* (PKCS #1, v2.0) PSS pad then sign */
 | 
			
		||||
int rsa_sign_hash(const unsigned char *msghash,  unsigned long  msghashlen, 
 | 
			
		||||
                        unsigned char *sig,      unsigned long *siglen, 
 | 
			
		||||
                        prng_state    *prng,     int            prng_idx,
 | 
			
		||||
 | 
			
		||||
@ -26,6 +26,9 @@ int rsa_v15_decrypt_key(const unsigned char *in,     unsigned long  inlen,
 | 
			
		||||
  _ARGCHK(outkey != NULL);
 | 
			
		||||
  _ARGCHK(key    != NULL);
 | 
			
		||||
  _ARGCHK(res    != NULL);
 | 
			
		||||
 
 | 
			
		||||
  /* default to invalid */
 | 
			
		||||
  *res = 0;
 | 
			
		||||
 | 
			
		||||
  /* valid prng ? */
 | 
			
		||||
  if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
 | 
			
		||||
#ifdef MRSA
 | 
			
		||||
 | 
			
		||||
/* design then PKCS v1.5 depad */
 | 
			
		||||
/* de-sign then PKCS v1.5 depad */
 | 
			
		||||
int rsa_v15_verify_hash(const unsigned char *sig,      unsigned long siglen,
 | 
			
		||||
                        const unsigned char *msghash,  unsigned long msghashlen,
 | 
			
		||||
                              prng_state    *prng,     int           prng_idx,
 | 
			
		||||
@ -28,6 +28,9 @@ int rsa_v15_verify_hash(const unsigned char *sig,      unsigned long siglen,
 | 
			
		||||
  _ARGCHK(sig      != NULL);
 | 
			
		||||
  _ARGCHK(stat     != NULL);
 | 
			
		||||
  _ARGCHK(key      != NULL);
 | 
			
		||||
 | 
			
		||||
  /* default to invalid */
 | 
			
		||||
  *stat = 0;
 | 
			
		||||
  
 | 
			
		||||
  /* valid hash ? */
 | 
			
		||||
  if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
 | 
			
		||||
#ifdef MRSA
 | 
			
		||||
 | 
			
		||||
/* design then PSS depad */
 | 
			
		||||
/* (PKCS #1, v2.0) de-sign then PSS depad */
 | 
			
		||||
int rsa_verify_hash(const unsigned char *sig,      unsigned long siglen,
 | 
			
		||||
                    const unsigned char *msghash,  unsigned long msghashlen,
 | 
			
		||||
                          prng_state    *prng,     int           prng_idx,
 | 
			
		||||
@ -28,6 +28,9 @@ int rsa_verify_hash(const unsigned char *sig,      unsigned long siglen,
 | 
			
		||||
  _ARGCHK(sig      != NULL);
 | 
			
		||||
  _ARGCHK(stat     != NULL);
 | 
			
		||||
  _ARGCHK(key      != NULL);
 | 
			
		||||
 | 
			
		||||
  /* default to invalid */
 | 
			
		||||
  *stat = 0;
 | 
			
		||||
  
 | 
			
		||||
  /* valid hash ? */
 | 
			
		||||
  if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										444
									
								
								sober128.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										444
									
								
								sober128.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,444 @@
 | 
			
		||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
 | 
			
		||||
 *
 | 
			
		||||
 * LibTomCrypt is a library that provides various cryptographic
 | 
			
		||||
 * algorithms in a highly modular and flexible manner.
 | 
			
		||||
 *
 | 
			
		||||
 * The library is free for all purposes without any express
 | 
			
		||||
 * guarantee it works.
 | 
			
		||||
 *
 | 
			
		||||
 * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
 | 
			
		||||
 */
 | 
			
		||||
#include "mycrypt.h"
 | 
			
		||||
 | 
			
		||||
/* Implementation of SOBER-128 by Tom St Denis.
 | 
			
		||||
 * Based on s128fast.c reference code supplied by Greg Rose of QUALCOMM.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef SOBER128
 | 
			
		||||
 | 
			
		||||
#include "sober128tab.c"
 | 
			
		||||
 | 
			
		||||
const struct _prng_descriptor sober128_desc = 
 | 
			
		||||
{
 | 
			
		||||
   "sober128", 64,
 | 
			
		||||
    &sober128_start,
 | 
			
		||||
    &sober128_add_entropy,
 | 
			
		||||
    &sober128_ready,
 | 
			
		||||
    &sober128_read,
 | 
			
		||||
    &sober128_done,
 | 
			
		||||
    &sober128_export,
 | 
			
		||||
    &sober128_import,
 | 
			
		||||
    &sober128_test
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* don't change these... */
 | 
			
		||||
#define N                        17
 | 
			
		||||
#define FOLD                      N /* how many iterations of folding to do */
 | 
			
		||||
#define INITKONST        0x6996c53a /* value of KONST to use during key loading */
 | 
			
		||||
#define KEYP                     15 /* where to insert key words */
 | 
			
		||||
#define FOLDP                     4 /* where to insert non-linear feedback */
 | 
			
		||||
 | 
			
		||||
#define B(x,i) ((unsigned char)(((x) >> (8*i)) & 0xFF))
 | 
			
		||||
 | 
			
		||||
static ulong32 BYTE2WORD(unsigned char *b)
 | 
			
		||||
{
 | 
			
		||||
   ulong32 t;
 | 
			
		||||
   LOAD32L(t, b);
 | 
			
		||||
   return t;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define WORD2BYTE(w, b) STORE32L(b, w)
 | 
			
		||||
 | 
			
		||||
static void XORWORD(ulong32 w, unsigned char *b)
 | 
			
		||||
{
 | 
			
		||||
   ulong32 t;
 | 
			
		||||
   LOAD32L(t, b);
 | 
			
		||||
   t ^= w;
 | 
			
		||||
   STORE32L(t, b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* give correct offset for the current position of the register,
 | 
			
		||||
 * where logically R[0] is at position "zero".
 | 
			
		||||
 */
 | 
			
		||||
#define OFF(zero, i) (((zero)+(i)) % N)
 | 
			
		||||
 | 
			
		||||
/* step the LFSR */
 | 
			
		||||
/* After stepping, "zero" moves right one place */
 | 
			
		||||
#define STEP(R,z) \
 | 
			
		||||
    R[OFF(z,0)] = R[OFF(z,15)] ^ R[OFF(z,4)] ^ (R[OFF(z,0)] << 8) ^ Multab[(R[OFF(z,0)] >> 24) & 0xFF];
 | 
			
		||||
 | 
			
		||||
static void cycle(ulong32 *R)
 | 
			
		||||
{
 | 
			
		||||
    ulong32 t;
 | 
			
		||||
    int     i;
 | 
			
		||||
 | 
			
		||||
    STEP(R,0);
 | 
			
		||||
    t = R[0];
 | 
			
		||||
    for (i = 1; i < N; ++i) {
 | 
			
		||||
        R[i-1] = R[i];
 | 
			
		||||
    }
 | 
			
		||||
    R[N-1] = t;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Return a non-linear function of some parts of the register.
 | 
			
		||||
 */
 | 
			
		||||
#define NLFUNC(c,z) \
 | 
			
		||||
{ \
 | 
			
		||||
    t = c->R[OFF(z,0)] + c->R[OFF(z,16)]; \
 | 
			
		||||
    t ^= Sbox[(t >> 24) & 0xFF]; \
 | 
			
		||||
    t = ROR(t, 8); \
 | 
			
		||||
    t = ((t + c->R[OFF(z,1)]) ^ c->konst) + c->R[OFF(z,6)]; \
 | 
			
		||||
    t ^= Sbox[(t >> 24) & 0xFF]; \
 | 
			
		||||
    t = t + c->R[OFF(z,13)]; \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ulong32 nltap(struct sober128_prng *c)
 | 
			
		||||
{
 | 
			
		||||
    ulong32 t;
 | 
			
		||||
    NLFUNC(c, 0);
 | 
			
		||||
    return t;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* initialise to known state
 | 
			
		||||
 */
 | 
			
		||||
int sober128_start(prng_state *prng)
 | 
			
		||||
{
 | 
			
		||||
    int                   i;
 | 
			
		||||
    struct sober128_prng *c;
 | 
			
		||||
 | 
			
		||||
    _ARGCHK(prng != NULL);
 | 
			
		||||
 | 
			
		||||
    c = &(prng->sober128);
 | 
			
		||||
    
 | 
			
		||||
    /* Register initialised to Fibonacci numbers */
 | 
			
		||||
    c->R[0] = 1;
 | 
			
		||||
    c->R[1] = 1;
 | 
			
		||||
    for (i = 2; i < N; ++i) {
 | 
			
		||||
       c->R[i] = c->R[i-1] + c->R[i-2];
 | 
			
		||||
    }
 | 
			
		||||
    c->konst = INITKONST;
 | 
			
		||||
 | 
			
		||||
    /* next add_entropy will be the key */
 | 
			
		||||
    c->flag  = 1;
 | 
			
		||||
    c->set   = 0;
 | 
			
		||||
 | 
			
		||||
    return CRYPT_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Save the current register state
 | 
			
		||||
 */
 | 
			
		||||
static void s128_savestate(struct sober128_prng *c)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    for (i = 0; i < N; ++i) {
 | 
			
		||||
        c->initR[i] = c->R[i];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* initialise to previously saved register state
 | 
			
		||||
 */
 | 
			
		||||
static void s128_reloadstate(struct sober128_prng *c)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < N; ++i) {
 | 
			
		||||
        c->R[i] = c->initR[i];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Initialise "konst"
 | 
			
		||||
 */
 | 
			
		||||
static void s128_genkonst(struct sober128_prng *c)
 | 
			
		||||
{
 | 
			
		||||
    ulong32 newkonst;
 | 
			
		||||
 | 
			
		||||
    do {
 | 
			
		||||
       cycle(c->R);
 | 
			
		||||
       newkonst = nltap(c);
 | 
			
		||||
    } while ((newkonst & 0xFF000000) == 0);
 | 
			
		||||
    c->konst = newkonst;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Load key material into the register
 | 
			
		||||
 */
 | 
			
		||||
#define ADDKEY(k) \
 | 
			
		||||
   c->R[KEYP] += (k);
 | 
			
		||||
 | 
			
		||||
#define XORNL(nl) \
 | 
			
		||||
   c->R[FOLDP] ^= (nl);
 | 
			
		||||
 | 
			
		||||
/* nonlinear diffusion of register for key */
 | 
			
		||||
#define DROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); c->R[OFF((z+1),FOLDP)] ^= t; 
 | 
			
		||||
static void s128_diffuse(struct sober128_prng *c)
 | 
			
		||||
{
 | 
			
		||||
    ulong32 t;
 | 
			
		||||
    /* relies on FOLD == N == 17! */
 | 
			
		||||
    DROUND(0);
 | 
			
		||||
    DROUND(1);
 | 
			
		||||
    DROUND(2);
 | 
			
		||||
    DROUND(3);
 | 
			
		||||
    DROUND(4);
 | 
			
		||||
    DROUND(5);
 | 
			
		||||
    DROUND(6);
 | 
			
		||||
    DROUND(7);
 | 
			
		||||
    DROUND(8);
 | 
			
		||||
    DROUND(9);
 | 
			
		||||
    DROUND(10);
 | 
			
		||||
    DROUND(11);
 | 
			
		||||
    DROUND(12);
 | 
			
		||||
    DROUND(13);
 | 
			
		||||
    DROUND(14);
 | 
			
		||||
    DROUND(15);
 | 
			
		||||
    DROUND(16);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int sober128_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng)
 | 
			
		||||
{
 | 
			
		||||
    struct sober128_prng *c;
 | 
			
		||||
    ulong32               i, k;
 | 
			
		||||
 | 
			
		||||
    _ARGCHK(buf != NULL);
 | 
			
		||||
    _ARGCHK(prng != NULL);
 | 
			
		||||
    c = &(prng->sober128);
 | 
			
		||||
 | 
			
		||||
    if (c->flag == 1) {
 | 
			
		||||
       /* this is the first call to the add_entropy so this input is the key */
 | 
			
		||||
       /* len must be multiple of 4 bytes */
 | 
			
		||||
       if ((len & 3) != 0) {
 | 
			
		||||
          return CRYPT_INVALID_KEYSIZE;
 | 
			
		||||
       }
 | 
			
		||||
    
 | 
			
		||||
       for (i = 0; i < len; i += 4) {
 | 
			
		||||
           k = BYTE2WORD((unsigned char *)&buf[i]);
 | 
			
		||||
          ADDKEY(k);
 | 
			
		||||
          cycle(c->R);
 | 
			
		||||
          XORNL(nltap(c));
 | 
			
		||||
       }
 | 
			
		||||
 | 
			
		||||
       /* also fold in the length of the key */
 | 
			
		||||
       ADDKEY(len);
 | 
			
		||||
 | 
			
		||||
       /* now diffuse */
 | 
			
		||||
       s128_diffuse(c);
 | 
			
		||||
 | 
			
		||||
       s128_genkonst(c);
 | 
			
		||||
       s128_savestate(c);
 | 
			
		||||
       c->nbuf = 0;
 | 
			
		||||
       c->flag = 0;       
 | 
			
		||||
       c->set  = 1;
 | 
			
		||||
    } else {
 | 
			
		||||
       /* ok we are adding an IV then... */
 | 
			
		||||
       s128_reloadstate(c);
 | 
			
		||||
 | 
			
		||||
       /* len must be multiple of 4 bytes */
 | 
			
		||||
       if ((len & 3) != 0) {
 | 
			
		||||
          return CRYPT_INVALID_KEYSIZE;
 | 
			
		||||
       }
 | 
			
		||||
    
 | 
			
		||||
       for (i = 0; i < len; i += 4) {
 | 
			
		||||
           k = BYTE2WORD((unsigned char *)&buf[i]);
 | 
			
		||||
          ADDKEY(k);
 | 
			
		||||
          cycle(c->R);
 | 
			
		||||
          XORNL(nltap(c));
 | 
			
		||||
       }
 | 
			
		||||
 | 
			
		||||
       /* also fold in the length of the key */
 | 
			
		||||
       ADDKEY(len);
 | 
			
		||||
 | 
			
		||||
       /* now diffuse */
 | 
			
		||||
       s128_diffuse(c);
 | 
			
		||||
       c->nbuf = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return CRYPT_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int sober128_ready(prng_state *prng)
 | 
			
		||||
{
 | 
			
		||||
   return prng->sober128.set == 1 ? CRYPT_OK : CRYPT_ERROR;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* XOR pseudo-random bytes into buffer
 | 
			
		||||
 */
 | 
			
		||||
#define SROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); XORWORD(t, buf+(z*4));
 | 
			
		||||
 | 
			
		||||
unsigned long sober128_read(unsigned char *buf, unsigned long nbytes, prng_state *prng)
 | 
			
		||||
{
 | 
			
		||||
   struct sober128_prng *c;
 | 
			
		||||
   ulong32               t, tlen;
 | 
			
		||||
 | 
			
		||||
   _ARGCHK(buf  != NULL);
 | 
			
		||||
   _ARGCHK(prng != NULL);
 | 
			
		||||
 | 
			
		||||
   c = &(prng->sober128);
 | 
			
		||||
   t = 0;
 | 
			
		||||
   tlen = nbytes;
 | 
			
		||||
   
 | 
			
		||||
   /* handle any previously buffered bytes */
 | 
			
		||||
   while (c->nbuf != 0 && nbytes != 0) {
 | 
			
		||||
      *buf++ ^= c->sbuf & 0xFF;
 | 
			
		||||
       c->sbuf >>= 8;
 | 
			
		||||
       c->nbuf -= 8;
 | 
			
		||||
       --nbytes;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
#ifndef SMALL_CODE
 | 
			
		||||
    /* do lots at a time, if there's enough to do */
 | 
			
		||||
    while (nbytes >= N*4) {
 | 
			
		||||
      SROUND(0);
 | 
			
		||||
      SROUND(1);
 | 
			
		||||
      SROUND(2);
 | 
			
		||||
      SROUND(3);
 | 
			
		||||
      SROUND(4);
 | 
			
		||||
      SROUND(5);
 | 
			
		||||
      SROUND(6);
 | 
			
		||||
      SROUND(7);
 | 
			
		||||
      SROUND(8);
 | 
			
		||||
      SROUND(9);
 | 
			
		||||
      SROUND(10);
 | 
			
		||||
      SROUND(11);
 | 
			
		||||
      SROUND(12);
 | 
			
		||||
      SROUND(13);
 | 
			
		||||
      SROUND(14);
 | 
			
		||||
      SROUND(15);
 | 
			
		||||
      SROUND(16);
 | 
			
		||||
      buf    += 4*N;
 | 
			
		||||
      nbytes -= 4*N;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /* do small or odd size buffers the slow way */
 | 
			
		||||
    while (4 <= nbytes) {
 | 
			
		||||
      cycle(c->R);
 | 
			
		||||
      t = nltap(c);
 | 
			
		||||
      XORWORD(t, buf);
 | 
			
		||||
      buf    += 4;
 | 
			
		||||
      nbytes -= 4;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* handle any trailing bytes */
 | 
			
		||||
    if (nbytes != 0) {
 | 
			
		||||
      cycle(c->R);
 | 
			
		||||
      c->sbuf = nltap(c);
 | 
			
		||||
      c->nbuf = 32;
 | 
			
		||||
      while (c->nbuf != 0 && nbytes != 0) {
 | 
			
		||||
          *buf++ ^= c->sbuf & 0xFF;
 | 
			
		||||
          c->sbuf >>= 8;
 | 
			
		||||
          c->nbuf -= 8;
 | 
			
		||||
          --nbytes;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return tlen;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int sober128_done(prng_state *prng)
 | 
			
		||||
{
 | 
			
		||||
   _ARGCHK(prng != NULL);
 | 
			
		||||
   return CRYPT_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
 | 
			
		||||
{
 | 
			
		||||
   _ARGCHK(outlen != NULL);
 | 
			
		||||
   _ARGCHK(out    != NULL);
 | 
			
		||||
   _ARGCHK(prng   != NULL);
 | 
			
		||||
 | 
			
		||||
   if (*outlen < 64) {
 | 
			
		||||
      return CRYPT_BUFFER_OVERFLOW;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   if (sober128_read(out, 64, prng) != 64) {
 | 
			
		||||
      return CRYPT_ERROR_READPRNG;
 | 
			
		||||
   }
 | 
			
		||||
   *outlen = 64;
 | 
			
		||||
 | 
			
		||||
   return CRYPT_OK;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
int sober128_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
 | 
			
		||||
{
 | 
			
		||||
   int err;
 | 
			
		||||
   _ARGCHK(in   != NULL);
 | 
			
		||||
   _ARGCHK(prng != NULL);
 | 
			
		||||
 | 
			
		||||
   if (inlen != 64) {
 | 
			
		||||
      return CRYPT_INVALID_ARG;
 | 
			
		||||
   }
 | 
			
		||||
   
 | 
			
		||||
   if ((err = sober128_start(prng)) != CRYPT_OK) {
 | 
			
		||||
      return err;
 | 
			
		||||
   }
 | 
			
		||||
   if ((err = sober128_add_entropy(in, 64, prng)) != CRYPT_OK) {
 | 
			
		||||
      return err;
 | 
			
		||||
   }
 | 
			
		||||
   return sober128_ready(prng);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int sober128_test(void)
 | 
			
		||||
{
 | 
			
		||||
#ifndef LTC_TEST
 | 
			
		||||
   return CRYPT_NOP;
 | 
			
		||||
#else
 | 
			
		||||
   static const struct { 
 | 
			
		||||
     int keylen, ivlen, len;
 | 
			
		||||
     unsigned char key[16], iv[4], out[20];
 | 
			
		||||
   } tests[] = {
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
   16, 4, 20,
 | 
			
		||||
 | 
			
		||||
   /* key */
 | 
			
		||||
   { 't', 'e', 's', 't', ' ', 'k', 'e', 'y', 
 | 
			
		||||
     ' ', '1', '2', '8', 'b', 'i', 't', 's' },
 | 
			
		||||
 | 
			
		||||
   /* IV */
 | 
			
		||||
   { 0x00, 0x00, 0x00, 0x0 },
 | 
			
		||||
 | 
			
		||||
   /* expected output */
 | 
			
		||||
   { 0x43, 0x50, 0x0c, 0xcf, 0x89, 0x91, 0x9f, 0x1d,
 | 
			
		||||
     0xaa, 0x37, 0x74, 0x95, 0xf4, 0xb4, 0x58, 0xc2, 
 | 
			
		||||
     0x40, 0x37, 0x8b, 0xbb }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
   prng_state    prng;
 | 
			
		||||
   unsigned char dst[20];
 | 
			
		||||
   int           err, x;
 | 
			
		||||
 | 
			
		||||
   for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
 | 
			
		||||
       if ((err = sober128_start(&prng)) != CRYPT_OK) {
 | 
			
		||||
          return err;
 | 
			
		||||
       }
 | 
			
		||||
       if ((err = sober128_add_entropy(tests[x].key, tests[x].keylen, &prng)) != CRYPT_OK) {
 | 
			
		||||
          return err;
 | 
			
		||||
       }
 | 
			
		||||
       /* add IV */
 | 
			
		||||
       if ((err = sober128_add_entropy(tests[x].iv, tests[x].ivlen, &prng)) != CRYPT_OK) {
 | 
			
		||||
          return err;
 | 
			
		||||
       }
 | 
			
		||||
 | 
			
		||||
       /* ready up */
 | 
			
		||||
       if ((err = sober128_ready(&prng)) != CRYPT_OK) {
 | 
			
		||||
          return err;
 | 
			
		||||
       }
 | 
			
		||||
       memset(dst, 0, tests[x].len);
 | 
			
		||||
       if (sober128_read(dst, tests[x].len, &prng) != (unsigned long)tests[x].len) {
 | 
			
		||||
          return CRYPT_ERROR_READPRNG;
 | 
			
		||||
       }
 | 
			
		||||
       sober128_done(&prng);
 | 
			
		||||
       if (memcmp(dst, tests[x].out, tests[x].len)) {
 | 
			
		||||
#if 0
 | 
			
		||||
          printf("\n\nSOBER128 failed, I got:\n"); 
 | 
			
		||||
          for (y = 0; y < tests[x].len; y++) printf("%02x ", dst[y]);
 | 
			
		||||
          printf("\n");
 | 
			
		||||
#endif
 | 
			
		||||
          return CRYPT_FAIL_TESTVECTOR;
 | 
			
		||||
       }
 | 
			
		||||
   }
 | 
			
		||||
   return CRYPT_OK;
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										154
									
								
								sober128tab.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								sober128tab.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,154 @@
 | 
			
		||||
/* $ID$ */
 | 
			
		||||
/* @(#)TuringMultab.h	1.3 (QUALCOMM) 02/09/03 */
 | 
			
		||||
/* Multiplication table for Turing using 0xD02B4367 */
 | 
			
		||||
static const ulong32 Multab[256] = {
 | 
			
		||||
    0x00000000, 0xD02B4367, 0xED5686CE, 0x3D7DC5A9,
 | 
			
		||||
    0x97AC41D1, 0x478702B6, 0x7AFAC71F, 0xAAD18478,
 | 
			
		||||
    0x631582EF, 0xB33EC188, 0x8E430421, 0x5E684746,
 | 
			
		||||
    0xF4B9C33E, 0x24928059, 0x19EF45F0, 0xC9C40697,
 | 
			
		||||
    0xC62A4993, 0x16010AF4, 0x2B7CCF5D, 0xFB578C3A,
 | 
			
		||||
    0x51860842, 0x81AD4B25, 0xBCD08E8C, 0x6CFBCDEB,
 | 
			
		||||
    0xA53FCB7C, 0x7514881B, 0x48694DB2, 0x98420ED5,
 | 
			
		||||
    0x32938AAD, 0xE2B8C9CA, 0xDFC50C63, 0x0FEE4F04,
 | 
			
		||||
    0xC154926B, 0x117FD10C, 0x2C0214A5, 0xFC2957C2,
 | 
			
		||||
    0x56F8D3BA, 0x86D390DD, 0xBBAE5574, 0x6B851613,
 | 
			
		||||
    0xA2411084, 0x726A53E3, 0x4F17964A, 0x9F3CD52D,
 | 
			
		||||
    0x35ED5155, 0xE5C61232, 0xD8BBD79B, 0x089094FC,
 | 
			
		||||
    0x077EDBF8, 0xD755989F, 0xEA285D36, 0x3A031E51,
 | 
			
		||||
    0x90D29A29, 0x40F9D94E, 0x7D841CE7, 0xADAF5F80,
 | 
			
		||||
    0x646B5917, 0xB4401A70, 0x893DDFD9, 0x59169CBE,
 | 
			
		||||
    0xF3C718C6, 0x23EC5BA1, 0x1E919E08, 0xCEBADD6F,
 | 
			
		||||
    0xCFA869D6, 0x1F832AB1, 0x22FEEF18, 0xF2D5AC7F,
 | 
			
		||||
    0x58042807, 0x882F6B60, 0xB552AEC9, 0x6579EDAE,
 | 
			
		||||
    0xACBDEB39, 0x7C96A85E, 0x41EB6DF7, 0x91C02E90,
 | 
			
		||||
    0x3B11AAE8, 0xEB3AE98F, 0xD6472C26, 0x066C6F41,
 | 
			
		||||
    0x09822045, 0xD9A96322, 0xE4D4A68B, 0x34FFE5EC,
 | 
			
		||||
    0x9E2E6194, 0x4E0522F3, 0x7378E75A, 0xA353A43D,
 | 
			
		||||
    0x6A97A2AA, 0xBABCE1CD, 0x87C12464, 0x57EA6703,
 | 
			
		||||
    0xFD3BE37B, 0x2D10A01C, 0x106D65B5, 0xC04626D2,
 | 
			
		||||
    0x0EFCFBBD, 0xDED7B8DA, 0xE3AA7D73, 0x33813E14,
 | 
			
		||||
    0x9950BA6C, 0x497BF90B, 0x74063CA2, 0xA42D7FC5,
 | 
			
		||||
    0x6DE97952, 0xBDC23A35, 0x80BFFF9C, 0x5094BCFB,
 | 
			
		||||
    0xFA453883, 0x2A6E7BE4, 0x1713BE4D, 0xC738FD2A,
 | 
			
		||||
    0xC8D6B22E, 0x18FDF149, 0x258034E0, 0xF5AB7787,
 | 
			
		||||
    0x5F7AF3FF, 0x8F51B098, 0xB22C7531, 0x62073656,
 | 
			
		||||
    0xABC330C1, 0x7BE873A6, 0x4695B60F, 0x96BEF568,
 | 
			
		||||
    0x3C6F7110, 0xEC443277, 0xD139F7DE, 0x0112B4B9,
 | 
			
		||||
    0xD31DD2E1, 0x03369186, 0x3E4B542F, 0xEE601748,
 | 
			
		||||
    0x44B19330, 0x949AD057, 0xA9E715FE, 0x79CC5699,
 | 
			
		||||
    0xB008500E, 0x60231369, 0x5D5ED6C0, 0x8D7595A7,
 | 
			
		||||
    0x27A411DF, 0xF78F52B8, 0xCAF29711, 0x1AD9D476,
 | 
			
		||||
    0x15379B72, 0xC51CD815, 0xF8611DBC, 0x284A5EDB,
 | 
			
		||||
    0x829BDAA3, 0x52B099C4, 0x6FCD5C6D, 0xBFE61F0A,
 | 
			
		||||
    0x7622199D, 0xA6095AFA, 0x9B749F53, 0x4B5FDC34,
 | 
			
		||||
    0xE18E584C, 0x31A51B2B, 0x0CD8DE82, 0xDCF39DE5,
 | 
			
		||||
    0x1249408A, 0xC26203ED, 0xFF1FC644, 0x2F348523,
 | 
			
		||||
    0x85E5015B, 0x55CE423C, 0x68B38795, 0xB898C4F2,
 | 
			
		||||
    0x715CC265, 0xA1778102, 0x9C0A44AB, 0x4C2107CC,
 | 
			
		||||
    0xE6F083B4, 0x36DBC0D3, 0x0BA6057A, 0xDB8D461D,
 | 
			
		||||
    0xD4630919, 0x04484A7E, 0x39358FD7, 0xE91ECCB0,
 | 
			
		||||
    0x43CF48C8, 0x93E40BAF, 0xAE99CE06, 0x7EB28D61,
 | 
			
		||||
    0xB7768BF6, 0x675DC891, 0x5A200D38, 0x8A0B4E5F,
 | 
			
		||||
    0x20DACA27, 0xF0F18940, 0xCD8C4CE9, 0x1DA70F8E,
 | 
			
		||||
    0x1CB5BB37, 0xCC9EF850, 0xF1E33DF9, 0x21C87E9E,
 | 
			
		||||
    0x8B19FAE6, 0x5B32B981, 0x664F7C28, 0xB6643F4F,
 | 
			
		||||
    0x7FA039D8, 0xAF8B7ABF, 0x92F6BF16, 0x42DDFC71,
 | 
			
		||||
    0xE80C7809, 0x38273B6E, 0x055AFEC7, 0xD571BDA0,
 | 
			
		||||
    0xDA9FF2A4, 0x0AB4B1C3, 0x37C9746A, 0xE7E2370D,
 | 
			
		||||
    0x4D33B375, 0x9D18F012, 0xA06535BB, 0x704E76DC,
 | 
			
		||||
    0xB98A704B, 0x69A1332C, 0x54DCF685, 0x84F7B5E2,
 | 
			
		||||
    0x2E26319A, 0xFE0D72FD, 0xC370B754, 0x135BF433,
 | 
			
		||||
    0xDDE1295C, 0x0DCA6A3B, 0x30B7AF92, 0xE09CECF5,
 | 
			
		||||
    0x4A4D688D, 0x9A662BEA, 0xA71BEE43, 0x7730AD24,
 | 
			
		||||
    0xBEF4ABB3, 0x6EDFE8D4, 0x53A22D7D, 0x83896E1A,
 | 
			
		||||
    0x2958EA62, 0xF973A905, 0xC40E6CAC, 0x14252FCB,
 | 
			
		||||
    0x1BCB60CF, 0xCBE023A8, 0xF69DE601, 0x26B6A566,
 | 
			
		||||
    0x8C67211E, 0x5C4C6279, 0x6131A7D0, 0xB11AE4B7,
 | 
			
		||||
    0x78DEE220, 0xA8F5A147, 0x958864EE, 0x45A32789,
 | 
			
		||||
    0xEF72A3F1, 0x3F59E096, 0x0224253F, 0xD20F6658,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* $ID$ */
 | 
			
		||||
/* Sbox for SOBER-128 */
 | 
			
		||||
/*
 | 
			
		||||
 * This is really the combination of two SBoxes; the least significant
 | 
			
		||||
 * 24 bits comes from:
 | 
			
		||||
 * 8->32 Sbox generated by Millan et. al. at Queensland University of
 | 
			
		||||
 * Technology. See: E. Dawson, W. Millan, L. Burnett, G. Carter,
 | 
			
		||||
 * "On the Design of 8*32 S-boxes". Unpublished report, by the
 | 
			
		||||
 * Information Systems Research Centre,
 | 
			
		||||
 * Queensland University of Technology, 1999.
 | 
			
		||||
 * 
 | 
			
		||||
 * The most significant 8 bits are the Skipjack "F table", which can be
 | 
			
		||||
 * found at http://csrc.nist.gov/CryptoToolkit/skipjack/skipjack.pdf .
 | 
			
		||||
 * In this optimised table, though, the intent is to XOR the word from
 | 
			
		||||
 * the table selected by the high byte with the input word. Thus, the
 | 
			
		||||
 * high byte is actually the Skipjack F-table entry XORED with its
 | 
			
		||||
 * table index.
 | 
			
		||||
 */
 | 
			
		||||
static const ulong32 Sbox[256] = {
 | 
			
		||||
    0xa3aa1887, 0xd65e435c, 0x0b65c042, 0x800e6ef4,
 | 
			
		||||
    0xfc57ee20, 0x4d84fed3, 0xf066c502, 0xf354e8ae,
 | 
			
		||||
    0xbb2ee9d9, 0x281f38d4, 0x1f829b5d, 0x735cdf3c,
 | 
			
		||||
    0x95864249, 0xbc2e3963, 0xa1f4429f, 0xf6432c35,
 | 
			
		||||
    0xf7f40325, 0x3cc0dd70, 0x5f973ded, 0x9902dc5e,
 | 
			
		||||
    0xda175b42, 0x590012bf, 0xdc94d78c, 0x39aab26b,
 | 
			
		||||
    0x4ac11b9a, 0x8c168146, 0xc3ea8ec5, 0x058ac28f,
 | 
			
		||||
    0x52ed5c0f, 0x25b4101c, 0x5a2db082, 0x370929e1,
 | 
			
		||||
    0x2a1843de, 0xfe8299fc, 0x202fbc4b, 0x833915dd,
 | 
			
		||||
    0x33a803fa, 0xd446b2de, 0x46233342, 0x4fcee7c3,
 | 
			
		||||
    0x3ad607ef, 0x9e97ebab, 0x507f859b, 0xe81f2e2f,
 | 
			
		||||
    0xc55b71da, 0xd7e2269a, 0x1339c3d1, 0x7ca56b36,
 | 
			
		||||
    0xa6c9def2, 0xb5c9fc5f, 0x5927b3a3, 0x89a56ddf,
 | 
			
		||||
    0xc625b510, 0x560f85a7, 0xace82e71, 0x2ecb8816,
 | 
			
		||||
    0x44951e2a, 0x97f5f6af, 0xdfcbc2b3, 0xce4ff55d,
 | 
			
		||||
    0xcb6b6214, 0x2b0b83e3, 0x549ea6f5, 0x9de041af,
 | 
			
		||||
    0x792f1f17, 0xf73b99ee, 0x39a65ec0, 0x4c7016c6,
 | 
			
		||||
    0x857709a4, 0xd6326e01, 0xc7b280d9, 0x5cfb1418,
 | 
			
		||||
    0xa6aff227, 0xfd548203, 0x506b9d96, 0xa117a8c0,
 | 
			
		||||
    0x9cd5bf6e, 0xdcee7888, 0x61fcfe64, 0xf7a193cd,
 | 
			
		||||
    0x050d0184, 0xe8ae4930, 0x88014f36, 0xd6a87088,
 | 
			
		||||
    0x6bad6c2a, 0x1422c678, 0xe9204de7, 0xb7c2e759,
 | 
			
		||||
    0x0200248e, 0x013b446b, 0xda0d9fc2, 0x0414a895,
 | 
			
		||||
    0x3a6cc3a1, 0x56fef170, 0x86c19155, 0xcf7b8a66,
 | 
			
		||||
    0x551b5e69, 0xb4a8623e, 0xa2bdfa35, 0xc4f068cc,
 | 
			
		||||
    0x573a6acd, 0x6355e936, 0x03602db9, 0x0edf13c1,
 | 
			
		||||
    0x2d0bb16d, 0x6980b83c, 0xfeb23763, 0x3dd8a911,
 | 
			
		||||
    0x01b6bc13, 0xf55579d7, 0xf55c2fa8, 0x19f4196e,
 | 
			
		||||
    0xe7db5476, 0x8d64a866, 0xc06e16ad, 0xb17fc515,
 | 
			
		||||
    0xc46feb3c, 0x8bc8a306, 0xad6799d9, 0x571a9133,
 | 
			
		||||
    0x992466dd, 0x92eb5dcd, 0xac118f50, 0x9fafb226,
 | 
			
		||||
    0xa1b9cef3, 0x3ab36189, 0x347a19b1, 0x62c73084,
 | 
			
		||||
    0xc27ded5c, 0x6c8bc58f, 0x1cdde421, 0xed1e47fb,
 | 
			
		||||
    0xcdcc715e, 0xb9c0ff99, 0x4b122f0f, 0xc4d25184,
 | 
			
		||||
    0xaf7a5e6c, 0x5bbf18bc, 0x8dd7c6e0, 0x5fb7e420,
 | 
			
		||||
    0x521f523f, 0x4ad9b8a2, 0xe9da1a6b, 0x97888c02,
 | 
			
		||||
    0x19d1e354, 0x5aba7d79, 0xa2cc7753, 0x8c2d9655,
 | 
			
		||||
    0x19829da1, 0x531590a7, 0x19c1c149, 0x3d537f1c,
 | 
			
		||||
    0x50779b69, 0xed71f2b7, 0x463c58fa, 0x52dc4418,
 | 
			
		||||
    0xc18c8c76, 0xc120d9f0, 0xafa80d4d, 0x3b74c473,
 | 
			
		||||
    0xd09410e9, 0x290e4211, 0xc3c8082b, 0x8f6b334a,
 | 
			
		||||
    0x3bf68ed2, 0xa843cc1b, 0x8d3c0ff3, 0x20e564a0,
 | 
			
		||||
    0xf8f55a4f, 0x2b40f8e7, 0xfea7f15f, 0xcf00fe21,
 | 
			
		||||
    0x8a6d37d6, 0xd0d506f1, 0xade00973, 0xefbbde36,
 | 
			
		||||
    0x84670fa8, 0xfa31ab9e, 0xaedab618, 0xc01f52f5,
 | 
			
		||||
    0x6558eb4f, 0x71b9e343, 0x4b8d77dd, 0x8cb93da6,
 | 
			
		||||
    0x740fd52d, 0x425412f8, 0xc5a63360, 0x10e53ad0,
 | 
			
		||||
    0x5a700f1c, 0x8324ed0b, 0xe53dc1ec, 0x1a366795,
 | 
			
		||||
    0x6d549d15, 0xc5ce46d7, 0xe17abe76, 0x5f48e0a0,
 | 
			
		||||
    0xd0f07c02, 0x941249b7, 0xe49ed6ba, 0x37a47f78,
 | 
			
		||||
    0xe1cfffbd, 0xb007ca84, 0xbb65f4da, 0xb59f35da,
 | 
			
		||||
    0x33d2aa44, 0x417452ac, 0xc0d674a7, 0x2d61a46a,
 | 
			
		||||
    0xdc63152a, 0x3e12b7aa, 0x6e615927, 0xa14fb118,
 | 
			
		||||
    0xa151758d, 0xba81687b, 0xe152f0b3, 0x764254ed,
 | 
			
		||||
    0x34c77271, 0x0a31acab, 0x54f94aec, 0xb9e994cd,
 | 
			
		||||
    0x574d9e81, 0x5b623730, 0xce8a21e8, 0x37917f0b,
 | 
			
		||||
    0xe8a9b5d6, 0x9697adf8, 0xf3d30431, 0x5dcac921,
 | 
			
		||||
    0x76b35d46, 0xaa430a36, 0xc2194022, 0x22bca65e,
 | 
			
		||||
    0xdaec70ba, 0xdfaea8cc, 0x777bae8b, 0x242924d5,
 | 
			
		||||
    0x1f098a5a, 0x4b396b81, 0x55de2522, 0x435c1cb8,
 | 
			
		||||
    0xaeb8fe1d, 0x9db3c697, 0x5b164f83, 0xe0c16376,
 | 
			
		||||
    0xa319224c, 0xd0203b35, 0x433ac0fe, 0x1466a19a,
 | 
			
		||||
    0x45f0b24f, 0x51fda998, 0xc0d52d71, 0xfa0896a8,
 | 
			
		||||
    0xf9e6053f, 0xa4b0d300, 0xd499cbcc, 0xb95e3d40,
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										15
									
								
								sprng.c
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								sprng.c
									
									
									
									
									
								
							@ -19,15 +19,15 @@
 | 
			
		||||
 | 
			
		||||
const struct _prng_descriptor sprng_desc =
 | 
			
		||||
{
 | 
			
		||||
    "sprng",
 | 
			
		||||
    "sprng", 0,
 | 
			
		||||
    &sprng_start,
 | 
			
		||||
    &sprng_add_entropy,
 | 
			
		||||
    &sprng_ready,
 | 
			
		||||
    &sprng_read,
 | 
			
		||||
    &sprng_done,
 | 
			
		||||
    &sprng_export,
 | 
			
		||||
    &sprng_import
 | 
			
		||||
 | 
			
		||||
    &sprng_import,
 | 
			
		||||
    &sprng_test
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int sprng_start(prng_state *prng)
 | 
			
		||||
@ -51,9 +51,9 @@ unsigned long sprng_read(unsigned char *buf, unsigned long len, prng_state *prng
 | 
			
		||||
   return rng_get_bytes(buf, len, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sprng_done(prng_state *prng)
 | 
			
		||||
int sprng_done(prng_state *prng)
 | 
			
		||||
{
 | 
			
		||||
   _ARGCHK(prng != NULL);
 | 
			
		||||
   return CRYPT_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int sprng_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
 | 
			
		||||
@ -69,6 +69,11 @@ int sprng_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
 | 
			
		||||
   return CRYPT_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int sprng_test(void)
 | 
			
		||||
{
 | 
			
		||||
   return CRYPT_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										35
									
								
								yarrow.c
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								yarrow.c
									
									
									
									
									
								
							@ -15,14 +15,15 @@
 | 
			
		||||
 | 
			
		||||
const struct _prng_descriptor yarrow_desc =
 | 
			
		||||
{
 | 
			
		||||
    "yarrow",
 | 
			
		||||
    "yarrow", 64,
 | 
			
		||||
    &yarrow_start,
 | 
			
		||||
    &yarrow_add_entropy,
 | 
			
		||||
    &yarrow_ready,
 | 
			
		||||
    &yarrow_read,
 | 
			
		||||
    &yarrow_done,
 | 
			
		||||
    &yarrow_export,
 | 
			
		||||
    &yarrow_import
 | 
			
		||||
    &yarrow_import,
 | 
			
		||||
    &yarrow_test
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int yarrow_start(prng_state *prng)
 | 
			
		||||
@ -183,10 +184,12 @@ unsigned long yarrow_read(unsigned char *buf, unsigned long len, prng_state *prn
 | 
			
		||||
   return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void yarrow_done(prng_state *prng)
 | 
			
		||||
int yarrow_done(prng_state *prng)
 | 
			
		||||
{
 | 
			
		||||
   _ARGCHK(prng != NULL);
 | 
			
		||||
   /* call cipher done when we invent one ;-) */
 | 
			
		||||
 | 
			
		||||
   return CRYPT_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
 | 
			
		||||
@ -222,10 +225,32 @@ int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng
 | 
			
		||||
   if ((err = yarrow_start(prng)) != CRYPT_OK) {
 | 
			
		||||
      return err;
 | 
			
		||||
   }
 | 
			
		||||
   if ((err = yarrow_add_entropy(in, 64, &prng)) != CRYPT_OK) {
 | 
			
		||||
   return yarrow_add_entropy(in, 64, prng);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int yarrow_test(void)
 | 
			
		||||
{
 | 
			
		||||
#ifndef LTC_TEST
 | 
			
		||||
   return CRYPT_NOP;
 | 
			
		||||
#else
 | 
			
		||||
   int err;
 | 
			
		||||
   prng_state prng;
 | 
			
		||||
 | 
			
		||||
   if ((err = yarrow_start(&prng)) != CRYPT_OK) {
 | 
			
		||||
      return err;
 | 
			
		||||
   }
 | 
			
		||||
   return yarrow_ready(&prng);
 | 
			
		||||
   
 | 
			
		||||
   /* now let's test the hash/cipher that was chosen */
 | 
			
		||||
   if ((err = cipher_descriptor[prng.yarrow.cipher].test()) != CRYPT_OK) {
 | 
			
		||||
      return err; 
 | 
			
		||||
   }
 | 
			
		||||
   if ((err = hash_descriptor[prng.yarrow.hash].test()) != CRYPT_OK) {
 | 
			
		||||
      return err; 
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   yarrow_done(&prng);
 | 
			
		||||
   return CRYPT_OK;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user