]> git.proxmox.com Git - mirror_corosync.git/commitdiff
Remove libtomcrypt
authorJan Friesse <jfriesse@redhat.com>
Mon, 12 Mar 2012 15:46:51 +0000 (16:46 +0100)
committerJan Friesse <jfriesse@redhat.com>
Tue, 13 Mar 2012 08:19:47 +0000 (09:19 +0100)
Tomcrypt in corosync is for long time not updated. Because we have
support for libnss, libtomcrypt can be removed.

Also few leftovers (AES is 256 bits, not 128, ...) are removed.

Signed-off-by: Jan Friesse <jfriesse@redhat.com>
Reviewed-by: Steven Dake <sdake@redhat.com>
23 files changed:
LICENSE
SECURITY
conf/lenses/corosync.aug
configure.ac
corosync.spec.in
cts/agents/Makefile.am
cts/agents/cpg_test_agent.c
cts/corotests.py
exec/Makefile.am
exec/coroparse.c
exec/crypto.c [deleted file]
exec/crypto.h [deleted file]
exec/totemconfig.c
exec/totemsrp.c
exec/totemudp.c
exec/totemudpu.c
include/corosync/totem/totem.h
man/corosync.conf.5
man/corosync_overview.8
test/Makefile.am
test/cpgverify.c
test/stress_cpgcontext.c
test/stress_cpgfdget.c

diff --git a/LICENSE b/LICENSE
index 250db9ad08e6987ab0993275eecd66748fb33115..8d32cd17a11c1b3cab0f30942f3838572bc50943 100644 (file)
--- a/LICENSE
+++ b/LICENSE
@@ -1,17 +1,6 @@
-***
-All cryptographic software in this package is subject to the following legal
-notice:
-This package includes publicly available encryption source code which,
-together with object code resulting from the compiling of publicly
-available source code, may be exported from the United States under License
-Exception TSU prsuant to 15 C.F.R Section 740.13(e).
-***
 -----------------------------------------------------------------------------
 The following license applies to every file in this source distribution except
-for the files exec/crypto.c, exec/crypto.h, git-version-gen, and
-gitlog-to-changelog.  The exec/crypto[c|h] file license is described in its
-full content later in this file and are part of the executive runtime and
-components of binary images produced by the source code.
+for the files git-version-gen, and gitlog-to-changelog.
 
 The git* files, which are available under GPLv3 or later,  are only used by
 our release process to generate text file content and are not part of any
@@ -49,21 +38,6 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 THE POSSIBILITY OF SUCH DAMAGE.
 
------------------------------------------------------------------------------
-The corosync project uses software from the LibTomCrypt project
-www.libtomcrypt.org.  This software is contained the files exec/crypto.c and
-exec/crypto.h.  The following license applies to the files exec/crypto.c and
-exec/crytpo.h:
------------------------------------------------------------------------------
-LibTomCrypt is public domain.  As should all quality software be.
-
-All of the software was either written by or donated to Tom St Denis for the
-purposes of this project.  The only exception is the SAFER.C source which has
-no known license status (assumed copyrighted) which is why SAFER,C is shipped
-as disabled.
-
-Tom St Denis
-
 -----------------------------------------------------------------------------
 The corosync project uses software for release processing which generates
 changelogs and version information for the software.  These programs are not
index 09fb894fe29ad7301e40f0b1a5466bf70e70c076..a2a4fdf1ee5a97f3b2f36ec68d2efe9c64dca323 100644 (file)
--- a/SECURITY
+++ b/SECURITY
@@ -1,11 +1,3 @@
-***
-All cryptographic software in this package is subject to the following legal
-notice:
-This package includes publicly available encryption source code which,
-together with object code resulting from the compiling of publicly
-available source code, may be exported from the United States under License
-Exception TSU prsuant to 15 C.F.R Section 740.13(e).
-***
 Security Design of corosync
 
 The corosync project intends to mitigate the following threats:
@@ -61,14 +53,12 @@ encrypt_and_sign to prepare the message to be sent.  When the executive
 wants to receive a message from the network, it uses
 authenticate_and_decrypt to verify the message is valid and decrypt it.
 
-There are currently two encryption methods available in corosync.
-sha1/hmac/sober which are coded internally, and AES/SHA256 which
-are in the Mozilla Network Security Services (libnss) library.
+Corosync uses AES256/SHA-1 which from the Mozilla Network Security
+Services (libnss) library.
 
 The internal functions utilize the following algorithms:
 sha1 - hash algorithm secure for using with hmac
 hmac - produces a 16 byte digest from any length input
-sober - pseudo random number generator and stream cipher
 
 Every message starts with a
 struct security {
@@ -76,65 +66,9 @@ struct security {
        unsigned char salt[16]; A securely generated random number
 }
 
-INTERNAL SECURITY CODE:
------------------------
-The hmac algorithm requires a 16 byte key.
-The sober algorithm requires a 16 byte private key.
-The sober algorithm requires a 16 byte public initial vector.
-
-The private key is read from disk and stored in memory for use with the
-sober algorithm to generate the three required keys.
-
-When a message is sent (encrypt_and_sign):
-------------------------------------------
-1. sober is used to create a 16 byte random number (salt) using the md4
-   algorithm
-2. sober is keyed with the private key and the initial vector is set to the
-   salt.  Then a 48 byte key is read from the sober algorithm.  This 48 byte
-   key is split into 3 16 byte keys.  The keys are the hmac key, the sober key
-   and the sober initial vector.
-3. A sober instance is keyed with the sober key and sober initial vector
-   from step #2.
-4. The data of the packet, except for the security header, is encrypted using
-   the sober cipher that was initialized in step #3.
-5. The salt is stored in the security header of the outgoing message.
-6. The hmac is initialized with the hmac key generated in step #2.
-7. The message, except for the security header, is hmaced to produce a digest
-   using the sha1 algorithm.
-8. The digest is stored in the outgoing message.
-9. The message is transmitted.
-
-
-When a message is received (decrypt_and_authenticate):
-------------------------------------------------------
-1. sober is keyed with the private key and the initial vector is set to the
-   salt in the received message.  Then a 48 byte key is read from the sober
-   algorithm.  This 48 byte key is split into 3 16 byte keys.  The keys are the
-   hmac key, the sober key and the sober initial vector.
-2. The sober key and sober initial vector from step #1 are used to key a
-   new sober instance.
-3. The hmac is setup using the hmac key generated in step #1 using sha1.
-5. The message is authenticated, except for the security header.
-6. If the message was not authenticated, the caller is told of the result.
-   The caller ignores the message.
-7. The message is decrypted, except for the security header, using the sober
-   algorithm in step #2.
-8. The message is processed.
-
-This does consume some resources.  It ensures the private key is never shared
-openly, that messages are authenticated, that messages are encrypted, and that
-any key exposure of the sober encryption key, sober initial vector, or hmac
-key can only be used to attack one of the algorithms.  Finally every key used
-is randomly unique (within the 2^128 search space of the input to sober) to
-ensure that keys are never reused, nonce's are never reused, and hmac's are
-never reused.
-
-
 USING LIBNSS
 ------------
-
-The process is similar in concept to the above, but most of the details are
-hidden inside the NSS library. When corosync is started up libnss is initialised,
+When corosync is started up libnss is initialised,
 the private key is read into memory and stored for later use by the code.
 
 When a message is sent (encrypt_and_sign):
@@ -157,9 +91,9 @@ Compatibility
 
 The encryption type can be changed at runtime with a single command:
 
-# corosync-cfgtool -c1
+# corosync-cfgtool -c0
 
-(0 for sober, 1 for nss)
+(0 for nss)
 
 This will tell all cluster nodes to start using libnss encryption. Note that
 it is possible to upgrade node individially by setting the encryption type in
index 4a8317b8c516e2188d982a77d6abebf86d4c8296..30504784697a6ff94f0cfb0614ca0ed1cadfb7ea 100644 (file)
@@ -50,7 +50,7 @@ let totem =
     |kv "rrp_mode" /none|active|passive/
     |kv "vsftype" /none|ykd/
     |kv "secauth" /on|off/
-    |kv "crypto_type" /nss|sober/
+    |kv "crypto_type" /nss|aes256/
     |kv "transport" /udp|iba/
     |kv "version" Rx.integer
     |kv "nodeid" Rx.integer
index fbaabacfc0fe4a91ba8bc2bd87527fd4502af7a4..c6b04e7f0cd567eb61452c3ce97f61ce3e7192c5 100644 (file)
@@ -81,6 +81,7 @@ AC_CHECK_LIB([qb], [qb_log_thread_priority_set], \
 if test "x${have_qb_log_thread_priority_set}" = xyes; then
        AC_DEFINE_UNQUOTED([HAVE_QB_LOG_THREAD_PRIORITY_SET], 1, [have qb_log_thread_priority_set])
 fi
+PKG_CHECK_MODULES([nss],[nss])
 
 # Checks for header files.
 AC_FUNC_ALLOCA
@@ -246,10 +247,6 @@ AC_ARG_ENABLE([small-memory-footprint],
        [  --enable-small-memory-footprint : Use small message queues and small messages sizes. ],
        [ default="no" ])
 
-AC_ARG_ENABLE([nss],
-       [  --enable-nss                    : Network Security Services encryption. ],,
-       [ enable_nss="yes" ])
-
 AC_ARG_ENABLE([dbus],
        [  --enable-dbus                   : dbus events. ],,
        [ enable_dbus="no" ])
@@ -394,13 +391,6 @@ else
        GDB_FLAGS="-g"
 fi
 
-# Look for libnss
-if test "x${enable_nss}" = xyes; then
-       PKG_CHECK_MODULES([nss],[nss])
-       AC_DEFINE_UNQUOTED([HAVE_LIBNSS], 1, [have libnss])
-       PACKAGE_FEATURES="$PACKAGE_FEATURES nss"
-fi
-
 # Look for dbus-1
 if test "x${enable_dbus}" = xyes; then
        PKG_CHECK_MODULES([DBUS],[dbus-1])
index f73e39eee472dc67f2473b0dc7985c5f8b7beafe..7539c32e2421c470656fb8b9f5c4d549f14c7dbb 100644 (file)
@@ -12,7 +12,6 @@
 %bcond_with dbus
 %bcond_with rdma
 %bcond_with systemd
-%bcond_with nss
 %bcond_with xmlconf
 
 Name: corosync
@@ -37,12 +36,10 @@ Conflicts: openais <= 0.89, openais-devel <= 0.89
 %{?_with_buildtrunk: %define buildtrunk 1}
 
 BuildRequires: libqb-devel
+BuildRequires: nss-devel
 %if %{buildtrunk}
 BuildRequires: autoconf automake
 %endif
-%if %{with nss}
-BuildRequires: nss-devel
-%endif
 %if %{with rdma}
 BuildRequires: libibverbs-devel librdmacm-devel
 %endif
@@ -76,11 +73,6 @@ export rdmacm_CFLAGS=-I/usr/include/rdma \
 export rdmacm_LIBS=-lrdmacm \
 %endif
 %{configure} \
-%if %{with nss}
-       --enable-nss \
-%else
-       --disable-nss \
-%endif
 %if %{with testagents}
        --enable-testagents \
 %endif
index d9aaa84661e05afec2f39ebd1f9e4bebb26d3770..6e8bb6a6d88426beff02a0f185cdc60f0e6455b4 100644 (file)
@@ -49,7 +49,8 @@ endif
 noinst_HEADERS          = common_test_agent.h
 
 cpg_test_agent_SOURCES = cpg_test_agent.c common_test_agent.c
-cpg_test_agent_LDADD =  -lcpg -lcfg ../../exec/crypto.o -lcorosync_common $(LIBQB_LIBS)
+cpg_test_agent_CFLAGS =  $(nss_CFLAGS)
+cpg_test_agent_LDADD =  -lcpg -lcfg -lcorosync_common $(LIBQB_LIBS) $(nss_LIBS)
 cpg_test_agent_LDFLAGS =  -L../../lib -L. -L../../common_lib
 
 sam_test_agent_SOURCES = sam_test_agent.c common_test_agent.c
index e99f522900fa81587b40878f3169aa927f8b1625..f9e0350d5ce1044541f422ecfce20f3395176e40 100644 (file)
 #include <qb/qblog.h>
 #include <corosync/cpg.h>
 #include <corosync/cfg.h>
-#include "../../exec/crypto.h"
 #include "common_test_agent.h"
 
+#include <nss.h>
+#include <pk11pub.h>
 
 typedef enum {
        MSG_OK,
@@ -100,6 +101,7 @@ static int32_t total_stored_msgs = 0;
 static int32_t total_msgs_revd = 0;
 static int32_t in_cnchg = 0;
 static int32_t pcmk_test = 0;
+PK11Context* sha1_context;
 
 static void send_some_more_messages (void * unused);
 
@@ -148,7 +150,7 @@ static void delivery_callback (
        msg_status_t status = MSG_OK;
        char status_buf[20];
        unsigned char sha1_compare[20];
-       hash_state sha1_hash;
+       unsigned int sha1_len;
 
        if (record_messages_g == 0) {
                return;
@@ -163,9 +165,9 @@ static void delivery_callback (
        if (msg_len != msg_pt->size) {
                status = MSG_SIZE_ERR;
        }
-       sha1_init (&sha1_hash);
-       sha1_process (&sha1_hash, msg_pt->payload, (msg_pt->size - sizeof (msg_t)));
-       sha1_done (&sha1_hash, sha1_compare);
+       PK11_DigestBegin(sha1_context);
+       PK11_DigestOp(sha1_context, msg_pt->payload, (msg_pt->size - sizeof (msg_t)));
+        PK11_DigestFinal(sha1_context, sha1_compare, &sha1_len, sizeof(sha1_compare));
        if (memcmp (sha1_compare, msg_pt->sha1, 20) != 0) {
                qb_log (LOG_ERR, "msg seq:%d; incorrect hash",
                        msg_pt->seq);
@@ -344,7 +346,7 @@ static void send_some_more_messages_zcb (void)
        int send_now;
        size_t payload_size;
        size_t total_size;
-       hash_state sha1_hash;
+       unsigned int sha1_len;
        cs_error_t res;
        cpg_flow_control_state_t fc_state;
        void *zcb_buffer;
@@ -367,9 +369,9 @@ static void send_some_more_messages_zcb (void)
        for (i = 0; i < payload_size; i++) {
                my_msg->payload[i] = i;
        }
-       sha1_init (&sha1_hash);
-       sha1_process (&sha1_hash, my_msg->payload, payload_size);
-       sha1_done (&sha1_hash, my_msg->sha1);
+       PK11_DigestBegin(sha1_context);
+       PK11_DigestOp(sha1_context,  my_msg->payload, payload_size);
+       PK11_DigestFinal(sha1_context, my_msg->sha1, &sha1_len, sizeof(my_msg->sha1));
 
        for (i = 0; i < send_now; i++) {
 
@@ -415,11 +417,11 @@ static void send_some_more_messages_normal (void)
        int i;
        int send_now;
        size_t payload_size;
-       hash_state sha1_hash;
        cs_error_t res;
        cpg_flow_control_state_t fc_state;
        int retries = 0;
        time_t before;
+       unsigned int sha1_len;
 
        if (cpg_fd < 0)
                return;
@@ -436,9 +438,9 @@ static void send_some_more_messages_normal (void)
        for (i = 0; i < payload_size; i++) {
                buffer[i] = i;
        }
-       sha1_init (&sha1_hash);
-       sha1_process (&sha1_hash, buffer, payload_size);
-       sha1_done (&sha1_hash, my_msg.sha1);
+       PK11_DigestBegin(sha1_context);
+       PK11_DigestOp(sha1_context,  buffer, payload_size);
+       PK11_DigestFinal(sha1_context, my_msg.sha1, &sha1_len, sizeof(my_msg.sha1));
 
        iov[0].iov_len = sizeof (msg_t);
        iov[0].iov_base = &my_msg;
@@ -628,7 +630,6 @@ static void do_command (int sock, char* func, char*args[], int num_args)
 
                strcpy (group_name.value, args[0]);
                group_name.length = strlen(args[0]);
-
                result = cpg_join (cpg_handle, &group_name);
                if (result != CS_OK) {
                        qb_log (LOG_ERR,
@@ -756,6 +757,8 @@ static void my_pre_exit(void)
                corosync_cfg_finalize (cfg_handle);
                cfg_handle = 0;
        }
+
+       PK11_DestroyContext(sha1_context, PR_TRUE);
 }
 
 int
@@ -764,6 +767,16 @@ main(int argc, char *argv[])
        list_init (&msg_log_head);
        list_init (&config_chg_log_head);
 
+       if (NSS_NoDB_Init(".") != SECSuccess) {
+               qb_log(LOG_ERR, "Couldn't initialize nss");
+               exit (0);
+       }
+
+       if ((sha1_context = PK11_CreateDigestContext(SEC_OID_SHA1)) == NULL) {
+               qb_log(LOG_ERR, "Couldn't initialize nss");
+               exit (0);
+       }
+
        return test_agent_run ("cpg_test_agent", 9034, do_command, my_pre_exit);
 }
 
index f52ca3d0529d16f992b3f8b62c0766b94b166cb1..f7b29a5200f1d6526620e91a790102362db0edbc 100644 (file)
@@ -1574,9 +1574,9 @@ def CoroTestList(cm, audits):
 #    s['totem/max_messages'] = 20
 #    configs.append(s)
 #
-    d = ConfigContainer('sec_sober')
+    d = ConfigContainer('sec_nss')
     d['totem/secauth'] = 'on'
-    d['totem/crypto_type'] = 'sober'
+    d['totem/crypto_type'] = 'nss'
     configs.append(d)
 
     if not cm.Env["RrpBindAddr"] is None:
index 78f3a3ee11b501e0b4efcf295e8cd32fe84c38eb..c481c0ae87b0ad731219e6720d7f19e534f08296 100644 (file)
@@ -37,7 +37,7 @@ INCLUDES              = -I$(top_builddir)/include -I$(top_srcdir)/include $(nss_CFLAGS) $(rd
 
 TOTEM_SRC              = totemip.c totemnet.c totemudp.c \
                          totemudpu.c totemrrp.c totemsrp.c totemmrp.c \
-                         totempg.c crypto.c cs_queue.h
+                         totempg.c cs_queue.h
 if BUILD_RDMA
 TOTEM_SRC              += totemiba.c
 endif
@@ -62,7 +62,7 @@ SHARED_LIBS           = $(lib_LIBRARIES:%.a=%.so.$(SONAME))
 SHARED_LIBS_SO         = $(SHARED_LIBS:%.so.$(SONAME)=%.so)
 SHARED_LIBS_SO_TWO     = $(SHARED_LIBS:%.so.$(SONAME)=%.so.$(SOMAJOR))
 
-noinst_HEADERS         = apidef.h crypto.h mainconfig.h main.h \
+noinst_HEADERS         = apidef.h mainconfig.h main.h \
                          quorum.h service.h timer.h totemconfig.h \
                          totemmrp.h totemnet.h totemudp.h totemiba.h totemrrp.h \
                          totemudpu.h totemsrp.h util.h vsf.h schedwrk.h \
index e9081ff384aa838002eec4adfb21ef7aeb161cd9..5efffc0dcdb1c2b766bd5e9cc7ab7f8dbaa44e95 100644 (file)
@@ -462,6 +462,14 @@ static int main_config_parser_cb(const char *path,
                                icmap_set_uint32(path, i);
                                add_as_string = 0;
                        }
+                       if (strcmp(path, "totem.crypto_type") == 0) {
+                               if ((strcmp(value, "nss") != 0) &&
+                                   (strcmp(value, "aes256") != 0)) {
+                                       *error_string = "Invalid crypto type";
+
+                                       return (0);
+                               }
+                       }
                        break;
 
                case MAIN_CP_CB_DATA_STATE_INTERFACE:
diff --git a/exec/crypto.c b/exec/crypto.c
deleted file mode 100644 (file)
index 14fb807..0000000
+++ /dev/null
@@ -1,1340 +0,0 @@
-/* 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.com
- */
-
-#include <config.h>
-
-#include <assert.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/poll.h>
-#if defined(COROSYNC_BSD)
-#include <sys/endian.h>
-#endif
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdint.h>
-
-#include "crypto.h"
-
-#define CONST64(n) n ## ULL
-
-typedef uint32_t ulong32;
-typedef uint64_t ulong64;
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define ENDIAN_LITTLE
-#elif __BYTE_ORDER == __BIG_ENDIAN
-#define ENDIAN_BIG
-#else
-#error "cannot detect byte order"
-#endif
-
-#if defined(COROSYNC_LINUX)
-#if __WORDSIZE == 64
-#define ENDIAN_64BITWORD
-#endif
-#if __WORDSIZE == 32
-#define ENDIAN_32BITWORD
-#endif
-#else
-/* XXX need to find a better default
- */
-#define ENDIAN_32BITWORD
-#endif
-
-/* ---- HELPER MACROS ---- */
-#ifdef ENDIAN_NEUTRAL
-
-#define STORE32L(x, y)                                                                     \
-     { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);   \
-       (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
-
-#define LOAD32L(x, y)                            \
-     { x = ((unsigned long)((y)[3] & 255)<<24) | \
-           ((unsigned long)((y)[2] & 255)<<16) | \
-           ((unsigned long)((y)[1] & 255)<<8)  | \
-           ((unsigned long)((y)[0] & 255)); }
-
-#define STORE64L(x, y)                                                                     \
-     { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255);   \
-       (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255);   \
-       (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);   \
-       (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
-
-#define LOAD64L(x, y)                                                       \
-     { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
-           (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
-           (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
-           (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
-
-#define STORE32H(x, y)                                                                     \
-     { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255);   \
-       (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
-
-#define LOAD32H(x, y)                            \
-     { x = ((unsigned long)((y)[0] & 255)<<24) | \
-           ((unsigned long)((y)[1] & 255)<<16) | \
-           ((unsigned long)((y)[2] & 255)<<8)  | \
-           ((unsigned long)((y)[3] & 255)); }
-
-#define STORE64H(x, y)                                                                     \
-   { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255);     \
-     (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255);     \
-     (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255);     \
-     (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
-
-#define LOAD64H(x, y)                                                      \
-   { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
-         (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
-         (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
-         (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }
-
-#endif /* ENDIAN_NEUTRAL */
-
-#ifdef ENDIAN_LITTLE
-
-#define STORE32H(x, y)                                                                     \
-     { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255);   \
-       (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
-
-#define LOAD32H(x, y)                            \
-     { x = ((unsigned long)((y)[0] & 255)<<24) | \
-           ((unsigned long)((y)[1] & 255)<<16) | \
-           ((unsigned long)((y)[2] & 255)<<8)  | \
-           ((unsigned long)((y)[3] & 255)); }
-
-#define STORE64H(x, y)                                                                     \
-   { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255);     \
-     (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255);     \
-     (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255);     \
-     (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
-
-#define LOAD64H(x, y)                                                      \
-   { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
-         (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
-         (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
-         (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }
-
-#ifdef ENDIAN_32BITWORD
-
-#define STORE32L(x, y)        \
-     { unsigned long __t = (x); memcpy(y, &__t, 4); }
-
-#define LOAD32L(x, y)         \
-     memcpy(&(x), y, 4);
-
-#define STORE64L(x, y)                                                                     \
-     { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255);   \
-       (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255);   \
-       (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);   \
-       (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
-
-#define LOAD64L(x, y)                                                       \
-     { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
-           (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
-           (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
-           (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
-
-#else /* 64-bit words then  */
-
-#define STORE32L(x, y)        \
-     { unsigned long __t = (x); memcpy(y, &__t, 4); }
-
-#define LOAD32L(x, y)         \
-     { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }
-
-#define STORE64L(x, y)        \
-     { ulong64 __t = (x); memcpy(y, &__t, 8); }
-
-#define LOAD64L(x, y)         \
-    { memcpy(&(x), y, 8); }
-
-#endif /* ENDIAN_64BITWORD */
-
-#endif /* ENDIAN_LITTLE */
-
-#ifdef ENDIAN_BIG
-#define STORE32L(x, y)                                                                     \
-     { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);   \
-       (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
-
-#define LOAD32L(x, y)                            \
-     { x = ((unsigned long)((y)[3] & 255)<<24) | \
-           ((unsigned long)((y)[2] & 255)<<16) | \
-           ((unsigned long)((y)[1] & 255)<<8)  | \
-           ((unsigned long)((y)[0] & 255)); }
-
-#define STORE64L(x, y)                                                                     \
-   { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255);     \
-     (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255);     \
-     (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);     \
-     (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
-
-#define LOAD64L(x, y)                                                      \
-   { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \
-         (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32) | \
-         (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16) | \
-         (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
-
-#ifdef ENDIAN_32BITWORD
-
-#define STORE32H(x, y)        \
-     { unsigned long __t = (x); memcpy(y, &__t, 4); }
-
-#define LOAD32H(x, y)         \
-     memcpy(&(x), y, 4);
-
-#define STORE64H(x, y)                                                                     \
-     { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255);   \
-       (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255);   \
-       (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255);   \
-       (y)[6] = (unsigned char)(((x)>>8)&255);  (y)[7] = (unsigned char)((x)&255); }
-
-#define LOAD64H(x, y)                                                       \
-     { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \
-           (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32)| \
-           (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16)| \
-           (((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); }
-
-#else /* 64-bit words then  */
-
-#define STORE32H(x, y)        \
-     { unsigned long __t = (x); memcpy(y, &__t, 4); }
-
-#define LOAD32H(x, y)         \
-     { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }
-
-#define STORE64H(x, y)        \
-     { ulong64 __t = (x); memcpy(y, &__t, 8); }
-
-#define LOAD64H(x, y)         \
-    { memcpy(&(x), y, 8); }
-
-#endif /* ENDIAN_64BITWORD */
-#endif /* ENDIAN_BIG */
-
-#define BSWAP(x)  ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL)  | \
-                    ((x>>8)&0x0000FF00UL)  | ((x<<8)&0x00FF0000UL) )
-
-#if defined(__GNUC__) && defined(__i386__) && !defined(INTEL_CC)
-
-static inline unsigned long ROL(unsigned long word, int i)
-{
-   __asm__("roll %%cl,%0"
-      :"=r" (word)
-      :"0" (word),"c" (i));
-   return word;
-}
-
-static inline unsigned long ROR(unsigned long word, int i)
-{
-   __asm__("rorl %%cl,%0"
-      :"=r" (word)
-      :"0" (word),"c" (i));
-   return word;
-}
-
-#else
-
-/* rotates the hard way */
-#define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
-#define ROR(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
-
-#endif
-
-#define ROL64(x, y) \
-    ( (((x)<<((ulong64)(y)&63)) | \
-      (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF))
-
-#define ROR64(x, y) \
-    ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \
-      ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF))
-
-#undef MAX
-#undef MIN
-#define MAX(x, y) ( ((x)>(y))?(x):(y) )
-#define MIN(x, y) ( ((x)<(y))?(x):(y) )
-
-/* extract a byte portably */
-#define byte(x, n) (((x) >> (8 * (n))) & 255)
-
-#define CONST64(n) n ## ULL
-
-/* a simple macro for making hash "process" functions */
-#define HASH_PROCESS(func_name, compress_name, state_var, block_size)                       \
-int func_name (hash_state * md, const unsigned char *buf, unsigned long len)               \
-{                                                                                           \
-    unsigned long n;                                                                        \
-    if (md-> state_var .curlen > sizeof(md-> state_var .buf)) {                             \
-       return CRYPT_INVALID_ARG;                                                            \
-    }                                                                                       \
-    while (len > 0) {                                                                       \
-        if (md-> state_var .curlen == 0 && len >= block_size) {                             \
-           compress_name (md, (unsigned char *)buf);                                        \
-           md-> state_var .length += block_size * 8;                                        \
-           buf             += block_size;                                                   \
-           len             -= block_size;                                                   \
-        } else {                                                                            \
-           n = MIN(len, (block_size - md-> state_var .curlen));                             \
-           memcpy(md-> state_var .buf + md-> state_var.curlen, buf, (size_t)n);             \
-           md-> state_var .curlen += n;                                                     \
-           buf             += n;                                                            \
-           len             -= n;                                                            \
-           if (md-> state_var .curlen == block_size) {                                      \
-              compress_name (md, md-> state_var .buf);                                      \
-              md-> state_var .length += 8*block_size;                                       \
-              md-> state_var .curlen = 0;                                                   \
-           }                                                                                \
-       }                                                                                    \
-    }                                                                                       \
-    return CRYPT_OK;                                                                        \
-}
-
-#define MAXBLOCKSIZE 128
-
-/*
- * The mycrypt_macros.h file
- */
-
-/* ---- HELPER MACROS ---- */
-#ifdef ENDIAN_NEUTRAL
-
-#define STORE32L(x, y)                                                                     \
-     { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);   \
-       (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
-
-#define LOAD32L(x, y)                            \
-     { x = ((unsigned long)((y)[3] & 255)<<24) | \
-           ((unsigned long)((y)[2] & 255)<<16) | \
-           ((unsigned long)((y)[1] & 255)<<8)  | \
-           ((unsigned long)((y)[0] & 255)); }
-
-#define STORE64L(x, y)                                                                     \
-     { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255);   \
-       (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255);   \
-       (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);   \
-       (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
-
-#define LOAD64L(x, y)                                                       \
-     { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
-           (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
-           (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
-           (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
-
-#define STORE32H(x, y)                                                                     \
-     { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255);   \
-       (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
-
-#define LOAD32H(x, y)                            \
-     { x = ((unsigned long)((y)[0] & 255)<<24) | \
-           ((unsigned long)((y)[1] & 255)<<16) | \
-           ((unsigned long)((y)[2] & 255)<<8)  | \
-           ((unsigned long)((y)[3] & 255)); }
-
-#define STORE64H(x, y)                                                                     \
-   { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255);     \
-     (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255);     \
-     (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255);     \
-     (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
-
-#define LOAD64H(x, y)                                                      \
-   { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
-         (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
-         (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
-         (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }
-
-#endif /* ENDIAN_NEUTRAL */
-
-#ifdef ENDIAN_LITTLE
-
-#define STORE32H(x, y)                                                                     \
-     { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255);   \
-       (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
-
-#define LOAD32H(x, y)                            \
-     { x = ((unsigned long)((y)[0] & 255)<<24) | \
-           ((unsigned long)((y)[1] & 255)<<16) | \
-           ((unsigned long)((y)[2] & 255)<<8)  | \
-           ((unsigned long)((y)[3] & 255)); }
-
-#define STORE64H(x, y)                                                                     \
-   { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255);     \
-     (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255);     \
-     (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255);     \
-     (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
-
-#define LOAD64H(x, y)                                                      \
-   { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
-         (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
-         (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
-         (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }
-
-#ifdef ENDIAN_32BITWORD
-
-#define STORE32L(x, y)        \
-     { unsigned long __t = (x); memcpy(y, &__t, 4); }
-
-#define LOAD32L(x, y)         \
-     memcpy(&(x), y, 4);
-
-#define STORE64L(x, y)                                                                     \
-     { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255);   \
-       (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255);   \
-       (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);   \
-       (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
-
-#define LOAD64L(x, y)                                                       \
-     { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
-           (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
-           (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
-           (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
-
-#else /* 64-bit words then  */
-
-#define STORE32L(x, y)        \
-     { unsigned long __t = (x); memcpy(y, &__t, 4); }
-
-#define LOAD32L(x, y)         \
-     { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }
-
-#define STORE64L(x, y)        \
-     { ulong64 __t = (x); memcpy(y, &__t, 8); }
-
-#define LOAD64L(x, y)         \
-    { memcpy(&(x), y, 8); }
-
-#endif /* ENDIAN_64BITWORD */
-
-#endif /* ENDIAN_LITTLE */
-
-#ifdef ENDIAN_BIG
-#define STORE32L(x, y)                                                                     \
-     { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);   \
-       (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
-
-#define LOAD32L(x, y)                            \
-     { x = ((unsigned long)((y)[3] & 255)<<24) | \
-           ((unsigned long)((y)[2] & 255)<<16) | \
-           ((unsigned long)((y)[1] & 255)<<8)  | \
-           ((unsigned long)((y)[0] & 255)); }
-
-#define STORE64L(x, y)                                                                     \
-   { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255);     \
-     (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255);     \
-     (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);     \
-     (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
-
-#define LOAD64L(x, y)                                                      \
-   { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \
-         (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32) | \
-         (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16) | \
-         (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
-
-#ifdef ENDIAN_32BITWORD
-
-#define STORE32H(x, y)        \
-     { unsigned long __t = (x); memcpy(y, &__t, 4); }
-
-#define LOAD32H(x, y)         \
-     memcpy(&(x), y, 4);
-
-#define STORE64H(x, y)                                                                     \
-     { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255);   \
-       (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255);   \
-       (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255);   \
-       (y)[6] = (unsigned char)(((x)>>8)&255);  (y)[7] = (unsigned char)((x)&255); }
-
-#define LOAD64H(x, y)                                                       \
-     { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \
-           (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32)| \
-           (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16)| \
-           (((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); }
-
-#else /* 64-bit words then  */
-
-#define STORE32H(x, y)        \
-     { unsigned long __t = (x); memcpy(y, &__t, 4); }
-
-#define LOAD32H(x, y)         \
-     { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }
-
-#define STORE64H(x, y)        \
-     { ulong64 __t = (x); memcpy(y, &__t, 8); }
-
-#define LOAD64H(x, y)         \
-    { memcpy(&(x), y, 8); }
-
-#endif /* ENDIAN_64BITWORD */
-#endif /* ENDIAN_BIG */
-
-#define BSWAP(x)  ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL)  | \
-                    ((x>>8)&0x0000FF00UL)  | ((x<<8)&0x00FF0000UL) )
-
-
-#define ROL64(x, y) \
-    ( (((x)<<((ulong64)(y)&63)) | \
-      (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF))
-
-#define ROR64(x, y) \
-    ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \
-      ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF))
-
-#undef MAX
-#undef MIN
-#define MAX(x, y) ( ((x)>(y))?(x):(y) )
-#define MIN(x, y) ( ((x)<(y))?(x):(y) )
-
-/* extract a byte portably */
-#define byte(x, n) (((x) >> (8 * (n))) & 255)
-
-/* $Id: s128multab.h 213 2003-12-16 04:27:12Z ggr $ */
-/* @(#)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: s128sbox.h 213 2003-12-16 04:27:12Z ggr $ */
-/* 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,
-};
-
-
-/* Implementation of SOBER-128 by Tom St Denis.
- * Based on s128fast.c reference code supplied by Greg Rose of QUALCOMM.
- */
-
-const struct _prng_descriptor sober128_desc =
-{
-   "sober128", 64,
-    &sober128_start,
-    &sober128_add_entropy,
-    &sober128_ready,
-    &sober128_read,
-};
-
-const struct _prng_descriptor *prng_descriptor[] = {
-       &sober128_desc
-};
-
-/* 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(const 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;
-
-    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;
-
-    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 */
-       assert ((len & 3) == 0);
-
-       for (i = 0; i < len; i += 4) {
-           k = BYTE2WORD(&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 */
-       assert ((len & 3) == 0);
-
-       for (i = 0; i < len; i += 4) {
-           k = BYTE2WORD(&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;
-
-   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;
-}
-
-/* SHA1 code by Tom St Denis */
-
-const struct _hash_descriptor sha1_desc =
-{
-    "sha1",
-    2,
-    20,
-    64,
-
-    /* DER identifier */
-    { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E,
-      0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14 },
-    15,
-
-    &sha1_init,
-    &sha1_process,
-    &sha1_done,
-};
-
-#define F0(x,y,z)  (z ^ (x & (y ^ z)))
-#define F1(x,y,z)  (x ^ y ^ z)
-#define F2(x,y,z)  ((x & y) | (z & (x | y)))
-#define F3(x,y,z)  (x ^ y ^ z)
-
-static void sha1_compress(hash_state *md, const unsigned char *buf)
-{
-    ulong32 a,b,c,d,e,W[80],i;
-
-    /* copy the state into 512-bits into W[0..15] */
-    for (i = 0; i < 16; i++) {
-        LOAD32H(W[i], buf + (4*i));
-    }
-
-    /* copy state */
-    a = md->sha1.state[0];
-    b = md->sha1.state[1];
-    c = md->sha1.state[2];
-    d = md->sha1.state[3];
-    e = md->sha1.state[4];
-
-    /* expand it */
-    for (i = 16; i < 80; i++) {
-        W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
-    }
-
-    /* compress */
-    /* round one */
-    #define FF0(a,b,c,d,e,i) e = (ROL(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROL(b, 30);
-    #define FF1(a,b,c,d,e,i) e = (ROL(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROL(b, 30);
-    #define FF2(a,b,c,d,e,i) e = (ROL(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROL(b, 30);
-    #define FF3(a,b,c,d,e,i) e = (ROL(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROL(b, 30);
-
-    for (i = 0; i < 20; ) {
-       FF0(a,b,c,d,e,i++);
-       FF0(e,a,b,c,d,i++);
-       FF0(d,e,a,b,c,i++);
-       FF0(c,d,e,a,b,i++);
-       FF0(b,c,d,e,a,i++);
-    }
-
-    /* round two */
-    for (; i < 40; )  {
-       FF1(a,b,c,d,e,i++);
-       FF1(e,a,b,c,d,i++);
-       FF1(d,e,a,b,c,i++);
-       FF1(c,d,e,a,b,i++);
-       FF1(b,c,d,e,a,i++);
-    }
-
-    /* round three */
-    for (; i < 60; )  {
-       FF2(a,b,c,d,e,i++);
-       FF2(e,a,b,c,d,i++);
-       FF2(d,e,a,b,c,i++);
-       FF2(c,d,e,a,b,i++);
-       FF2(b,c,d,e,a,i++);
-    }
-
-    /* round four */
-    for (; i < 80; )  {
-       FF3(a,b,c,d,e,i++);
-       FF3(e,a,b,c,d,i++);
-       FF3(d,e,a,b,c,i++);
-       FF3(c,d,e,a,b,i++);
-       FF3(b,c,d,e,a,i++);
-    }
-
-    #undef FF0
-    #undef FF1
-    #undef FF2
-    #undef FF3
-
-    /* store */
-    md->sha1.state[0] = md->sha1.state[0] + a;
-    md->sha1.state[1] = md->sha1.state[1] + b;
-    md->sha1.state[2] = md->sha1.state[2] + c;
-    md->sha1.state[3] = md->sha1.state[3] + d;
-    md->sha1.state[4] = md->sha1.state[4] + e;
-}
-
-void sha1_init(hash_state * md)
-{
-   md->sha1.state[0] = 0x67452301UL;
-   md->sha1.state[1] = 0xefcdab89UL;
-   md->sha1.state[2] = 0x98badcfeUL;
-   md->sha1.state[3] = 0x10325476UL;
-   md->sha1.state[4] = 0xc3d2e1f0UL;
-   md->sha1.curlen = 0;
-   md->sha1.length = 0;
-}
-
-HASH_PROCESS(sha1_process, sha1_compress, sha1, 64)
-
-int sha1_done(hash_state * md, unsigned char *hash)
-{
-    int i;
-
-       /*
-        * Assert there isn't an invalid argument
-        */
-       assert (md->sha1.curlen < sizeof (md->sha1.buf));
-
-    /* increase the length of the message */
-    md->sha1.length += md->sha1.curlen * 8;
-
-    /* append the '1' bit */
-    md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80;
-
-    /* if the length is currently above 56 bytes we append zeros
-     * then compress.  Then we can fall back to padding zeros and length
-     * encoding like normal.
-     */
-    if (md->sha1.curlen > 56) {
-        while (md->sha1.curlen < 64) {
-            md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
-        }
-        sha1_compress(md, md->sha1.buf);
-        md->sha1.curlen = 0;
-    }
-
-    /* pad upto 56 bytes of zeroes */
-    while (md->sha1.curlen < 56) {
-        md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
-    }
-
-    /* store length */
-    STORE64H(md->sha1.length, md->sha1.buf+56);
-    sha1_compress(md, md->sha1.buf);
-
-    /* copy output */
-    for (i = 0; i < 5; i++) {
-        STORE32H(md->sha1.state[i], hash+(4*i));
-    }
-    return CRYPT_OK;
-}
-
-/* Submited by Dobes Vandermeer  (dobes@smartt.com) */
-
-/*
-    (1) append zeros to the end of K to create a B byte string
-        (e.g., if K is of length 20 bytes and B=64, then K will be
-         appended with 44 zero bytes 0x00)
-    (2) XOR (bitwise exclusive-OR) the B byte string computed in step
-        (1) with ipad (ipad = the byte 0x36 repeated B times)
-    (3) append the stream of data 'text' to the B byte string resulting
-        from step (2)
-    (4) apply H to the stream generated in step (3)
-    (5) XOR (bitwise exclusive-OR) the B byte string computed in
-        step (1) with opad (opad = the byte 0x5C repeated B times.)
-    (6) append the H result from step (4) to the B byte string
-        resulting from step (5)
-    (7) apply H to the stream generated in step (6) and output
-        the result
-*/
-
-int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen)
-{
-    unsigned char buf[128];
-    unsigned long i;
-    int err;
-
-    hmac->hash = hash;
-
-    /* valid key length? */
-       assert (keylen > 0);
-       assert (keylen <= hash_descriptor[hash]->blocksize);
-
-    memcpy(hmac->key, key, (size_t)keylen);
-    if(keylen < hash_descriptor[hash]->blocksize) {
-        memset((hmac->key) + keylen, 0, (size_t)(hash_descriptor[hash]->blocksize - keylen));
-    }
-
-    // Create the initial vector for step (3)
-    for(i=0; i < hash_descriptor[hash]->blocksize;   i++) {
-       buf[i] = hmac->key[i] ^ 0x36;
-    }
-
-    // Pre-pend that to the hash data
-    hash_descriptor[hash]->init(&hmac->md);
-    err = hash_descriptor[hash]->process(&hmac->md, buf, hash_descriptor[hash]->blocksize);
-
-   return err;
-}
-
-int hmac_process(hmac_state *hmac, const unsigned char *buf, unsigned long len)
-{
-    return hash_descriptor[hmac->hash]->process(&hmac->md, buf, len);
-}
-
-/* Submited by Dobes Vandermeer  (dobes@smartt.com) */
-
-/*
-    (1) append zeros to the end of K to create a B byte string
-        (e.g., if K is of length 20 bytes and B=64, then K will be
-         appended with 44 zero bytes 0x00)
-    (2) XOR (bitwise exclusive-OR) the B byte string computed in step
-        (1) with ipad (ipad = the byte 0x36 repeated B times)
-    (3) append the stream of data 'text' to the B byte string resulting
-        from step (2)
-    (4) apply H to the stream generated in step (3)
-    (5) XOR (bitwise exclusive-OR) the B byte string computed in
-        step (1) with opad (opad = the byte 0x5C repeated B times.)
-    (6) append the H result from step (4) to the B byte string
-        resulting from step (5)
-    (7) apply H to the stream generated in step (6) and output
-        the result
-*/
-
-int hmac_done(hmac_state *hmac, unsigned char *hashOut, unsigned long *outlen)
-{
-    unsigned char buf[128];
-       unsigned char isha[256];
-    unsigned long hashsize, i;
-    int hash, err;
-
-    /* test hash */
-    hash = hmac->hash;
-
-    /* get the hash message digest size */
-    hashsize = hash_descriptor[hash]->hashsize;
-
-    // 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)
-    for(i=0; i < hash_descriptor[hash]->blocksize; i++) {
-        buf[i] = hmac->key[i] ^ 0x5C;
-    }
-
-    // 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, hash_descriptor[hash]->blocksize)) != CRYPT_OK) {
-       goto __ERR;
-    }
-    if ((err = hash_descriptor[hash]->process(&hmac->md, isha, hashsize)) != CRYPT_OK) {
-       goto __ERR;
-    }
-    if ((err = hash_descriptor[hash]->done(&hmac->md, buf)) != CRYPT_OK) {
-       goto __ERR;
-    }
-
-    // copy to output
-    for (i = 0; i < hashsize && i < *outlen; i++) {
-        hashOut[i] = buf[i];
-    }
-    *outlen = i;
-
-    err = CRYPT_OK;
-__ERR:
-
-    return err;
-}
-
-const struct _hash_descriptor *hash_descriptor[] =
-{
-       &sha1_desc
-};
-
-/* portable way to get secure random bits to feed a PRNG */
-/* on *NIX read /dev/random */
-static unsigned long rng_nix(unsigned char *buf, unsigned long len,
-                             void (*callback)(void))
-{
-       int fd;
-       unsigned long rb = 0;
-
-       fd = open ("/dev/urandom", O_RDONLY);
-
-       if (fd >= 0) {
-               rb = (unsigned long)read (fd, buf, len);
-               close (fd);
-       }
-
-       return (rb);
-}
-
-/* on ANSI C platforms with 100 < CLOCKS_PER_SEC < 10000 */
-#if defined(XCLOCKS_PER_SEC)
-
-#define ANSI_RNG
-
-static unsigned long rng_ansic(unsigned char *buf, unsigned long len,
-                               void (*callback)(void))
-{
-   clock_t t1;
-   int l, acc, bits, a, b;
-
-   if (XCLOCKS_PER_SEC < 100 || XCLOCKS_PER_SEC > 10000) {
-      return 0;
-   }
-
-   l = len;
-   bits = 8;
-   acc  = a = b = 0;
-   while (len--) {
-       if (callback != NULL) callback();
-       while (bits--) {
-          do {
-             t1 = XCLOCK(); while (t1 == XCLOCK()) a ^= 1;
-             t1 = XCLOCK(); while (t1 == XCLOCK()) b ^= 1;
-          } while (a == b);
-          acc = (acc << 1) | a;
-       }
-       *buf++ = acc;
-       acc  = 0;
-       bits = 8;
-   }
-   acc = bits = a = b = 0;
-   return l;
-}
-
-#endif
-
-unsigned long rng_get_bytes(unsigned char *buf, unsigned long len,
-                            void (*callback)(void))
-{
-   unsigned long x;
-
-   x = rng_nix(buf, len, callback);   if (x != 0) { return x; }
-#ifdef ANSI_RNG
-   x = rng_ansic(buf, len, callback); if (x != 0) { return x; }
-#endif
-   return 0;
-}
-
-int rng_make_prng(int bits, int wprng, prng_state *prng,
-                  void (*callback)(void))
-{
-   unsigned char buf[258];
-   int err;
-
-   if (bits < 64 || bits > 1024) {
-      return CRYPT_INVALID_PRNGSIZE;
-   }
-
-   if ((err = prng_descriptor[wprng]->start(prng)) != CRYPT_OK) {
-      return err;
-   }
-
-   bits = ((bits/8)+((bits&7)!=0?1:0)) * 2;
-   if (rng_get_bytes(buf, (unsigned long)bits, callback) != (unsigned long)bits) {
-      return CRYPT_ERROR_READPRNG;
-   }
-
-   if ((err = prng_descriptor[wprng]->add_entropy(buf, (unsigned long)bits, prng)) != CRYPT_OK) {
-      return err;
-   }
-
-   if ((err = prng_descriptor[wprng]->ready(prng)) != CRYPT_OK) {
-      return err;
-   }
-
-   return CRYPT_OK;
-}
diff --git a/exec/crypto.h b/exec/crypto.h
deleted file mode 100644 (file)
index a154ff7..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-#ifndef CRYPTO_H_DEFINED
-#define CRYPTO_H_DEFINED
-
-#include <stdint.h>
-
-#define DIGEST_SHA1     0
-#define PRNG_SOBER      0
-
-
-enum {
-   CRYPT_OK=0,             /* Result OK */
-   CRYPT_ERROR,            /* Generic Error */
-   CRYPT_NOP,              /* Not a failure but no operation was performed */
-
-   CRYPT_INVALID_KEYSIZE,  /* Invalid key size given */
-   CRYPT_INVALID_ROUNDS,   /* Invalid number of rounds */
-   CRYPT_FAIL_TESTVECTOR,  /* Algorithm failed test vectors */
-
-   CRYPT_BUFFER_OVERFLOW,  /* Not enough space for output */
-   CRYPT_INVALID_PACKET,   /* Invalid input packet given */
-
-   CRYPT_INVALID_PRNGSIZE, /* Invalid number of bits for a PRNG */
-   CRYPT_ERROR_READPRNG,   /* Could not read enough from PRNG */
-
-   CRYPT_INVALID_CIPHER,   /* Invalid cipher specified */
-   CRYPT_INVALID_HASH,     /* Invalid hash specified */
-   CRYPT_INVALID_PRNG,     /* Invalid PRNG specified */
-
-   CRYPT_MEM,              /* Out of memory */
-   CRYPT_PK_TYPE_MISMATCH, /* Not equivalent types of PK keys */
-   CRYPT_PK_NOT_PRIVATE,   /* Requires a private PK key */
-
-   CRYPT_INVALID_ARG,      /* Generic invalid argument */
-   CRYPT_FILE_NOTFOUND,    /* File Not Found */
-
-   CRYPT_PK_INVALID_TYPE,  /* Invalid type of PK key */
-   CRYPT_PK_INVALID_SYSTEM,/* Invalid PK system specified */
-   CRYPT_PK_DUP,           /* Duplicate key already in key ring */
-   CRYPT_PK_NOT_FOUND,     /* Key not found in keyring */
-   CRYPT_PK_INVALID_SIZE,  /* Invalid size input for PK parameters */
-
-   CRYPT_INVALID_PRIME_SIZE/* Invalid size of prime requested */
-};
-
-struct sha1_state {
-    unsigned long long length;
-    unsigned long state[5], curlen;
-    unsigned char buf[64];
-};
-typedef union Hash_state {
-    struct sha1_state   sha1;
-} hash_state;
-
-struct _hash_descriptor {
-    const char *name;
-    unsigned char ID;
-    unsigned long hashsize;       /* digest output size in bytes  */
-    unsigned long blocksize;      /* the block size the hash uses */
-    unsigned char DER[64];        /* DER encoded identifier */
-    unsigned long DERlen;         /* length of DER encoding */
-    void (*init)(hash_state *);
-    int (*process)(hash_state *, const unsigned char *, unsigned long);
-    int (*done)(hash_state *, unsigned char *);
-    int  (*test)(void);
-};
-
-extern const struct _hash_descriptor *hash_descriptor[];
-
-void sha1_init(hash_state * md);
-int sha1_process(hash_state * md, const unsigned char *buf, unsigned long len);
-int sha1_done(hash_state * md, unsigned char *hash);
-int sha1_test(void);
-
-int hash_memory(int hash, const unsigned char *data, unsigned long len, unsigned char *dst, unsigned long *outlen);
-
-#define MAXBLOCKSIZE 128
-typedef struct Hmac_state {
-     hash_state     md;
-     int            hash;
-     hash_state     hashstate;
-     unsigned char  key[MAXBLOCKSIZE];
-} hmac_state;
-
-int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen);
-int hmac_process(hmac_state *hmac, const unsigned char *buf, unsigned long len);
-int hmac_done(hmac_state *hmac, unsigned char *hashOut, unsigned long *outlen);
-int hmac_test(void);
-int hmac_memory(int hash, const unsigned char *key, unsigned long keylen,
-                       const unsigned char *data, unsigned long len,
-                       unsigned char *dst, unsigned long *dstlen);
-
-struct sober128_prng {
-    uint32_t      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 {
-    struct sober128_prng sober128;
-} prng_state;
-
-struct _prng_descriptor {
-    const 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 *);
-};
-
-extern const struct _prng_descriptor *prng_descriptor[];
-
-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);
-
-unsigned long rng_get_bytes(unsigned char *buf,
-                                   unsigned long len,
-                                   void (*callback)(void));
-
-int rng_make_prng(int bits, int wprng, prng_state *prng, void (*callback)(void));
-
-#endif /* CRYPTO_H_DEFINED */
index e53163f0a8b7922e00cc21c0d2a00c3eaa2f8b75..dcc9b66e23e916c82fd19599e15d38741dea2552 100644 (file)
 #include <corosync/logsys.h>
 #include <corosync/icmap.h>
 
-#ifdef HAVE_LIBNSS
 #include <nss.h>
 #include <pk11pub.h>
 #include <pkcs11.h>
 #include <prerror.h>
-#endif
 
 #include "util.h"
 #include "totemconfig.h"
@@ -127,26 +125,17 @@ static void totem_get_crypto_type(struct totem_config *totem_config)
 {
        char *str;
 
-       totem_config->crypto_type = TOTEM_CRYPTO_SOBER;
-
-#ifdef HAVE_LIBNSS
-       /*
-        * We must set these even if the key does not exist.
-        * Encryption type can be set on-the-fly using CFG
-        */
+        /*
+         * We must set these even if the key does not exist.
+         * Encryption type can be set on-the-fly using CFG
+         */
        totem_config->crypto_crypt_type = CKM_AES_CBC_PAD;
        totem_config->crypto_sign_type = CKM_SHA256_RSA_PKCS;
-#endif
 
        if (icmap_get_string("totem.crypto_type", &str) == CS_OK) {
-               if (strcmp(str, "sober") == 0) {
-                       totem_config->crypto_type = TOTEM_CRYPTO_SOBER;
-               }
-#ifdef HAVE_LIBNSS
-               if (strcmp(str, "nss") == 0) {
-                       totem_config->crypto_type = TOTEM_CRYPTO_NSS;
+               if (strcmp(str, "nss") == 0 || strcmp(str, "aes256") == 0) {
+                       totem_config->crypto_type = TOTEM_CRYPTO_AES256;
                }
-#endif
                free(str);
        }
 }
index c3195534e08682ace3d23f6d68d823ab5d59cf04..6a16db8e3d673a44acd282d4f3f0cd0b2cc8f1e3 100644 (file)
@@ -41,7 +41,7 @@
  *     http://citeseer.ist.psu.edu/amir95totem.html
  *
  * The deviations from the above published protocols are:
- * - encryption of message contents with SOBER128
+ * - encryption of message contents with nss
  * - authentication of meessage contents with SHA1/HMAC
  * - token hold mode where token doesn't rotate on unused ring - reduces cpu
  *   usage on 1.6ghz xeon from 35% to less then .1 % as measured by top
@@ -89,7 +89,6 @@
 #include "totemrrp.h"
 #include "totemnet.h"
 
-#include "crypto.h"
 #include "cs_queue.h"
 
 #define LOCALHOST_IP                           inet_addr("127.0.0.1")
@@ -282,7 +281,6 @@ struct sort_queue_item {
 
 struct orf_token_mcast_thread_state {
        char iobuf[9000];
-       prng_state prng_state;
 };
 
 enum memb_state {
index 0fe52aa1dafde327c8084c4e775d24ac735a974c..407df30ef10953ea5a0bb5060db61d946e7e0507 100644 (file)
 #include <corosync/logsys.h>
 #include "totemudp.h"
 
-#include "crypto.h"
 #include "util.h"
 
-#ifdef HAVE_LIBNSS
 #include <nss.h>
 #include <pk11pub.h>
 #include <pkcs11.h>
 #include <prerror.h>
-#endif
 
 #ifndef MSG_NOSIGNAL
 #define MSG_NOSIGNAL 0
@@ -98,11 +95,6 @@ struct security_header {
        char msg[0];
 } __attribute__((packed));
 
-struct totemudp_mcast_thread_state {
-       unsigned char iobuf[FRAME_SIZE_MAX];
-       prng_state prng_state;
-};
-
 struct totemudp_socket {
        int mcast_recv;
        int mcast_send;
@@ -110,14 +102,8 @@ struct totemudp_socket {
 };
 
 struct totemudp_instance {
-       hmac_state totemudp_hmac_state;
-
-       prng_state totemudp_prng_state;
-
-#ifdef HAVE_LIBNSS
        PK11SymKey   *nss_sym_key;
        PK11SymKey   *nss_sym_key_sign;
-#endif
 
        unsigned char totemudp_private_key[1024];
 
@@ -262,77 +248,6 @@ do {                                                                                               \
        } while(0)
 
 
-static int authenticate_and_decrypt_sober (
-       struct totemudp_instance *instance,
-       struct iovec *iov,
-       unsigned int iov_len)
-{
-       unsigned char keys[48];
-       struct security_header *header = (struct security_header *)iov[0].iov_base;
-       prng_state keygen_prng_state;
-       prng_state stream_prng_state;
-       unsigned char *hmac_key = &keys[32];
-       unsigned char *cipher_key = &keys[16];
-       unsigned char *initial_vector = &keys[0];
-       unsigned char digest_comparison[HMAC_HASH_SIZE];
-       unsigned long len;
-
-       /*
-        * Generate MAC, CIPHER, IV keys from private key
-        */
-       memset (keys, 0, sizeof (keys));
-       sober128_start (&keygen_prng_state);
-       sober128_add_entropy (instance->totemudp_private_key,
-               instance->totemudp_private_key_len, &keygen_prng_state);
-       sober128_add_entropy (header->salt, sizeof (header->salt), &keygen_prng_state);
-
-       sober128_read (keys, sizeof (keys), &keygen_prng_state);
-
-       /*
-        * Setup stream cipher
-        */
-       sober128_start (&stream_prng_state);
-       sober128_add_entropy (cipher_key, 16, &stream_prng_state);
-       sober128_add_entropy (initial_vector, 16, &stream_prng_state);
-
-       /*
-        * Authenticate contents of message
-        */
-       hmac_init (&instance->totemudp_hmac_state, DIGEST_SHA1, hmac_key, 16);
-
-       hmac_process (&instance->totemudp_hmac_state,
-               (unsigned char *)iov->iov_base + HMAC_HASH_SIZE,
-               iov->iov_len - HMAC_HASH_SIZE);
-
-       len = hash_descriptor[DIGEST_SHA1]->hashsize;
-       assert (HMAC_HASH_SIZE >= len);
-       hmac_done (&instance->totemudp_hmac_state, digest_comparison, &len);
-
-       if (memcmp (digest_comparison, header->hash_digest, len) != 0) {
-               return (-1);
-       }
-
-       /*
-        * Decrypt the contents of the message with the cipher key
-        */
-       sober128_read ((unsigned char*)iov->iov_base +
-                       sizeof (struct security_header),
-               iov->iov_len - sizeof (struct security_header),
-               &stream_prng_state);
-
-       return (0);
-}
-
-static void init_sober_crypto(
-       struct totemudp_instance *instance)
-{
-       log_printf(instance->totemudp_log_level_notice,
-               "Initializing transmit/receive security: libtomcrypt SOBER128/SHA1HMAC (mode 0).");
-       rng_make_prng (128, PRNG_SOBER, &instance->totemudp_prng_state, NULL);
-}
-
-#ifdef HAVE_LIBNSS
-
 static unsigned char *copy_from_iovec(
        const struct iovec *iov,
        unsigned int iov_len,
@@ -393,7 +308,7 @@ static void init_nss_crypto(
        SECStatus          rv;
 
        log_printf(instance->totemudp_log_level_notice,
-               "Initializing transmit/receive security: NSS AES128CBC/SHA1HMAC (mode 1).");
+               "Initializing transmit/receive security: NSS AES256CBC/SHA1HMAC (mode %u).", TOTEM_CRYPTO_AES256);
        rv = NSS_NoDB_Init(".");
        if (rv != SECSuccess)
        {
@@ -422,7 +337,7 @@ static void init_nss_crypto(
         */
        key_item.type = siBuffer;
        key_item.data = instance->totem_config->private_key;
-       key_item.len = 32; /* Use 128 bits */
+       key_item.len = 32; /* Use 256 bits */
 
        instance->nss_sym_key = PK11_ImportSymKey(aes_slot,
                instance->totem_config->crypto_crypt_type,
@@ -696,91 +611,6 @@ static int authenticate_and_decrypt_nss (
 
        return 0;
 }
-#endif
-
-static int encrypt_and_sign_sober (
-       struct totemudp_instance *instance,
-       unsigned char *buf,
-       size_t *buf_len,
-       const struct iovec *iovec,
-       unsigned int iov_len)
-{
-       int i;
-       unsigned char *addr;
-       unsigned char keys[48];
-       struct security_header *header;
-       unsigned char *hmac_key = &keys[32];
-       unsigned char *cipher_key = &keys[16];
-       unsigned char *initial_vector = &keys[0];
-       unsigned long len;
-       size_t outlen = 0;
-       hmac_state hmac_st;
-       prng_state keygen_prng_state;
-       prng_state stream_prng_state;
-       prng_state *prng_state_in = &instance->totemudp_prng_state;
-
-       header = (struct security_header *)buf;
-       addr = buf + sizeof (struct security_header);
-
-       memset (keys, 0, sizeof (keys));
-       memset (header->salt, 0, sizeof (header->salt));
-
-       /*
-        * Generate MAC, CIPHER, IV keys from private key
-        */
-       sober128_read (header->salt, sizeof (header->salt), prng_state_in);
-       sober128_start (&keygen_prng_state);
-       sober128_add_entropy (instance->totemudp_private_key,
-               instance->totemudp_private_key_len,
-               &keygen_prng_state);
-       sober128_add_entropy (header->salt, sizeof (header->salt),
-               &keygen_prng_state);
-
-       sober128_read (keys, sizeof (keys), &keygen_prng_state);
-
-       /*
-        * Setup stream cipher
-        */
-       sober128_start (&stream_prng_state);
-       sober128_add_entropy (cipher_key, 16, &stream_prng_state);
-       sober128_add_entropy (initial_vector, 16, &stream_prng_state);
-
-       outlen = sizeof (struct security_header);
-       /*
-        * Copy remainder of message, then encrypt it
-        */
-       for (i = 1; i < iov_len; i++) {
-               memcpy (addr, iovec[i].iov_base, iovec[i].iov_len);
-               addr += iovec[i].iov_len;
-               outlen += iovec[i].iov_len;
-       }
-
-       /*
-        * Encrypt message by XORing stream cipher data
-        */
-       sober128_read (buf + sizeof (struct security_header),
-               outlen - sizeof (struct security_header),
-               &stream_prng_state);
-
-       memset (&hmac_st, 0, sizeof (hmac_st));
-
-       /*
-        * Sign the contents of the message with the hmac key and store signature in message
-        */
-       hmac_init (&hmac_st, DIGEST_SHA1, hmac_key, 16);
-
-       hmac_process (&hmac_st,
-               buf + HMAC_HASH_SIZE,
-               outlen - HMAC_HASH_SIZE);
-
-       len = hash_descriptor[DIGEST_SHA1]->hashsize;
-
-       hmac_done (&hmac_st, header->hash_digest, &len);
-
-       *buf_len = outlen;
-
-       return 0;
-}
 
 static int encrypt_and_sign_worker (
        struct totemudp_instance *instance,
@@ -789,14 +619,11 @@ static int encrypt_and_sign_worker (
        const struct iovec *iovec,
        unsigned int iov_len)
 {
-       if (instance->totem_config->crypto_type == TOTEM_CRYPTO_SOBER) {
-               return encrypt_and_sign_sober(instance, buf, buf_len, iovec, iov_len);
-       }
-#ifdef HAVE_LIBNSS
-       if (instance->totem_config->crypto_type == TOTEM_CRYPTO_NSS) {
+
+       if (instance->totem_config->crypto_type == TOTEM_CRYPTO_AES256) {
                return encrypt_and_sign_nss(instance, buf, buf_len, iovec, iov_len);
        }
-#endif
+
        return -1;
 }
 
@@ -815,23 +642,9 @@ static int authenticate_and_decrypt (
        type = endbuf[iov[iov_len-1].iov_len-1];
        iov[iov_len-1].iov_len -= 1;
 
-       if (type == TOTEM_CRYPTO_SOBER) {
-               res = authenticate_and_decrypt_sober(instance, iov, iov_len);
-       }
-
-#ifdef HAVE_LIBNSS
-       if (type == TOTEM_CRYPTO_NSS) {
+       if (type == TOTEM_CRYPTO_AES256) {
                    res = authenticate_and_decrypt_nss(instance, iov, iov_len);
        }
-#endif
-
-       /*
-        * If it failed, then try decrypting the whole packet
-        */
-       if (res == -1) {
-               iov[iov_len-1].iov_len += 1;
-               res = authenticate_and_decrypt_sober(instance, iov, iov_len);
-       }
 
        return res;
 }
@@ -839,10 +652,8 @@ static int authenticate_and_decrypt (
 static void init_crypto(
        struct totemudp_instance *instance)
 {
-       init_sober_crypto(instance);
-#ifdef HAVE_LIBNSS
+
        init_nss_crypto(instance);
-#endif
 }
 
 int totemudp_crypto_set (
@@ -856,13 +667,9 @@ int totemudp_crypto_set (
         * Validate crypto algorithm
         */
        switch (type) {
-               case TOTEM_CRYPTO_SOBER:
+               case TOTEM_CRYPTO_AES256:
                        log_printf(instance->totemudp_log_level_security,
-                               "Transmit security set to: libtomcrypt SOBER128/SHA1HMAC (mode 0)");
-                       break;
-               case TOTEM_CRYPTO_NSS:
-                       log_printf(instance->totemudp_log_level_security,
-                               "Transmit security set to: NSS AES128CBC/SHA1HMAC (mode 1)");
+                               "Transmit security set to: NSS AES256CBC/SHA1HMAC (mode %u)", type);
                        break;
                default:
                        res = -1;
@@ -896,7 +703,6 @@ static inline void ucast_sendmsg (
                iovec_encrypt[0].iov_len = sizeof (struct security_header);
                iovec_encrypt[1].iov_base = (void *)msg;
                iovec_encrypt[1].iov_len = msg_len;
-
                /*
                 * Encrypt and digest the message
                 */
index 250921e45a00ed4e4d07103684410ab0283b0d64..36a50238e3171f84fff6faf5b8ec334e0e1b54df 100644 (file)
 #include <corosync/logsys.h>
 #include "totemudpu.h"
 
-#include "crypto.h"
 #include "util.h"
 
-#ifdef HAVE_LIBNSS
 #include <nss.h>
 #include <pk11pub.h>
 #include <pkcs11.h>
 #include <prerror.h>
-#endif
 
 #ifndef MSG_NOSIGNAL
 #define MSG_NOSIGNAL 0
@@ -103,14 +100,8 @@ struct totemudpu_member {
 };
 
 struct totemudpu_instance {
-       hmac_state totemudpu_hmac_state;
-
-       prng_state totemudpu_prng_state;
-
-#ifdef HAVE_LIBNSS
        PK11SymKey   *nss_sym_key;
        PK11SymKey   *nss_sym_key_sign;
-#endif
 
        unsigned char totemudpu_private_key[1024];
 
@@ -244,77 +235,6 @@ do {                                                                                               \
                fmt ": %s (%d)", ##args, _error_ptr, err_num);                          \
        } while(0)
 
-static int authenticate_and_decrypt_sober (
-       struct totemudpu_instance *instance,
-       struct iovec *iov,
-       unsigned int iov_len)
-{
-       unsigned char keys[48];
-       struct security_header *header = (struct security_header *)iov[0].iov_base;
-       prng_state keygen_prng_state;
-       prng_state stream_prng_state;
-       unsigned char *hmac_key = &keys[32];
-       unsigned char *cipher_key = &keys[16];
-       unsigned char *initial_vector = &keys[0];
-       unsigned char digest_comparison[HMAC_HASH_SIZE];
-       unsigned long len;
-
-       /*
-        * Generate MAC, CIPHER, IV keys from private key
-        */
-       memset (keys, 0, sizeof (keys));
-       sober128_start (&keygen_prng_state);
-       sober128_add_entropy (instance->totemudpu_private_key,
-               instance->totemudpu_private_key_len, &keygen_prng_state);
-       sober128_add_entropy (header->salt, sizeof (header->salt), &keygen_prng_state);
-
-       sober128_read (keys, sizeof (keys), &keygen_prng_state);
-
-       /*
-        * Setup stream cipher
-        */
-       sober128_start (&stream_prng_state);
-       sober128_add_entropy (cipher_key, 16, &stream_prng_state);
-       sober128_add_entropy (initial_vector, 16, &stream_prng_state);
-
-       /*
-        * Authenticate contents of message
-        */
-       hmac_init (&instance->totemudpu_hmac_state, DIGEST_SHA1, hmac_key, 16);
-
-       hmac_process (&instance->totemudpu_hmac_state,
-               (unsigned char *)iov->iov_base + HMAC_HASH_SIZE,
-               iov->iov_len - HMAC_HASH_SIZE);
-
-       len = hash_descriptor[DIGEST_SHA1]->hashsize;
-       assert (HMAC_HASH_SIZE >= len);
-       hmac_done (&instance->totemudpu_hmac_state, digest_comparison, &len);
-
-       if (memcmp (digest_comparison, header->hash_digest, len) != 0) {
-               return (-1);
-       }
-
-       /*
-        * Decrypt the contents of the message with the cipher key
-        */
-       sober128_read ((unsigned char*)iov->iov_base +
-                       sizeof (struct security_header),
-               iov->iov_len - sizeof (struct security_header),
-               &stream_prng_state);
-
-       return (0);
-}
-
-static void init_sober_crypto(
-       struct totemudpu_instance *instance)
-{
-       log_printf(instance->totemudpu_log_level_notice,
-               "Initializing transmit/receive security: libtomcrypt SOBER128/SHA1HMAC (mode 0).");
-       rng_make_prng (128, PRNG_SOBER, &instance->totemudpu_prng_state, NULL);
-}
-
-#ifdef HAVE_LIBNSS
-
 static unsigned char *copy_from_iovec(
        const struct iovec *iov,
        unsigned int iov_len,
@@ -375,7 +295,7 @@ static void init_nss_crypto(
        SECStatus          rv;
 
        log_printf(instance->totemudpu_log_level_notice,
-               "Initializing transmit/receive security: NSS AES128CBC/SHA1HMAC (mode 1).");
+               "Initializing transmit/receive security: NSS AES256CBC/SHA1HMAC (mode %u).", TOTEM_CRYPTO_AES256);
        rv = NSS_NoDB_Init(".");
        if (rv != SECSuccess)
        {
@@ -404,7 +324,7 @@ static void init_nss_crypto(
         */
        key_item.type = siBuffer;
        key_item.data = instance->totem_config->private_key;
-       key_item.len = 32; /* Use 128 bits */
+       key_item.len = 32; /* Use 256 bits */
 
        instance->nss_sym_key = PK11_ImportSymKey(aes_slot,
                instance->totem_config->crypto_crypt_type,
@@ -678,91 +598,6 @@ static int authenticate_and_decrypt_nss (
 
        return 0;
 }
-#endif
-
-static int encrypt_and_sign_sober (
-       struct totemudpu_instance *instance,
-       unsigned char *buf,
-       size_t *buf_len,
-       const struct iovec *iovec,
-       unsigned int iov_len)
-{
-       int i;
-       unsigned char *addr;
-       unsigned char keys[48];
-       struct security_header *header;
-       unsigned char *hmac_key = &keys[32];
-       unsigned char *cipher_key = &keys[16];
-       unsigned char *initial_vector = &keys[0];
-       unsigned long len;
-       size_t outlen = 0;
-       hmac_state hmac_st;
-       prng_state keygen_prng_state;
-       prng_state stream_prng_state;
-       prng_state *prng_state_in = &instance->totemudpu_prng_state;
-
-       header = (struct security_header *)buf;
-       addr = buf + sizeof (struct security_header);
-
-       memset (keys, 0, sizeof (keys));
-       memset (header->salt, 0, sizeof (header->salt));
-
-       /*
-        * Generate MAC, CIPHER, IV keys from private key
-        */
-       sober128_read (header->salt, sizeof (header->salt), prng_state_in);
-       sober128_start (&keygen_prng_state);
-       sober128_add_entropy (instance->totemudpu_private_key,
-               instance->totemudpu_private_key_len,
-               &keygen_prng_state);
-       sober128_add_entropy (header->salt, sizeof (header->salt),
-               &keygen_prng_state);
-
-       sober128_read (keys, sizeof (keys), &keygen_prng_state);
-
-       /*
-        * Setup stream cipher
-        */
-       sober128_start (&stream_prng_state);
-       sober128_add_entropy (cipher_key, 16, &stream_prng_state);
-       sober128_add_entropy (initial_vector, 16, &stream_prng_state);
-
-       outlen = sizeof (struct security_header);
-       /*
-        * Copy remainder of message, then encrypt it
-        */
-       for (i = 1; i < iov_len; i++) {
-               memcpy (addr, iovec[i].iov_base, iovec[i].iov_len);
-               addr += iovec[i].iov_len;
-               outlen += iovec[i].iov_len;
-       }
-
-       /*
-        * Encrypt message by XORing stream cipher data
-        */
-       sober128_read (buf + sizeof (struct security_header),
-               outlen - sizeof (struct security_header),
-               &stream_prng_state);
-
-       memset (&hmac_st, 0, sizeof (hmac_st));
-
-       /*
-        * Sign the contents of the message with the hmac key and store signature in message
-        */
-       hmac_init (&hmac_st, DIGEST_SHA1, hmac_key, 16);
-
-       hmac_process (&hmac_st,
-               buf + HMAC_HASH_SIZE,
-               outlen - HMAC_HASH_SIZE);
-
-       len = hash_descriptor[DIGEST_SHA1]->hashsize;
-
-       hmac_done (&hmac_st, header->hash_digest, &len);
-
-       *buf_len = outlen;
-
-       return 0;
-}
 
 static int encrypt_and_sign_worker (
        struct totemudpu_instance *instance,
@@ -771,14 +606,11 @@ static int encrypt_and_sign_worker (
        const struct iovec *iovec,
        unsigned int iov_len)
 {
-       if (instance->totem_config->crypto_type == TOTEM_CRYPTO_SOBER) {
-               return encrypt_and_sign_sober(instance, buf, buf_len, iovec, iov_len);
-       }
-#ifdef HAVE_LIBNSS
-       if (instance->totem_config->crypto_type == TOTEM_CRYPTO_NSS) {
+
+       if (instance->totem_config->crypto_type == TOTEM_CRYPTO_AES256) {
                return encrypt_and_sign_nss(instance, buf, buf_len, iovec, iov_len);
        }
-#endif
+
        return -1;
 }
 
@@ -797,23 +629,9 @@ static int authenticate_and_decrypt (
        type = endbuf[iov[iov_len-1].iov_len-1];
        iov[iov_len-1].iov_len -= 1;
 
-       if (type == TOTEM_CRYPTO_SOBER) {
-               res = authenticate_and_decrypt_sober(instance, iov, iov_len);
-       }
-
-#ifdef HAVE_LIBNSS
-       if (type == TOTEM_CRYPTO_NSS) {
+       if (type == TOTEM_CRYPTO_AES256) {
                    res = authenticate_and_decrypt_nss(instance, iov, iov_len);
        }
-#endif
-
-       /*
-        * If it failed, then try decrypting the whole packet
-        */
-       if (res == -1) {
-               iov[iov_len-1].iov_len += 1;
-               res = authenticate_and_decrypt_sober(instance, iov, iov_len);
-       }
 
        return res;
 }
@@ -821,10 +639,8 @@ static int authenticate_and_decrypt (
 static void init_crypto(
        struct totemudpu_instance *instance)
 {
-       init_sober_crypto(instance);
-#ifdef HAVE_LIBNSS
+
        init_nss_crypto(instance);
-#endif
 }
 
 int totemudpu_crypto_set (
@@ -838,13 +654,9 @@ int totemudpu_crypto_set (
         * Validate crypto algorithm
         */
        switch (type) {
-               case TOTEM_CRYPTO_SOBER:
-                       log_printf(instance->totemudpu_log_level_security,
-                               "Transmit security set to: libtomcrypt SOBER128/SHA1HMAC (mode 0)");
-                       break;
-               case TOTEM_CRYPTO_NSS:
+               case TOTEM_CRYPTO_AES256:
                        log_printf(instance->totemudpu_log_level_security,
-                               "Transmit security set to: NSS AES128CBC/SHA1HMAC (mode 1)");
+                               "Transmit security set to: NSS AES256CBC/SHA1HMAC (mode %u)", type);
                        break;
                default:
                        res = -1;
index a9cb1f3deeaa4e4527c742c5f2c7ee3da0bf0bec..31285378a439c9b4b45bdf8e4cead14f4f19eb8a 100644 (file)
@@ -169,7 +169,7 @@ struct totem_config {
 
        unsigned int broadcast_use;
 
-       enum { TOTEM_CRYPTO_SOBER=0, TOTEM_CRYPTO_NSS } crypto_type;
+       enum { TOTEM_CRYPTO_AES256 = 0} crypto_type;
 
        int crypto_crypt_type;
        int crypto_sign_type;
index 7cd1824ffe393bd3e157fa25b0cb0d4a1e058e19..e7722da1c757f6ed7316c2de1925a659163cb6e7 100644 (file)
@@ -163,23 +163,11 @@ a subset of the cluster (for example during a rolling upgrade).
 secauth
 This specifies that HMAC/SHA1 authentication should be used to authenticate
 all messages.  It further specifies that all data should be encrypted with the
-sober128 encryption algorithm to protect data from eavesdropping.
-
-Enabling this option adds a 36 byte header to every message sent by totem which
-reduces total throughput.  Encryption and authentication consume 75% of CPU
-cycles in aisexec as measured with gprof when enabled.
-
-For 100mbit networks with 1500 MTU frame transmissions:
-A throughput of 9mb/sec is possible with 100% cpu utilization when this
-option is enabled on 3ghz cpus.
-A throughput of 10mb/sec is possible wth 20% cpu utilization when this
-optin is disabled on 3ghz cpus.
-
-For gig-e networks with large frame transmissions:
-A throughput of 20mb/sec is possible when this option is enabled on
-3ghz cpus.
-A throughput of 60mb/sec is possible when this option is disabled on
-3ghz cpus.
+nss library and aes256 encryption algorithm to protect data from eavesdropping.
+
+Enabling this option adds a encryption header to every message sent by totem which
+reduces total throughput. Also encryption and authentication consume extra CPU
+cycles in corosync.
 
 The default is on.
 
index 999ced9bb8d8b0017d2445f95f9309c9eef5fb78..459ccfc9cadd199c23ce33f4d10b4ba5ccd30a32 100644 (file)
@@ -166,8 +166,8 @@ The default is /etc/corosync/authkey.
 
 .SH SECURITY
 The corosync executive optionally encrypts all messages sent over the network
-using the SOBER-128 stream cipher.  The corosync executive uses HMAC and SHA1 to
-authenticate all messages.  The corosync executive library uses SOBER-128
+using the AES-128 cipher.  The corosync executive uses HMAC and SHA1 to
+authenticate all messages.  The corosync executive library uses NSS
 as a pseudo random number generator.
 
 If membership messages can be captured by intruders, it is possible to execute
index a7895f32377335988bf565e1500ab3c6a801bdb2..7010c50a0e37ba028972736cb724ed132439a97c 100644 (file)
@@ -64,7 +64,8 @@ testvotequorum1_LDADD = -lvotequorum $(LIBQB_LIBS)
 testvotequorum1_LDFLAGS        = $(COMMON_OPTS)
 testvotequorum2_LDADD  = -lvotequorum $(LIBQB_LIBS)
 testvotequorum2_LDFLAGS        = $(COMMON_OPTS)
-cpgverify_LDADD                = -lcpg -ltotem_pg $(LIBQB_LIBS)
+cpgverify_CFLAGS       = $(nss_CFLAGS)
+cpgverify_LDADD                = -lcpg -ltotem_pg $(LIBQB_LIBS) $(nss_LIBS)
 cpgverify_LDFLAGS      = $(COMMON_OPTS) -L../exec
 cpgbound_LDADD         = -lcpg $(LIBQB_LIBS)
 cpgbound_LDFLAGS       = $(COMMON_OPTS)
index 56a9b8b8c6cf78feae8e4e00d12ec48905a483fc..350c6b2d65fdb260eb063e83fb7d4dea18380abf 100644 (file)
@@ -44,7 +44,9 @@
 #include <string.h>
 #include <corosync/corotypes.h>
 #include <corosync/cpg.h>
-#include "../exec/crypto.h"
+
+#include <nss.h>
+#include <pk11pub.h>
 
 struct my_msg {
        unsigned int msg_size;
@@ -53,6 +55,8 @@ struct my_msg {
 };
 
 static int deliveries = 0;
+PK11Context* sha1_context;
+
 static void cpg_deliver_fn (
         cpg_handle_t handle,
         const struct cpg_name *group_name,
@@ -63,13 +67,13 @@ static void cpg_deliver_fn (
 {
        const struct my_msg *msg2 = m;
        unsigned char sha1_compare[20];
-       hash_state sha1_hash;
        unsigned int i;
+       unsigned int sha1_len;
 
        printf ("msg '%s'\n", msg2->buffer);
-       sha1_init (&sha1_hash);
-       sha1_process (&sha1_hash, msg2->buffer, msg2->msg_size);
-       sha1_done (&sha1_hash, sha1_compare);
+       PK11_DigestBegin(sha1_context);
+       PK11_DigestOp(sha1_context, msg2->buffer, msg2->msg_size);
+       PK11_DigestFinal(sha1_context, sha1_compare, &sha1_len, sizeof(sha1_compare));
 printf ("SIZE %d HASH: ", msg2->msg_size);
 for (i = 0; i < 20; i++) {
 printf ("%x", sha1_compare[i]);
@@ -110,12 +114,12 @@ int main (int argc, char *argv[])
        int i = 0;
        int j;
        struct my_msg msg;
-       hash_state sha1_hash;
        struct iovec iov[2];
        const char *options = "i:";
        int iter = 1000;
        int opt;
        int run_forever = 1;
+       unsigned int sha1_len;
 
        while ((opt = getopt(argc, argv, options)) != -1) {
                switch (opt) {
@@ -132,6 +136,16 @@ int main (int argc, char *argv[])
                exit (0);
        }
 
+       if (NSS_NoDB_Init(".") != SECSuccess) {
+               printf ("Couldn't initialize nss\n");
+               exit (0);
+       }
+
+       if ((sha1_context = PK11_CreateDigestContext(SEC_OID_SHA1)) == NULL) {
+               printf ("Couldn't initialize nss\n");
+               exit (0);
+       }
+
         result = cpg_join (handle, &group_name);
         if (result != CS_OK) {
                 printf ("cpg_join failed with result %d\n", result);
@@ -154,9 +168,10 @@ int main (int argc, char *argv[])
                }
                sprintf ((char *)buffer,
                        "cpg_mcast_joined: This is message %12d", i);
-               sha1_init (&sha1_hash);
-               sha1_process (&sha1_hash, buffer, msg.msg_size);
-               sha1_done (&sha1_hash, msg.sha1);
+
+               PK11_DigestBegin(sha1_context);
+               PK11_DigestOp(sha1_context, buffer, msg.msg_size);
+               PK11_DigestFinal(sha1_context, msg.sha1, &sha1_len, sizeof(msg.sha1));
 try_again_one:
                result = cpg_mcast_joined (handle, CPG_TYPE_AGREED,
                        iov, 2);
@@ -167,6 +182,8 @@ try_again_one:
                i++;
        } while (run_forever || i < iter);
 
+       PK11_DestroyContext(sha1_context, PR_TRUE);
+
        cpg_finalize (handle);
 
        return (0);
index 0e03f40dfb75cd86b98e753449ddf0e53feca555..ba14f63d6e862eae93d0e47e2a7aa1d7e98b1505 100644 (file)
@@ -44,7 +44,6 @@
 #include <corosync/corotypes.h>
 #include <corosync/cpg.h>
 #include <signal.h>
-#include "../exec/crypto.h"
 
 struct my_msg {
        unsigned int msg_size;
index e7b3fe6357a89d1a01454c2bbd7f98f60b67bb57..af1357e273cc9c201fd4af8c65f8c1541aa3fef8 100644 (file)
@@ -44,7 +44,6 @@
 #include <corosync/corotypes.h>
 #include <corosync/cpg.h>
 #include <signal.h>
-#include "../exec/crypto.h"
 
 struct my_msg {
        unsigned int msg_size;