Import of code from heimdal
authorHeimdal Developers <heimdal-discuss@sics.se>
Sun, 9 May 2010 18:33:54 +0000 (19:33 +0100)
committerDerrick Brashear <shadow@dementia.org>
Tue, 17 Aug 2010 12:19:46 +0000 (05:19 -0700)
This commit updates the code imported from the external
heimdal git repository to their revision
40ef7759b917648938416e15521d383e2eade5cf
which is described as switch-from-svn-to-git-1333-g40ef775

Change-Id: Ie03ff2d99293272f9ce4c900367eefa063ce8d98
Reviewed-on: http://gerrit.openafs.org/2574
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>

53 files changed:
src/external/heimdal/hcrypto/aes.c [new file with mode: 0644]
src/external/heimdal/hcrypto/aes.h [new file with mode: 0644]
src/external/heimdal/hcrypto/camellia-ntt.c [new file with mode: 0644]
src/external/heimdal/hcrypto/camellia-ntt.h [new file with mode: 0644]
src/external/heimdal/hcrypto/camellia.c [new file with mode: 0644]
src/external/heimdal/hcrypto/camellia.h [new file with mode: 0644]
src/external/heimdal/hcrypto/des-tables.h [new file with mode: 0644]
src/external/heimdal/hcrypto/des.c [new file with mode: 0644]
src/external/heimdal/hcrypto/des.h [new file with mode: 0644]
src/external/heimdal/hcrypto/evp-cc.c [new file with mode: 0644]
src/external/heimdal/hcrypto/evp-cc.h [new file with mode: 0644]
src/external/heimdal/hcrypto/evp-hcrypto.c [new file with mode: 0644]
src/external/heimdal/hcrypto/evp-hcrypto.h [new file with mode: 0644]
src/external/heimdal/hcrypto/evp.c [new file with mode: 0644]
src/external/heimdal/hcrypto/evp.h [new file with mode: 0644]
src/external/heimdal/hcrypto/hash.h [new file with mode: 0644]
src/external/heimdal/hcrypto/hmac.c [new file with mode: 0644]
src/external/heimdal/hcrypto/hmac.h [new file with mode: 0644]
src/external/heimdal/hcrypto/md2.c [new file with mode: 0644]
src/external/heimdal/hcrypto/md2.h [new file with mode: 0644]
src/external/heimdal/hcrypto/md4.c [new file with mode: 0644]
src/external/heimdal/hcrypto/md4.h [new file with mode: 0644]
src/external/heimdal/hcrypto/md5.c [new file with mode: 0644]
src/external/heimdal/hcrypto/md5.h [new file with mode: 0644]
src/external/heimdal/hcrypto/pkcs5.c [new file with mode: 0644]
src/external/heimdal/hcrypto/rand-egd.c [new file with mode: 0644]
src/external/heimdal/hcrypto/rand-fortuna.c [new file with mode: 0644]
src/external/heimdal/hcrypto/rand-timer.c [new file with mode: 0644]
src/external/heimdal/hcrypto/rand-unix.c [new file with mode: 0644]
src/external/heimdal/hcrypto/rand.c [new file with mode: 0644]
src/external/heimdal/hcrypto/rand.h [new file with mode: 0644]
src/external/heimdal/hcrypto/randi.h [new file with mode: 0644]
src/external/heimdal/hcrypto/rc2.c [new file with mode: 0644]
src/external/heimdal/hcrypto/rc2.h [new file with mode: 0644]
src/external/heimdal/hcrypto/rc4.c [new file with mode: 0644]
src/external/heimdal/hcrypto/rc4.h [new file with mode: 0644]
src/external/heimdal/hcrypto/rijndael-alg-fst.c [new file with mode: 0644]
src/external/heimdal/hcrypto/rijndael-alg-fst.h [new file with mode: 0644]
src/external/heimdal/hcrypto/rnd_keys.c [new file with mode: 0644]
src/external/heimdal/hcrypto/sha.c [new file with mode: 0644]
src/external/heimdal/hcrypto/sha.h [new file with mode: 0644]
src/external/heimdal/hcrypto/sha256.c [new file with mode: 0644]
src/external/heimdal/hcrypto/test_cipher.c [new file with mode: 0644]
src/external/heimdal/hcrypto/ui.c [new file with mode: 0644]
src/external/heimdal/hcrypto/ui.h [new file with mode: 0644]
src/external/heimdal/krb5/config_file.c
src/external/heimdal/roken/cloexec.c [new file with mode: 0644]
src/external/heimdal/roken/ct.c [new file with mode: 0644]
src/external/heimdal/roken/hex.c [new file with mode: 0644]
src/external/heimdal/roken/issuid.c [new file with mode: 0644]
src/external/heimdal/roken/net_read.c [new file with mode: 0644]
src/external/heimdal/roken/net_write.c [new file with mode: 0644]
src/external/heimdal/roken/strlcpy.c [new file with mode: 0644]

diff --git a/src/external/heimdal/hcrypto/aes.c b/src/external/heimdal/hcrypto/aes.c
new file mode 100644 (file)
index 0000000..77847e4
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+#include "config.h"
+
+
+#ifdef KRB5
+#include <krb5-types.h>
+#endif
+
+#include <string.h>
+
+#include "rijndael-alg-fst.h"
+#include "aes.h"
+
+int
+AES_set_encrypt_key(const unsigned char *userkey, const int bits, AES_KEY *key)
+{
+    key->rounds = rijndaelKeySetupEnc(key->key, userkey, bits);
+    if (key->rounds == 0)
+       return -1;
+    return 0;
+}
+
+int
+AES_set_decrypt_key(const unsigned char *userkey, const int bits, AES_KEY *key)
+{
+    key->rounds = rijndaelKeySetupDec(key->key, userkey, bits);
+    if (key->rounds == 0)
+       return -1;
+    return 0;
+}
+
+void
+AES_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key)
+{
+    rijndaelEncrypt(key->key, key->rounds, in, out);
+}
+
+void
+AES_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key)
+{
+    rijndaelDecrypt(key->key, key->rounds, in, out);
+}
+
+void
+AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+               unsigned long size, const AES_KEY *key,
+               unsigned char *iv, int forward_encrypt)
+{
+    unsigned char tmp[AES_BLOCK_SIZE];
+    int i;
+
+    if (forward_encrypt) {
+       while (size >= AES_BLOCK_SIZE) {
+           for (i = 0; i < AES_BLOCK_SIZE; i++)
+               tmp[i] = in[i] ^ iv[i];
+           AES_encrypt(tmp, out, key);
+           memcpy(iv, out, AES_BLOCK_SIZE);
+           size -= AES_BLOCK_SIZE;
+           in += AES_BLOCK_SIZE;
+           out += AES_BLOCK_SIZE;
+       }
+       if (size) {
+           for (i = 0; i < size; i++)
+               tmp[i] = in[i] ^ iv[i];
+           for (i = size; i < AES_BLOCK_SIZE; i++)
+               tmp[i] = iv[i];
+           AES_encrypt(tmp, out, key);
+           memcpy(iv, out, AES_BLOCK_SIZE);
+       }
+    } else {
+       while (size >= AES_BLOCK_SIZE) {
+           memcpy(tmp, in, AES_BLOCK_SIZE);
+           AES_decrypt(tmp, out, key);
+           for (i = 0; i < AES_BLOCK_SIZE; i++)
+               out[i] ^= iv[i];
+           memcpy(iv, tmp, AES_BLOCK_SIZE);
+           size -= AES_BLOCK_SIZE;
+           in += AES_BLOCK_SIZE;
+           out += AES_BLOCK_SIZE;
+       }
+       if (size) {
+           memcpy(tmp, in, AES_BLOCK_SIZE);
+           AES_decrypt(tmp, out, key);
+           for (i = 0; i < size; i++)
+               out[i] ^= iv[i];
+           memcpy(iv, tmp, AES_BLOCK_SIZE);
+       }
+    }
+}
+
+void
+AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
+                 unsigned long size, const AES_KEY *key,
+                 unsigned char *iv, int forward_encrypt)
+{
+    int i;
+
+    for (i = 0; i < size; i++) {
+        unsigned char tmp[AES_BLOCK_SIZE + 1];
+
+        memcpy(tmp, iv, AES_BLOCK_SIZE);
+        AES_encrypt(iv, iv, key);
+        if (!forward_encrypt) {
+            tmp[AES_BLOCK_SIZE] = in[i];
+        }
+        out[i] = in[i] ^ iv[0];
+        if (forward_encrypt) {
+            tmp[AES_BLOCK_SIZE] = out[i];
+        }
+        memcpy(iv, &tmp[1], AES_BLOCK_SIZE);
+    }
+}
diff --git a/src/external/heimdal/hcrypto/aes.h b/src/external/heimdal/hcrypto/aes.h
new file mode 100644 (file)
index 0000000..1afa922
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2003-2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+/* $Id$ */
+
+#ifndef HEIM_AES_H
+#define HEIM_AES_H 1
+
+/* symbol renaming */
+#define AES_set_encrypt_key hc_AES_set_encrypt_key
+#define AES_set_decrypt_key hc_AES_decrypt_key
+#define AES_encrypt hc_AES_encrypt
+#define AES_decrypt hc_AES_decrypt
+#define AES_cbc_encrypt hc_AES_cbc_encrypt
+#define AES_cfb8_encrypt hc_AES_cfb8_encrypt
+
+/*
+ *
+ */
+
+#define AES_BLOCK_SIZE 16
+#define AES_MAXNR 14
+
+#define AES_ENCRYPT 1
+#define AES_DECRYPT 0
+
+typedef struct aes_key {
+    uint32_t key[(AES_MAXNR+1)*4];
+    int rounds;
+} AES_KEY;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int AES_set_encrypt_key(const unsigned char *, const int, AES_KEY *);
+int AES_set_decrypt_key(const unsigned char *, const int, AES_KEY *);
+
+void AES_encrypt(const unsigned char *, unsigned char *, const AES_KEY *);
+void AES_decrypt(const unsigned char *, unsigned char *, const AES_KEY *);
+
+void AES_cbc_encrypt(const unsigned char *, unsigned char *,
+                    unsigned long, const AES_KEY *,
+                    unsigned char *, int);
+void AES_cfb8_encrypt(const unsigned char *, unsigned char *,
+                     unsigned long, const AES_KEY *,
+                     unsigned char *, int);
+
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* HEIM_AES_H */
diff --git a/src/external/heimdal/hcrypto/camellia-ntt.c b/src/external/heimdal/hcrypto/camellia-ntt.c
new file mode 100644 (file)
index 0000000..4a27a94
--- /dev/null
@@ -0,0 +1,1469 @@
+/* camellia.c ver 1.2.0
+ *
+ * Copyright (c) 2006,2007
+ * NTT (Nippon Telegraph and Telephone Corporation) . All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer as
+ *   the first lines of this file unmodified.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NTT ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL NTT BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+/*
+ * Algorithm Specification
+ *  http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <krb5-types.h>
+#include "camellia-ntt.h"
+
+#include <roken.h>
+
+/* key constants */
+
+#define CAMELLIA_SIGMA1L (0xA09E667FL)
+#define CAMELLIA_SIGMA1R (0x3BCC908BL)
+#define CAMELLIA_SIGMA2L (0xB67AE858L)
+#define CAMELLIA_SIGMA2R (0x4CAA73B2L)
+#define CAMELLIA_SIGMA3L (0xC6EF372FL)
+#define CAMELLIA_SIGMA3R (0xE94F82BEL)
+#define CAMELLIA_SIGMA4L (0x54FF53A5L)
+#define CAMELLIA_SIGMA4R (0xF1D36F1CL)
+#define CAMELLIA_SIGMA5L (0x10E527FAL)
+#define CAMELLIA_SIGMA5R (0xDE682D1DL)
+#define CAMELLIA_SIGMA6L (0xB05688C2L)
+#define CAMELLIA_SIGMA6R (0xB3E6C1FDL)
+
+/*
+ *  macros
+ */
+
+
+#if defined(_MSC_VER)
+
+# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
+# define GETU32(p) SWAP(*((u32 *)(p)))
+# define PUTU32(ct, st) {*((u32 *)(ct)) = SWAP((st));}
+
+#else /* not MS-VC */
+
+# define GETU32(pt)                            \
+    (((u32)(pt)[0] << 24)                      \
+     ^ ((u32)(pt)[1] << 16)                    \
+     ^ ((u32)(pt)[2] <<  8)                    \
+     ^ ((u32)(pt)[3]))
+
+# define PUTU32(ct, st)  {                     \
+       (ct)[0] = (u8)((st) >> 24);             \
+       (ct)[1] = (u8)((st) >> 16);             \
+       (ct)[2] = (u8)((st) >>  8);             \
+       (ct)[3] = (u8)(st); }
+
+#endif
+
+#define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2])
+#define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1])
+
+/* rotation right shift 1byte */
+#define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24))
+/* rotation left shift 1bit */
+#define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31))
+/* rotation left shift 1byte */
+#define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24))
+
+#define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits)   \
+    do {                                               \
+       w0 = ll;                                        \
+       ll = (ll << bits) + (lr >> (32 - bits));        \
+       lr = (lr << bits) + (rl >> (32 - bits));        \
+       rl = (rl << bits) + (rr >> (32 - bits));        \
+       rr = (rr << bits) + (w0 >> (32 - bits));        \
+    } while(0)
+
+#define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits)        \
+    do {                                               \
+       w0 = ll;                                        \
+       w1 = lr;                                        \
+       ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \
+       lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \
+       rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \
+       rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \
+    } while(0)
+
+#define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)])
+#define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)])
+#define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)])
+#define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)])
+
+#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)     \
+    do {                                                       \
+       il = xl ^ kl;                                           \
+       ir = xr ^ kr;                                           \
+       t0 = il >> 16;                                          \
+       t1 = ir >> 16;                                          \
+       yl = CAMELLIA_SP1110(ir & 0xff)                         \
+           ^ CAMELLIA_SP0222((t1 >> 8) & 0xff)                 \
+           ^ CAMELLIA_SP3033(t1 & 0xff)                        \
+           ^ CAMELLIA_SP4404((ir >> 8) & 0xff);                \
+       yr = CAMELLIA_SP1110((t0 >> 8) & 0xff)                  \
+           ^ CAMELLIA_SP0222(t0 & 0xff)                        \
+           ^ CAMELLIA_SP3033((il >> 8) & 0xff)                 \
+           ^ CAMELLIA_SP4404(il & 0xff);                       \
+       yl ^= yr;                                               \
+       yr = CAMELLIA_RR8(yr);                                  \
+       yr ^= yl;                                               \
+    } while(0)
+
+
+/*
+ * for speed up
+ *
+ */
+#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
+    do {                                                               \
+       t0 = kll;                                                       \
+       t0 &= ll;                                                       \
+       lr ^= CAMELLIA_RL1(t0);                                         \
+       t1 = klr;                                                       \
+       t1 |= lr;                                                       \
+       ll ^= t1;                                                       \
+                                                                       \
+       t2 = krr;                                                       \
+       t2 |= rr;                                                       \
+       rl ^= t2;                                                       \
+       t3 = krl;                                                       \
+       t3 &= rl;                                                       \
+       rr ^= CAMELLIA_RL1(t3);                                         \
+    } while(0)
+
+#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)       \
+    do {                                                               \
+       ir = CAMELLIA_SP1110(xr & 0xff)                                 \
+           ^ CAMELLIA_SP0222((xr >> 24) & 0xff)                        \
+           ^ CAMELLIA_SP3033((xr >> 16) & 0xff)                        \
+           ^ CAMELLIA_SP4404((xr >> 8) & 0xff);                        \
+       il = CAMELLIA_SP1110((xl >> 24) & 0xff)                         \
+           ^ CAMELLIA_SP0222((xl >> 16) & 0xff)                        \
+           ^ CAMELLIA_SP3033((xl >> 8) & 0xff)                         \
+           ^ CAMELLIA_SP4404(xl & 0xff);                               \
+       il ^= kl;                                                       \
+       ir ^= kr;                                                       \
+       ir ^= il;                                                       \
+       il = CAMELLIA_RR8(il);                                          \
+       il ^= ir;                                                       \
+       yl ^= ir;                                                       \
+       yr ^= il;                                                       \
+    } while(0)
+
+
+static const u32 camellia_sp1110[256] = {
+    0x70707000,0x82828200,0x2c2c2c00,0xececec00,
+    0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500,
+    0xe4e4e400,0x85858500,0x57575700,0x35353500,
+    0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100,
+    0x23232300,0xefefef00,0x6b6b6b00,0x93939300,
+    0x45454500,0x19191900,0xa5a5a500,0x21212100,
+    0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00,
+    0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00,
+    0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00,
+    0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00,
+    0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00,
+    0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00,
+    0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00,
+    0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00,
+    0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600,
+    0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00,
+    0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600,
+    0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00,
+    0x74747400,0x12121200,0x2b2b2b00,0x20202000,
+    0xf0f0f000,0xb1b1b100,0x84848400,0x99999900,
+    0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200,
+    0x34343400,0x7e7e7e00,0x76767600,0x05050500,
+    0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100,
+    0xd1d1d100,0x17171700,0x04040400,0xd7d7d700,
+    0x14141400,0x58585800,0x3a3a3a00,0x61616100,
+    0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00,
+    0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600,
+    0x53535300,0x18181800,0xf2f2f200,0x22222200,
+    0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200,
+    0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100,
+    0x24242400,0x08080800,0xe8e8e800,0xa8a8a800,
+    0x60606000,0xfcfcfc00,0x69696900,0x50505000,
+    0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00,
+    0xa1a1a100,0x89898900,0x62626200,0x97979700,
+    0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500,
+    0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200,
+    0x10101000,0xc4c4c400,0x00000000,0x48484800,
+    0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00,
+    0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00,
+    0x09090900,0x3f3f3f00,0xdddddd00,0x94949400,
+    0x87878700,0x5c5c5c00,0x83838300,0x02020200,
+    0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300,
+    0x73737300,0x67676700,0xf6f6f600,0xf3f3f300,
+    0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200,
+    0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600,
+    0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00,
+    0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00,
+    0x13131300,0xbebebe00,0x63636300,0x2e2e2e00,
+    0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00,
+    0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00,
+    0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600,
+    0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900,
+    0x78787800,0x98989800,0x06060600,0x6a6a6a00,
+    0xe7e7e700,0x46464600,0x71717100,0xbababa00,
+    0xd4d4d400,0x25252500,0xababab00,0x42424200,
+    0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00,
+    0x72727200,0x07070700,0xb9b9b900,0x55555500,
+    0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00,
+    0x36363600,0x49494900,0x2a2a2a00,0x68686800,
+    0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400,
+    0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00,
+    0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100,
+    0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400,
+    0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00,
+};
+
+static const u32 camellia_sp0222[256] = {
+    0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9,
+    0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb,
+    0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a,
+    0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282,
+    0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727,
+    0x008a8a8a,0x00323232,0x004b4b4b,0x00424242,
+    0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c,
+    0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b,
+    0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f,
+    0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d,
+    0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe,
+    0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434,
+    0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595,
+    0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a,
+    0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad,
+    0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a,
+    0x00171717,0x001a1a1a,0x00353535,0x00cccccc,
+    0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a,
+    0x00e8e8e8,0x00242424,0x00565656,0x00404040,
+    0x00e1e1e1,0x00636363,0x00090909,0x00333333,
+    0x00bfbfbf,0x00989898,0x00979797,0x00858585,
+    0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a,
+    0x00dadada,0x006f6f6f,0x00535353,0x00626262,
+    0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf,
+    0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2,
+    0x00bdbdbd,0x00363636,0x00222222,0x00383838,
+    0x00646464,0x001e1e1e,0x00393939,0x002c2c2c,
+    0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444,
+    0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565,
+    0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323,
+    0x00484848,0x00101010,0x00d1d1d1,0x00515151,
+    0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0,
+    0x00555555,0x00a1a1a1,0x00414141,0x00fafafa,
+    0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f,
+    0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b,
+    0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5,
+    0x00202020,0x00898989,0x00000000,0x00909090,
+    0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7,
+    0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5,
+    0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929,
+    0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404,
+    0x009b9b9b,0x00949494,0x00212121,0x00666666,
+    0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7,
+    0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5,
+    0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c,
+    0x00919191,0x006e6e6e,0x008d8d8d,0x00767676,
+    0x00030303,0x002d2d2d,0x00dedede,0x00969696,
+    0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c,
+    0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919,
+    0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d,
+    0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d,
+    0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2,
+    0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4,
+    0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575,
+    0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484,
+    0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5,
+    0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa,
+    0x00f1f1f1,0x00dddddd,0x00595959,0x00141414,
+    0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0,
+    0x00787878,0x00707070,0x00e3e3e3,0x00494949,
+    0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6,
+    0x00777777,0x00939393,0x00868686,0x00838383,
+    0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9,
+    0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d,
+};
+
+static const u32 camellia_sp3033[256] = {
+    0x38003838,0x41004141,0x16001616,0x76007676,
+    0xd900d9d9,0x93009393,0x60006060,0xf200f2f2,
+    0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a,
+    0x75007575,0x06000606,0x57005757,0xa000a0a0,
+    0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9,
+    0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090,
+    0xf600f6f6,0x07000707,0xa700a7a7,0x27002727,
+    0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede,
+    0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7,
+    0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767,
+    0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf,
+    0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d,
+    0x53005353,0xf000f0f0,0x9c009c9c,0x65006565,
+    0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e,
+    0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b,
+    0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6,
+    0xc500c5c5,0x86008686,0x4d004d4d,0x33003333,
+    0xfd00fdfd,0x66006666,0x58005858,0x96009696,
+    0x3a003a3a,0x09000909,0x95009595,0x10001010,
+    0x78007878,0xd800d8d8,0x42004242,0xcc00cccc,
+    0xef00efef,0x26002626,0xe500e5e5,0x61006161,
+    0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282,
+    0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898,
+    0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb,
+    0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0,
+    0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e,
+    0x19001919,0x87008787,0x4e004e4e,0x0b000b0b,
+    0xa900a9a9,0x0c000c0c,0x79007979,0x11001111,
+    0x7f007f7f,0x22002222,0xe700e7e7,0x59005959,
+    0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8,
+    0x12001212,0x04000404,0x74007474,0x54005454,
+    0x30003030,0x7e007e7e,0xb400b4b4,0x28002828,
+    0x55005555,0x68006868,0x50005050,0xbe00bebe,
+    0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb,
+    0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca,
+    0x70007070,0xff00ffff,0x32003232,0x69006969,
+    0x08000808,0x62006262,0x00000000,0x24002424,
+    0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded,
+    0x45004545,0x81008181,0x73007373,0x6d006d6d,
+    0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a,
+    0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101,
+    0xe600e6e6,0x25002525,0x48004848,0x99009999,
+    0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9,
+    0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171,
+    0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313,
+    0x64006464,0x9b009b9b,0x63006363,0x9d009d9d,
+    0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5,
+    0x89008989,0x5f005f5f,0xb100b1b1,0x17001717,
+    0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646,
+    0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747,
+    0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b,
+    0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac,
+    0x3c003c3c,0x4c004c4c,0x03000303,0x35003535,
+    0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d,
+    0x6a006a6a,0x92009292,0xd500d5d5,0x21002121,
+    0x44004444,0x51005151,0xc600c6c6,0x7d007d7d,
+    0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa,
+    0x7c007c7c,0x77007777,0x56005656,0x05000505,
+    0x1b001b1b,0xa400a4a4,0x15001515,0x34003434,
+    0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252,
+    0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd,
+    0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0,
+    0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a,
+    0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f,
+};
+
+static const u32 camellia_sp4404[256] = {
+    0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0,
+    0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae,
+    0x23230023,0x6b6b006b,0x45450045,0xa5a500a5,
+    0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092,
+    0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f,
+    0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b,
+    0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d,
+    0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c,
+    0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0,
+    0x74740074,0x2b2b002b,0xf0f000f0,0x84840084,
+    0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076,
+    0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004,
+    0x14140014,0x3a3a003a,0xdede00de,0x11110011,
+    0x32320032,0x9c9c009c,0x53530053,0xf2f200f2,
+    0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a,
+    0x24240024,0xe8e800e8,0x60600060,0x69690069,
+    0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062,
+    0x54540054,0x1e1e001e,0xe0e000e0,0x64640064,
+    0x10100010,0x00000000,0xa3a300a3,0x75750075,
+    0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd,
+    0x87870087,0x83830083,0xcdcd00cd,0x90900090,
+    0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf,
+    0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6,
+    0x81810081,0x6f6f006f,0x13130013,0x63630063,
+    0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc,
+    0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4,
+    0x78780078,0x06060006,0xe7e700e7,0x71710071,
+    0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d,
+    0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac,
+    0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1,
+    0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043,
+    0x15150015,0xadad00ad,0x77770077,0x80800080,
+    0x82820082,0xecec00ec,0x27270027,0xe5e500e5,
+    0x85850085,0x35350035,0x0c0c000c,0x41410041,
+    0xefef00ef,0x93930093,0x19190019,0x21210021,
+    0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd,
+    0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce,
+    0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a,
+    0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d,
+    0x01010001,0xd6d600d6,0x56560056,0x4d4d004d,
+    0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d,
+    0x12120012,0x20200020,0xb1b100b1,0x99990099,
+    0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005,
+    0xb7b700b7,0x31310031,0x17170017,0xd7d700d7,
+    0x58580058,0x61610061,0x1b1b001b,0x1c1c001c,
+    0x0f0f000f,0x16160016,0x18180018,0x22220022,
+    0x44440044,0xb2b200b2,0xb5b500b5,0x91910091,
+    0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050,
+    0xd0d000d0,0x7d7d007d,0x89890089,0x97970097,
+    0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2,
+    0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db,
+    0x03030003,0xdada00da,0x3f3f003f,0x94940094,
+    0x5c5c005c,0x02020002,0x4a4a004a,0x33330033,
+    0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2,
+    0x9b9b009b,0x26260026,0x37370037,0x3b3b003b,
+    0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e,
+    0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e,
+    0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059,
+    0x98980098,0x6a6a006a,0x46460046,0xbaba00ba,
+    0x25250025,0x42420042,0xa2a200a2,0xfafa00fa,
+    0x07070007,0x55550055,0xeeee00ee,0x0a0a000a,
+    0x49490049,0x68680068,0x38380038,0xa4a400a4,
+    0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1,
+    0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e,
+};
+
+
+/**
+ * Stuff related to the Camellia key schedule
+ */
+#define subl(x) subL[(x)]
+#define subr(x) subR[(x)]
+
+static void camellia_setup128(const unsigned char *key, u32 *subkey)
+{
+    u32 kll, klr, krl, krr;
+    u32 il, ir, t0, t1, w0, w1;
+    u32 kw4l, kw4r, dw, tl, tr;
+    u32 subL[26];
+    u32 subR[26];
+
+    /**
+     *  k == kll || klr || krl || krr (|| is concatination)
+     */
+    kll = GETU32(key     );
+    klr = GETU32(key +  4);
+    krl = GETU32(key +  8);
+    krr = GETU32(key + 12);
+    /**
+     * generate KL dependent subkeys
+     */
+    subl(0) = kll; subr(0) = klr;
+    subl(1) = krl; subr(1) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(4) = kll; subr(4) = klr;
+    subl(5) = krl; subr(5) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
+    subl(10) = kll; subr(10) = klr;
+    subl(11) = krl; subr(11) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(13) = krl; subr(13) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(16) = kll; subr(16) = klr;
+    subl(17) = krl; subr(17) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(18) = kll; subr(18) = klr;
+    subl(19) = krl; subr(19) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(22) = kll; subr(22) = klr;
+    subl(23) = krl; subr(23) = krr;
+
+    /* generate KA */
+    kll = subl(0); klr = subr(0);
+    krl = subl(1); krr = subr(1);
+    CAMELLIA_F(kll, klr,
+              CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
+              w0, w1, il, ir, t0, t1);
+    krl ^= w0; krr ^= w1;
+    CAMELLIA_F(krl, krr,
+              CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
+              kll, klr, il, ir, t0, t1);
+    CAMELLIA_F(kll, klr,
+              CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
+              krl, krr, il, ir, t0, t1);
+    krl ^= w0; krr ^= w1;
+    CAMELLIA_F(krl, krr,
+              CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
+              w0, w1, il, ir, t0, t1);
+    kll ^= w0; klr ^= w1;
+
+    /* generate KA dependent subkeys */
+    subl(2) = kll; subr(2) = klr;
+    subl(3) = krl; subr(3) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(6) = kll; subr(6) = klr;
+    subl(7) = krl; subr(7) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(8) = kll; subr(8) = klr;
+    subl(9) = krl; subr(9) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(12) = kll; subr(12) = klr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(14) = kll; subr(14) = klr;
+    subl(15) = krl; subr(15) = krr;
+    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
+    subl(20) = kll; subr(20) = klr;
+    subl(21) = krl; subr(21) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(24) = kll; subr(24) = klr;
+    subl(25) = krl; subr(25) = krr;
+
+
+    /* absorb kw2 to other subkeys */
+    subl(3) ^= subl(1); subr(3) ^= subr(1);
+    subl(5) ^= subl(1); subr(5) ^= subr(1);
+    subl(7) ^= subl(1); subr(7) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(9);
+    dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(11) ^= subl(1); subr(11) ^= subr(1);
+    subl(13) ^= subl(1); subr(13) ^= subr(1);
+    subl(15) ^= subl(1); subr(15) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(17);
+    dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(19) ^= subl(1); subr(19) ^= subr(1);
+    subl(21) ^= subl(1); subr(21) ^= subr(1);
+    subl(23) ^= subl(1); subr(23) ^= subr(1);
+    subl(24) ^= subl(1); subr(24) ^= subr(1);
+
+    /* absorb kw4 to other subkeys */
+    kw4l = subl(25); kw4r = subr(25);
+    subl(22) ^= kw4l; subr(22) ^= kw4r;
+    subl(20) ^= kw4l; subr(20) ^= kw4r;
+    subl(18) ^= kw4l; subr(18) ^= kw4r;
+    kw4l ^= kw4r & ~subr(16);
+    dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
+    subl(14) ^= kw4l; subr(14) ^= kw4r;
+    subl(12) ^= kw4l; subr(12) ^= kw4r;
+    subl(10) ^= kw4l; subr(10) ^= kw4r;
+    kw4l ^= kw4r & ~subr(8);
+    dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
+    subl(6) ^= kw4l; subr(6) ^= kw4r;
+    subl(4) ^= kw4l; subr(4) ^= kw4r;
+    subl(2) ^= kw4l; subr(2) ^= kw4r;
+    subl(0) ^= kw4l; subr(0) ^= kw4r;
+
+    /* key XOR is end of F-function */
+    CamelliaSubkeyL(0) = subl(0) ^ subl(2);
+    CamelliaSubkeyR(0) = subr(0) ^ subr(2);
+    CamelliaSubkeyL(2) = subl(3);
+    CamelliaSubkeyR(2) = subr(3);
+    CamelliaSubkeyL(3) = subl(2) ^ subl(4);
+    CamelliaSubkeyR(3) = subr(2) ^ subr(4);
+    CamelliaSubkeyL(4) = subl(3) ^ subl(5);
+    CamelliaSubkeyR(4) = subr(3) ^ subr(5);
+    CamelliaSubkeyL(5) = subl(4) ^ subl(6);
+    CamelliaSubkeyR(5) = subr(4) ^ subr(6);
+    CamelliaSubkeyL(6) = subl(5) ^ subl(7);
+    CamelliaSubkeyR(6) = subr(5) ^ subr(7);
+    tl = subl(10) ^ (subr(10) & ~subr(8));
+    dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(7) = subl(6) ^ tl;
+    CamelliaSubkeyR(7) = subr(6) ^ tr;
+    CamelliaSubkeyL(8) = subl(8);
+    CamelliaSubkeyR(8) = subr(8);
+    CamelliaSubkeyL(9) = subl(9);
+    CamelliaSubkeyR(9) = subr(9);
+    tl = subl(7) ^ (subr(7) & ~subr(9));
+    dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(10) = tl ^ subl(11);
+    CamelliaSubkeyR(10) = tr ^ subr(11);
+    CamelliaSubkeyL(11) = subl(10) ^ subl(12);
+    CamelliaSubkeyR(11) = subr(10) ^ subr(12);
+    CamelliaSubkeyL(12) = subl(11) ^ subl(13);
+    CamelliaSubkeyR(12) = subr(11) ^ subr(13);
+    CamelliaSubkeyL(13) = subl(12) ^ subl(14);
+    CamelliaSubkeyR(13) = subr(12) ^ subr(14);
+    CamelliaSubkeyL(14) = subl(13) ^ subl(15);
+    CamelliaSubkeyR(14) = subr(13) ^ subr(15);
+    tl = subl(18) ^ (subr(18) & ~subr(16));
+    dw = tl & subl(16),        tr = subr(18) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(15) = subl(14) ^ tl;
+    CamelliaSubkeyR(15) = subr(14) ^ tr;
+    CamelliaSubkeyL(16) = subl(16);
+    CamelliaSubkeyR(16) = subr(16);
+    CamelliaSubkeyL(17) = subl(17);
+    CamelliaSubkeyR(17) = subr(17);
+    tl = subl(15) ^ (subr(15) & ~subr(17));
+    dw = tl & subl(17),        tr = subr(15) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(18) = tl ^ subl(19);
+    CamelliaSubkeyR(18) = tr ^ subr(19);
+    CamelliaSubkeyL(19) = subl(18) ^ subl(20);
+    CamelliaSubkeyR(19) = subr(18) ^ subr(20);
+    CamelliaSubkeyL(20) = subl(19) ^ subl(21);
+    CamelliaSubkeyR(20) = subr(19) ^ subr(21);
+    CamelliaSubkeyL(21) = subl(20) ^ subl(22);
+    CamelliaSubkeyR(21) = subr(20) ^ subr(22);
+    CamelliaSubkeyL(22) = subl(21) ^ subl(23);
+    CamelliaSubkeyR(22) = subr(21) ^ subr(23);
+    CamelliaSubkeyL(23) = subl(22);
+    CamelliaSubkeyR(23) = subr(22);
+    CamelliaSubkeyL(24) = subl(24) ^ subl(23);
+    CamelliaSubkeyR(24) = subr(24) ^ subr(23);
+
+    /* apply the inverse of the last half of P-function */
+    dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;
+    dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;
+    dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;
+    dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;
+    dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;
+    dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;
+    dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;
+    dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;
+    dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;
+    dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;
+    dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;
+    dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;
+    dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;
+    dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;
+    dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;
+    dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;
+    dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;
+    dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;
+
+    return;
+}
+
+static void camellia_setup256(const unsigned char *key, u32 *subkey)
+{
+    u32 kll,klr,krl,krr;           /* left half of key */
+    u32 krll,krlr,krrl,krrr;       /* right half of key */
+    u32 il, ir, t0, t1, w0, w1;    /* temporary variables */
+    u32 kw4l, kw4r, dw, tl, tr;
+    u32 subL[34];
+    u32 subR[34];
+
+    /**
+     *  key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
+     *  (|| is concatination)
+     */
+
+    kll  = GETU32(key     );
+    klr  = GETU32(key +  4);
+    krl  = GETU32(key +  8);
+    krr  = GETU32(key + 12);
+    krll = GETU32(key + 16);
+    krlr = GETU32(key + 20);
+    krrl = GETU32(key + 24);
+    krrr = GETU32(key + 28);
+
+    /* generate KL dependent subkeys */
+    subl(0) = kll; subr(0) = klr;
+    subl(1) = krl; subr(1) = krr;
+    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
+    subl(12) = kll; subr(12) = klr;
+    subl(13) = krl; subr(13) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(16) = kll; subr(16) = klr;
+    subl(17) = krl; subr(17) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(22) = kll; subr(22) = klr;
+    subl(23) = krl; subr(23) = krr;
+    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
+    subl(30) = kll; subr(30) = klr;
+    subl(31) = krl; subr(31) = krr;
+
+    /* generate KR dependent subkeys */
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
+    subl(4) = krll; subr(4) = krlr;
+    subl(5) = krrl; subr(5) = krrr;
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
+    subl(8) = krll; subr(8) = krlr;
+    subl(9) = krrl; subr(9) = krrr;
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+    subl(18) = krll; subr(18) = krlr;
+    subl(19) = krrl; subr(19) = krrr;
+    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
+    subl(26) = krll; subr(26) = krlr;
+    subl(27) = krrl; subr(27) = krrr;
+    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
+
+    /* generate KA */
+    kll = subl(0) ^ krll; klr = subr(0) ^ krlr;
+    krl = subl(1) ^ krrl; krr = subr(1) ^ krrr;
+    CAMELLIA_F(kll, klr,
+              CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
+              w0, w1, il, ir, t0, t1);
+    krl ^= w0; krr ^= w1;
+    CAMELLIA_F(krl, krr,
+              CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
+              kll, klr, il, ir, t0, t1);
+    kll ^= krll; klr ^= krlr;
+    CAMELLIA_F(kll, klr,
+              CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
+              krl, krr, il, ir, t0, t1);
+    krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
+    CAMELLIA_F(krl, krr,
+              CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
+              w0, w1, il, ir, t0, t1);
+    kll ^= w0; klr ^= w1;
+
+    /* generate KB */
+    krll ^= kll; krlr ^= klr;
+    krrl ^= krl; krrr ^= krr;
+    CAMELLIA_F(krll, krlr,
+              CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
+              w0, w1, il, ir, t0, t1);
+    krrl ^= w0; krrr ^= w1;
+    CAMELLIA_F(krrl, krrr,
+              CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
+              w0, w1, il, ir, t0, t1);
+    krll ^= w0; krlr ^= w1;
+
+    /* generate KA dependent subkeys */
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(6) = kll; subr(6) = klr;
+    subl(7) = krl; subr(7) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
+    subl(14) = kll; subr(14) = klr;
+    subl(15) = krl; subr(15) = krr;
+    subl(24) = klr; subr(24) = krl;
+    subl(25) = krr; subr(25) = kll;
+    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
+    subl(28) = kll; subr(28) = klr;
+    subl(29) = krl; subr(29) = krr;
+
+    /* generate KB dependent subkeys */
+    subl(2) = krll; subr(2) = krlr;
+    subl(3) = krrl; subr(3) = krrr;
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+    subl(10) = krll; subr(10) = krlr;
+    subl(11) = krrl; subr(11) = krrr;
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+    subl(20) = krll; subr(20) = krlr;
+    subl(21) = krrl; subr(21) = krrr;
+    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
+    subl(32) = krll; subr(32) = krlr;
+    subl(33) = krrl; subr(33) = krrr;
+
+    /* absorb kw2 to other subkeys */
+    subl(3) ^= subl(1); subr(3) ^= subr(1);
+    subl(5) ^= subl(1); subr(5) ^= subr(1);
+    subl(7) ^= subl(1); subr(7) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(9);
+    dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(11) ^= subl(1); subr(11) ^= subr(1);
+    subl(13) ^= subl(1); subr(13) ^= subr(1);
+    subl(15) ^= subl(1); subr(15) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(17);
+    dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(19) ^= subl(1); subr(19) ^= subr(1);
+    subl(21) ^= subl(1); subr(21) ^= subr(1);
+    subl(23) ^= subl(1); subr(23) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(25);
+    dw = subl(1) & subl(25), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(27) ^= subl(1); subr(27) ^= subr(1);
+    subl(29) ^= subl(1); subr(29) ^= subr(1);
+    subl(31) ^= subl(1); subr(31) ^= subr(1);
+    subl(32) ^= subl(1); subr(32) ^= subr(1);
+
+    /* absorb kw4 to other subkeys */
+    kw4l = subl(33); kw4r = subr(33);
+    subl(30) ^= kw4l; subr(30) ^= kw4r;
+    subl(28) ^= kw4l; subr(28) ^= kw4r;
+    subl(26) ^= kw4l; subr(26) ^= kw4r;
+    kw4l ^= kw4r & ~subr(24);
+    dw = kw4l & subl(24), kw4r ^= CAMELLIA_RL1(dw);
+    subl(22) ^= kw4l; subr(22) ^= kw4r;
+    subl(20) ^= kw4l; subr(20) ^= kw4r;
+    subl(18) ^= kw4l; subr(18) ^= kw4r;
+    kw4l ^= kw4r & ~subr(16);
+    dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
+    subl(14) ^= kw4l; subr(14) ^= kw4r;
+    subl(12) ^= kw4l; subr(12) ^= kw4r;
+    subl(10) ^= kw4l; subr(10) ^= kw4r;
+    kw4l ^= kw4r & ~subr(8);
+    dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
+    subl(6) ^= kw4l; subr(6) ^= kw4r;
+    subl(4) ^= kw4l; subr(4) ^= kw4r;
+    subl(2) ^= kw4l; subr(2) ^= kw4r;
+    subl(0) ^= kw4l; subr(0) ^= kw4r;
+
+    /* key XOR is end of F-function */
+    CamelliaSubkeyL(0) = subl(0) ^ subl(2);
+    CamelliaSubkeyR(0) = subr(0) ^ subr(2);
+    CamelliaSubkeyL(2) = subl(3);
+    CamelliaSubkeyR(2) = subr(3);
+    CamelliaSubkeyL(3) = subl(2) ^ subl(4);
+    CamelliaSubkeyR(3) = subr(2) ^ subr(4);
+    CamelliaSubkeyL(4) = subl(3) ^ subl(5);
+    CamelliaSubkeyR(4) = subr(3) ^ subr(5);
+    CamelliaSubkeyL(5) = subl(4) ^ subl(6);
+    CamelliaSubkeyR(5) = subr(4) ^ subr(6);
+    CamelliaSubkeyL(6) = subl(5) ^ subl(7);
+    CamelliaSubkeyR(6) = subr(5) ^ subr(7);
+    tl = subl(10) ^ (subr(10) & ~subr(8));
+    dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(7) = subl(6) ^ tl;
+    CamelliaSubkeyR(7) = subr(6) ^ tr;
+    CamelliaSubkeyL(8) = subl(8);
+    CamelliaSubkeyR(8) = subr(8);
+    CamelliaSubkeyL(9) = subl(9);
+    CamelliaSubkeyR(9) = subr(9);
+    tl = subl(7) ^ (subr(7) & ~subr(9));
+    dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(10) = tl ^ subl(11);
+    CamelliaSubkeyR(10) = tr ^ subr(11);
+    CamelliaSubkeyL(11) = subl(10) ^ subl(12);
+    CamelliaSubkeyR(11) = subr(10) ^ subr(12);
+    CamelliaSubkeyL(12) = subl(11) ^ subl(13);
+    CamelliaSubkeyR(12) = subr(11) ^ subr(13);
+    CamelliaSubkeyL(13) = subl(12) ^ subl(14);
+    CamelliaSubkeyR(13) = subr(12) ^ subr(14);
+    CamelliaSubkeyL(14) = subl(13) ^ subl(15);
+    CamelliaSubkeyR(14) = subr(13) ^ subr(15);
+    tl = subl(18) ^ (subr(18) & ~subr(16));
+    dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(15) = subl(14) ^ tl;
+    CamelliaSubkeyR(15) = subr(14) ^ tr;
+    CamelliaSubkeyL(16) = subl(16);
+    CamelliaSubkeyR(16) = subr(16);
+    CamelliaSubkeyL(17) = subl(17);
+    CamelliaSubkeyR(17) = subr(17);
+    tl = subl(15) ^ (subr(15) & ~subr(17));
+    dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(18) = tl ^ subl(19);
+    CamelliaSubkeyR(18) = tr ^ subr(19);
+    CamelliaSubkeyL(19) = subl(18) ^ subl(20);
+    CamelliaSubkeyR(19) = subr(18) ^ subr(20);
+    CamelliaSubkeyL(20) = subl(19) ^ subl(21);
+    CamelliaSubkeyR(20) = subr(19) ^ subr(21);
+    CamelliaSubkeyL(21) = subl(20) ^ subl(22);
+    CamelliaSubkeyR(21) = subr(20) ^ subr(22);
+    CamelliaSubkeyL(22) = subl(21) ^ subl(23);
+    CamelliaSubkeyR(22) = subr(21) ^ subr(23);
+    tl = subl(26) ^ (subr(26) & ~subr(24));
+    dw = tl & subl(24), tr = subr(26) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(23) = subl(22) ^ tl;
+    CamelliaSubkeyR(23) = subr(22) ^ tr;
+    CamelliaSubkeyL(24) = subl(24);
+    CamelliaSubkeyR(24) = subr(24);
+    CamelliaSubkeyL(25) = subl(25);
+    CamelliaSubkeyR(25) = subr(25);
+    tl = subl(23) ^ (subr(23) &  ~subr(25));
+    dw = tl & subl(25), tr = subr(23) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(26) = tl ^ subl(27);
+    CamelliaSubkeyR(26) = tr ^ subr(27);
+    CamelliaSubkeyL(27) = subl(26) ^ subl(28);
+    CamelliaSubkeyR(27) = subr(26) ^ subr(28);
+    CamelliaSubkeyL(28) = subl(27) ^ subl(29);
+    CamelliaSubkeyR(28) = subr(27) ^ subr(29);
+    CamelliaSubkeyL(29) = subl(28) ^ subl(30);
+    CamelliaSubkeyR(29) = subr(28) ^ subr(30);
+    CamelliaSubkeyL(30) = subl(29) ^ subl(31);
+    CamelliaSubkeyR(30) = subr(29) ^ subr(31);
+    CamelliaSubkeyL(31) = subl(30);
+    CamelliaSubkeyR(31) = subr(30);
+    CamelliaSubkeyL(32) = subl(32) ^ subl(31);
+    CamelliaSubkeyR(32) = subr(32) ^ subr(31);
+
+    /* apply the inverse of the last half of P-function */
+    dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;
+    dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;
+    dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;
+    dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;
+    dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;
+    dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;
+    dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;
+    dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;
+    dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;
+    dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;
+    dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;
+    dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;
+    dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;
+    dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;
+    dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;
+    dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;
+    dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;
+    dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;
+    dw = CamelliaSubkeyL(26) ^ CamelliaSubkeyR(26), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(26) = CamelliaSubkeyL(26) ^ dw, CamelliaSubkeyL(26) = dw;
+    dw = CamelliaSubkeyL(27) ^ CamelliaSubkeyR(27), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(27) = CamelliaSubkeyL(27) ^ dw, CamelliaSubkeyL(27) = dw;
+    dw = CamelliaSubkeyL(28) ^ CamelliaSubkeyR(28), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(28) = CamelliaSubkeyL(28) ^ dw, CamelliaSubkeyL(28) = dw;
+    dw = CamelliaSubkeyL(29) ^ CamelliaSubkeyR(29), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(29) = CamelliaSubkeyL(29) ^ dw, CamelliaSubkeyL(29) = dw;
+    dw = CamelliaSubkeyL(30) ^ CamelliaSubkeyR(30), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(30) = CamelliaSubkeyL(30) ^ dw, CamelliaSubkeyL(30) = dw;
+    dw = CamelliaSubkeyL(31) ^ CamelliaSubkeyR(31), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(31) = CamelliaSubkeyL(31) ^ dw,CamelliaSubkeyL(31) = dw;
+
+    return;
+}
+
+static void camellia_setup192(const unsigned char *key, u32 *subkey)
+{
+    unsigned char kk[32];
+    u32 krll, krlr, krrl,krrr;
+
+    memcpy(kk, key, 24);
+    memcpy((unsigned char *)&krll, key+16,4);
+    memcpy((unsigned char *)&krlr, key+20,4);
+    krrl = ~krll;
+    krrr = ~krlr;
+    memcpy(kk+24, (unsigned char *)&krrl, 4);
+    memcpy(kk+28, (unsigned char *)&krrr, 4);
+    camellia_setup256(kk, subkey);
+    return;
+}
+
+
+/**
+ * Stuff related to camellia encryption/decryption
+ *
+ * "io" must be 4byte aligned and big-endian data.
+ */
+static void camellia_encrypt128(const u32 *subkey, u32 *io)
+{
+    u32 il, ir, t0, t1;
+
+    /* pre whitening but absorb kw2*/
+    io[0] ^= CamelliaSubkeyL(0);
+    io[1] ^= CamelliaSubkeyR(0);
+    /* main iteration */
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+                CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+                CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+                    io[0],io[1],il,ir,t0,t1);
+
+    /* post whitening but kw4 */
+    io[2] ^= CamelliaSubkeyL(24);
+    io[3] ^= CamelliaSubkeyR(24);
+
+    t0 = io[0];
+    t1 = io[1];
+    io[0] = io[2];
+    io[1] = io[3];
+    io[2] = t0;
+    io[3] = t1;
+
+    return;
+}
+
+static void camellia_decrypt128(const u32 *subkey, u32 *io)
+{
+    u32 il,ir,t0,t1;               /* temporary valiables */
+
+    /* pre whitening but absorb kw2*/
+    io[0] ^= CamelliaSubkeyL(24);
+    io[1] ^= CamelliaSubkeyR(24);
+
+    /* main iteration */
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+                CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+                CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+                    io[0],io[1],il,ir,t0,t1);
+
+    /* post whitening but kw4 */
+    io[2] ^= CamelliaSubkeyL(0);
+    io[3] ^= CamelliaSubkeyR(0);
+
+    t0 = io[0];
+    t1 = io[1];
+    io[0] = io[2];
+    io[1] = io[3];
+    io[2] = t0;
+    io[3] = t1;
+
+    return;
+}
+
+/**
+ * stuff for 192 and 256bit encryption/decryption
+ */
+static void camellia_encrypt256(const u32 *subkey, u32 *io)
+{
+    u32 il,ir,t0,t1;           /* temporary valiables */
+
+    /* pre whitening but absorb kw2*/
+    io[0] ^= CamelliaSubkeyL(0);
+    io[1] ^= CamelliaSubkeyR(0);
+
+    /* main iteration */
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+                CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+                CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(24),CamelliaSubkeyR(24),
+                CamelliaSubkeyL(25),CamelliaSubkeyR(25),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(26),CamelliaSubkeyR(26),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(27),CamelliaSubkeyR(27),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(28),CamelliaSubkeyR(28),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(29),CamelliaSubkeyR(29),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(30),CamelliaSubkeyR(30),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(31),CamelliaSubkeyR(31),
+                    io[0],io[1],il,ir,t0,t1);
+
+    /* post whitening but kw4 */
+    io[2] ^= CamelliaSubkeyL(32);
+    io[3] ^= CamelliaSubkeyR(32);
+
+    t0 = io[0];
+    t1 = io[1];
+    io[0] = io[2];
+    io[1] = io[3];
+    io[2] = t0;
+    io[3] = t1;
+
+    return;
+}
+
+static void camellia_decrypt256(const u32 *subkey, u32 *io)
+{
+    u32 il,ir,t0,t1;           /* temporary valiables */
+
+    /* pre whitening but absorb kw2*/
+    io[0] ^= CamelliaSubkeyL(32);
+    io[1] ^= CamelliaSubkeyR(32);
+
+    /* main iteration */
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(31),CamelliaSubkeyR(31),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(30),CamelliaSubkeyR(30),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(29),CamelliaSubkeyR(29),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(28),CamelliaSubkeyR(28),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(27),CamelliaSubkeyR(27),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(26),CamelliaSubkeyR(26),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(25),CamelliaSubkeyR(25),
+                CamelliaSubkeyL(24),CamelliaSubkeyR(24),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+                CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+                CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+                    io[0],io[1],il,ir,t0,t1);
+
+    /* post whitening but kw4 */
+    io[2] ^= CamelliaSubkeyL(0);
+    io[3] ^= CamelliaSubkeyR(0);
+
+    t0 = io[0];
+    t1 = io[1];
+    io[0] = io[2];
+    io[1] = io[3];
+    io[2] = t0;
+    io[3] = t1;
+
+    return;
+}
+
+/***
+ *
+ * API for compatibility
+ */
+
+void Camellia_Ekeygen(const int keyBitLength,
+                     const unsigned char *rawKey,
+                     KEY_TABLE_TYPE keyTable)
+{
+    switch(keyBitLength) {
+    case 128:
+       camellia_setup128(rawKey, keyTable);
+       break;
+    case 192:
+       camellia_setup192(rawKey, keyTable);
+       break;
+    case 256:
+       camellia_setup256(rawKey, keyTable);
+       break;
+    default:
+       break;
+    }
+}
+
+
+void Camellia_EncryptBlock(const int keyBitLength,
+                          const unsigned char *plaintext,
+                          const KEY_TABLE_TYPE keyTable,
+                          unsigned char *ciphertext)
+{
+    u32 tmp[4];
+
+    tmp[0] = GETU32(plaintext);
+    tmp[1] = GETU32(plaintext + 4);
+    tmp[2] = GETU32(plaintext + 8);
+    tmp[3] = GETU32(plaintext + 12);
+
+    switch (keyBitLength) {
+    case 128:
+       camellia_encrypt128(keyTable, tmp);
+       break;
+    case 192:
+       /* fall through */
+    case 256:
+       camellia_encrypt256(keyTable, tmp);
+       break;
+    default:
+       break;
+    }
+
+    PUTU32(ciphertext, tmp[0]);
+    PUTU32(ciphertext + 4, tmp[1]);
+    PUTU32(ciphertext + 8, tmp[2]);
+    PUTU32(ciphertext + 12, tmp[3]);
+}
+
+void Camellia_DecryptBlock(const int keyBitLength,
+                          const unsigned char *ciphertext,
+                          const KEY_TABLE_TYPE keyTable,
+                          unsigned char *plaintext)
+{
+    u32 tmp[4];
+
+    tmp[0] = GETU32(ciphertext);
+    tmp[1] = GETU32(ciphertext + 4);
+    tmp[2] = GETU32(ciphertext + 8);
+    tmp[3] = GETU32(ciphertext + 12);
+
+    switch (keyBitLength) {
+    case 128:
+       camellia_decrypt128(keyTable, tmp);
+       break;
+    case 192:
+       /* fall through */
+    case 256:
+       camellia_decrypt256(keyTable, tmp);
+       break;
+    default:
+       break;
+    }
+    PUTU32(plaintext, tmp[0]);
+    PUTU32(plaintext + 4, tmp[1]);
+    PUTU32(plaintext + 8, tmp[2]);
+    PUTU32(plaintext + 12, tmp[3]);
+}
diff --git a/src/external/heimdal/hcrypto/camellia-ntt.h b/src/external/heimdal/hcrypto/camellia-ntt.h
new file mode 100644 (file)
index 0000000..31db336
--- /dev/null
@@ -0,0 +1,65 @@
+/* camellia.h ver 1.2.0
+ *
+ * Copyright (c) 2006,2007
+ * NTT (Nippon Telegraph and Telephone Corporation) . All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer as
+ *   the first lines of this file unmodified.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NTT ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL NTT BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+#ifndef HEADER_CAMELLIA_H
+#define HEADER_CAMELLIA_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#define CAMELLIA_BLOCK_SIZE 16
+#define CAMELLIA_TABLE_BYTE_LEN 272
+#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)
+
+/* u32 must be 32bit word */
+typedef uint32_t u32;
+typedef unsigned char u8;
+
+typedef u32 KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN];
+
+
+void Camellia_Ekeygen(const int keyBitLength,
+                     const unsigned char *rawKey,
+                     KEY_TABLE_TYPE keyTable);
+
+void Camellia_EncryptBlock(const int keyBitLength,
+                          const unsigned char *plaintext,
+                          const KEY_TABLE_TYPE keyTable,
+                          unsigned char *cipherText);
+
+void Camellia_DecryptBlock(const int keyBitLength,
+                          const unsigned char *cipherText,
+                          const KEY_TABLE_TYPE keyTable,
+                          unsigned char *plaintext);
+
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* HEADER_CAMELLIA_H */
diff --git a/src/external/heimdal/hcrypto/camellia.c b/src/external/heimdal/hcrypto/camellia.c
new file mode 100644 (file)
index 0000000..c88822d
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+#include "config.h"
+
+#ifdef KRB5
+#include <krb5-types.h>
+#endif
+
+#include <string.h>
+
+#include "camellia-ntt.h"
+#include "camellia.h"
+
+#include <roken.h>
+
+int
+CAMELLIA_set_key(const unsigned char *userkey,
+                const int bits, CAMELLIA_KEY *key)
+{
+    key->bits = bits;
+    Camellia_Ekeygen(bits, userkey, key->key);
+    return 1;
+}
+
+void
+CAMELLIA_encrypt(const unsigned char *in, unsigned char *out,
+                const CAMELLIA_KEY *key)
+{
+    Camellia_EncryptBlock(key->bits, in, key->key, out);
+
+}
+
+void
+CAMELLIA_decrypt(const unsigned char *in, unsigned char *out,
+                const CAMELLIA_KEY *key)
+{
+    Camellia_DecryptBlock(key->bits, in, key->key, out);
+}
+
+void
+CAMELLIA_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                    unsigned long size, const CAMELLIA_KEY *key,
+                    unsigned char *iv, int mode_encrypt)
+{
+    unsigned char tmp[CAMELLIA_BLOCK_SIZE];
+    int i;
+
+    if (mode_encrypt) {
+       while (size >= CAMELLIA_BLOCK_SIZE) {
+           for (i = 0; i < CAMELLIA_BLOCK_SIZE; i++)
+               tmp[i] = in[i] ^ iv[i];
+           CAMELLIA_encrypt(tmp, out, key);
+           memcpy(iv, out, CAMELLIA_BLOCK_SIZE);
+           size -= CAMELLIA_BLOCK_SIZE;
+           in += CAMELLIA_BLOCK_SIZE;
+           out += CAMELLIA_BLOCK_SIZE;
+       }
+       if (size) {
+           for (i = 0; i < size; i++)
+               tmp[i] = in[i] ^ iv[i];
+           for (i = size; i < CAMELLIA_BLOCK_SIZE; i++)
+               tmp[i] = iv[i];
+           CAMELLIA_encrypt(tmp, out, key);
+           memcpy(iv, out, CAMELLIA_BLOCK_SIZE);
+       }
+    } else {
+       while (size >= CAMELLIA_BLOCK_SIZE) {
+           memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
+           CAMELLIA_decrypt(tmp, out, key);
+           for (i = 0; i < CAMELLIA_BLOCK_SIZE; i++)
+               out[i] ^= iv[i];
+           memcpy(iv, tmp, CAMELLIA_BLOCK_SIZE);
+           size -= CAMELLIA_BLOCK_SIZE;
+           in += CAMELLIA_BLOCK_SIZE;
+           out += CAMELLIA_BLOCK_SIZE;
+       }
+       if (size) {
+           memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
+           CAMELLIA_decrypt(tmp, out, key);
+           for (i = 0; i < size; i++)
+               out[i] ^= iv[i];
+           memcpy(iv, tmp, CAMELLIA_BLOCK_SIZE);
+       }
+    }
+}
diff --git a/src/external/heimdal/hcrypto/camellia.h b/src/external/heimdal/hcrypto/camellia.h
new file mode 100644 (file)
index 0000000..feabae1
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+/* $Id$ */
+
+#ifndef HEIM_CAMELLIA_H
+#define HEIM_CAMELLIA_H 1
+
+/* symbol renaming */
+#define CAMELLIA_set_key hc_CAMELLIA_set_encrypt_key
+#define CAMELLIA_encrypt hc_CAMELLIA_encrypt
+#define CAMELLIA_decrypt hc_CAMELLIA_decrypt
+#define CAMELLIA_cbc_encrypt hc_CAMELLIA_cbc_encrypt
+
+/*
+ *
+ */
+
+#define CAMELLIA_BLOCK_SIZE 16
+#define CAMELLIA_TABLE_BYTE_LEN 272
+#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)
+
+#define CAMELLIA_ENCRYPT 1
+#define CAMELLIA_DECRYPT 0
+
+typedef struct camellia_key {
+    unsigned int bits;
+    uint32_t key[CAMELLIA_TABLE_WORD_LEN];
+} CAMELLIA_KEY;
+
+int CAMELLIA_set_key(const unsigned char *, const int, CAMELLIA_KEY *);
+
+void CAMELLIA_encrypt(const unsigned char *, unsigned char *,
+                     const CAMELLIA_KEY *);
+void CAMELLIA_decrypt(const unsigned char *, unsigned char *,
+                     const CAMELLIA_KEY *);
+
+void CAMELLIA_cbc_encrypt(const unsigned char *, unsigned char *,
+                         const unsigned long, const CAMELLIA_KEY *,
+                         unsigned char *, int);
+
+#endif /* HEIM_CAMELLIA_H */
diff --git a/src/external/heimdal/hcrypto/des-tables.h b/src/external/heimdal/hcrypto/des-tables.h
new file mode 100644 (file)
index 0000000..95f3711
--- /dev/null
@@ -0,0 +1,196 @@
+/* GENERATE FILE from gen-des.pl, do not edit */
+
+/* pc1_c_3 bit pattern 5 13 21 */
+static int pc1_c_3[8] = {
+    0x00000000, 0x00000010, 0x00001000, 0x00001010,
+    0x00100000, 0x00100010, 0x00101000, 0x00101010
+};
+/* pc1_c_4 bit pattern 1 9 17 25 */
+static int pc1_c_4[16] = {
+    0x00000000, 0x00000001, 0x00000100, 0x00000101,
+    0x00010000, 0x00010001, 0x00010100, 0x00010101,
+    0x01000000, 0x01000001, 0x01000100, 0x01000101,
+    0x01010000, 0x01010001, 0x01010100, 0x01010101
+};
+/* pc1_d_3 bit pattern 49 41 33 */
+static int pc1_d_3[8] = {
+    0x00000000, 0x01000000, 0x00010000, 0x01010000,
+    0x00000100, 0x01000100, 0x00010100, 0x01010100
+};
+/* pc1_d_4 bit pattern 57 53 45 37 */
+static int pc1_d_4[16] = {
+    0x00000000, 0x00100000, 0x00001000, 0x00101000,
+    0x00000010, 0x00100010, 0x00001010, 0x00101010,
+    0x00000001, 0x00100001, 0x00001001, 0x00101001,
+    0x00000011, 0x00100011, 0x00001011, 0x00101011
+};
+/* pc2_c_1 bit pattern 5 24 7 16 6 10 */
+static int pc2_c_1[64] = {
+    0x00000000, 0x00004000, 0x00040000, 0x00044000,
+    0x00000100, 0x00004100, 0x00040100, 0x00044100,
+    0x00020000, 0x00024000, 0x00060000, 0x00064000,
+    0x00020100, 0x00024100, 0x00060100, 0x00064100,
+    0x00000001, 0x00004001, 0x00040001, 0x00044001,
+    0x00000101, 0x00004101, 0x00040101, 0x00044101,
+    0x00020001, 0x00024001, 0x00060001, 0x00064001,
+    0x00020101, 0x00024101, 0x00060101, 0x00064101,
+    0x00080000, 0x00084000, 0x000c0000, 0x000c4000,
+    0x00080100, 0x00084100, 0x000c0100, 0x000c4100,
+    0x000a0000, 0x000a4000, 0x000e0000, 0x000e4000,
+    0x000a0100, 0x000a4100, 0x000e0100, 0x000e4100,
+    0x00080001, 0x00084001, 0x000c0001, 0x000c4001,
+    0x00080101, 0x00084101, 0x000c0101, 0x000c4101,
+    0x000a0001, 0x000a4001, 0x000e0001, 0x000e4001,
+    0x000a0101, 0x000a4101, 0x000e0101, 0x000e4101
+};
+/* pc2_c_2 bit pattern 20 18 12 3 15 23 */
+static int pc2_c_2[64] = {
+    0x00000000, 0x00000002, 0x00000200, 0x00000202,
+    0x00200000, 0x00200002, 0x00200200, 0x00200202,
+    0x00001000, 0x00001002, 0x00001200, 0x00001202,
+    0x00201000, 0x00201002, 0x00201200, 0x00201202,
+    0x00000040, 0x00000042, 0x00000240, 0x00000242,
+    0x00200040, 0x00200042, 0x00200240, 0x00200242,
+    0x00001040, 0x00001042, 0x00001240, 0x00001242,
+    0x00201040, 0x00201042, 0x00201240, 0x00201242,
+    0x00000010, 0x00000012, 0x00000210, 0x00000212,
+    0x00200010, 0x00200012, 0x00200210, 0x00200212,
+    0x00001010, 0x00001012, 0x00001210, 0x00001212,
+    0x00201010, 0x00201012, 0x00201210, 0x00201212,
+    0x00000050, 0x00000052, 0x00000250, 0x00000252,
+    0x00200050, 0x00200052, 0x00200250, 0x00200252,
+    0x00001050, 0x00001052, 0x00001250, 0x00001252,
+    0x00201050, 0x00201052, 0x00201250, 0x00201252
+};
+/* pc2_c_3 bit pattern 1 9 19 2 14 22 */
+static int pc2_c_3[64] = {
+    0x00000000, 0x00000004, 0x00000400, 0x00000404,
+    0x00400000, 0x00400004, 0x00400400, 0x00400404,
+    0x00000020, 0x00000024, 0x00000420, 0x00000424,
+    0x00400020, 0x00400024, 0x00400420, 0x00400424,
+    0x00008000, 0x00008004, 0x00008400, 0x00008404,
+    0x00408000, 0x00408004, 0x00408400, 0x00408404,
+    0x00008020, 0x00008024, 0x00008420, 0x00008424,
+    0x00408020, 0x00408024, 0x00408420, 0x00408424,
+    0x00800000, 0x00800004, 0x00800400, 0x00800404,
+    0x00c00000, 0x00c00004, 0x00c00400, 0x00c00404,
+    0x00800020, 0x00800024, 0x00800420, 0x00800424,
+    0x00c00020, 0x00c00024, 0x00c00420, 0x00c00424,
+    0x00808000, 0x00808004, 0x00808400, 0x00808404,
+    0x00c08000, 0x00c08004, 0x00c08400, 0x00c08404,
+    0x00808020, 0x00808024, 0x00808420, 0x00808424,
+    0x00c08020, 0x00c08024, 0x00c08420, 0x00c08424
+};
+/* pc2_c_4 bit pattern 11 13 4 17 21 8 */
+static int pc2_c_4[64] = {
+    0x00000000, 0x00010000, 0x00000008, 0x00010008,
+    0x00000080, 0x00010080, 0x00000088, 0x00010088,
+    0x00100000, 0x00110000, 0x00100008, 0x00110008,
+    0x00100080, 0x00110080, 0x00100088, 0x00110088,
+    0x00000800, 0x00010800, 0x00000808, 0x00010808,
+    0x00000880, 0x00010880, 0x00000888, 0x00010888,
+    0x00100800, 0x00110800, 0x00100808, 0x00110808,
+    0x00100880, 0x00110880, 0x00100888, 0x00110888,
+    0x00002000, 0x00012000, 0x00002008, 0x00012008,
+    0x00002080, 0x00012080, 0x00002088, 0x00012088,
+    0x00102000, 0x00112000, 0x00102008, 0x00112008,
+    0x00102080, 0x00112080, 0x00102088, 0x00112088,
+    0x00002800, 0x00012800, 0x00002808, 0x00012808,
+    0x00002880, 0x00012880, 0x00002888, 0x00012888,
+    0x00102800, 0x00112800, 0x00102808, 0x00112808,
+    0x00102880, 0x00112880, 0x00102888, 0x00112888
+};
+/* pc2_d_1 bit pattern 51 35 31 52 39 45 */
+static int pc2_d_1[64] = {
+    0x00000000, 0x00000080, 0x00002000, 0x00002080,
+    0x00000001, 0x00000081, 0x00002001, 0x00002081,
+    0x00200000, 0x00200080, 0x00202000, 0x00202080,
+    0x00200001, 0x00200081, 0x00202001, 0x00202081,
+    0x00020000, 0x00020080, 0x00022000, 0x00022080,
+    0x00020001, 0x00020081, 0x00022001, 0x00022081,
+    0x00220000, 0x00220080, 0x00222000, 0x00222080,
+    0x00220001, 0x00220081, 0x00222001, 0x00222081,
+    0x00000002, 0x00000082, 0x00002002, 0x00002082,
+    0x00000003, 0x00000083, 0x00002003, 0x00002083,
+    0x00200002, 0x00200082, 0x00202002, 0x00202082,
+    0x00200003, 0x00200083, 0x00202003, 0x00202083,
+    0x00020002, 0x00020082, 0x00022002, 0x00022082,
+    0x00020003, 0x00020083, 0x00022003, 0x00022083,
+    0x00220002, 0x00220082, 0x00222002, 0x00222082,
+    0x00220003, 0x00220083, 0x00222003, 0x00222083
+};
+/* pc2_d_2 bit pattern 50 32 43 36 29 48 */
+static int pc2_d_2[64] = {
+    0x00000000, 0x00000010, 0x00800000, 0x00800010,
+    0x00010000, 0x00010010, 0x00810000, 0x00810010,
+    0x00000200, 0x00000210, 0x00800200, 0x00800210,
+    0x00010200, 0x00010210, 0x00810200, 0x00810210,
+    0x00100000, 0x00100010, 0x00900000, 0x00900010,
+    0x00110000, 0x00110010, 0x00910000, 0x00910010,
+    0x00100200, 0x00100210, 0x00900200, 0x00900210,
+    0x00110200, 0x00110210, 0x00910200, 0x00910210,
+    0x00000004, 0x00000014, 0x00800004, 0x00800014,
+    0x00010004, 0x00010014, 0x00810004, 0x00810014,
+    0x00000204, 0x00000214, 0x00800204, 0x00800214,
+    0x00010204, 0x00010214, 0x00810204, 0x00810214,
+    0x00100004, 0x00100014, 0x00900004, 0x00900014,
+    0x00110004, 0x00110014, 0x00910004, 0x00910014,
+    0x00100204, 0x00100214, 0x00900204, 0x00900214,
+    0x00110204, 0x00110214, 0x00910204, 0x00910214
+};
+/* pc2_d_3 bit pattern 41 38 47 33 40 42 */
+static int pc2_d_3[64] = {
+    0x00000000, 0x00000400, 0x00001000, 0x00001400,
+    0x00080000, 0x00080400, 0x00081000, 0x00081400,
+    0x00000020, 0x00000420, 0x00001020, 0x00001420,
+    0x00080020, 0x00080420, 0x00081020, 0x00081420,
+    0x00004000, 0x00004400, 0x00005000, 0x00005400,
+    0x00084000, 0x00084400, 0x00085000, 0x00085400,
+    0x00004020, 0x00004420, 0x00005020, 0x00005420,
+    0x00084020, 0x00084420, 0x00085020, 0x00085420,
+    0x00000800, 0x00000c00, 0x00001800, 0x00001c00,
+    0x00080800, 0x00080c00, 0x00081800, 0x00081c00,
+    0x00000820, 0x00000c20, 0x00001820, 0x00001c20,
+    0x00080820, 0x00080c20, 0x00081820, 0x00081c20,
+    0x00004800, 0x00004c00, 0x00005800, 0x00005c00,
+    0x00084800, 0x00084c00, 0x00085800, 0x00085c00,
+    0x00004820, 0x00004c20, 0x00005820, 0x00005c20,
+    0x00084820, 0x00084c20, 0x00085820, 0x00085c20
+};
+/* pc2_d_4 bit pattern 49 37 30 46 34 44 */
+static int pc2_d_4[64] = {
+    0x00000000, 0x00000100, 0x00040000, 0x00040100,
+    0x00000040, 0x00000140, 0x00040040, 0x00040140,
+    0x00400000, 0x00400100, 0x00440000, 0x00440100,
+    0x00400040, 0x00400140, 0x00440040, 0x00440140,
+    0x00008000, 0x00008100, 0x00048000, 0x00048100,
+    0x00008040, 0x00008140, 0x00048040, 0x00048140,
+    0x00408000, 0x00408100, 0x00448000, 0x00448100,
+    0x00408040, 0x00408140, 0x00448040, 0x00448140,
+    0x00000008, 0x00000108, 0x00040008, 0x00040108,
+    0x00000048, 0x00000148, 0x00040048, 0x00040148,
+    0x00400008, 0x00400108, 0x00440008, 0x00440108,
+    0x00400048, 0x00400148, 0x00440048, 0x00440148,
+    0x00008008, 0x00008108, 0x00048008, 0x00048108,
+    0x00008048, 0x00008148, 0x00048048, 0x00048148,
+    0x00408008, 0x00408108, 0x00448008, 0x00448108,
+    0x00408048, 0x00408148, 0x00448048, 0x00448148
+};
+static unsigned char odd_parity[256] = {
+  1,  1,  2,  2,  4,  4,  7,  7,  8,  8, 11, 11, 13, 13, 14, 14,
+ 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
+ 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
+ 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
+ 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
+ 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
+ 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
+112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
+128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
+145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
+161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
+176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
+193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
+208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
+224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
+241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254,
+ };
diff --git a/src/external/heimdal/hcrypto/des.c b/src/external/heimdal/hcrypto/des.c
new file mode 100644 (file)
index 0000000..2e3192b
--- /dev/null
@@ -0,0 +1,1184 @@
+/*
+ * Copyright (c) 2005 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+/**
+ * @page page_des DES - Data Encryption Standard crypto interface
+ *
+ * See the library functions here: @ref hcrypto_des
+ *
+ * DES was created by IBM, modififed by NSA and then adopted by NBS
+ * (now NIST) and published ad FIPS PUB 46 (updated by FIPS 46-1).
+ *
+ * Since the 19th May 2005 DES was withdrawn by NIST and should no
+ * longer be used. See @ref page_evp for replacement encryption
+ * algorithms and interfaces.
+ *
+ * Read more the iteresting history of DES on Wikipedia
+ * http://www.wikipedia.org/wiki/Data_Encryption_Standard .
+ *
+ * @section des_keygen DES key generation
+ *
+ * To generate a DES key safely you have to use the code-snippet
+ * below. This is because the DES_random_key() can fail with an
+ * abort() in case of and failure to start the random generator.
+ *
+ * There is a replacement function DES_new_random_key(), however that
+ * function does not exists in OpenSSL.
+ *
+ * @code
+ * DES_cblock key;
+ * do {
+ *     if (RAND_rand(&key, sizeof(key)) != 1)
+ *          goto failure;
+ *     DES_set_odd_parity(key);
+ * } while (DES_is_weak_key(&key));
+ * @endcode
+ *
+ * @section des_impl DES implementation history
+ *
+ * There was no complete BSD licensed, fast, GPL compatible
+ * implementation of DES, so Love wrote the part that was missing,
+ * fast key schedule setup and adapted the interface to the orignal
+ * libdes.
+ *
+ * The document that got me started for real was "Efficient
+ * Implementation of the Data Encryption Standard" by Dag Arne Osvik.
+ * I never got to the PC1 transformation was working, instead I used
+ * table-lookup was used for all key schedule setup. The document was
+ * very useful since it de-mystified other implementations for me.
+ *
+ * The core DES function (SBOX + P transformation) is from Richard
+ * Outerbridge public domain DES implementation. My sanity is saved
+ * thanks to his work. Thank you Richard.
+ */
+
+#include <config.h>
+
+#define HC_DEPRECATED
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <krb5-types.h>
+#include <assert.h>
+
+#include <roken.h>
+
+#include "des.h"
+#include "ui.h"
+
+static void desx(uint32_t [2], DES_key_schedule *, int);
+static void IP(uint32_t [2]);
+static void FP(uint32_t [2]);
+
+#include "des-tables.h"
+
+#define ROTATE_LEFT28(x,one)                           \
+    if (one) {                                         \
+       x = ( ((x)<<(1)) & 0xffffffe) | ((x) >> 27);    \
+    } else {                                           \
+       x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26);    \
+    }
+
+/**
+ * Set the parity of the key block, used to generate a des key from a
+ * random key. See @ref des_keygen.
+ *
+ * @param key key to fixup the parity for.
+ * @ingroup hcrypto_des
+ */
+
+void
+DES_set_odd_parity(DES_cblock *key)
+{
+    unsigned int i;
+    for (i = 0; i < DES_CBLOCK_LEN; i++)
+       (*key)[i] = odd_parity[(*key)[i]];
+}
+
+/**
+ * Check if the key have correct parity.
+ *
+ * @param key key to check the parity.
+ * @return 1 on success, 0 on failure.
+ * @ingroup hcrypto_des
+ */
+
+int HC_DEPRECATED
+DES_check_key_parity(DES_cblock *key)
+{
+    unsigned int i;
+
+    for (i = 0; i <  DES_CBLOCK_LEN; i++)
+       if ((*key)[i] != odd_parity[(*key)[i]])
+           return 0;
+    return 1;
+}
+
+/*
+ *
+ */
+
+/* FIPS 74 */
+static DES_cblock weak_keys[] = {
+    {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, /* weak keys */
+    {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
+    {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
+    {0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1},
+    {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE}, /* semi-weak keys */
+    {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
+    {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
+    {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
+    {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
+    {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
+    {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
+    {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
+    {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
+    {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
+    {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
+    {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}
+};
+
+/**
+ * Checks if the key is any of the weaks keys that makes DES attacks
+ * trival.
+ *
+ * @param key key to check.
+ *
+ * @return 1 if the key is weak, 0 otherwise.
+ * @ingroup hcrypto_des
+ */
+
+int
+DES_is_weak_key(DES_cblock *key)
+{
+    int weak = 0;
+    int i;
+
+    for (i = 0; i < sizeof(weak_keys)/sizeof(weak_keys[0]); i++)
+       weak ^= (ct_memcmp(weak_keys[i], key, DES_CBLOCK_LEN) == 0);
+
+    return !!weak;
+}
+
+/**
+ * Setup a des key schedule from a key. Deprecated function, use
+ * DES_set_key_unchecked() or DES_set_key_checked() instead.
+ *
+ * @param key a key to initialize the key schedule with.
+ * @param ks a key schedule to initialize.
+ *
+ * @return 0 on success
+ * @ingroup hcrypto_des
+ */
+
+int HC_DEPRECATED
+DES_set_key(DES_cblock *key, DES_key_schedule *ks)
+{
+    return DES_set_key_checked(key, ks);
+}
+
+/**
+ * Setup a des key schedule from a key. The key is no longer needed
+ * after this transaction and can cleared.
+ *
+ * Does NOT check that the key is weak for or have wrong parity.
+ *
+ * @param key a key to initialize the key schedule with.
+ * @param ks a key schedule to initialize.
+ *
+ * @return 0 on success
+ * @ingroup hcrypto_des
+ */
+
+int
+DES_set_key_unchecked(DES_cblock *key, DES_key_schedule *ks)
+{
+    uint32_t t1, t2;
+    uint32_t c, d;
+    int shifts[16] = { 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
+    uint32_t *k = &ks->ks[0];
+    int i;
+
+    t1 = (*key)[0] << 24 | (*key)[1] << 16 | (*key)[2] << 8 | (*key)[3];
+    t2 = (*key)[4] << 24 | (*key)[5] << 16 | (*key)[6] << 8 | (*key)[7];
+
+    c =   (pc1_c_3[(t1 >> (5            )) & 0x7] << 3)
+       | (pc1_c_3[(t1 >> (5 + 8        )) & 0x7] << 2)
+       | (pc1_c_3[(t1 >> (5 + 8 + 8    )) & 0x7] << 1)
+       | (pc1_c_3[(t1 >> (5 + 8 + 8 + 8)) & 0x7] << 0)
+       | (pc1_c_4[(t2 >> (4            )) & 0xf] << 3)
+       | (pc1_c_4[(t2 >> (4 + 8        )) & 0xf] << 2)
+       | (pc1_c_4[(t2 >> (4 + 8 + 8    )) & 0xf] << 1)
+       | (pc1_c_4[(t2 >> (4 + 8 + 8 + 8)) & 0xf] << 0);
+
+
+    d =   (pc1_d_3[(t2 >> (1            )) & 0x7] << 3)
+       | (pc1_d_3[(t2 >> (1 + 8        )) & 0x7] << 2)
+       | (pc1_d_3[(t2 >> (1 + 8 + 8    )) & 0x7] << 1)
+       | (pc1_d_3[(t2 >> (1 + 8 + 8 + 8)) & 0x7] << 0)
+       | (pc1_d_4[(t1 >> (1            )) & 0xf] << 3)
+       | (pc1_d_4[(t1 >> (1 + 8        )) & 0xf] << 2)
+       | (pc1_d_4[(t1 >> (1 + 8 + 8    )) & 0xf] << 1)
+       | (pc1_d_4[(t1 >> (1 + 8 + 8 + 8)) & 0xf] << 0);
+
+    for (i = 0; i < 16; i++) {
+       uint32_t kc, kd;
+
+       ROTATE_LEFT28(c, shifts[i]);
+       ROTATE_LEFT28(d, shifts[i]);
+
+       kc = pc2_c_1[(c >> 22) & 0x3f] |
+           pc2_c_2[((c >> 16) & 0x30) | ((c >> 15) & 0xf)] |
+           pc2_c_3[((c >> 9 ) & 0x3c) | ((c >> 8 ) & 0x3)] |
+           pc2_c_4[((c >> 2 ) & 0x20) | ((c >> 1) & 0x18) | (c & 0x7)];
+       kd = pc2_d_1[(d >> 22) & 0x3f] |
+           pc2_d_2[((d >> 15) & 0x30) | ((d >> 14) & 0xf)] |
+           pc2_d_3[ (d >> 7 ) & 0x3f] |
+           pc2_d_4[((d >> 1 ) & 0x3c) | ((d      ) & 0x3)];
+
+       /* Change to byte order used by the S boxes */
+       *k  =    (kc & 0x00fc0000L) << 6;
+       *k |=    (kc & 0x00000fc0L) << 10;
+       *k |=    (kd & 0x00fc0000L) >> 10;
+       *k++  |= (kd & 0x00000fc0L) >> 6;
+       *k  =    (kc & 0x0003f000L) << 12;
+       *k |=    (kc & 0x0000003fL) << 16;
+       *k |=    (kd & 0x0003f000L) >> 4;
+       *k++  |= (kd & 0x0000003fL);
+    }
+
+    return 0;
+}
+
+/**
+ * Just like DES_set_key_unchecked() except checking that the key is
+ * not weak for or have correct parity.
+ *
+ * @param key a key to initialize the key schedule with.
+ * @param ks a key schedule to initialize.
+ *
+ * @return 0 on success, -1 on invalid parity, -2 on weak key.
+ * @ingroup hcrypto_des
+ */
+
+int
+DES_set_key_checked(DES_cblock *key, DES_key_schedule *ks)
+{
+    if (!DES_check_key_parity(key)) {
+       memset(ks, 0, sizeof(*ks));
+       return -1;
+    }
+    if (DES_is_weak_key(key)) {
+       memset(ks, 0, sizeof(*ks));
+       return -2;
+    }
+    return DES_set_key_unchecked(key, ks);
+}
+
+/**
+ * Compatibility function for eay libdes, works just like
+ * DES_set_key_checked().
+ *
+ * @param key a key to initialize the key schedule with.
+ * @param ks a key schedule to initialize.
+ *
+ * @return 0 on success, -1 on invalid parity, -2 on weak key.
+ * @ingroup hcrypto_des
+ */
+
+int
+DES_key_sched(DES_cblock *key, DES_key_schedule *ks)
+{
+    return DES_set_key_checked(key, ks);
+}
+
+/*
+ *
+ */
+
+static void
+load(const unsigned char *b, uint32_t v[2])
+{
+    v[0] =  b[0] << 24;
+    v[0] |= b[1] << 16;
+    v[0] |= b[2] << 8;
+    v[0] |= b[3] << 0;
+    v[1] =  b[4] << 24;
+    v[1] |= b[5] << 16;
+    v[1] |= b[6] << 8;
+    v[1] |= b[7] << 0;
+}
+
+static void
+store(const uint32_t v[2], unsigned char *b)
+{
+    b[0] = (v[0] >> 24) & 0xff;
+    b[1] = (v[0] >> 16) & 0xff;
+    b[2] = (v[0] >>  8) & 0xff;
+    b[3] = (v[0] >>  0) & 0xff;
+    b[4] = (v[1] >> 24) & 0xff;
+    b[5] = (v[1] >> 16) & 0xff;
+    b[6] = (v[1] >>  8) & 0xff;
+    b[7] = (v[1] >>  0) & 0xff;
+}
+
+/**
+ * Encrypt/decrypt a block using DES. Also called ECB mode
+ *
+ * @param u data to encrypt
+ * @param ks key schedule to use
+ * @param encp if non zero, encrypt. if zero, decrypt.
+ *
+ * @ingroup hcrypto_des
+ */
+
+void
+DES_encrypt(uint32_t u[2], DES_key_schedule *ks, int encp)
+{
+    IP(u);
+    desx(u, ks, encp);
+    FP(u);
+}
+
+/**
+ * Encrypt/decrypt a block using DES.
+ *
+ * @param input data to encrypt
+ * @param output data to encrypt
+ * @param ks key schedule to use
+ * @param encp if non zero, encrypt. if zero, decrypt.
+ *
+ * @ingroup hcrypto_des
+ */
+
+void
+DES_ecb_encrypt(DES_cblock *input, DES_cblock *output,
+               DES_key_schedule *ks, int encp)
+{
+    uint32_t u[2];
+    load(*input, u);
+    DES_encrypt(u, ks, encp);
+    store(u, *output);
+}
+
+/**
+ * Encrypt/decrypt a block using DES in Chain Block Cipher mode (cbc).
+ *
+ * The IV must always be diffrent for diffrent input data blocks.
+ *
+ * @param in data to encrypt
+ * @param out data to encrypt
+ * @param length length of data
+ * @param ks key schedule to use
+ * @param iv initial vector to use
+ * @param encp if non zero, encrypt. if zero, decrypt.
+ *
+ * @ingroup hcrypto_des
+ */
+
+void
+DES_cbc_encrypt(const void *in, void *out, long length,
+               DES_key_schedule *ks, DES_cblock *iv, int encp)
+{
+    const unsigned char *input = in;
+    unsigned char *output = out;
+    uint32_t u[2];
+    uint32_t uiv[2];
+
+    load(*iv, uiv);
+
+    if (encp) {
+       while (length >= DES_CBLOCK_LEN) {
+           load(input, u);
+           u[0] ^= uiv[0]; u[1] ^= uiv[1];
+           DES_encrypt(u, ks, 1);
+           uiv[0] = u[0]; uiv[1] = u[1];
+           store(u, output);
+
+           length -= DES_CBLOCK_LEN;
+           input += DES_CBLOCK_LEN;
+           output += DES_CBLOCK_LEN;
+       }
+       if (length) {
+           unsigned char tmp[DES_CBLOCK_LEN];
+           memcpy(tmp, input, length);
+           memset(tmp + length, 0, DES_CBLOCK_LEN - length);
+           load(tmp, u);
+           u[0] ^= uiv[0]; u[1] ^= uiv[1];
+           DES_encrypt(u, ks, 1);
+           store(u, output);
+       }
+    } else {
+       uint32_t t[2];
+       while (length >= DES_CBLOCK_LEN) {
+           load(input, u);
+           t[0] = u[0]; t[1] = u[1];
+           DES_encrypt(u, ks, 0);
+           u[0] ^= uiv[0]; u[1] ^= uiv[1];
+           store(u, output);
+           uiv[0] = t[0]; uiv[1] = t[1];
+
+           length -= DES_CBLOCK_LEN;
+           input += DES_CBLOCK_LEN;
+           output += DES_CBLOCK_LEN;
+       }
+       if (length) {
+           unsigned char tmp[DES_CBLOCK_LEN];
+           memcpy(tmp, input, length);
+           memset(tmp + length, 0, DES_CBLOCK_LEN - length);
+           load(tmp, u);
+           DES_encrypt(u, ks, 0);
+           u[0] ^= uiv[0]; u[1] ^= uiv[1];
+           store(u, output);
+       }
+    }
+    uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
+}
+
+/**
+ * Encrypt/decrypt a block using DES in Propagating Cipher Block
+ * Chaining mode. This mode is only used for Kerberos 4, and it should
+ * stay that way.
+ *
+ * The IV must always be diffrent for diffrent input data blocks.
+ *
+ * @param in data to encrypt
+ * @param out data to encrypt
+ * @param length length of data
+ * @param ks key schedule to use
+ * @param iv initial vector to use
+ * @param encp if non zero, encrypt. if zero, decrypt.
+ *
+ * @ingroup hcrypto_des
+ */
+
+void
+DES_pcbc_encrypt(const void *in, void *out, long length,
+                DES_key_schedule *ks, DES_cblock *iv, int encp)
+{
+    const unsigned char *input = in;
+    unsigned char *output = out;
+    uint32_t u[2];
+    uint32_t uiv[2];
+
+    load(*iv, uiv);
+
+    if (encp) {
+       uint32_t t[2];
+       while (length >= DES_CBLOCK_LEN) {
+           load(input, u);
+           t[0] = u[0]; t[1] = u[1];
+           u[0] ^= uiv[0]; u[1] ^= uiv[1];
+           DES_encrypt(u, ks, 1);
+           uiv[0] = u[0] ^ t[0]; uiv[1] = u[1] ^ t[1];
+           store(u, output);
+
+           length -= DES_CBLOCK_LEN;
+           input += DES_CBLOCK_LEN;
+           output += DES_CBLOCK_LEN;
+       }
+       if (length) {
+           unsigned char tmp[DES_CBLOCK_LEN];
+           memcpy(tmp, input, length);
+           memset(tmp + length, 0, DES_CBLOCK_LEN - length);
+           load(tmp, u);
+           u[0] ^= uiv[0]; u[1] ^= uiv[1];
+           DES_encrypt(u, ks, 1);
+           store(u, output);
+       }
+    } else {
+       uint32_t t[2];
+       while (length >= DES_CBLOCK_LEN) {
+           load(input, u);
+           t[0] = u[0]; t[1] = u[1];
+           DES_encrypt(u, ks, 0);
+           u[0] ^= uiv[0]; u[1] ^= uiv[1];
+           store(u, output);
+           uiv[0] = t[0] ^ u[0]; uiv[1] = t[1] ^ u[1];
+
+           length -= DES_CBLOCK_LEN;
+           input += DES_CBLOCK_LEN;
+           output += DES_CBLOCK_LEN;
+       }
+       if (length) {
+           unsigned char tmp[DES_CBLOCK_LEN];
+           memcpy(tmp, input, length);
+           memset(tmp + length, 0, DES_CBLOCK_LEN - length);
+           load(tmp, u);
+           DES_encrypt(u, ks, 0);
+           u[0] ^= uiv[0]; u[1] ^= uiv[1];
+       }
+    }
+    uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
+}
+
+/*
+ *
+ */
+
+static void
+_des3_encrypt(uint32_t u[2], DES_key_schedule *ks1, DES_key_schedule *ks2,
+             DES_key_schedule *ks3, int encp)
+{
+    IP(u);
+    if (encp) {
+       desx(u, ks1, 1); /* IP + FP cancel out each other */
+       desx(u, ks2, 0);
+       desx(u, ks3, 1);
+    } else {
+       desx(u, ks3, 0);
+       desx(u, ks2, 1);
+       desx(u, ks1, 0);
+    }
+    FP(u);
+}
+
+/**
+ * Encrypt/decrypt a block using triple DES using EDE mode,
+ * encrypt/decrypt/encrypt.
+ *
+ * @param input data to encrypt
+ * @param output data to encrypt
+ * @param ks1 key schedule to use
+ * @param ks2 key schedule to use
+ * @param ks3 key schedule to use
+ * @param encp if non zero, encrypt. if zero, decrypt.
+ *
+ * @ingroup hcrypto_des
+ */
+
+void
+DES_ecb3_encrypt(DES_cblock *input,
+                DES_cblock *output,
+                DES_key_schedule *ks1,
+                DES_key_schedule *ks2,
+                DES_key_schedule *ks3,
+                int encp)
+{
+    uint32_t u[2];
+    load(*input, u);
+    _des3_encrypt(u, ks1, ks2, ks3, encp);
+    store(u, *output);
+    return;
+}
+
+/**
+ * Encrypt/decrypt using Triple DES in Chain Block Cipher mode (cbc).
+ *
+ * The IV must always be diffrent for diffrent input data blocks.
+ *
+ * @param in data to encrypt
+ * @param out data to encrypt
+ * @param length length of data
+ * @param ks1 key schedule to use
+ * @param ks2 key schedule to use
+ * @param ks3 key schedule to use
+ * @param iv initial vector to use
+ * @param encp if non zero, encrypt. if zero, decrypt.
+ *
+ * @ingroup hcrypto_des
+ */
+
+void
+DES_ede3_cbc_encrypt(const void *in, void *out,
+                    long length, DES_key_schedule *ks1,
+                    DES_key_schedule *ks2, DES_key_schedule *ks3,
+                    DES_cblock *iv, int encp)
+{
+    const unsigned char *input = in;
+    unsigned char *output = out;
+    uint32_t u[2];
+    uint32_t uiv[2];
+
+    load(*iv, uiv);
+
+    if (encp) {
+       while (length >= DES_CBLOCK_LEN) {
+           load(input, u);
+           u[0] ^= uiv[0]; u[1] ^= uiv[1];
+           _des3_encrypt(u, ks1, ks2, ks3, 1);
+           uiv[0] = u[0]; uiv[1] = u[1];
+           store(u, output);
+
+           length -= DES_CBLOCK_LEN;
+           input += DES_CBLOCK_LEN;
+           output += DES_CBLOCK_LEN;
+       }
+       if (length) {
+           unsigned char tmp[DES_CBLOCK_LEN];
+           memcpy(tmp, input, length);
+           memset(tmp + length, 0, DES_CBLOCK_LEN - length);
+           load(tmp, u);
+           u[0] ^= uiv[0]; u[1] ^= uiv[1];
+           _des3_encrypt(u, ks1, ks2, ks3, 1);
+           store(u, output);
+       }
+    } else {
+       uint32_t t[2];
+       while (length >= DES_CBLOCK_LEN) {
+           load(input, u);
+           t[0] = u[0]; t[1] = u[1];
+           _des3_encrypt(u, ks1, ks2, ks3, 0);
+           u[0] ^= uiv[0]; u[1] ^= uiv[1];
+           store(u, output);
+           uiv[0] = t[0]; uiv[1] = t[1];
+
+           length -= DES_CBLOCK_LEN;
+           input += DES_CBLOCK_LEN;
+           output += DES_CBLOCK_LEN;
+       }
+       if (length) {
+           unsigned char tmp[DES_CBLOCK_LEN];
+           memcpy(tmp, input, length);
+           memset(tmp + length, 0, DES_CBLOCK_LEN - length);
+           load(tmp, u);
+           _des3_encrypt(u, ks1, ks2, ks3, 0);
+           u[0] ^= uiv[0]; u[1] ^= uiv[1];
+           store(u, output);
+       }
+    }
+    store(uiv, *iv);
+    uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
+}
+
+/**
+ * Encrypt/decrypt using DES in cipher feedback mode with 64 bit
+ * feedback.
+ *
+ * The IV must always be diffrent for diffrent input data blocks.
+ *
+ * @param in data to encrypt
+ * @param out data to encrypt
+ * @param length length of data
+ * @param ks key schedule to use
+ * @param iv initial vector to use
+ * @param num offset into in cipher block encryption/decryption stop last time.
+ * @param encp if non zero, encrypt. if zero, decrypt.
+ *
+ * @ingroup hcrypto_des
+ */
+
+void
+DES_cfb64_encrypt(const void *in, void *out,
+                 long length, DES_key_schedule *ks, DES_cblock *iv,
+                 int *num, int encp)
+{
+    const unsigned char *input = in;
+    unsigned char *output = out;
+    unsigned char tmp[DES_CBLOCK_LEN];
+    uint32_t uiv[2];
+
+    load(*iv, uiv);
+
+    assert(*num >= 0 && *num < DES_CBLOCK_LEN);
+
+    if (encp) {
+       int i = *num;
+
+       while (length > 0) {
+           if (i == 0)
+               DES_encrypt(uiv, ks, 1);
+           store(uiv, tmp);
+           for (; i < DES_CBLOCK_LEN && i < length; i++) {
+               output[i] = tmp[i] ^ input[i];
+           }
+           if (i == DES_CBLOCK_LEN)
+               load(output, uiv);
+           output += i;
+           input += i;
+           length -= i;
+           if (i == DES_CBLOCK_LEN)
+               i = 0;
+       }
+       store(uiv, *iv);
+       *num = i;
+    } else {
+       int i = *num;
+       unsigned char c;
+
+       while (length > 0) {
+           if (i == 0) {
+               DES_encrypt(uiv, ks, 1);
+               store(uiv, tmp);
+           }
+           for (; i < DES_CBLOCK_LEN && i < length; i++) {
+               c = input[i];
+               output[i] = tmp[i] ^ input[i];
+               (*iv)[i] = c;
+           }
+           output += i;
+           input += i;
+           length -= i;
+           if (i == DES_CBLOCK_LEN) {
+               i = 0;
+               load(*iv, uiv);
+           }
+       }
+       store(uiv, *iv);
+       *num = i;
+    }
+}
+
+/**
+ * Crete a checksum using DES in CBC encryption mode. This mode is
+ * only used for Kerberos 4, and it should stay that way.
+ *
+ * The IV must always be diffrent for diffrent input data blocks.
+ *
+ * @param in data to checksum
+ * @param output the checksum
+ * @param length length of data
+ * @param ks key schedule to use
+ * @param iv initial vector to use
+ *
+ * @ingroup hcrypto_des
+ */
+
+uint32_t
+DES_cbc_cksum(const void *in, DES_cblock *output,
+             long length, DES_key_schedule *ks, DES_cblock *iv)
+{
+    const unsigned char *input = in;
+    uint32_t uiv[2];
+    uint32_t u[2] = { 0, 0 };
+
+    load(*iv, uiv);
+
+    while (length >= DES_CBLOCK_LEN) {
+       load(input, u);
+       u[0] ^= uiv[0]; u[1] ^= uiv[1];
+       DES_encrypt(u, ks, 1);
+       uiv[0] = u[0]; uiv[1] = u[1];
+
+       length -= DES_CBLOCK_LEN;
+       input += DES_CBLOCK_LEN;
+    }
+    if (length) {
+       unsigned char tmp[DES_CBLOCK_LEN];
+       memcpy(tmp, input, length);
+       memset(tmp + length, 0, DES_CBLOCK_LEN - length);
+       load(tmp, u);
+       u[0] ^= uiv[0]; u[1] ^= uiv[1];
+       DES_encrypt(u, ks, 1);
+    }
+    if (output)
+       store(u, *output);
+
+    uiv[0] = 0; u[0] = 0; uiv[1] = 0;
+    return u[1];
+}
+
+/*
+ *
+ */
+
+static unsigned char
+bitswap8(unsigned char b)
+{
+    unsigned char r = 0;
+    int i;
+    for (i = 0; i < 8; i++) {
+       r = r << 1 | (b & 1);
+       b = b >> 1;
+    }
+    return r;
+}
+
+/**
+ * Convert a string to a DES key. Use something like
+ * PKCS5_PBKDF2_HMAC_SHA1() to create key from passwords.
+ *
+ * @param str The string to convert to a key
+ * @param key the resulting key
+ *
+ * @ingroup hcrypto_des
+ */
+
+void
+DES_string_to_key(const char *str, DES_cblock *key)
+{
+    const unsigned char *s;
+    unsigned char *k;
+    DES_key_schedule ks;
+    size_t i, len;
+
+    memset(key, 0, sizeof(*key));
+    k = *key;
+    s = (const unsigned char *)str;
+
+    len = strlen(str);
+    for (i = 0; i < len; i++) {
+       if ((i % 16) < 8)
+           k[i % 8] ^= s[i] << 1;
+       else
+           k[7 - (i % 8)] ^= bitswap8(s[i]);
+    }
+    DES_set_odd_parity(key);
+    if (DES_is_weak_key(key))
+       k[7] ^= 0xF0;
+    DES_set_key(key, &ks);
+    DES_cbc_cksum(s, key, len, &ks, key);
+    memset(&ks, 0, sizeof(ks));
+    DES_set_odd_parity(key);
+    if (DES_is_weak_key(key))
+       k[7] ^= 0xF0;
+}
+
+/**
+ * Read password from prompt and create a DES key. Internal uses
+ * DES_string_to_key(). Really, go use a really string2key function
+ * like PKCS5_PBKDF2_HMAC_SHA1().
+ *
+ * @param key key to convert to
+ * @param prompt prompt to display user
+ * @param verify prompt twice.
+ *
+ * @return 1 on success, non 1 on failure.
+ */
+
+int
+DES_read_password(DES_cblock *key, char *prompt, int verify)
+{
+    char buf[512];
+    int ret;
+
+    ret = UI_UTIL_read_pw_string(buf, sizeof(buf) - 1, prompt, verify);
+    if (ret == 1)
+       DES_string_to_key(buf, key);
+    return ret;
+}
+
+/*
+ *
+ */
+
+
+void
+_DES_ipfp_test(void)
+{
+    DES_cblock k = "\x01\x02\x04\x08\x10\x20\x40\x80", k2;
+    uint32_t u[2] = { 1, 0 };
+    IP(u);
+    FP(u);
+    IP(u);
+    FP(u);
+    if (u[0] != 1 || u[1] != 0)
+       abort();
+
+    load(k, u);
+    store(u, k2);
+    if (memcmp(k, k2, 8) != 0)
+       abort();
+}
+
+/* D3DES (V5.09) -
+ *
+ * A portable, public domain, version of the Data Encryption Standard.
+ *
+ * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
+ * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
+ * code;  Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
+ * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
+ * for humouring me on.
+ *
+ * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
+ * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
+ */
+
+static uint32_t SP1[64] = {
+    0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
+    0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
+    0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
+    0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
+    0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
+    0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
+    0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
+    0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
+    0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
+    0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
+    0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
+    0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
+    0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
+    0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
+    0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
+    0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L };
+
+static uint32_t SP2[64] = {
+    0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
+    0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
+    0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
+    0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
+    0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
+    0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
+    0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
+    0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
+    0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
+    0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
+    0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
+    0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
+    0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
+    0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
+    0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
+    0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L };
+
+static uint32_t SP3[64] = {
+    0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
+    0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
+    0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
+    0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
+    0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
+    0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
+    0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
+    0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
+    0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
+    0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
+    0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
+    0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
+    0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
+    0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
+    0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
+    0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L };
+
+static uint32_t SP4[64] = {
+    0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
+    0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
+    0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
+    0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
+    0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
+    0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
+    0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
+    0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
+    0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
+    0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
+    0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
+    0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
+    0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
+    0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
+    0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
+    0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L };
+
+static uint32_t SP5[64] = {
+    0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
+    0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
+    0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
+    0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
+    0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
+    0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
+    0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
+    0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
+    0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
+    0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
+    0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
+    0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
+    0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
+    0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
+    0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
+    0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L };
+
+static uint32_t SP6[64] = {
+    0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
+    0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
+    0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
+    0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
+    0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
+    0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
+    0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
+    0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
+    0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
+    0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
+    0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
+    0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
+    0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
+    0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
+    0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
+    0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L };
+
+static uint32_t SP7[64] = {
+    0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
+    0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
+    0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
+    0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
+    0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
+    0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
+    0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
+    0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
+    0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
+    0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
+    0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
+    0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
+    0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
+    0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
+    0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
+    0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };
+
+static uint32_t SP8[64] = {
+    0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
+    0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
+    0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
+    0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
+    0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
+    0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
+    0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
+    0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
+    0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
+    0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
+    0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
+    0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
+    0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
+    0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
+    0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
+    0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };
+
+static void
+IP(uint32_t v[2])
+{
+    uint32_t work;
+
+    work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
+    v[1] ^= work;
+    v[0] ^= (work << 4);
+    work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
+    v[1] ^= work;
+    v[0] ^= (work << 16);
+    work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
+    v[0] ^= work;
+    v[1] ^= (work << 2);
+    work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
+    v[0] ^= work;
+    v[1] ^= (work << 8);
+    v[1] = ((v[1] << 1) | ((v[1] >> 31) & 1L)) & 0xffffffffL;
+    work = (v[0] ^ v[1]) & 0xaaaaaaaaL;
+    v[0] ^= work;
+    v[1] ^= work;
+    v[0] = ((v[0] << 1) | ((v[0] >> 31) & 1L)) & 0xffffffffL;
+}
+
+static void
+FP(uint32_t v[2])
+{
+    uint32_t work;
+
+    v[0] = (v[0] << 31) | (v[0] >> 1);
+    work = (v[1] ^ v[0]) & 0xaaaaaaaaL;
+    v[1] ^= work;
+    v[0] ^= work;
+    v[1] = (v[1] << 31) | (v[1] >> 1);
+    work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
+    v[0] ^= work;
+    v[1] ^= (work << 8);
+    work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
+    v[0] ^= work;
+    v[1] ^= (work << 2);
+    work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
+    v[1] ^= work;
+    v[0] ^= (work << 16);
+    work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
+    v[1] ^= work;
+    v[0] ^= (work << 4);
+}
+
+static void
+desx(uint32_t block[2], DES_key_schedule *ks, int encp)
+{
+    uint32_t *keys;
+    uint32_t fval, work, right, left;
+    int round;
+
+    left = block[0];
+    right = block[1];
+
+    if (encp) {
+       keys = &ks->ks[0];
+
+       for( round = 0; round < 8; round++ ) {
+           work  = (right << 28) | (right >> 4);
+           work ^= *keys++;
+           fval  = SP7[ work     & 0x3fL];
+           fval |= SP5[(work >>  8) & 0x3fL];
+           fval |= SP3[(work >> 16) & 0x3fL];
+           fval |= SP1[(work >> 24) & 0x3fL];
+           work  = right ^ *keys++;
+           fval |= SP8[ work     & 0x3fL];
+           fval |= SP6[(work >>  8) & 0x3fL];
+           fval |= SP4[(work >> 16) & 0x3fL];
+           fval |= SP2[(work >> 24) & 0x3fL];
+           left ^= fval;
+           work  = (left << 28) | (left >> 4);
+           work ^= *keys++;
+           fval  = SP7[ work     & 0x3fL];
+           fval |= SP5[(work >>  8) & 0x3fL];
+           fval |= SP3[(work >> 16) & 0x3fL];
+           fval |= SP1[(work >> 24) & 0x3fL];
+           work  = left ^ *keys++;
+           fval |= SP8[ work     & 0x3fL];
+           fval |= SP6[(work >>  8) & 0x3fL];
+           fval |= SP4[(work >> 16) & 0x3fL];
+           fval |= SP2[(work >> 24) & 0x3fL];
+           right ^= fval;
+       }
+    } else {
+       keys = &ks->ks[30];
+
+       for( round = 0; round < 8; round++ ) {
+           work  = (right << 28) | (right >> 4);
+           work ^= *keys++;
+           fval  = SP7[ work     & 0x3fL];
+           fval |= SP5[(work >>  8) & 0x3fL];
+           fval |= SP3[(work >> 16) & 0x3fL];
+           fval |= SP1[(work >> 24) & 0x3fL];
+           work  = right ^ *keys++;
+           fval |= SP8[ work     & 0x3fL];
+           fval |= SP6[(work >>  8) & 0x3fL];
+           fval |= SP4[(work >> 16) & 0x3fL];
+           fval |= SP2[(work >> 24) & 0x3fL];
+           left ^= fval;
+           work  = (left << 28) | (left >> 4);
+           keys -= 4;
+           work ^= *keys++;
+           fval  = SP7[ work     & 0x3fL];
+           fval |= SP5[(work >>  8) & 0x3fL];
+           fval |= SP3[(work >> 16) & 0x3fL];
+           fval |= SP1[(work >> 24) & 0x3fL];
+           work  = left ^ *keys++;
+           fval |= SP8[ work     & 0x3fL];
+           fval |= SP6[(work >>  8) & 0x3fL];
+           fval |= SP4[(work >> 16) & 0x3fL];
+           fval |= SP2[(work >> 24) & 0x3fL];
+           right ^= fval;
+           keys -= 4;
+       }
+    }
+    block[0] = right;
+    block[1] = left;
+}
diff --git a/src/external/heimdal/hcrypto/des.h b/src/external/heimdal/hcrypto/des.h
new file mode 100644 (file)
index 0000000..0824408
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2005 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+/* $Id$ */
+
+#ifndef _DESperate_H
+#define _DESperate_H 1
+
+/* symbol renaming */
+#define        _DES_ipfp_test _hc_DES_ipfp_test
+#define DES_cbc_cksum hc_DES_cbc_cksum
+#define DES_cbc_encrypt hc_DES_cbc_encrypt
+#define DES_cfb64_encrypt hc_DES_cfb64_encrypt
+#define DES_check_key_parity hc_DES_check_key_parity
+#define DES_ecb3_encrypt hc_DES_ecb3_encrypt
+#define DES_ecb_encrypt hc_DES_ecb_encrypt
+#define DES_ede3_cbc_encrypt hc_DES_ede3_cbc_encrypt
+#define DES_encrypt hc_DES_encrypt
+#define DES_generate_random_block hc_DES_generate_random_block
+#define DES_init_random_number_generator hc_DES_init_random_number_generator
+#define DES_is_weak_key hc_DES_is_weak_key
+#define DES_key_sched hc_DES_key_sched
+#define DES_new_random_key hc_DES_new_random_key
+#define DES_pcbc_encrypt hc_DES_pcbc_encrypt
+#define DES_rand_data hc_DES_rand_data
+#define DES_random_key hc_DES_random_key
+#define DES_read_password hc_DES_read_password
+#define DES_set_key hc_DES_set_key
+#define DES_set_key_checked hc_DES_set_key_checked
+#define DES_set_key_unchecked hc_DES_set_key_unchecked
+#define DES_set_key_sched hc_DES_set_key_sched
+#define DES_set_odd_parity hc_DES_set_odd_parity
+#define DES_set_random_generator_seed hc_DES_set_random_generator_seed
+#define DES_set_sequence_number hc_DES_set_sequence_number
+#define DES_string_to_key hc_DES_string_to_key
+
+/*
+ *
+ */
+
+#define DES_CBLOCK_LEN 8
+#define DES_KEY_SZ 8
+
+#define DES_ENCRYPT 1
+#define DES_DECRYPT 0
+
+typedef unsigned char DES_cblock[DES_CBLOCK_LEN];
+typedef struct DES_key_schedule
+{
+       uint32_t ks[32];
+} DES_key_schedule;
+
+/*
+ *
+ */
+
+#ifndef HC_DEPRECATED
+#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1 )))
+#define HC_DEPRECATED __attribute__((deprecated))
+#elif defined(_MSC_VER) && (_MSC_VER>1200)
+#define HC_DEPRECATED __declspec(deprecated)
+#else
+#define HC_DEPRECATED
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void   DES_set_odd_parity(DES_cblock *);
+int    DES_check_key_parity(DES_cblock *);
+int    DES_is_weak_key(DES_cblock *);
+int    HC_DEPRECATED DES_set_key(DES_cblock *, DES_key_schedule *);
+int    DES_set_key_checked(DES_cblock *, DES_key_schedule *);
+int    DES_set_key_unchecked(DES_cblock *, DES_key_schedule *);
+int    DES_key_sched(DES_cblock *, DES_key_schedule *);
+void   DES_string_to_key(const char *, DES_cblock *);
+int    DES_read_password(DES_cblock *, char *, int);
+
+void   HC_DEPRECATED DES_rand_data(void *, int);
+void   HC_DEPRECATED DES_set_random_generator_seed(DES_cblock *);
+void   HC_DEPRECATED DES_generate_random_block(DES_cblock *);
+void   HC_DEPRECATED DES_set_sequence_number(void *);
+void   HC_DEPRECATED DES_init_random_number_generator(DES_cblock *);
+void   HC_DEPRECATED DES_random_key(DES_cblock *);
+int    HC_DEPRECATED DES_new_random_key(DES_cblock *);
+
+
+void   DES_encrypt(uint32_t [2], DES_key_schedule *, int);
+void   DES_ecb_encrypt(DES_cblock *, DES_cblock *, DES_key_schedule *, int);
+void   DES_ecb3_encrypt(DES_cblock *,DES_cblock *, DES_key_schedule *,
+                        DES_key_schedule *, DES_key_schedule *, int);
+void   DES_pcbc_encrypt(const void *, void *, long,
+                        DES_key_schedule *, DES_cblock *, int);
+void   DES_cbc_encrypt(const void *, void *, long,
+                       DES_key_schedule *, DES_cblock *, int);
+void   DES_ede3_cbc_encrypt(const void *, void *, long,
+                            DES_key_schedule *, DES_key_schedule *,
+                            DES_key_schedule *, DES_cblock *, int);
+void   DES_cfb64_encrypt(const void *, void *, long,
+                         DES_key_schedule *, DES_cblock *, int *, int);
+
+
+uint32_t DES_cbc_cksum(const void *, DES_cblock *,
+                     long, DES_key_schedule *, DES_cblock *);
+
+
+void   _DES_ipfp_test(void);
+
+#ifdef  __cplusplus
+}
+#endif
+
+
+#endif /* _DESperate_H */
diff --git a/src/external/heimdal/hcrypto/evp-cc.c b/src/external/heimdal/hcrypto/evp-cc.c
new file mode 100644 (file)
index 0000000..9bc84f3
--- /dev/null
@@ -0,0 +1,794 @@
+/*
+ * Copyright (c) 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+/* CommonCrypto provider */
+
+#ifdef __APPLE__
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
+#include <CommonCrypto/CommonDigest.h>
+#endif
+#include <CommonCrypto/CommonCryptor.h>
+
+#include <evp.h>
+#include <evp-cc.h>
+
+/*
+ *
+ */
+
+struct cc_key {
+    CCCryptorRef href;
+};
+
+static int
+cc_do_cipher(EVP_CIPHER_CTX *ctx,
+            unsigned char *out,
+            const unsigned char *in,
+            unsigned int size)
+{
+    struct cc_key *cc = ctx->cipher_data;
+    CCCryptorStatus ret;
+    size_t moved;
+
+    memcpy(out, in, size);
+
+    ret = CCCryptorUpdate(cc->href, in, size, out, size, &moved);
+    if (ret)
+       return 0;
+
+    if (moved != size)
+       return 0;
+
+    return 1;
+}
+
+static int
+cc_do_cfb8_cipher(EVP_CIPHER_CTX *ctx,
+                  unsigned char *out,
+                  const unsigned char *in,
+                  unsigned int size)
+{
+    struct cc_key *cc = ctx->cipher_data;
+    CCCryptorStatus ret;
+    size_t moved;
+    unsigned int i;
+
+    for (i = 0; i < size; i++) {
+        unsigned char oiv[EVP_MAX_IV_LENGTH + 1];
+
+        assert(ctx->cipher->iv_len + 1 <= sizeof(oiv));
+        memcpy(oiv, ctx->iv, ctx->cipher->iv_len);
+
+        ret = CCCryptorUpdate(cc->href, ctx->iv, ctx->cipher->iv_len,
+                              ctx->iv, ctx->cipher->iv_len, &moved);
+        if (ret)
+            return 0;
+
+        if (moved != ctx->cipher->iv_len)
+            return 0;
+
+        if (!ctx->encrypt)
+            oiv[ctx->cipher->iv_len] = in[i];
+        out[i] = in[i] ^ ctx->iv[0];
+        if (ctx->encrypt)
+            oiv[ctx->cipher->iv_len] = out[i];
+
+        memcpy(ctx->iv, &oiv[1], ctx->cipher->iv_len);
+    }
+
+     return 1;
+ }
+
+
+static int
+cc_cleanup(EVP_CIPHER_CTX *ctx)
+{
+    struct cc_key *cc = ctx->cipher_data;
+    if (cc->href)
+       CCCryptorRelease(cc->href);
+    return 1;
+}
+
+static int
+init_cc_key(int encp, CCAlgorithm alg, CCOptions opts, const void *key,
+           size_t keylen, const void *iv, CCCryptorRef *ref)
+{
+    CCOperation op = encp ? kCCEncrypt : kCCDecrypt;
+    CCCryptorStatus ret;
+
+    if (*ref) {
+       if (key == NULL && iv) {
+           CCCryptorReset(*ref, iv);
+           return 1;
+       }
+       CCCryptorRelease(*ref);
+    }
+
+    ret = CCCryptorCreate(op, alg, opts, key, keylen, iv, ref);
+    if (ret)
+       return 0;
+    return 1;
+}
+
+static int
+cc_des_ede3_cbc_init(EVP_CIPHER_CTX *ctx,
+                    const unsigned char * key,
+                    const unsigned char * iv,
+                    int encp)
+{
+    struct cc_key *cc = ctx->cipher_data;
+    return init_cc_key(encp, kCCAlgorithm3DES, 0, key, kCCKeySize3DES, iv, &cc->href);
+}
+
+/**
+ * The tripple DES cipher type (Apple CommonCrypto provider)
+ *
+ * @return the DES-EDE3-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_des_ede3_cbc(void)
+{
+    static const EVP_CIPHER des_ede3_cbc = {
+       0,
+       8,
+       24,
+       8,
+       EVP_CIPH_CBC_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
+       cc_des_ede3_cbc_init,
+       cc_do_cipher,
+       cc_cleanup,
+       sizeof(struct cc_key),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &des_ede3_cbc;
+}
+
+/*
+ *
+ */
+
+static int
+cc_des_cbc_init(EVP_CIPHER_CTX *ctx,
+               const unsigned char * key,
+               const unsigned char * iv,
+               int encp)
+{
+    struct cc_key *cc = ctx->cipher_data;
+    return init_cc_key(encp, kCCAlgorithmDES, 0, key, kCCBlockSizeDES, iv, &cc->href);
+}
+
+/**
+ * The DES cipher type (Apple CommonCrypto provider)
+ *
+ * @return the DES-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_des_cbc(void)
+{
+    static const EVP_CIPHER des_ede3_cbc = {
+       0,
+       kCCBlockSizeDES,
+       kCCBlockSizeDES,
+       kCCBlockSizeDES,
+       EVP_CIPH_CBC_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
+       cc_des_cbc_init,
+       cc_do_cipher,
+       cc_cleanup,
+       sizeof(struct cc_key),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &des_ede3_cbc;
+}
+
+/*
+ *
+ */
+
+static int
+cc_aes_cbc_init(EVP_CIPHER_CTX *ctx,
+               const unsigned char * key,
+               const unsigned char * iv,
+               int encp)
+{
+    struct cc_key *cc = ctx->cipher_data;
+    return init_cc_key(encp, kCCAlgorithmAES128, 0, key, ctx->cipher->key_len, iv, &cc->href);
+}
+
+/**
+ * The AES-128 cipher type (Apple CommonCrypto provider)
+ *
+ * @return the AES-128-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_aes_128_cbc(void)
+{
+    static const EVP_CIPHER c = {
+       0,
+       kCCBlockSizeAES128,
+       kCCKeySizeAES128,
+       kCCBlockSizeAES128,
+       EVP_CIPH_CBC_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
+       cc_aes_cbc_init,
+       cc_do_cipher,
+       cc_cleanup,
+       sizeof(struct cc_key),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &c;
+}
+
+/**
+ * The AES-192 cipher type (Apple CommonCrypto provider)
+ *
+ * @return the AES-192-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_aes_192_cbc(void)
+{
+    static const EVP_CIPHER c = {
+       0,
+       kCCBlockSizeAES128,
+       kCCKeySizeAES192,
+       kCCBlockSizeAES128,
+       EVP_CIPH_CBC_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
+       cc_aes_cbc_init,
+       cc_do_cipher,
+       cc_cleanup,
+       sizeof(struct cc_key),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &c;
+}
+
+/**
+ * The AES-256 cipher type (Apple CommonCrypto provider)
+ *
+ * @return the AES-256-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_aes_256_cbc(void)
+{
+    static const EVP_CIPHER c = {
+       0,
+       kCCBlockSizeAES128,
+       kCCKeySizeAES256,
+       kCCBlockSizeAES128,
+       EVP_CIPH_CBC_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
+       cc_aes_cbc_init,
+       cc_do_cipher,
+       cc_cleanup,
+       sizeof(struct cc_key),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &c;
+}
+
+static int
+cc_aes_cfb8_init(EVP_CIPHER_CTX *ctx,
+               const unsigned char * key,
+               const unsigned char * iv,
+               int encp)
+{
+    struct cc_key *cc = ctx->cipher_data;
+    return init_cc_key(1, kCCAlgorithmAES128, kCCOptionECBMode,
+                      key, ctx->cipher->key_len, NULL, &cc->href);
+}
+
+/**
+ * The AES-128 CFB8 cipher type (Apple CommonCrypto provider)
+ *
+ * @return the AES-128-CFB8 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_aes_128_cfb8(void)
+{
+    static const EVP_CIPHER c = {
+       0,
+       1,
+       kCCKeySizeAES128,
+       kCCBlockSizeAES128,
+       EVP_CIPH_CFB8_MODE,
+       cc_aes_cfb8_init,
+       cc_do_cfb8_cipher,
+       cc_cleanup,
+       sizeof(struct cc_key),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &c;
+}
+
+/**
+ * The AES-192 CFB8 cipher type (Apple CommonCrypto provider)
+ *
+ * @return the AES-192-CFB8 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_aes_192_cfb8(void)
+{
+    static const EVP_CIPHER c = {
+       0,
+       1,
+       kCCKeySizeAES192,
+       kCCBlockSizeAES128,
+       EVP_CIPH_CFB8_MODE,
+       cc_aes_cfb8_init,
+       cc_do_cfb8_cipher,
+       cc_cleanup,
+       sizeof(struct cc_key),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &c;
+}
+
+/**
+ * The AES-256 CFB8 cipher type (Apple CommonCrypto provider)
+ *
+ * @return the AES-256-CFB8 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_aes_256_cfb8(void)
+{
+    static const EVP_CIPHER c = {
+       0,
+       1,
+       kCCKeySizeAES256,
+       kCCBlockSizeAES128,
+       EVP_CIPH_CFB8_MODE,
+       cc_aes_cfb8_init,
+       cc_do_cfb8_cipher,
+       cc_cleanup,
+       sizeof(struct cc_key),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &c;
+}
+
+/*
+ *
+ */
+
+#ifdef COMMONCRYPTO_SUPPORTS_RC2
+static int
+cc_rc2_cbc_init(EVP_CIPHER_CTX *ctx,
+               const unsigned char * key,
+               const unsigned char * iv,
+               int encp)
+{
+    struct cc_key *cc = ctx->cipher_data;
+    return init_cc_key(encp, kCCAlgorithmRC2, 0, key, ctx->cipher->key_len, iv, &cc->href);
+}
+#endif
+
+/**
+ * The RC2 cipher type - common crypto
+ *
+ * @return the RC2 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+
+const EVP_CIPHER *
+EVP_cc_rc2_cbc(void)
+{
+#ifdef COMMONCRYPTO_SUPPORTS_RC2
+    static const EVP_CIPHER rc2_cbc = {
+       0,
+       kCCBlockSizeRC2,
+       16,
+       kCCBlockSizeRC2,
+       EVP_CIPH_CBC_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
+       cc_rc2_cbc_init,
+       cc_do_cipher,
+       cc_cleanup,
+       sizeof(struct cc_key),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &rc2_cbc;
+#else
+    return NULL;
+#endif
+}
+
+/**
+ * The RC2-40 cipher type - common crypto
+ *
+ * @return the RC2-40 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+
+const EVP_CIPHER *
+EVP_cc_rc2_40_cbc(void)
+{
+#ifdef COMMONCRYPTO_SUPPORTS_RC2
+    static const EVP_CIPHER rc2_40_cbc = {
+       0,
+       kCCBlockSizeRC2,
+       5,
+       kCCBlockSizeRC2,
+       EVP_CIPH_CBC_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
+       cc_rc2_cbc_init,
+       cc_do_cipher,
+       cc_cleanup,
+       sizeof(struct cc_key),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &rc2_40_cbc;
+#else
+    return NULL;
+#endif
+}
+
+
+/**
+ * The RC2-64 cipher type - common crypto
+ *
+ * @return the RC2-64 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+
+const EVP_CIPHER *
+EVP_cc_rc2_64_cbc(void)
+{
+#ifdef COMMONCRYPTO_SUPPORTS_RC2
+    static const EVP_CIPHER rc2_64_cbc = {
+       0,
+       kCCBlockSizeRC2,
+       8,
+       kCCBlockSizeRC2,
+       EVP_CIPH_CBC_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
+       cc_rc2_cbc_init,
+       cc_do_cipher,
+       cc_cleanup,
+       sizeof(struct cc_key),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &rc2_64_cbc;
+#else
+    return NULL;
+#endif
+}
+
+/**
+ * The CommonCrypto md2 provider
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_MD *
+EVP_cc_md2(void)
+{
+#ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
+    static const struct hc_evp_md md2 = {
+       CC_MD2_DIGEST_LENGTH,
+       CC_MD2_BLOCK_BYTES,
+       sizeof(CC_MD2_CTX),
+       (hc_evp_md_init)CC_MD2_Init,
+       (hc_evp_md_update)CC_MD2_Update,
+       (hc_evp_md_final)CC_MD2_Final,
+       (hc_evp_md_cleanup)NULL
+    };
+    return &md2;
+#else
+    return NULL;
+#endif
+}
+
+/**
+ * The CommonCrypto md4 provider
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_MD *
+EVP_cc_md4(void)
+{
+#ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
+    static const struct hc_evp_md md4 = {
+       CC_MD4_DIGEST_LENGTH,
+       CC_MD4_BLOCK_BYTES,
+       sizeof(CC_MD4_CTX),
+       (hc_evp_md_init)CC_MD4_Init,
+       (hc_evp_md_update)CC_MD4_Update,
+       (hc_evp_md_final)CC_MD4_Final,
+       (hc_evp_md_cleanup)NULL
+    };
+    return &md4;
+#else
+    return NULL;
+#endif
+}
+
+/**
+ * The CommonCrypto md5 provider
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_MD *
+EVP_cc_md5(void)
+{
+#ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
+    static const struct hc_evp_md md5 = {
+       CC_MD5_DIGEST_LENGTH,
+       CC_MD5_BLOCK_BYTES,
+       sizeof(CC_MD5_CTX),
+       (hc_evp_md_init)CC_MD5_Init,
+       (hc_evp_md_update)CC_MD5_Update,
+       (hc_evp_md_final)CC_MD5_Final,
+       (hc_evp_md_cleanup)NULL
+    };
+    return &md5;
+#else
+    return NULL;
+#endif
+}
+
+/**
+ * The CommonCrypto sha1 provider
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_MD *
+EVP_cc_sha1(void)
+{
+#ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
+    static const struct hc_evp_md sha1 = {
+       CC_SHA1_DIGEST_LENGTH,
+       CC_SHA1_BLOCK_BYTES,
+       sizeof(CC_SHA1_CTX),
+       (hc_evp_md_init)CC_SHA1_Init,
+       (hc_evp_md_update)CC_SHA1_Update,
+       (hc_evp_md_final)CC_SHA1_Final,
+       (hc_evp_md_cleanup)NULL
+    };
+    return &sha1;
+#else
+    return NULL;
+#endif
+}
+
+/**
+ * The CommonCrypto sha256 provider
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_MD *
+EVP_cc_sha256(void)
+{
+#ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
+    static const struct hc_evp_md sha256 = {
+       CC_SHA256_DIGEST_LENGTH,
+       CC_SHA256_BLOCK_BYTES,
+       sizeof(CC_SHA256_CTX),
+       (hc_evp_md_init)CC_SHA256_Init,
+       (hc_evp_md_update)CC_SHA256_Update,
+       (hc_evp_md_final)CC_SHA256_Final,
+       (hc_evp_md_cleanup)NULL
+    };
+    return &sha256;
+#else
+    return NULL;
+#endif
+}
+
+/**
+ * The Camellia-128 cipher type - CommonCrypto
+ *
+ * @return the Camellia-128 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_camellia_128_cbc(void)
+{
+    return NULL;
+}
+
+/**
+ * The Camellia-198 cipher type - CommonCrypto
+ *
+ * @return the Camellia-198 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_camellia_192_cbc(void)
+{
+    return NULL;
+}
+
+/**
+ * The Camellia-256 cipher type - CommonCrypto
+ *
+ * @return the Camellia-256 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_camellia_256_cbc(void)
+{
+    return NULL;
+}
+
+/*
+ *
+ */
+
+static int
+cc_rc4_init(EVP_CIPHER_CTX *ctx,
+           const unsigned char * key,
+           const unsigned char * iv,
+           int encp)
+{
+    struct cc_key *cc = ctx->cipher_data;
+    return init_cc_key(encp, kCCAlgorithmRC4, 0, key, ctx->key_len, iv, &cc->href);
+}
+
+/**
+ * The RC4 cipher type (Apple CommonCrypto provider)
+ *
+ * @return the RC4 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_rc4(void)
+{
+    static const EVP_CIPHER rc4 = {
+       0,
+       1,
+       16,
+       0,
+       EVP_CIPH_STREAM_CIPHER|EVP_CIPH_VARIABLE_LENGTH,
+       cc_rc4_init,
+       cc_do_cipher,
+       cc_cleanup,
+       sizeof(struct cc_key),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &rc4;
+}
+
+
+/**
+ * The RC4-40 cipher type (Apple CommonCrypto provider)
+ *
+ * @return the RC4 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_rc4_40(void)
+{
+    static const EVP_CIPHER rc4_40 = {
+       0,
+       1,
+       5,
+       0,
+       EVP_CIPH_STREAM_CIPHER|EVP_CIPH_VARIABLE_LENGTH,
+       cc_rc4_init,
+       cc_do_cipher,
+       cc_cleanup,
+       sizeof(struct cc_key),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &rc4_40;
+}
+
+#endif /* __APPLE__ */
diff --git a/src/external/heimdal/hcrypto/evp-cc.h b/src/external/heimdal/hcrypto/evp-cc.h
new file mode 100644 (file)
index 0000000..1ac3cfb
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2009 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+/* $Id$ */
+
+#ifndef HEIM_EVP_CC_H
+#define HEIM_EVP_CC_H 1
+
+/* symbol renaming */
+#define EVP_cc_md2 hc_EVP_cc_md2
+#define EVP_cc_md4 hc_EVP_cc_md4
+#define EVP_cc_md5 hc_EVP_cc_md5
+#define EVP_cc_sha1 hc_EVP_cc_sha1
+#define EVP_cc_sha256 hc_EVP_cc_sha256
+#define EVP_cc_des_cbc hc_EVP_cc_des_cbc
+#define EVP_cc_des_ede3_cbc hc_EVP_cc_des_ede3_cbc
+#define EVP_cc_aes_128_cbc hc_EVP_cc_aes_128_cbc
+#define EVP_cc_aes_192_cbc hc_EVP_cc_aes_192_cbc
+#define EVP_cc_aes_256_cbc hc_EVP_cc_aes_256_cbc
+#define EVP_cc_aes_cfb_128_cbc hc_EVP_cc_aes_128_cfb8
+#define EVP_cc_aes_cfb_192_cbc hc_EVP_cc_aes_192_cfb8
+#define EVP_cc_aes_cfb_256_cbc hc_EVP_cc_aes_256_cfb8
+#define EVP_cc_rc4 hc_EVP_cc_rc4
+#define EVP_cc_rc4_40 hc_EVP_cc_rc4_40
+#define EVP_cc_rc2_40_cbc hc_EVP_cc_rc2_40_cbc
+#define EVP_cc_rc2_64_cbc hc_EVP_cc_rc2_64_cbc
+#define EVP_cc_rc2_cbc hc_EVP_cc_rc2_cbc
+#define EVP_cc_camellia_128_cbc hc_EVP_cc_camellia_128_cbc
+#define EVP_cc_camellia_192_cbc hc_EVP_cc_camellia_192_cbc
+#define EVP_cc_camellia_256_cbc hc_EVP_cc_camellia_256_cbc
+
+/*
+ *
+ */
+
+HC_CPP_BEGIN
+
+const EVP_MD * EVP_cc_md2(void);
+const EVP_MD * EVP_cc_md4(void);
+const EVP_MD * EVP_cc_md5(void);
+const EVP_MD * EVP_cc_sha1(void);
+const EVP_MD * EVP_cc_sha256(void);
+
+const EVP_CIPHER * EVP_cc_rc2_cbc(void);
+const EVP_CIPHER * EVP_cc_rc2_40_cbc(void);
+const EVP_CIPHER * EVP_cc_rc2_64_cbc(void);
+
+const EVP_CIPHER * EVP_cc_rc4(void);
+const EVP_CIPHER * EVP_cc_rc4_40(void);
+
+const EVP_CIPHER * EVP_cc_des_cbc(void);
+const EVP_CIPHER * EVP_cc_des_ede3_cbc(void);
+
+const EVP_CIPHER * EVP_cc_aes_128_cbc(void);
+const EVP_CIPHER * EVP_cc_aes_192_cbc(void);
+const EVP_CIPHER * EVP_cc_aes_256_cbc(void);
+
+const EVP_CIPHER * EVP_cc_aes_128_cfb8(void);
+const EVP_CIPHER * EVP_cc_aes_192_cfb8(void);
+const EVP_CIPHER * EVP_cc_aes_256_cfb8(void);
+
+const EVP_CIPHER * EVP_cc_camellia_128_cbc(void);
+const EVP_CIPHER * EVP_cc_camellia_192_cbc(void);
+const EVP_CIPHER * EVP_cc_camellia_256_cbc(void);
+
+HC_CPP_END
+
+#endif /* HEIM_EVP_CC_H */
diff --git a/src/external/heimdal/hcrypto/evp-hcrypto.c b/src/external/heimdal/hcrypto/evp-hcrypto.c
new file mode 100644 (file)
index 0000000..9e06354
--- /dev/null
@@ -0,0 +1,811 @@
+/*
+ * Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+#include <config.h>
+
+#define HC_DEPRECATED
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <evp.h>
+#include <evp-hcrypto.h>
+
+#include <krb5-types.h>
+
+#include <des.h>
+#include "camellia.h"
+#include <aes.h>
+
+#include <rc2.h>
+#include <rc4.h>
+
+#include <sha.h>
+#include <md2.h>
+#include <md4.h>
+#include <md5.h>
+
+/*
+ *
+ */
+
+static int
+aes_init(EVP_CIPHER_CTX *ctx,
+        const unsigned char * key,
+        const unsigned char * iv,
+        int encp)
+{
+    AES_KEY *k = ctx->cipher_data;
+    if (ctx->encrypt)
+       AES_set_encrypt_key(key, ctx->cipher->key_len * 8, k);
+    else
+       AES_set_decrypt_key(key, ctx->cipher->key_len * 8, k);
+    return 1;
+}
+
+static int
+aes_do_cipher(EVP_CIPHER_CTX *ctx,
+             unsigned char *out,
+             const unsigned char *in,
+             unsigned int size)
+{
+    AES_KEY *k = ctx->cipher_data;
+    if (ctx->flags & EVP_CIPH_CFB8_MODE)
+        AES_cfb8_encrypt(in, out, size, k, ctx->iv, ctx->encrypt);
+    else
+        AES_cbc_encrypt(in, out, size, k, ctx->iv, ctx->encrypt);
+    return 1;
+}
+
+/**
+ * The AES-128 cipher type (hcrypto)
+ *
+ * @return the AES-128 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_hcrypto_aes_128_cbc(void)
+{
+    static const EVP_CIPHER aes_128_cbc = {
+       0,
+       16,
+       16,
+       16,
+       EVP_CIPH_CBC_MODE,
+       aes_init,
+       aes_do_cipher,
+       NULL,
+       sizeof(AES_KEY),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+
+    return &aes_128_cbc;
+}
+
+/**
+ * The AES-192 cipher type (hcrypto)
+ *
+ * @return the AES-192 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_hcrypto_aes_192_cbc(void)
+{
+    static const EVP_CIPHER aes_192_cbc = {
+       0,
+       16,
+       24,
+       16,
+       EVP_CIPH_CBC_MODE,
+       aes_init,
+       aes_do_cipher,
+       NULL,
+       sizeof(AES_KEY),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &aes_192_cbc;
+}
+
+/**
+ * The AES-256 cipher type (hcrypto)
+ *
+ * @return the AES-256 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_hcrypto_aes_256_cbc(void)
+{
+    static const EVP_CIPHER aes_256_cbc = {
+       0,
+       16,
+       32,
+       16,
+       EVP_CIPH_CBC_MODE,
+       aes_init,
+       aes_do_cipher,
+       NULL,
+       sizeof(AES_KEY),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &aes_256_cbc;
+}
+
+/**
+ * The AES-128 CFB8 cipher type (hcrypto)
+ *
+ * @return the AES-128 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_hcrypto_aes_128_cfb8(void)
+{
+    static const EVP_CIPHER aes_128_cfb8 = {
+       0,
+       1,
+       16,
+       16,
+       EVP_CIPH_CFB8_MODE,
+       aes_init,
+       aes_do_cipher,
+       NULL,
+       sizeof(AES_KEY),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+
+    return &aes_128_cfb8;
+}
+
+/**
+ * The AES-192 CFB8 cipher type (hcrypto)
+ *
+ * @return the AES-192 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_hcrypto_aes_192_cfb8(void)
+{
+    static const EVP_CIPHER aes_192_cfb8 = {
+       0,
+       1,
+       24,
+       16,
+       EVP_CIPH_CFB8_MODE,
+       aes_init,
+       aes_do_cipher,
+       NULL,
+       sizeof(AES_KEY),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &aes_192_cfb8;
+}
+
+/**
+ * The AES-256 CFB8 cipher type (hcrypto)
+ *
+ * @return the AES-256 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_hcrypto_aes_256_cfb8(void)
+{
+    static const EVP_CIPHER aes_256_cfb8 = {
+       0,
+       1,
+       32,
+       16,
+       EVP_CIPH_CFB8_MODE,
+       aes_init,
+       aes_do_cipher,
+       NULL,
+       sizeof(AES_KEY),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &aes_256_cfb8;
+}
+
+/**
+ * The message digest SHA256 - hcrypto
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_MD *
+EVP_hcrypto_sha256(void)
+{
+    static const struct hc_evp_md sha256 = {
+       32,
+       64,
+       sizeof(SHA256_CTX),
+       (hc_evp_md_init)SHA256_Init,
+       (hc_evp_md_update)SHA256_Update,
+       (hc_evp_md_final)SHA256_Final,
+       NULL
+    };
+    return &sha256;
+}
+
+/**
+ * The message digest SHA1 - hcrypto
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_MD *
+EVP_hcrypto_sha1(void)
+{
+    static const struct hc_evp_md sha1 = {
+       20,
+       64,
+       sizeof(SHA_CTX),
+       (hc_evp_md_init)SHA1_Init,
+       (hc_evp_md_update)SHA1_Update,
+       (hc_evp_md_final)SHA1_Final,
+       NULL
+    };
+    return &sha1;
+}
+
+/**
+ * The message digest MD5 - hcrypto
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_MD *
+EVP_hcrypto_md5(void)
+{
+    static const struct hc_evp_md md5 = {
+       16,
+       64,
+       sizeof(MD5_CTX),
+       (hc_evp_md_init)MD5_Init,
+       (hc_evp_md_update)MD5_Update,
+       (hc_evp_md_final)MD5_Final,
+       NULL
+    };
+    return &md5;
+}
+
+/**
+ * The message digest MD4 - hcrypto
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_MD *
+EVP_hcrypto_md4(void)
+{
+    static const struct hc_evp_md md4 = {
+       16,
+       64,
+       sizeof(MD4_CTX),
+       (hc_evp_md_init)MD4_Init,
+       (hc_evp_md_update)MD4_Update,
+       (hc_evp_md_final)MD4_Final,
+       NULL
+    };
+    return &md4;
+}
+
+/**
+ * The message digest MD2 - hcrypto
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_MD *
+EVP_hcrypto_md2(void)
+{
+    static const struct hc_evp_md md2 = {
+       16,
+       16,
+       sizeof(MD2_CTX),
+       (hc_evp_md_init)MD2_Init,
+       (hc_evp_md_update)MD2_Update,
+       (hc_evp_md_final)MD2_Final,
+       NULL
+    };
+    return &md2;
+}
+
+/*
+ *
+ */
+
+static int
+des_cbc_init(EVP_CIPHER_CTX *ctx,
+            const unsigned char * key,
+            const unsigned char * iv,
+            int encp)
+{
+    DES_key_schedule *k = ctx->cipher_data;
+    DES_cblock deskey;
+    memcpy(&deskey, key, sizeof(deskey));
+    DES_set_key_unchecked(&deskey, k);
+    return 1;
+}
+
+static int
+des_cbc_do_cipher(EVP_CIPHER_CTX *ctx,
+                 unsigned char *out,
+                 const unsigned char *in,
+                 unsigned int size)
+{
+    DES_key_schedule *k = ctx->cipher_data;
+    DES_cbc_encrypt(in, out, size,
+                   k, (DES_cblock *)ctx->iv, ctx->encrypt);
+    return 1;
+}
+
+/**
+ * The DES cipher type
+ *
+ * @return the DES-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_hcrypto_des_cbc(void)
+{
+    static const EVP_CIPHER des_cbc = {
+       0,
+       8,
+       8,
+       8,
+       EVP_CIPH_CBC_MODE,
+       des_cbc_init,
+       des_cbc_do_cipher,
+       NULL,
+       sizeof(DES_key_schedule),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &des_cbc;
+}
+
+/*
+ *
+ */
+
+struct des_ede3_cbc {
+    DES_key_schedule ks[3];
+};
+
+static int
+des_ede3_cbc_init(EVP_CIPHER_CTX *ctx,
+                 const unsigned char * key,
+                 const unsigned char * iv,
+                 int encp)
+{
+    struct des_ede3_cbc *k = ctx->cipher_data;
+    DES_cblock deskey;
+
+    memcpy(&deskey, key, sizeof(deskey));
+    DES_set_odd_parity(&deskey);
+    DES_set_key_unchecked(&deskey, &k->ks[0]);
+
+    memcpy(&deskey, key + 8, sizeof(deskey));
+    DES_set_odd_parity(&deskey);
+    DES_set_key_unchecked(&deskey, &k->ks[1]);
+
+    memcpy(&deskey, key + 16, sizeof(deskey));
+    DES_set_odd_parity(&deskey);
+    DES_set_key_unchecked(&deskey, &k->ks[2]);
+
+    return 1;
+}
+
+static int
+des_ede3_cbc_do_cipher(EVP_CIPHER_CTX *ctx,
+                      unsigned char *out,
+                      const unsigned char *in,
+                      unsigned int size)
+{
+    struct des_ede3_cbc *k = ctx->cipher_data;
+    DES_ede3_cbc_encrypt(in, out, size,
+                        &k->ks[0], &k->ks[1], &k->ks[2],
+                        (DES_cblock *)ctx->iv, ctx->encrypt);
+    return 1;
+}
+
+/**
+ * The tripple DES cipher type - hcrypto
+ *
+ * @return the DES-EDE3-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_hcrypto_des_ede3_cbc(void)
+{
+    static const EVP_CIPHER des_ede3_cbc = {
+       0,
+       8,
+       24,
+       8,
+       EVP_CIPH_CBC_MODE,
+       des_ede3_cbc_init,
+       des_ede3_cbc_do_cipher,
+       NULL,
+       sizeof(struct des_ede3_cbc),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &des_ede3_cbc;
+}
+
+/*
+ *
+ */
+
+struct rc2_cbc {
+    unsigned int maximum_effective_key;
+    RC2_KEY key;
+};
+
+static int
+rc2_init(EVP_CIPHER_CTX *ctx,
+        const unsigned char * key,
+        const unsigned char * iv,
+        int encp)
+{
+    struct rc2_cbc *k = ctx->cipher_data;
+    k->maximum_effective_key = EVP_CIPHER_CTX_key_length(ctx) * 8;
+    RC2_set_key(&k->key,
+               EVP_CIPHER_CTX_key_length(ctx),
+               key,
+               k->maximum_effective_key);
+    return 1;
+}
+
+static int
+rc2_do_cipher(EVP_CIPHER_CTX *ctx,
+             unsigned char *out,
+             const unsigned char *in,
+             unsigned int size)
+{
+    struct rc2_cbc *k = ctx->cipher_data;
+    RC2_cbc_encrypt(in, out, size, &k->key, ctx->iv, ctx->encrypt);
+    return 1;
+}
+
+/**
+ * The RC2 cipher type - hcrypto
+ *
+ * @return the RC2 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_hcrypto_rc2_cbc(void)
+{
+    static const EVP_CIPHER rc2_cbc = {
+       0,
+       RC2_BLOCK_SIZE,
+       RC2_KEY_LENGTH,
+       RC2_BLOCK_SIZE,
+       EVP_CIPH_CBC_MODE|EVP_CIPH_VARIABLE_LENGTH,
+       rc2_init,
+       rc2_do_cipher,
+       NULL,
+       sizeof(struct rc2_cbc),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &rc2_cbc;
+}
+
+/**
+ * The RC2-40 cipher type
+ *
+ * @return the RC2-40 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_hcrypto_rc2_40_cbc(void)
+{
+    static const EVP_CIPHER rc2_40_cbc = {
+       0,
+       RC2_BLOCK_SIZE,
+       5,
+       RC2_BLOCK_SIZE,
+       EVP_CIPH_CBC_MODE,
+       rc2_init,
+       rc2_do_cipher,
+       NULL,
+       sizeof(struct rc2_cbc),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &rc2_40_cbc;
+}
+
+/**
+ * The RC2-64 cipher type
+ *
+ * @return the RC2-64 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_hcrypto_rc2_64_cbc(void)
+{
+    static const EVP_CIPHER rc2_64_cbc = {
+       0,
+       RC2_BLOCK_SIZE,
+       8,
+       RC2_BLOCK_SIZE,
+       EVP_CIPH_CBC_MODE,
+       rc2_init,
+       rc2_do_cipher,
+       NULL,
+       sizeof(struct rc2_cbc),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &rc2_64_cbc;
+}
+
+static int
+camellia_init(EVP_CIPHER_CTX *ctx,
+        const unsigned char * key,
+        const unsigned char * iv,
+        int encp)
+{
+    CAMELLIA_KEY *k = ctx->cipher_data;
+    k->bits = ctx->cipher->key_len * 8;
+    CAMELLIA_set_key(key, ctx->cipher->key_len * 8, k);
+    return 1;
+}
+
+static int
+camellia_do_cipher(EVP_CIPHER_CTX *ctx,
+             unsigned char *out,
+             const unsigned char *in,
+             unsigned int size)
+{
+    CAMELLIA_KEY *k = ctx->cipher_data;
+    CAMELLIA_cbc_encrypt(in, out, size, k, ctx->iv, ctx->encrypt);
+    return 1;
+}
+
+/**
+ * The Camellia-128 cipher type - hcrypto
+ *
+ * @return the Camellia-128 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_hcrypto_camellia_128_cbc(void)
+{
+    static const EVP_CIPHER cipher = {
+       0,
+       16,
+       16,
+       16,
+       EVP_CIPH_CBC_MODE,
+       camellia_init,
+       camellia_do_cipher,
+       NULL,
+       sizeof(CAMELLIA_KEY),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &cipher;
+}
+
+/**
+ * The Camellia-198 cipher type - hcrypto
+ *
+ * @return the Camellia-198 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_hcrypto_camellia_192_cbc(void)
+{
+    static const EVP_CIPHER cipher = {
+       0,
+       16,
+       24,
+       16,
+       EVP_CIPH_CBC_MODE,
+       camellia_init,
+       camellia_do_cipher,
+       NULL,
+       sizeof(CAMELLIA_KEY),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &cipher;
+}
+
+/**
+ * The Camellia-256 cipher type - hcrypto
+ *
+ * @return the Camellia-256 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_hcrypto_camellia_256_cbc(void)
+{
+    static const EVP_CIPHER cipher = {
+       0,
+       16,
+       32,
+       16,
+       EVP_CIPH_CBC_MODE,
+       camellia_init,
+       camellia_do_cipher,
+       NULL,
+       sizeof(CAMELLIA_KEY),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &cipher;
+}
+
+static int
+rc4_init(EVP_CIPHER_CTX *ctx,
+        const unsigned char *key,
+        const unsigned char *iv,
+        int enc)
+{
+    RC4_KEY *k = ctx->cipher_data;
+    RC4_set_key(k, ctx->key_len, key);
+    return 1;
+}
+
+static int
+rc4_do_cipher(EVP_CIPHER_CTX *ctx,
+             unsigned char *out,
+             const unsigned char *in,
+             unsigned int size)
+{
+    RC4_KEY *k = ctx->cipher_data;
+    RC4(k, size, in, out);
+    return 1;
+}
+
+const EVP_CIPHER *
+EVP_hcrypto_rc4(void)
+{
+    static const EVP_CIPHER rc4 = {
+       0,
+       1,
+       16,
+       0,
+       EVP_CIPH_STREAM_CIPHER|EVP_CIPH_VARIABLE_LENGTH,
+       rc4_init,
+       rc4_do_cipher,
+       NULL,
+       sizeof(RC4_KEY),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &rc4;
+}
+
+
+const EVP_CIPHER *
+EVP_hcrypto_rc4_40(void)
+{
+    static const EVP_CIPHER rc4_40 = {
+       0,
+       1,
+       5,
+       0,
+       EVP_CIPH_STREAM_CIPHER|EVP_CIPH_VARIABLE_LENGTH,
+       rc4_init,
+       rc4_do_cipher,
+       NULL,
+       sizeof(RC4_KEY),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &rc4_40;
+}
diff --git a/src/external/heimdal/hcrypto/evp-hcrypto.h b/src/external/heimdal/hcrypto/evp-hcrypto.h
new file mode 100644 (file)
index 0000000..7915046
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2009 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+/* $Id$ */
+
+#ifndef HEIM_EVP_HCRYPTO_H
+#define HEIM_EVP_HCRYPTO_H 1
+
+/* symbol renaming */
+#define EVP_hcrypto_md2 hc_EVP_hcrypto_md2
+#define EVP_hcrypto_md4 hc_EVP_hcrypto_md4
+#define EVP_hcrypto_md5 hc_EVP_hcrypto_md5
+#define EVP_hcrypto_sha1 hc_EVP_hcrypto_sha1
+#define EVP_hcrypto_sha256 hc_EVP_hcrypto_sha256
+#define EVP_hcrypto_des_cbc hc_EVP_hcrypto_des_cbc
+#define EVP_hcrypto_des_ede3_cbc hc_EVP_hcrypto_des_ede3_cbc
+#define EVP_hcrypto_aes_128_cbc hc_EVP_hcrypto_aes_128_cbc
+#define EVP_hcrypto_aes_192_cbc hc_EVP_hcrypto_aes_192_cbc
+#define EVP_hcrypto_aes_256_cbc hc_EVP_hcrypto_aes_256_cbc
+#define EVP_hcrypto_aes_128_cfb8 hc_EVP_hcrypto_aes_128_cfb8
+#define EVP_hcrypto_aes_192_cfb8 hc_EVP_hcrypto_aes_192_cfb8
+#define EVP_hcrypto_aes_256_cfb8 hc_EVP_hcrypto_aes_256_cfb8
+#define EVP_hcrypto_rc4 hc_EVP_hcrypto_rc4
+#define EVP_hcrypto_rc4_40 hc_EVP_hcrypto_rc4_40
+#define EVP_hcrypto_rc2_40_cbc hc_EVP_hcrypto_rc2_40_cbc
+#define EVP_hcrypto_rc2_64_cbc hc_EVP_hcrypto_rc2_64_cbc
+#define EVP_hcrypto_rc2_cbc hc_EVP_hcrypto_rc2_cbc
+#define EVP_hcrypto_camellia_128_cbc hc_EVP_hcrypto_camellia_128_cbc
+#define EVP_hcrypto_camellia_192_cbc hc_EVP_hcrypto_camellia_192_cbc
+#define EVP_hcrypto_camellia_256_cbc hc_EVP_hcrypto_camellia_256_cbc
+
+/*
+ *
+ */
+
+HC_CPP_BEGIN
+
+const EVP_MD * EVP_hcrypto_md2(void);
+const EVP_MD * EVP_hcrypto_md4(void);
+const EVP_MD * EVP_hcrypto_md5(void);
+const EVP_MD * EVP_hcrypto_sha1(void);
+const EVP_MD * EVP_hcrypto_sha256(void);
+
+const EVP_CIPHER * EVP_hcrypto_rc4(void);
+const EVP_CIPHER * EVP_hcrypto_rc4_40(void);
+
+const EVP_CIPHER * EVP_hcrypto_rc2_cbc(void);
+const EVP_CIPHER * EVP_hcrypto_rc2_40_cbc(void);
+const EVP_CIPHER * EVP_hcrypto_rc2_64_cbc(void);
+
+const EVP_CIPHER * EVP_hcrypto_des_cbc(void);
+const EVP_CIPHER * EVP_hcrypto_des_ede3_cbc(void);
+
+const EVP_CIPHER * EVP_hcrypto_aes_128_cbc(void);
+const EVP_CIPHER * EVP_hcrypto_aes_192_cbc(void);
+const EVP_CIPHER * EVP_hcrypto_aes_256_cbc(void);
+
+const EVP_CIPHER * EVP_hcrypto_aes_128_cfb8(void);
+const EVP_CIPHER * EVP_hcrypto_aes_192_cfb8(void);
+const EVP_CIPHER * EVP_hcrypto_aes_256_cfb8(void);
+
+const EVP_CIPHER * EVP_hcrypto_camellia_128_cbc(void);
+const EVP_CIPHER * EVP_hcrypto_camellia_192_cbc(void);
+const EVP_CIPHER * EVP_hcrypto_camellia_256_cbc(void);
+
+
+HC_CPP_END
+
+#endif /* HEIM_EVP_HCRYPTO_H */
diff --git a/src/external/heimdal/hcrypto/evp.c b/src/external/heimdal/hcrypto/evp.c
new file mode 100644 (file)
index 0000000..6eaba33
--- /dev/null
@@ -0,0 +1,1442 @@
+/*
+ * Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define HC_DEPRECATED
+#define HC_DEPRECATED_CRYPTO
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <evp.h>
+#include <evp-hcrypto.h>
+#include <evp-cc.h>
+
+#include <krb5-types.h>
+#include <roken.h>
+
+#ifndef HCRYPTO_DEF_PROVIDER
+#define HCRYPTO_DEF_PROVIDER hcrypto
+#endif
+
+#define HC_CONCAT4(x,y,z,aa)   x ## y ## z ## aa
+
+
+#define EVP_DEF_OP(_prov,_op) HC_CONCAT4(EVP_,_prov,_,_op)()
+
+/**
+ * @page page_evp EVP - generic crypto interface
+ *
+ * See the library functions here: @ref hcrypto_evp
+ *
+ * @section evp_cipher EVP Cipher
+ *
+ * The use of EVP_CipherInit_ex() and EVP_Cipher() is pretty easy to
+ * understand forward, then EVP_CipherUpdate() and
+ * EVP_CipherFinal_ex() really needs an example to explain @ref
+ * example_evp_cipher.c .
+ *
+ * @example example_evp_cipher.c
+ *
+ * This is an example how to use EVP_CipherInit_ex(),
+ * EVP_CipherUpdate() and EVP_CipherFinal_ex().
+ */
+
+struct hc_EVP_MD_CTX {
+    const EVP_MD *md;
+    ENGINE *engine;
+    void *ptr;
+};
+
+
+/**
+ * Return the output size of the message digest function.
+ *
+ * @param md the evp message
+ *
+ * @return size output size of the message digest function.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+size_t
+EVP_MD_size(const EVP_MD *md)
+{
+    return md->hash_size;
+}
+
+/**
+ * Return the blocksize of the message digest function.
+ *
+ * @param md the evp message
+ *
+ * @return size size of the message digest block size
+ *
+ * @ingroup hcrypto_evp
+ */
+
+size_t
+EVP_MD_block_size(const EVP_MD *md)
+{
+    return md->block_size;
+}
+
+/**
+ * Allocate a messsage digest context object. Free with
+ * EVP_MD_CTX_destroy().
+ *
+ * @return a newly allocated message digest context object.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+EVP_MD_CTX *
+EVP_MD_CTX_create(void)
+{
+    return calloc(1, sizeof(EVP_MD_CTX));
+}
+
+/**
+ * Initiate a messsage digest context object. Deallocate with
+ * EVP_MD_CTX_cleanup(). Please use EVP_MD_CTX_create() instead.
+ *
+ * @param ctx variable to initiate.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+void
+EVP_MD_CTX_init(EVP_MD_CTX *ctx) HC_DEPRECATED
+{
+    memset(ctx, 0, sizeof(*ctx));
+}
+
+/**
+ * Free a messsage digest context object.
+ *
+ * @param ctx context to free.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+void
+EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
+{
+    EVP_MD_CTX_cleanup(ctx);
+    free(ctx);
+}
+
+/**
+ * Free the resources used by the EVP_MD context.
+ *
+ * @param ctx the context to free the resources from.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+int
+EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) HC_DEPRECATED
+{
+    if (ctx->md && ctx->md->cleanup)
+       (ctx->md->cleanup)(ctx);
+    else if (ctx->md)
+       memset(ctx->ptr, 0, ctx->md->ctx_size);
+    ctx->md = NULL;
+    ctx->engine = NULL;
+    free(ctx->ptr);
+    memset(ctx, 0, sizeof(*ctx));
+    return 1;
+}
+
+/**
+ * Get the EVP_MD use for a specified context.
+ *
+ * @param ctx the EVP_MD context to get the EVP_MD for.
+ *
+ * @return the EVP_MD used for the context.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_MD *
+EVP_MD_CTX_md(EVP_MD_CTX *ctx)
+{
+    return ctx->md;
+}
+
+/**
+ * Return the output size of the message digest function.
+ *
+ * @param ctx the evp message digest context
+ *
+ * @return size output size of the message digest function.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+size_t
+EVP_MD_CTX_size(EVP_MD_CTX *ctx)
+{
+    return EVP_MD_size(ctx->md);
+}
+
+/**
+ * Return the blocksize of the message digest function.
+ *
+ * @param ctx the evp message digest context
+ *
+ * @return size size of the message digest block size
+ *
+ * @ingroup hcrypto_evp
+ */
+
+size_t
+EVP_MD_CTX_block_size(EVP_MD_CTX *ctx)
+{
+    return EVP_MD_block_size(ctx->md);
+}
+
+/**
+ * Init a EVP_MD_CTX for use a specific message digest and engine.
+ *
+ * @param ctx the message digest context to init.
+ * @param md the message digest to use.
+ * @param engine the engine to use, NULL to use the default engine.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+int
+EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *md, ENGINE *engine)
+{
+    if (ctx->md != md || ctx->engine != engine) {
+       EVP_MD_CTX_cleanup(ctx);
+       ctx->md = md;
+       ctx->engine = engine;
+
+       ctx->ptr = calloc(1, md->ctx_size);
+       if (ctx->ptr == NULL)
+           return 0;
+    }
+    (ctx->md->init)(ctx->ptr);
+    return 1;
+}
+
+/**
+ * Update the digest with some data.
+ *
+ * @param ctx the context to update
+ * @param data the data to update the context with
+ * @param size length of data
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+int
+EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t size)
+{
+    (ctx->md->update)(ctx->ptr, data, size);
+    return 1;
+}
+
+/**
+ * Complete the message digest.
+ *
+ * @param ctx the context to complete.
+ * @param hash the output of the message digest function. At least
+ * EVP_MD_size().
+ * @param size the output size of hash.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+int
+EVP_DigestFinal_ex(EVP_MD_CTX *ctx, void *hash, unsigned int *size)
+{
+    (ctx->md->final)(hash, ctx->ptr);
+    if (size)
+       *size = ctx->md->hash_size;
+    return 1;
+}
+
+/**
+ * Do the whole EVP_MD_CTX_create(), EVP_DigestInit_ex(),
+ * EVP_DigestUpdate(), EVP_DigestFinal_ex(), EVP_MD_CTX_destroy()
+ * dance in one call.
+ *
+ * @param data the data to update the context with
+ * @param dsize length of data
+ * @param hash output data of at least EVP_MD_size() length.
+ * @param hsize output length of hash.
+ * @param md message digest to use
+ * @param engine engine to use, NULL for default engine.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+int
+EVP_Digest(const void *data, size_t dsize, void *hash, unsigned int *hsize,
+          const EVP_MD *md, ENGINE *engine)
+{
+    EVP_MD_CTX *ctx;
+    int ret;
+
+    ctx = EVP_MD_CTX_create();
+    if (ctx == NULL)
+       return 0;
+    ret = EVP_DigestInit_ex(ctx, md, engine);
+    if (ret != 1) {
+       EVP_MD_CTX_destroy(ctx);
+       return ret;
+    }
+    ret = EVP_DigestUpdate(ctx, data, dsize);
+    if (ret != 1) {
+       EVP_MD_CTX_destroy(ctx);
+       return ret;
+    }
+    ret = EVP_DigestFinal_ex(ctx, hash, hsize);
+    EVP_MD_CTX_destroy(ctx);
+    return ret;
+}
+
+/**
+ * The message digest SHA256
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_MD *
+EVP_sha256(void)
+{
+    return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, sha256);
+}
+
+/**
+ * The message digest SHA1
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_MD *
+EVP_sha1(void)
+{
+    return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, sha1);
+}
+
+/**
+ * The message digest SHA1
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_MD *
+EVP_sha(void) HC_DEPRECATED
+
+{
+    return EVP_sha1();
+}
+
+/**
+ * The message digest MD5
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_MD *
+EVP_md5(void) HC_DEPRECATED_CRYPTO
+{
+    return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, md5);
+}
+
+/**
+ * The message digest MD4
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_MD *
+EVP_md4(void) HC_DEPRECATED_CRYPTO
+{
+    return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, md4);
+}
+
+/**
+ * The message digest MD2
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_MD *
+EVP_md2(void) HC_DEPRECATED_CRYPTO
+{
+    return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, md2);
+}
+
+/*
+ *
+ */
+
+static void
+null_Init (void *m)
+{
+}
+static void
+null_Update (void *m, const void * data, size_t size)
+{
+}
+static void
+null_Final(void *res, void *m)
+{
+}
+
+/**
+ * The null message digest
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_MD *
+EVP_md_null(void)
+{
+    static const struct hc_evp_md null = {
+       0,
+       0,
+       0,
+       (hc_evp_md_init)null_Init,
+       (hc_evp_md_update)null_Update,
+       (hc_evp_md_final)null_Final,
+       NULL
+    };
+    return &null;
+}
+
+/**
+ * Return the block size of the cipher.
+ *
+ * @param c cipher to get the block size from.
+ *
+ * @return the block size of the cipher.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+size_t
+EVP_CIPHER_block_size(const EVP_CIPHER *c)
+{
+    return c->block_size;
+}
+
+/**
+ * Return the key size of the cipher.
+ *
+ * @param c cipher to get the key size from.
+ *
+ * @return the key size of the cipher.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+size_t
+EVP_CIPHER_key_length(const EVP_CIPHER *c)
+{
+    return c->key_len;
+}
+
+/**
+ * Return the IV size of the cipher.
+ *
+ * @param c cipher to get the IV size from.
+ *
+ * @return the IV size of the cipher.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+size_t
+EVP_CIPHER_iv_length(const EVP_CIPHER *c)
+{
+    return c->iv_len;
+}
+
+/**
+ * Initiate a EVP_CIPHER_CTX context. Clean up with
+ * EVP_CIPHER_CTX_cleanup().
+ *
+ * @param c the cipher initiate.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+void
+EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *c)
+{
+    memset(c, 0, sizeof(*c));
+}
+
+/**
+ * Clean up the EVP_CIPHER_CTX context.
+ *
+ * @param c the cipher to clean up.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+int
+EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
+{
+    if (c->cipher && c->cipher->cleanup)
+       c->cipher->cleanup(c);
+    if (c->cipher_data) {
+       memset(c->cipher_data, 0, c->cipher->ctx_size);
+       free(c->cipher_data);
+       c->cipher_data = NULL;
+    }
+    return 1;
+}
+
+/**
+ * If the cipher type supports it, change the key length
+ *
+ * @param c the cipher context to change the key length for
+ * @param length new key length
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+int
+EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int length)
+{
+    if ((c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH) && length > 0) {
+       c->key_len = length;
+       return 1;
+    }
+    return 0;
+}
+
+#if 0
+int
+EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad)
+{
+    return 0;
+}
+#endif
+
+/**
+ * Return the EVP_CIPHER for a EVP_CIPHER_CTX context.
+ *
+ * @param ctx the context to get the cipher type from.
+ *
+ * @return the EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_CIPHER_CTX_cipher(EVP_CIPHER_CTX *ctx)
+{
+    return ctx->cipher;
+}
+
+/**
+ * Return the block size of the cipher context.
+ *
+ * @param ctx cipher context to get the block size from.
+ *
+ * @return the block size of the cipher context.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+size_t
+EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx)
+{
+    return EVP_CIPHER_block_size(ctx->cipher);
+}
+
+/**
+ * Return the key size of the cipher context.
+ *
+ * @param ctx cipher context to get the key size from.
+ *
+ * @return the key size of the cipher context.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+size_t
+EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx)
+{
+    return EVP_CIPHER_key_length(ctx->cipher);
+}
+
+/**
+ * Return the IV size of the cipher context.
+ *
+ * @param ctx cipher context to get the IV size from.
+ *
+ * @return the IV size of the cipher context.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+size_t
+EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
+{
+    return EVP_CIPHER_iv_length(ctx->cipher);
+}
+
+/**
+ * Get the flags for an EVP_CIPHER_CTX context.
+ *
+ * @param ctx the EVP_CIPHER_CTX to get the flags from
+ *
+ * @return the flags for an EVP_CIPHER_CTX.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+unsigned long
+EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx)
+{
+    return ctx->cipher->flags;
+}
+
+/**
+ * Get the mode for an EVP_CIPHER_CTX context.
+ *
+ * @param ctx the EVP_CIPHER_CTX to get the mode from
+ *
+ * @return the mode for an EVP_CIPHER_CTX.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+int
+EVP_CIPHER_CTX_mode(const EVP_CIPHER_CTX *ctx)
+{
+    return EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_MODE;
+}
+
+/**
+ * Get the app data for an EVP_CIPHER_CTX context.
+ *
+ * @param ctx the EVP_CIPHER_CTX to get the app data from
+ *
+ * @return the app data for an EVP_CIPHER_CTX.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+void *
+EVP_CIPHER_CTX_get_app_data(EVP_CIPHER_CTX *ctx)
+{
+    return ctx->app_data;
+}
+
+/**
+ * Set the app data for an EVP_CIPHER_CTX context.
+ *
+ * @param ctx the EVP_CIPHER_CTX to set the app data for
+ * @param data the app data to set for an EVP_CIPHER_CTX.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+void
+EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data)
+{
+    ctx->app_data = data;
+}
+
+/**
+ * Initiate the EVP_CIPHER_CTX context to encrypt or decrypt data.
+ * Clean up with EVP_CIPHER_CTX_cleanup().
+ *
+ * @param ctx context to initiate
+ * @param c cipher to use.
+ * @param engine crypto engine to use, NULL to select default.
+ * @param key the crypto key to use, NULL will use the previous value.
+ * @param iv the IV to use, NULL will use the previous value.
+ * @param encp non zero will encrypt, -1 use the previous value.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+int
+EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *c, ENGINE *engine,
+                 const void *key, const void *iv, int encp)
+{
+    ctx->buf_len = 0;
+
+    if (encp == -1)
+       encp = ctx->encrypt;
+    else
+       ctx->encrypt = (encp ? 1 : 0);
+
+    if (c && (c != ctx->cipher)) {
+       EVP_CIPHER_CTX_cleanup(ctx);
+       ctx->cipher = c;
+       ctx->key_len = c->key_len;
+
+       ctx->cipher_data = calloc(1, c->ctx_size);
+       if (ctx->cipher_data == NULL && c->ctx_size != 0)
+           return 0;
+
+       /* assume block size is a multiple of 2 */
+       ctx->block_mask = EVP_CIPHER_block_size(c) - 1;
+
+    } else if (ctx->cipher == NULL) {
+       /* reuse of cipher, but not any cipher ever set! */
+       return 0;
+    }
+
+    switch (EVP_CIPHER_CTX_mode(ctx)) {
+    case EVP_CIPH_CBC_MODE:
+
+       assert(EVP_CIPHER_CTX_iv_length(ctx) <= sizeof(ctx->iv));
+
+       if (iv)
+           memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
+       memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
+       break;
+
+    case EVP_CIPH_STREAM_CIPHER:
+       break;
+    case EVP_CIPH_CFB8_MODE:
+       if (iv)
+           memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx));
+       break;
+
+    default:
+       return 0;
+    }
+
+    if (key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT))
+       ctx->cipher->init(ctx, key, iv, encp);
+
+    return 1;
+}
+
+/**
+ * Encipher/decipher partial data
+ *
+ * @param ctx the cipher context.
+ * @param out output data from the operation.
+ * @param outlen output length
+ * @param in input data to the operation.
+ * @param inlen length of data.
+ *
+ * The output buffer length should at least be EVP_CIPHER_block_size()
+ * byte longer then the input length.
+ *
+ * See @ref evp_cipher for an example how to use this function.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+int
+EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, void *out, int *outlen,
+                void *in, size_t inlen)
+{
+    int ret, left, blocksize;
+
+    *outlen = 0;
+
+    /**
+     * If there in no spare bytes in the left from last Update and the
+     * input length is on the block boundery, the EVP_CipherUpdate()
+     * function can take a shortcut (and preformance gain) and
+     * directly encrypt the data, otherwise we hav to fix it up and
+     * store extra it the EVP_CIPHER_CTX.
+     */
+    if (ctx->buf_len == 0 && (inlen & ctx->block_mask) == 0) {
+       ret = (*ctx->cipher->do_cipher)(ctx, out, in, inlen);
+       if (ret == 1)
+           *outlen = inlen;
+       else
+           *outlen = 0;
+       return ret;
+    }
+
+
+    blocksize = EVP_CIPHER_CTX_block_size(ctx);
+    left = blocksize - ctx->buf_len;
+    assert(left > 0);
+
+    if (ctx->buf_len) {
+
+       /* if total buffer is smaller then input, store locally */
+       if (inlen < left) {
+           memcpy(ctx->buf + ctx->buf_len, in, inlen);
+           ctx->buf_len += inlen;
+           return 1;
+       }
+
+       /* fill in local buffer and encrypt */
+       memcpy(ctx->buf + ctx->buf_len, in, left);
+       ret = (*ctx->cipher->do_cipher)(ctx, out, ctx->buf, blocksize);
+       memset(ctx->buf, 0, blocksize);
+       if (ret != 1)
+           return ret;
+
+       *outlen += blocksize;
+       inlen -= left;
+       in = ((unsigned char *)in) + left;
+       out = ((unsigned char *)out) + blocksize;
+       ctx->buf_len = 0;
+    }
+
+    if (inlen) {
+       ctx->buf_len = (inlen & ctx->block_mask);
+       inlen &= ~ctx->block_mask;
+
+       ret = (*ctx->cipher->do_cipher)(ctx, out, in, inlen);
+       if (ret != 1)
+           return ret;
+
+       *outlen += inlen;
+
+       in = ((unsigned char *)in) + inlen;
+       memcpy(ctx->buf, in, ctx->buf_len);
+    }
+
+    return 1;
+}
+
+/**
+ * Encipher/decipher final data
+ *
+ * @param ctx the cipher context.
+ * @param out output data from the operation.
+ * @param outlen output length
+ *
+ * The input length needs to be at least EVP_CIPHER_block_size() bytes
+ * long.
+ *
+ * See @ref evp_cipher for an example how to use this function.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+int
+EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, void *out, int *outlen)
+{
+    *outlen = 0;
+
+    if (ctx->buf_len) {
+       int ret, left, blocksize;
+
+       blocksize = EVP_CIPHER_CTX_block_size(ctx);
+
+       left = blocksize - ctx->buf_len;
+       assert(left > 0);
+
+       /* zero fill local buffer */
+       memset(ctx->buf + ctx->buf_len, 0, left);
+       ret = (*ctx->cipher->do_cipher)(ctx, out, ctx->buf, blocksize);
+       memset(ctx->buf, 0, blocksize);
+       if (ret != 1)
+           return ret;
+
+       *outlen += blocksize;
+    }
+
+    return 1;
+}
+
+/**
+ * Encipher/decipher data
+ *
+ * @param ctx the cipher context.
+ * @param out out data from the operation.
+ * @param in in data to the operation.
+ * @param size length of data.
+ *
+ * @return 1 on success.
+ */
+
+int
+EVP_Cipher(EVP_CIPHER_CTX *ctx, void *out, const void *in,size_t size)
+{
+    return ctx->cipher->do_cipher(ctx, out, in, size);
+}
+
+/*
+ *
+ */
+
+static int
+enc_null_init(EVP_CIPHER_CTX *ctx,
+                 const unsigned char * key,
+                 const unsigned char * iv,
+                 int encp)
+{
+    return 1;
+}
+
+static int
+enc_null_do_cipher(EVP_CIPHER_CTX *ctx,
+             unsigned char *out,
+             const unsigned char *in,
+             unsigned int size)
+{
+    memmove(out, in, size);
+    return 1;
+}
+
+static int
+enc_null_cleanup(EVP_CIPHER_CTX *ctx)
+{
+    return 1;
+}
+
+/**
+ * The NULL cipher type, does no encryption/decryption.
+ *
+ * @return the null EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_enc_null(void)
+{
+    static const EVP_CIPHER enc_null = {
+       0,
+       0,
+       0,
+       0,
+       EVP_CIPH_CBC_MODE,
+       enc_null_init,
+       enc_null_do_cipher,
+       enc_null_cleanup,
+       0,
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &enc_null;
+}
+
+/**
+ * The RC2 cipher type
+ *
+ * @return the RC2 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_rc2_cbc(void)
+{
+    return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, rc2_cbc);
+}
+
+/**
+ * The RC2 cipher type
+ *
+ * @return the RC2 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_rc2_40_cbc(void)
+{
+    return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, rc2_40_cbc);
+}
+
+/**
+ * The RC2 cipher type
+ *
+ * @return the RC2 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_rc2_64_cbc(void)
+{
+    return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, rc2_64_cbc);
+}
+
+/**
+ * The RC4 cipher type
+ *
+ * @return the RC4 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_rc4(void)
+{
+    return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, rc4);
+}
+
+/**
+ * The RC4-40 cipher type
+ *
+ * @return the RC4-40 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_rc4_40(void)
+{
+    return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, rc4_40);
+}
+
+/**
+ * The DES cipher type
+ *
+ * @return the DES-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_des_cbc(void)
+{
+    return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, des_cbc);
+}
+
+/**
+ * The tripple DES cipher type
+ *
+ * @return the DES-EDE3-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_des_ede3_cbc(void)
+{
+    return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, des_ede3_cbc);
+}
+
+/**
+ * The AES-128 cipher type
+ *
+ * @return the AES-128 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_aes_128_cbc(void)
+{
+    return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, aes_128_cbc);
+}
+
+/**
+ * The AES-192 cipher type
+ *
+ * @return the AES-192 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_aes_192_cbc(void)
+{
+    return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, aes_192_cbc);
+}
+
+/**
+ * The AES-256 cipher type
+ *
+ * @return the AES-256 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_aes_256_cbc(void)
+{
+    return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, aes_256_cbc);
+}
+
+/**
+ * The AES-128 cipher type
+ *
+ * @return the AES-128 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_aes_128_cfb8(void)
+{
+    return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, aes_128_cfb8);
+}
+
+/**
+ * The AES-192 cipher type
+ *
+ * @return the AES-192 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_aes_192_cfb8(void)
+{
+    return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, aes_192_cfb8);
+}
+
+/**
+ * The AES-256 cipher type
+ *
+ * @return the AES-256 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_aes_256_cfb8(void)
+{
+    return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, aes_256_cfb8);
+}
+
+/**
+ * The Camellia-128 cipher type
+ *
+ * @return the Camellia-128 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_camellia_128_cbc(void)
+{
+    return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, camellia_128_cbc);
+}
+
+/**
+ * The Camellia-198 cipher type
+ *
+ * @return the Camellia-198 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_camellia_192_cbc(void)
+{
+    return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, camellia_192_cbc);
+}
+
+/**
+ * The Camellia-256 cipher type
+ *
+ * @return the Camellia-256 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_camellia_256_cbc(void)
+{
+    return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, camellia_256_cbc);
+}
+
+/*
+ *
+ */
+
+static const struct cipher_name {
+    const char *name;
+    const EVP_CIPHER *(*func)(void);
+} cipher_name[] = {
+    { "des-ede3-cbc", EVP_des_ede3_cbc },
+    { "aes-128-cbc", EVP_aes_128_cbc },
+    { "aes-192-cbc", EVP_aes_192_cbc },
+    { "aes-256-cbc", EVP_aes_256_cbc },
+    { "aes-128-cfb8", EVP_aes_128_cfb8 },
+    { "aes-192-cfb8", EVP_aes_192_cfb8 },
+    { "aes-256-cfb8", EVP_aes_256_cfb8 },
+    { "camellia-128-cbc", EVP_camellia_128_cbc },
+    { "camellia-192-cbc", EVP_camellia_192_cbc },
+    { "camellia-256-cbc", EVP_camellia_256_cbc }
+};
+
+/**
+ * Get the cipher type using their name.
+ *
+ * @param name the name of the cipher.
+ *
+ * @return the selected EVP_CIPHER pointer or NULL if not found.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_get_cipherbyname(const char *name)
+{
+    int i;
+    for (i = 0; i < sizeof(cipher_name)/sizeof(cipher_name[0]); i++) {
+       if (strcasecmp(cipher_name[i].name, name) == 0)
+           return (*cipher_name[i].func)();
+    }
+    return NULL;
+}
+
+
+/*
+ *
+ */
+
+#ifndef min
+#define min(a,b) (((a)>(b))?(b):(a))
+#endif
+
+/**
+ * Provides a legancy string to key function, used in PEM files.
+ *
+ * New protocols should use new string to key functions like NIST
+ * SP56-800A or PKCS#5 v2.0 (see PKCS5_PBKDF2_HMAC_SHA1()).
+ *
+ * @param type type of cipher to use
+ * @param md message digest to use
+ * @param salt salt salt string, should be an binary 8 byte buffer.
+ * @param data the password/input key string.
+ * @param datalen length of data parameter.
+ * @param count iteration counter.
+ * @param keydata output keydata, needs to of the size EVP_CIPHER_key_length().
+ * @param ivdata output ivdata, needs to of the size EVP_CIPHER_block_size().
+ *
+ * @return the size of derived key.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+int
+EVP_BytesToKey(const EVP_CIPHER *type,
+              const EVP_MD *md,
+              const void *salt,
+              const void *data, size_t datalen,
+              unsigned int count,
+              void *keydata,
+              void *ivdata)
+{
+    int ivlen, keylen, first = 0;
+    unsigned int mds = 0, i;
+    unsigned char *key = keydata;
+    unsigned char *iv = ivdata;
+    unsigned char *buf;
+    EVP_MD_CTX c;
+
+    keylen = EVP_CIPHER_key_length(type);
+    ivlen = EVP_CIPHER_iv_length(type);
+
+    if (data == NULL)
+       return keylen;
+
+    buf = malloc(EVP_MD_size(md));
+    if (buf == NULL)
+       return -1;
+
+    EVP_MD_CTX_init(&c);
+
+    first = 1;
+    while (1) {
+       EVP_DigestInit_ex(&c, md, NULL);
+       if (!first)
+           EVP_DigestUpdate(&c, buf, mds);
+       first = 0;
+       EVP_DigestUpdate(&c,data,datalen);
+
+#define PKCS5_SALT_LEN 8
+
+       if (salt)
+           EVP_DigestUpdate(&c, salt, PKCS5_SALT_LEN);
+
+       EVP_DigestFinal_ex(&c, buf, &mds);
+       assert(mds == EVP_MD_size(md));
+
+       for (i = 1; i < count; i++) {
+           EVP_DigestInit_ex(&c, md, NULL);
+           EVP_DigestUpdate(&c, buf, mds);
+           EVP_DigestFinal_ex(&c, buf, &mds);
+           assert(mds == EVP_MD_size(md));
+       }
+
+       i = 0;
+       if (keylen) {
+           size_t sz = min(keylen, mds);
+           if (key) {
+               memcpy(key, buf, sz);
+               key += sz;
+           }
+           keylen -= sz;
+           i += sz;
+       }
+       if (ivlen && mds > i) {
+           size_t sz = min(ivlen, (mds - i));
+           if (iv) {
+               memcpy(iv, &buf[i], sz);
+               iv += sz;
+           }
+           ivlen -= sz;
+       }
+       if (keylen == 0 && ivlen == 0)
+           break;
+    }
+
+    EVP_MD_CTX_cleanup(&c);
+    free(buf);
+
+    return EVP_CIPHER_key_length(type);
+}
+
+/**
+ * Generate a random key for the specificed EVP_CIPHER.
+ *
+ * @param ctx EVP_CIPHER_CTX type to build the key for.
+ * @param key return key, must be at least EVP_CIPHER_key_length() byte long.
+ *
+ * @return 1 for success, 0 for failure.
+ *
+ * @ingroup hcrypto_core
+ */
+
+int
+EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, void *key)
+{
+    if (ctx->cipher->flags & EVP_CIPH_RAND_KEY)
+       return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key);
+    if (RAND_bytes(key, ctx->key_len) != 1)
+       return 0;
+    return 1;
+}
+
+/**
+ * Perform a operation on a ctx
+ *
+ * @param ctx context to perform operation on.
+ * @param type type of operation.
+ * @param arg argument to operation.
+ * @param data addition data to operation.
+
+ * @return 1 for success, 0 for failure.
+ *
+ * @ingroup hcrypto_core
+ */
+
+int
+EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *data)
+{
+    if (ctx->cipher == NULL || ctx->cipher->ctrl == NULL)
+       return 0;
+    return (*ctx->cipher->ctrl)(ctx, type, arg, data);
+}
+
+/**
+ * Add all algorithms to the crypto core.
+ *
+ * @ingroup hcrypto_core
+ */
+
+void
+OpenSSL_add_all_algorithms(void)
+{
+    return;
+}
+
+/**
+ * Add all algorithms to the crypto core using configuration file.
+ *
+ * @ingroup hcrypto_core
+ */
+
+void
+OpenSSL_add_all_algorithms_conf(void)
+{
+    return;
+}
+
+/**
+ * Add all algorithms to the crypto core, but don't use the
+ * configuration file.
+ *
+ * @ingroup hcrypto_core
+ */
+
+void
+OpenSSL_add_all_algorithms_noconf(void)
+{
+    return;
+}
diff --git a/src/external/heimdal/hcrypto/evp.h b/src/external/heimdal/hcrypto/evp.h
new file mode 100644 (file)
index 0000000..75ca744
--- /dev/null
@@ -0,0 +1,321 @@
+/*
+ * Copyright (c) 2005 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+/* $Id$ */
+
+#ifndef HEIM_EVP_H
+#define HEIM_EVP_H 1
+
+#include <hcrypto/engine.h>
+
+/* symbol renaming */
+#define EVP_CIPHER_CTX_block_size hc_EVP_CIPHER_CTX_block_size
+#define EVP_CIPHER_CTX_cipher hc_EVP_CIPHER_CTX_cipher
+#define EVP_CIPHER_CTX_cleanup hc_EVP_CIPHER_CTX_cleanup
+#define EVP_CIPHER_CTX_flags hc_EVP_CIPHER_CTX_flags
+#define EVP_CIPHER_CTX_get_app_data hc_EVP_CIPHER_CTX_get_app_data
+#define EVP_CIPHER_CTX_init hc_EVP_CIPHER_CTX_init
+#define EVP_CIPHER_CTX_iv_length hc_EVP_CIPHER_CTX_iv_length
+#define EVP_CIPHER_CTX_key_length hc_EVP_CIPHER_CTX_key_length
+#define EVP_CIPHER_CTX_mode hc_EVP_CIPHER_CTX_mode
+#define EVP_CIPHER_CTX_set_app_data hc_EVP_CIPHER_CTX_set_app_data
+#define EVP_CIPHER_CTX_set_key_length hc_EVP_CIPHER_CTX_set_key_length
+#define EVP_CIPHER_CTX_set_padding hc_EVP_CIPHER_CTX_set_padding
+#define EVP_CIPHER_block_size hc_EVP_CIPHER_block_size
+#define EVP_CIPHER_iv_length hc_EVP_CIPHER_iv_length
+#define EVP_CIPHER_key_length hc_EVP_CIPHER_key_length
+#define EVP_Cipher hc_EVP_Cipher
+#define EVP_CipherInit_ex hc_EVP_CipherInit_ex
+#define EVP_CipherUpdate hc_EVP_CipherUpdate
+#define EVP_CipherFinal_ex hc_EVP_CipherFinal_ex
+#define EVP_Digest hc_EVP_Digest
+#define EVP_DigestFinal_ex hc_EVP_DigestFinal_ex
+#define EVP_DigestInit_ex hc_EVP_DigestInit_ex
+#define EVP_DigestUpdate hc_EVP_DigestUpdate
+#define EVP_MD_CTX_block_size hc_EVP_MD_CTX_block_size
+#define EVP_MD_CTX_cleanup hc_EVP_MD_CTX_cleanup
+#define EVP_MD_CTX_create hc_EVP_MD_CTX_create
+#define EVP_MD_CTX_init hc_EVP_MD_CTX_init
+#define EVP_MD_CTX_destroy hc_EVP_MD_CTX_destroy
+#define EVP_MD_CTX_md hc_EVP_MD_CTX_md
+#define EVP_MD_CTX_size hc_EVP_MD_CTX_size
+#define EVP_MD_block_size hc_EVP_MD_block_size
+#define EVP_MD_size hc_EVP_MD_size
+#define EVP_aes_128_cbc hc_EVP_aes_128_cbc
+#define EVP_aes_192_cbc hc_EVP_aes_192_cbc
+#define EVP_aes_256_cbc hc_EVP_aes_256_cbc
+#define EVP_aes_128_cfb8 hc_EVP_aes_128_cfb8
+#define EVP_aes_192_cfb8 hc_EVP_aes_192_cfb8
+#define EVP_aes_256_cfb8 hc_EVP_aes_256_cfb8
+
+#define EVP_des_cbc hc_EVP_des_cbc
+#define EVP_des_ede3_cbc hc_EVP_des_ede3_cbc
+#define EVP_enc_null hc_EVP_enc_null
+#define EVP_md2 hc_EVP_md2
+#define EVP_md4 hc_EVP_md4
+#define EVP_md5 hc_EVP_md5
+#define EVP_md_null hc_EVP_md_null
+#define EVP_rc2_40_cbc hc_EVP_rc2_40_cbc
+#define EVP_rc2_64_cbc hc_EVP_rc2_64_cbc
+#define EVP_rc2_cbc hc_EVP_rc2_cbc
+#define EVP_rc4 hc_EVP_rc4
+#define EVP_rc4_40 hc_EVP_rc4_40
+#define EVP_camellia_128_cbc hc_EVP_camellia_128_cbc
+#define EVP_camellia_192_cbc hc_EVP_camellia_192_cbc
+#define EVP_camellia_256_cbc hc_EVP_camellia_256_cbc
+#define EVP_sha hc_EVP_sha
+#define EVP_sha1 hc_EVP_sha1
+#define EVP_sha256 hc_EVP_sha256
+#define PKCS5_PBKDF2_HMAC_SHA1 hc_PKCS5_PBKDF2_HMAC_SHA1
+#define EVP_BytesToKey hc_EVP_BytesToKey
+#define EVP_get_cipherbyname hc_EVP_get_cipherbyname
+#define        OpenSSL_add_all_algorithms hc_OpenSSL_add_all_algorithms
+#define        OpenSSL_add_all_algorithms_conf hc_OpenSSL_add_all_algorithms_conf
+#define        OpenSSL_add_all_algorithms_noconf hc_OpenSSL_add_all_algorithms_noconf
+#define EVP_CIPHER_CTX_ctrl hc_EVP_CIPHER_CTX_ctrl
+#define EVP_CIPHER_CTX_rand_key hc_EVP_CIPHER_CTX_rand_key
+
+/*
+ *
+ */
+
+typedef struct hc_EVP_MD_CTX EVP_MD_CTX;
+typedef struct hc_evp_pkey EVP_PKEY;
+typedef struct hc_evp_md EVP_MD;
+typedef struct hc_CIPHER EVP_CIPHER;
+typedef struct hc_CIPHER_CTX EVP_CIPHER_CTX;
+
+#define EVP_MAX_IV_LENGTH      16
+#define EVP_MAX_BLOCK_LENGTH   32
+
+#define EVP_MAX_MD_SIZE                64
+
+struct hc_CIPHER {
+    int nid;
+    int block_size;
+    int key_len;
+    int iv_len;
+    unsigned long flags;
+    /* The lowest 3 bits is used as integer field for the mode the
+     * cipher is used in (use EVP_CIPHER.._mode() to extract the
+     * mode). The rest of the flag field is a bitfield.
+     */
+#define EVP_CIPH_STREAM_CIPHER         0
+#define EVP_CIPH_CBC_MODE              2
+#define EVP_CIPH_CFB8_MODE              4
+#define EVP_CIPH_MODE                  0x7
+
+#define EVP_CIPH_VARIABLE_LENGTH       0x008 /* variable key length */
+#define EVP_CIPH_ALWAYS_CALL_INIT      0x020
+#define EVP_CIPH_RAND_KEY              0x200
+
+    int (*init)(EVP_CIPHER_CTX*,const unsigned char*,const unsigned char*,int);
+    int (*do_cipher)(EVP_CIPHER_CTX *, unsigned char *,
+                    const unsigned char *, unsigned int);
+    int (*cleanup)(EVP_CIPHER_CTX *);
+    int ctx_size;
+    void *set_asn1_parameters;
+    void *get_asn1_parameters;
+    int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr);
+#define EVP_CTRL_RAND_KEY              0x6
+
+    void *app_data;
+};
+
+struct hc_CIPHER_CTX {
+    const EVP_CIPHER *cipher;
+    ENGINE *engine;
+    int encrypt;
+    int buf_len; /* bytes stored in buf for EVP_CipherUpdate */
+    unsigned char oiv[EVP_MAX_IV_LENGTH];
+    unsigned char iv[EVP_MAX_IV_LENGTH];
+    unsigned char buf[EVP_MAX_BLOCK_LENGTH];
+    int num;
+    void *app_data;
+    int key_len;
+    unsigned long flags;
+    void *cipher_data;
+    int final_used;
+    int block_mask;
+    unsigned char final[EVP_MAX_BLOCK_LENGTH];
+};
+
+typedef int (*hc_evp_md_init)(EVP_MD_CTX *);
+typedef int (*hc_evp_md_update)(EVP_MD_CTX *,const void *, size_t);
+typedef int (*hc_evp_md_final)(void *, EVP_MD_CTX *);
+typedef int (*hc_evp_md_cleanup)(EVP_MD_CTX *);
+
+struct hc_evp_md {
+    int hash_size;
+    int block_size;
+    int ctx_size;
+    hc_evp_md_init init;
+    hc_evp_md_update update;
+    hc_evp_md_final final;
+    hc_evp_md_cleanup cleanup;
+};
+
+#if !defined(__GNUC__) && !defined(__attribute__)
+#define __attribute__(x)
+#endif
+
+#ifndef HC_DEPRECATED
+#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1 )))
+#define HC_DEPRECATED __attribute__((deprecated))
+#elif defined(_MSC_VER) && (_MSC_VER>1200)
+#define HC_DEPRECATED __declspec(deprecated)
+#else
+#define HC_DEPRECATED
+#endif
+#endif
+
+#ifndef HC_DEPRECATED_CRYPTO
+#define HC_DEPRECATED_CRYPTO HC_DEPRECATED
+#endif
+
+#ifdef __cplusplus
+#define HC_CPP_BEGIN extern "C" {
+#define HC_CPP_END }
+#else
+#define HC_CPP_BEGIN
+#define HC_CPP_END
+#endif
+
+HC_CPP_BEGIN
+
+/*
+ * Avaible crypto algs
+ */
+
+const EVP_MD *EVP_md_null(void);
+HC_DEPRECATED_CRYPTO const EVP_MD *EVP_md2(void);
+HC_DEPRECATED_CRYPTO const EVP_MD *EVP_md4(void);
+HC_DEPRECATED_CRYPTO const EVP_MD *EVP_md5(void);
+const EVP_MD *EVP_sha(void);
+const EVP_MD *EVP_sha1(void);
+const EVP_MD *EVP_sha256(void);
+
+const EVP_CIPHER * EVP_aes_128_cbc(void);
+const EVP_CIPHER * EVP_aes_192_cbc(void);
+const EVP_CIPHER * EVP_aes_256_cbc(void);
+const EVP_CIPHER * EVP_aes_128_cfb8(void);
+const EVP_CIPHER * EVP_aes_192_cfb8(void);
+const EVP_CIPHER * EVP_aes_256_cfb8(void);
+HC_DEPRECATED_CRYPTO const EVP_CIPHER * EVP_des_cbc(void);
+const EVP_CIPHER * EVP_des_ede3_cbc(void);
+const EVP_CIPHER * EVP_enc_null(void);
+HC_DEPRECATED_CRYPTO const EVP_CIPHER * EVP_rc2_40_cbc(void);
+HC_DEPRECATED_CRYPTO const EVP_CIPHER * EVP_rc2_64_cbc(void);
+HC_DEPRECATED_CRYPTO const EVP_CIPHER * EVP_rc2_cbc(void);
+const EVP_CIPHER * EVP_rc4(void);
+HC_DEPRECATED_CRYPTO const EVP_CIPHER * EVP_rc4_40(void);
+const EVP_CIPHER * EVP_camellia_128_cbc(void);
+const EVP_CIPHER * EVP_camellia_192_cbc(void);
+const EVP_CIPHER * EVP_camellia_256_cbc(void);
+
+size_t EVP_MD_size(const EVP_MD *);
+size_t EVP_MD_block_size(const EVP_MD *);
+
+const EVP_MD *
+       EVP_MD_CTX_md(EVP_MD_CTX *);
+size_t EVP_MD_CTX_size(EVP_MD_CTX *);
+size_t EVP_MD_CTX_block_size(EVP_MD_CTX *);
+
+EVP_MD_CTX *
+       EVP_MD_CTX_create(void);
+void   HC_DEPRECATED EVP_MD_CTX_init(EVP_MD_CTX *);
+void   EVP_MD_CTX_destroy(EVP_MD_CTX *);
+int    HC_DEPRECATED EVP_MD_CTX_cleanup(EVP_MD_CTX *);
+
+int    EVP_DigestInit_ex(EVP_MD_CTX *, const EVP_MD *, ENGINE *);
+int    EVP_DigestUpdate(EVP_MD_CTX *,const void *, size_t);
+int    EVP_DigestFinal_ex(EVP_MD_CTX *, void *, unsigned int *);
+int    EVP_Digest(const void *, size_t, void *, unsigned int *,
+                  const EVP_MD *, ENGINE *);
+/*
+ *
+ */
+
+const EVP_CIPHER *
+       EVP_get_cipherbyname(const char *);
+
+size_t EVP_CIPHER_block_size(const EVP_CIPHER *);
+size_t EVP_CIPHER_key_length(const EVP_CIPHER *);
+size_t EVP_CIPHER_iv_length(const EVP_CIPHER *);
+
+void   EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *);
+int    EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *);
+int    EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *, int);
+int    EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *, int);
+unsigned long
+       EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *);
+int    EVP_CIPHER_CTX_mode(const EVP_CIPHER_CTX *);
+
+const EVP_CIPHER *
+       EVP_CIPHER_CTX_cipher(EVP_CIPHER_CTX *);
+size_t EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *);
+size_t EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *);
+size_t EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *);
+void * EVP_CIPHER_CTX_get_app_data(EVP_CIPHER_CTX *);
+void   EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *, void *);
+
+int    EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *, int, int, void *);
+int    EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *, void *);
+
+
+int    EVP_CipherInit_ex(EVP_CIPHER_CTX *,const EVP_CIPHER *, ENGINE *,
+                         const void *, const void *, int);
+int    EVP_CipherUpdate(EVP_CIPHER_CTX *, void *, int *, void *, size_t);
+int    EVP_CipherFinal_ex(EVP_CIPHER_CTX *, void *, int *);
+
+int    EVP_Cipher(EVP_CIPHER_CTX *,void *,const void *,size_t);
+
+int    PKCS5_PBKDF2_HMAC_SHA1(const void *, size_t, const void *, size_t,
+                              unsigned long, size_t, void *);
+
+int    EVP_BytesToKey(const EVP_CIPHER *, const EVP_MD *,
+                      const void *, const void *, size_t,
+                      unsigned int, void *, void *);
+
+
+/*
+ *
+ */
+
+void   OpenSSL_add_all_algorithms(void);
+void   OpenSSL_add_all_algorithms_conf(void);
+void   OpenSSL_add_all_algorithms_noconf(void);
+
+HC_CPP_END
+
+#endif /* HEIM_EVP_H */
diff --git a/src/external/heimdal/hcrypto/hash.h b/src/external/heimdal/hcrypto/hash.h
new file mode 100644 (file)
index 0000000..cfec9cf
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN 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. */
+
+/* $Id$ */
+
+/* stuff in common between md4, md5, and sha1 */
+
+#ifndef __hash_h__
+#define __hash_h__
+
+#ifdef KRB5
+#include <krb5-types.h>
+#endif
+#include <roken.h>
+
+#ifndef min
+#define min(a,b) (((a)>(b))?(b):(a))
+#endif
+
+/* Vector Crays doesn't have a good 32-bit type, or more precisely,
+   int32_t as defined by <bind/bitypes.h> isn't 32 bits, and we don't
+   want to depend in being able to redefine this type.  To cope with
+   this we have to clamp the result in some places to [0,2^32); no
+   need to do this on other machines.  Did I say this was a mess?
+   */
+
+#ifdef _CRAY
+#define CRAYFIX(X) ((X) & 0xffffffff)
+#else
+#define CRAYFIX(X) (X)
+#endif
+
+static inline uint32_t
+cshift (uint32_t x, unsigned int n)
+{
+    x = CRAYFIX(x);
+    return CRAYFIX((x << n) | (x >> (32 - n)));
+}
+
+#endif /* __hash_h__ */
diff --git a/src/external/heimdal/hcrypto/hmac.c b/src/external/heimdal/hcrypto/hmac.c
new file mode 100644 (file)
index 0000000..d11bd98
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <hmac.h>
+
+void
+HMAC_CTX_init(HMAC_CTX *ctx)
+{
+    memset(ctx, 0, sizeof(*ctx));
+}
+
+void
+HMAC_CTX_cleanup(HMAC_CTX *ctx)
+{
+    if (ctx->buf) {
+       memset(ctx->buf, 0, ctx->key_length);
+       free(ctx->buf);
+       ctx->buf = NULL;
+    }
+    if (ctx->opad) {
+       memset(ctx->opad, 0, EVP_MD_block_size(ctx->md));
+       free(ctx->opad);
+       ctx->opad = NULL;
+    }
+    if (ctx->ipad) {
+       memset(ctx->ipad, 0, EVP_MD_block_size(ctx->md));
+       free(ctx->ipad);
+       ctx->ipad = NULL;
+    }
+    if (ctx->ctx) {
+       EVP_MD_CTX_destroy(ctx->ctx);
+       ctx->ctx = NULL;
+    }
+}
+
+size_t
+HMAC_size(const HMAC_CTX *ctx)
+{
+    return EVP_MD_size(ctx->md);
+}
+
+void
+HMAC_Init_ex(HMAC_CTX *ctx,
+            const void *key,
+            size_t keylen,
+            const EVP_MD *md,
+            ENGINE *engine)
+{
+    unsigned char *p;
+    size_t i;
+
+    if (ctx->md != md) {
+       ctx->md = md;
+       if (ctx->buf) {
+           memset(ctx->buf, 0, ctx->key_length);
+           free (ctx->buf);
+       }
+       ctx->key_length = EVP_MD_size(ctx->md);
+       ctx->buf = malloc(ctx->key_length);
+    }
+#if 0
+    ctx->engine = engine;
+#endif
+
+    if (keylen > EVP_MD_block_size(ctx->md)) {
+       EVP_Digest(key, keylen, ctx->buf, NULL, ctx->md, engine);
+       key = ctx->buf;
+       keylen = EVP_MD_size(ctx->md);
+    }
+
+    if (ctx->opad) {
+       memset(ctx->opad, 0, ctx->key_length);
+       free(ctx->opad);
+    }
+    if (ctx->ipad) {
+       memset(ctx->ipad, 0, ctx->key_length);
+       free(ctx->ipad);
+    }
+
+    ctx->opad = malloc(EVP_MD_block_size(ctx->md));
+    ctx->ipad = malloc(EVP_MD_block_size(ctx->md));
+    memset(ctx->ipad, 0x36, EVP_MD_block_size(ctx->md));
+    memset(ctx->opad, 0x5c, EVP_MD_block_size(ctx->md));
+
+    for (i = 0, p = ctx->ipad; i < keylen; i++)
+       p[i] ^= ((const unsigned char *)key)[i];
+    for (i = 0, p = ctx->opad; i < keylen; i++)
+       p[i] ^= ((const unsigned char *)key)[i];
+
+    if (ctx->ctx == NULL)
+       ctx->ctx = EVP_MD_CTX_create();
+
+    EVP_DigestInit_ex(ctx->ctx, ctx->md, ctx->engine);
+    EVP_DigestUpdate(ctx->ctx, ctx->ipad, EVP_MD_block_size(ctx->md));
+}
+
+void
+HMAC_Update(HMAC_CTX *ctx, const void *data, size_t len)
+{
+    EVP_DigestUpdate(ctx->ctx, data, len);
+}
+
+void
+HMAC_Final(HMAC_CTX *ctx, void *md, unsigned int *len)
+{
+    EVP_DigestFinal_ex(ctx->ctx, ctx->buf, NULL);
+
+    EVP_DigestInit_ex(ctx->ctx, ctx->md, ctx->engine);
+    EVP_DigestUpdate(ctx->ctx, ctx->opad, EVP_MD_block_size(ctx->md));
+    EVP_DigestUpdate(ctx->ctx, ctx->buf, ctx->key_length);
+    EVP_DigestFinal_ex(ctx->ctx, md, len);
+}
+
+void *
+HMAC(const EVP_MD *md,
+     const void *key, size_t key_size,
+     const void *data, size_t data_size,
+     void *hash, unsigned int *hash_len)
+{
+    HMAC_CTX ctx;
+
+    HMAC_CTX_init(&ctx);
+    HMAC_Init_ex(&ctx, key, key_size, md, NULL);
+    HMAC_Update(&ctx, data, data_size);
+    HMAC_Final(&ctx, hash, hash_len);
+    HMAC_CTX_cleanup(&ctx);
+    return hash;
+}
diff --git a/src/external/heimdal/hcrypto/hmac.h b/src/external/heimdal/hcrypto/hmac.h
new file mode 100644 (file)
index 0000000..3ea17a9
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2005 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+/* $Id$ */
+
+#ifndef HEIM_HMAC_H
+#define HEIM_HMAC_H 1
+
+#include <hcrypto/evp.h>
+
+/* symbol renaming */
+#define HMAC_CTX_init hc_HMAC_CTX_init
+#define HMAC_CTX_cleanup hc_HMAC_CTX_cleanup
+#define HMAC_size hc_HMAC_size
+#define HMAC_Init_ex hc_HMAC_Init_ex
+#define HMAC_Update hc_HMAC_Update
+#define HMAC_Final hc_HMAC_Final
+#define HMAC hc_HMAC
+
+/*
+ *
+ */
+
+#define HMAC_MAX_MD_CBLOCK     64
+
+typedef struct hc_HMAC_CTX HMAC_CTX;
+
+struct hc_HMAC_CTX {
+    const EVP_MD *md;
+    ENGINE *engine;
+    EVP_MD_CTX *ctx;
+    size_t key_length;
+    void *opad;
+    void *ipad;
+    void *buf;
+};
+
+
+void   HMAC_CTX_init(HMAC_CTX *);
+void   HMAC_CTX_cleanup(HMAC_CTX *ctx);
+
+size_t HMAC_size(const HMAC_CTX *ctx);
+
+void   HMAC_Init_ex(HMAC_CTX *, const void *, size_t,
+                    const EVP_MD *, ENGINE *);
+void   HMAC_Update(HMAC_CTX *ctx, const void *data, size_t len);
+void   HMAC_Final(HMAC_CTX *ctx, void *md, unsigned int *len);
+
+void * HMAC(const EVP_MD *evp_md, const void *key, size_t key_len,
+            const void *data, size_t n, void *md, unsigned int *md_len);
+
+#endif /* HEIM_HMAC_H */
diff --git a/src/external/heimdal/hcrypto/md2.c b/src/external/heimdal/hcrypto/md2.c
new file mode 100644 (file)
index 0000000..26254ac
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+#include "config.h"
+
+#include "hash.h"
+#include "md2.h"
+
+static const unsigned char subst[256] = {
+  41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
+  19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
+  76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
+  138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
+  245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
+  148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
+  39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
+  181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
+  150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
+  112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
+  96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
+  85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
+  234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
+  129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
+  8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
+  203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
+  166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
+  31, 26, 219, 153, 141, 51, 159, 17, 131, 20
+};
+
+void
+MD2_Init (struct md2 *m)
+{
+    memset(m, 0, sizeof(*m));
+}
+
+static void
+calc(struct md2 *m, const void *v)
+{
+    unsigned char x[48], L;
+    const unsigned char *p = v;
+    int i, j, t;
+
+    L = m->checksum[15];
+    for (i = 0; i < 16; i++)
+       L = m->checksum[i] ^= subst[p[i] ^ L];
+
+    for (i = 0; i < 16; i++) {
+       x[i]      = m->state[i];
+       x[i + 16] = p[i];
+       x[i + 32] = x[i] ^ p[i];
+    }
+
+    t = 0;
+    for (i = 0; i < 18; i++) {
+       for (j = 0; j < 48; j++)
+           t = x[j] ^= subst[t];
+       t = (t + i) & 0xff;
+    }
+
+    memcpy(m->state, x, 16);
+    memset(x, 0, sizeof(x));
+}
+
+void
+MD2_Update (struct md2 *m, const void *v, size_t len)
+{
+    size_t idx = m->len & 0xf;
+    const unsigned char *p = v;
+
+    m->len += len;
+    if (len + idx >= 16) {
+       if (idx) {
+           memcpy(m->data + idx, p, 16 - idx);
+           calc(m, m->data);
+           p += 16;
+           len -= 16 - idx;
+       }
+       while (len >= 16) {
+           calc(m, p);
+           p += 16;
+           len -= 16;
+       }
+       idx = 0;
+    }
+
+    memcpy(m->data + idx, p, len);
+}
+
+void
+MD2_Final (void *res, struct md2 *m)
+{
+    unsigned char pad[16];
+    size_t padlen;
+
+    padlen = 16 - (m->len % 16);
+    memset(pad, padlen, padlen);
+
+    MD2_Update(m, pad, padlen);
+    memcpy(pad, m->checksum, 16);
+    MD2_Update(m, pad, 16);
+
+    memcpy(res, m->state, MD2_DIGEST_LENGTH);
+    memset(m, 0, sizeof(m));
+}
diff --git a/src/external/heimdal/hcrypto/md2.h b/src/external/heimdal/hcrypto/md2.h
new file mode 100644 (file)
index 0000000..af76506
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+/* $Id$ */
+
+#ifndef HEIM_MD2_H
+#define HEIM_MD2_H 1
+
+/* symbol renaming */
+#define MD2_Init hc_MD2_Init
+#define MD2_Update hc_MD2_Update
+#define MD2_Final hc_MD2_Final
+
+/*
+ *
+ */
+
+#define MD2_DIGEST_LENGTH 16
+
+struct md2 {
+    size_t len;
+    unsigned char data[16]; /* stored unalligned data between Update's */
+    unsigned char checksum[16];
+    unsigned char state[16]; /* lower 16 bytes of X */
+};
+
+typedef struct md2 MD2_CTX;
+
+void MD2_Init (struct md2 *m);
+void MD2_Update (struct md2 *m, const void *p, size_t len);
+void MD2_Final (void *res, struct md2 *m);
+
+#endif /* HEIM_MD2_H */
diff --git a/src/external/heimdal/hcrypto/md4.c b/src/external/heimdal/hcrypto/md4.c
new file mode 100644 (file)
index 0000000..435e662
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+#include "config.h"
+
+#include "hash.h"
+#include "md4.h"
+
+#define A m->counter[0]
+#define B m->counter[1]
+#define C m->counter[2]
+#define D m->counter[3]
+#define X data
+
+void
+MD4_Init (struct md4 *m)
+{
+  m->sz[0] = 0;
+  m->sz[1] = 0;
+  D = 0x10325476;
+  C = 0x98badcfe;
+  B = 0xefcdab89;
+  A = 0x67452301;
+}
+
+#define F(x,y,z) CRAYFIX((x & y) | (~x & z))
+#define G(x,y,z) ((x & y) | (x & z) | (y & z))
+#define H(x,y,z) (x ^ y ^ z)
+
+#define DOIT(a,b,c,d,k,s,i,OP) \
+a = cshift(a + OP(b,c,d) + X[k] + i, s)
+
+#define DO1(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,F)
+#define DO2(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,G)
+#define DO3(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,H)
+
+static inline void
+calc (struct md4 *m, uint32_t *data)
+{
+  uint32_t AA, BB, CC, DD;
+
+  AA = A;
+  BB = B;
+  CC = C;
+  DD = D;
+
+  /* Round 1 */
+
+  DO1(A,B,C,D,0,3,0);
+  DO1(D,A,B,C,1,7,0);
+  DO1(C,D,A,B,2,11,0);
+  DO1(B,C,D,A,3,19,0);
+
+  DO1(A,B,C,D,4,3,0);
+  DO1(D,A,B,C,5,7,0);
+  DO1(C,D,A,B,6,11,0);
+  DO1(B,C,D,A,7,19,0);
+
+  DO1(A,B,C,D,8,3,0);
+  DO1(D,A,B,C,9,7,0);
+  DO1(C,D,A,B,10,11,0);
+  DO1(B,C,D,A,11,19,0);
+
+  DO1(A,B,C,D,12,3,0);
+  DO1(D,A,B,C,13,7,0);
+  DO1(C,D,A,B,14,11,0);
+  DO1(B,C,D,A,15,19,0);
+
+  /* Round 2 */
+
+  DO2(A,B,C,D,0,3,0x5A827999);
+  DO2(D,A,B,C,4,5,0x5A827999);
+  DO2(C,D,A,B,8,9,0x5A827999);
+  DO2(B,C,D,A,12,13,0x5A827999);
+
+  DO2(A,B,C,D,1,3,0x5A827999);
+  DO2(D,A,B,C,5,5,0x5A827999);
+  DO2(C,D,A,B,9,9,0x5A827999);
+  DO2(B,C,D,A,13,13,0x5A827999);
+
+  DO2(A,B,C,D,2,3,0x5A827999);
+  DO2(D,A,B,C,6,5,0x5A827999);
+  DO2(C,D,A,B,10,9,0x5A827999);
+  DO2(B,C,D,A,14,13,0x5A827999);
+
+  DO2(A,B,C,D,3,3,0x5A827999);
+  DO2(D,A,B,C,7,5,0x5A827999);
+  DO2(C,D,A,B,11,9,0x5A827999);
+  DO2(B,C,D,A,15,13,0x5A827999);
+
+  /* Round 3 */
+
+  DO3(A,B,C,D,0,3,0x6ED9EBA1);
+  DO3(D,A,B,C,8,9,0x6ED9EBA1);
+  DO3(C,D,A,B,4,11,0x6ED9EBA1);
+  DO3(B,C,D,A,12,15,0x6ED9EBA1);
+
+  DO3(A,B,C,D,2,3,0x6ED9EBA1);
+  DO3(D,A,B,C,10,9,0x6ED9EBA1);
+  DO3(C,D,A,B,6,11,0x6ED9EBA1);
+  DO3(B,C,D,A,14,15,0x6ED9EBA1);
+
+  DO3(A,B,C,D,1,3,0x6ED9EBA1);
+  DO3(D,A,B,C,9,9,0x6ED9EBA1);
+  DO3(C,D,A,B,5,11,0x6ED9EBA1);
+  DO3(B,C,D,A,13,15,0x6ED9EBA1);
+
+  DO3(A,B,C,D,3,3,0x6ED9EBA1);
+  DO3(D,A,B,C,11,9,0x6ED9EBA1);
+  DO3(C,D,A,B,7,11,0x6ED9EBA1);
+  DO3(B,C,D,A,15,15,0x6ED9EBA1);
+
+  A += AA;
+  B += BB;
+  C += CC;
+  D += DD;
+}
+
+/*
+ * From `Performance analysis of MD5' by Joseph D. Touch <touch@isi.edu>
+ */
+
+#if defined(WORDS_BIGENDIAN)
+static inline uint32_t
+swap_uint32_t (uint32_t t)
+{
+  uint32_t temp1, temp2;
+
+  temp1   = cshift(t, 16);
+  temp2   = temp1 >> 8;
+  temp1  &= 0x00ff00ff;
+  temp2  &= 0x00ff00ff;
+  temp1 <<= 8;
+  return temp1 | temp2;
+}
+#endif
+
+struct x32{
+  unsigned int a:32;
+  unsigned int b:32;
+};
+
+void
+MD4_Update (struct md4 *m, const void *v, size_t len)
+{
+    const unsigned char *p = v;
+    size_t old_sz = m->sz[0];
+    size_t offset;
+
+    m->sz[0] += len * 8;
+    if (m->sz[0] < old_sz)
+       ++m->sz[1];
+    offset = (old_sz / 8)  % 64;
+    while(len > 0) {
+       size_t l = min(len, 64 - offset);
+       memcpy(m->save + offset, p, l);
+       offset += l;
+       p += l;
+       len -= l;
+       if(offset == 64) {
+#if defined(WORDS_BIGENDIAN)
+           int i;
+           uint32_t current[16];
+           struct x32 *u = (struct x32*)m->save;
+           for(i = 0; i < 8; i++){
+               current[2*i+0] = swap_uint32_t(u[i].a);
+               current[2*i+1] = swap_uint32_t(u[i].b);
+           }
+           calc(m, current);
+#else
+           calc(m, (uint32_t*)m->save);
+#endif
+           offset = 0;
+       }
+    }
+}
+
+void
+MD4_Final (void *res, struct md4 *m)
+{
+  unsigned char zeros[72];
+  unsigned offset = (m->sz[0] / 8) % 64;
+  unsigned int dstart = (120 - offset - 1) % 64 + 1;
+
+  *zeros = 0x80;
+  memset (zeros + 1, 0, sizeof(zeros) - 1);
+  zeros[dstart+0] = (m->sz[0] >> 0) & 0xff;
+  zeros[dstart+1] = (m->sz[0] >> 8) & 0xff;
+  zeros[dstart+2] = (m->sz[0] >> 16) & 0xff;
+  zeros[dstart+3] = (m->sz[0] >> 24) & 0xff;
+  zeros[dstart+4] = (m->sz[1] >> 0) & 0xff;
+  zeros[dstart+5] = (m->sz[1] >> 8) & 0xff;
+  zeros[dstart+6] = (m->sz[1] >> 16) & 0xff;
+  zeros[dstart+7] = (m->sz[1] >> 24) & 0xff;
+  MD4_Update (m, zeros, dstart + 8);
+  {
+      int i;
+      unsigned char *r = (unsigned char *)res;
+
+      for (i = 0; i < 4; ++i) {
+         r[4*i]   = m->counter[i] & 0xFF;
+         r[4*i+1] = (m->counter[i] >> 8) & 0xFF;
+         r[4*i+2] = (m->counter[i] >> 16) & 0xFF;
+         r[4*i+3] = (m->counter[i] >> 24) & 0xFF;
+      }
+  }
+#if 0
+  {
+    int i;
+    uint32_t *r = (uint32_t *)res;
+
+    for (i = 0; i < 4; ++i)
+      r[i] = swap_uint32_t (m->counter[i]);
+  }
+#endif
+}
diff --git a/src/external/heimdal/hcrypto/md4.h b/src/external/heimdal/hcrypto/md4.h
new file mode 100644 (file)
index 0000000..ce17d0f
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+/* $Id$ */
+
+#ifndef HEIM_MD4_H
+#define HEIM_MD4_H 1
+
+/* symbol renaming */
+#define MD4_Init hc_MD4_Init
+#define MD4_Update hc_MD4_Update
+#define MD4_Final hc_MD4_Final
+
+/*
+ *
+ */
+
+#define MD4_DIGEST_LENGTH 16
+
+struct md4 {
+  unsigned int sz[2];
+  uint32_t counter[4];
+  unsigned char save[64];
+};
+
+typedef struct md4 MD4_CTX;
+
+void MD4_Init (struct md4 *m);
+void MD4_Update (struct md4 *m, const void *p, size_t len);
+void MD4_Final (void *res, struct md4 *m);
+
+#endif /* HEIM_MD4_H */
diff --git a/src/external/heimdal/hcrypto/md5.c b/src/external/heimdal/hcrypto/md5.c
new file mode 100644 (file)
index 0000000..f990787
--- /dev/null
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+#include "config.h"
+
+#include "hash.h"
+#include "md5.h"
+
+#define A m->counter[0]
+#define B m->counter[1]
+#define C m->counter[2]
+#define D m->counter[3]
+#define X data
+
+void
+MD5_Init (struct md5 *m)
+{
+  m->sz[0] = 0;
+  m->sz[1] = 0;
+  D = 0x10325476;
+  C = 0x98badcfe;
+  B = 0xefcdab89;
+  A = 0x67452301;
+}
+
+#define F(x,y,z) CRAYFIX((x & y) | (~x & z))
+#define G(x,y,z) CRAYFIX((x & z) | (y & ~z))
+#define H(x,y,z) (x ^ y ^ z)
+#define I(x,y,z) CRAYFIX(y ^ (x | ~z))
+
+#define DOIT(a,b,c,d,k,s,i,OP) \
+a = b + cshift(a + OP(b,c,d) + X[k] + (i), s)
+
+#define DO1(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,F)
+#define DO2(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,G)
+#define DO3(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,H)
+#define DO4(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,I)
+
+static inline void
+calc (struct md5 *m, uint32_t *data)
+{
+  uint32_t AA, BB, CC, DD;
+
+  AA = A;
+  BB = B;
+  CC = C;
+  DD = D;
+
+  /* Round 1 */
+
+  DO1(A,B,C,D,0,7,0xd76aa478);
+  DO1(D,A,B,C,1,12,0xe8c7b756);
+  DO1(C,D,A,B,2,17,0x242070db);
+  DO1(B,C,D,A,3,22,0xc1bdceee);
+
+  DO1(A,B,C,D,4,7,0xf57c0faf);
+  DO1(D,A,B,C,5,12,0x4787c62a);
+  DO1(C,D,A,B,6,17,0xa8304613);
+  DO1(B,C,D,A,7,22,0xfd469501);
+
+  DO1(A,B,C,D,8,7,0x698098d8);
+  DO1(D,A,B,C,9,12,0x8b44f7af);
+  DO1(C,D,A,B,10,17,0xffff5bb1);
+  DO1(B,C,D,A,11,22,0x895cd7be);
+
+  DO1(A,B,C,D,12,7,0x6b901122);
+  DO1(D,A,B,C,13,12,0xfd987193);
+  DO1(C,D,A,B,14,17,0xa679438e);
+  DO1(B,C,D,A,15,22,0x49b40821);
+
+  /* Round 2 */
+
+  DO2(A,B,C,D,1,5,0xf61e2562);
+  DO2(D,A,B,C,6,9,0xc040b340);
+  DO2(C,D,A,B,11,14,0x265e5a51);
+  DO2(B,C,D,A,0,20,0xe9b6c7aa);
+
+  DO2(A,B,C,D,5,5,0xd62f105d);
+  DO2(D,A,B,C,10,9,0x2441453);
+  DO2(C,D,A,B,15,14,0xd8a1e681);
+  DO2(B,C,D,A,4,20,0xe7d3fbc8);
+
+  DO2(A,B,C,D,9,5,0x21e1cde6);
+  DO2(D,A,B,C,14,9,0xc33707d6);
+  DO2(C,D,A,B,3,14,0xf4d50d87);
+  DO2(B,C,D,A,8,20,0x455a14ed);
+
+  DO2(A,B,C,D,13,5,0xa9e3e905);
+  DO2(D,A,B,C,2,9,0xfcefa3f8);
+  DO2(C,D,A,B,7,14,0x676f02d9);
+  DO2(B,C,D,A,12,20,0x8d2a4c8a);
+
+  /* Round 3 */
+
+  DO3(A,B,C,D,5,4,0xfffa3942);
+  DO3(D,A,B,C,8,11,0x8771f681);
+  DO3(C,D,A,B,11,16,0x6d9d6122);
+  DO3(B,C,D,A,14,23,0xfde5380c);
+
+  DO3(A,B,C,D,1,4,0xa4beea44);
+  DO3(D,A,B,C,4,11,0x4bdecfa9);
+  DO3(C,D,A,B,7,16,0xf6bb4b60);
+  DO3(B,C,D,A,10,23,0xbebfbc70);
+
+  DO3(A,B,C,D,13,4,0x289b7ec6);
+  DO3(D,A,B,C,0,11,0xeaa127fa);
+  DO3(C,D,A,B,3,16,0xd4ef3085);
+  DO3(B,C,D,A,6,23,0x4881d05);
+
+  DO3(A,B,C,D,9,4,0xd9d4d039);
+  DO3(D,A,B,C,12,11,0xe6db99e5);
+  DO3(C,D,A,B,15,16,0x1fa27cf8);
+  DO3(B,C,D,A,2,23,0xc4ac5665);
+
+  /* Round 4 */
+
+  DO4(A,B,C,D,0,6,0xf4292244);
+  DO4(D,A,B,C,7,10,0x432aff97);
+  DO4(C,D,A,B,14,15,0xab9423a7);
+  DO4(B,C,D,A,5,21,0xfc93a039);
+
+  DO4(A,B,C,D,12,6,0x655b59c3);
+  DO4(D,A,B,C,3,10,0x8f0ccc92);
+  DO4(C,D,A,B,10,15,0xffeff47d);
+  DO4(B,C,D,A,1,21,0x85845dd1);
+
+  DO4(A,B,C,D,8,6,0x6fa87e4f);
+  DO4(D,A,B,C,15,10,0xfe2ce6e0);
+  DO4(C,D,A,B,6,15,0xa3014314);
+  DO4(B,C,D,A,13,21,0x4e0811a1);
+
+  DO4(A,B,C,D,4,6,0xf7537e82);
+  DO4(D,A,B,C,11,10,0xbd3af235);
+  DO4(C,D,A,B,2,15,0x2ad7d2bb);
+  DO4(B,C,D,A,9,21,0xeb86d391);
+
+  A += AA;
+  B += BB;
+  C += CC;
+  D += DD;
+}
+
+/*
+ * From `Performance analysis of MD5' by Joseph D. Touch <touch@isi.edu>
+ */
+
+#if defined(WORDS_BIGENDIAN)
+static inline uint32_t
+swap_uint32_t (uint32_t t)
+{
+  uint32_t temp1, temp2;
+
+  temp1   = cshift(t, 16);
+  temp2   = temp1 >> 8;
+  temp1  &= 0x00ff00ff;
+  temp2  &= 0x00ff00ff;
+  temp1 <<= 8;
+  return temp1 | temp2;
+}
+#endif
+
+struct x32{
+  unsigned int a:32;
+  unsigned int b:32;
+};
+
+void
+MD5_Update (struct md5 *m, const void *v, size_t len)
+{
+  const unsigned char *p = v;
+  size_t old_sz = m->sz[0];
+  size_t offset;
+
+  m->sz[0] += len * 8;
+  if (m->sz[0] < old_sz)
+      ++m->sz[1];
+  offset = (old_sz / 8)  % 64;
+  while(len > 0){
+    size_t l = min(len, 64 - offset);
+    memcpy(m->save + offset, p, l);
+    offset += l;
+    p += l;
+    len -= l;
+    if(offset == 64){
+#if defined(WORDS_BIGENDIAN)
+      int i;
+      uint32_t current[16];
+      struct x32 *u = (struct x32*)m->save;
+      for(i = 0; i < 8; i++){
+       current[2*i+0] = swap_uint32_t(u[i].a);
+       current[2*i+1] = swap_uint32_t(u[i].b);
+      }
+      calc(m, current);
+#else
+      calc(m, (uint32_t*)m->save);
+#endif
+      offset = 0;
+    }
+  }
+}
+
+void
+MD5_Final (void *res, struct md5 *m)
+{
+  unsigned char zeros[72];
+  unsigned offset = (m->sz[0] / 8) % 64;
+  unsigned int dstart = (120 - offset - 1) % 64 + 1;
+
+  *zeros = 0x80;
+  memset (zeros + 1, 0, sizeof(zeros) - 1);
+  zeros[dstart+0] = (m->sz[0] >> 0) & 0xff;
+  zeros[dstart+1] = (m->sz[0] >> 8) & 0xff;
+  zeros[dstart+2] = (m->sz[0] >> 16) & 0xff;
+  zeros[dstart+3] = (m->sz[0] >> 24) & 0xff;
+  zeros[dstart+4] = (m->sz[1] >> 0) & 0xff;
+  zeros[dstart+5] = (m->sz[1] >> 8) & 0xff;
+  zeros[dstart+6] = (m->sz[1] >> 16) & 0xff;
+  zeros[dstart+7] = (m->sz[1] >> 24) & 0xff;
+  MD5_Update (m, zeros, dstart + 8);
+  {
+      int i;
+      unsigned char *r = (unsigned char *)res;
+
+      for (i = 0; i < 4; ++i) {
+         r[4*i]   = m->counter[i] & 0xFF;
+         r[4*i+1] = (m->counter[i] >> 8) & 0xFF;
+         r[4*i+2] = (m->counter[i] >> 16) & 0xFF;
+         r[4*i+3] = (m->counter[i] >> 24) & 0xFF;
+      }
+  }
+#if 0
+  {
+    int i;
+    uint32_t *r = (uint32_t *)res;
+
+    for (i = 0; i < 4; ++i)
+      r[i] = swap_uint32_t (m->counter[i]);
+  }
+#endif
+}
diff --git a/src/external/heimdal/hcrypto/md5.h b/src/external/heimdal/hcrypto/md5.h
new file mode 100644 (file)
index 0000000..b2df6e5
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+/* $Id$ */
+
+#ifndef HEIM_MD5_H
+#define HEIM_MD5_H 1
+
+/* symbol renaming */
+#define MD5_Init hc_MD5_Init
+#define MD5_Update hc_MD5_Update
+#define MD5_Final hc_MD5_Final
+
+/*
+ *
+ */
+
+#define MD5_DIGEST_LENGTH 16
+
+struct md5 {
+  unsigned int sz[2];
+  uint32_t counter[4];
+  unsigned char save[64];
+};
+
+typedef struct md5 MD5_CTX;
+
+void MD5_Init (struct md5 *m);
+void MD5_Update (struct md5 *m, const void *p, size_t len);
+void MD5_Final (void *res, struct md5 *m); /* uint32_t res[4] */
+
+#endif /* HEIM_MD5_H */
diff --git a/src/external/heimdal/hcrypto/pkcs5.c b/src/external/heimdal/hcrypto/pkcs5.c
new file mode 100644 (file)
index 0000000..18045e2
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+#include <config.h>
+
+#ifdef KRB5
+#include <krb5-types.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <evp.h>
+#include <hmac.h>
+
+#include <roken.h>
+
+/**
+ * As descriped in PKCS5, convert a password, salt, and iteration counter into a crypto key.
+ *
+ * @param password Password.
+ * @param password_len Length of password.
+ * @param salt Salt
+ * @param salt_len Length of salt.
+ * @param iter iteration counter.
+ * @param keylen the output key length.
+ * @param key the output key.
+ *
+ * @return 1 on success, non 1 on failure.
+ *
+ * @ingroup hcrypto_misc
+ */
+
+int
+PKCS5_PBKDF2_HMAC_SHA1(const void * password, size_t password_len,
+                      const void * salt, size_t salt_len,
+                      unsigned long iter,
+                      size_t keylen, void *key)
+{
+    size_t datalen, leftofkey, checksumsize;
+    char *data, *tmpcksum;
+    uint32_t keypart;
+    const EVP_MD *md;
+    unsigned long i;
+    int j;
+    char *p;
+    unsigned int hmacsize;
+
+    md = EVP_sha1();
+    checksumsize = EVP_MD_size(md);
+    datalen = salt_len + 4;
+
+    tmpcksum = malloc(checksumsize + datalen);
+    if (tmpcksum == NULL)
+       return 0;
+
+    data = &tmpcksum[checksumsize];
+
+    memcpy(data, salt, salt_len);
+
+    keypart = 1;
+    leftofkey = keylen;
+    p = key;
+
+    while (leftofkey) {
+       int len;
+
+       if (leftofkey > checksumsize)
+           len = checksumsize;
+       else
+           len = leftofkey;
+
+       data[datalen - 4] = (keypart >> 24) & 0xff;
+       data[datalen - 3] = (keypart >> 16) & 0xff;
+       data[datalen - 2] = (keypart >> 8)  & 0xff;
+       data[datalen - 1] = (keypart)       & 0xff;
+
+       HMAC(md, password, password_len, data, datalen,
+            tmpcksum, &hmacsize);
+
+       memcpy(p, tmpcksum, len);
+       for (i = 1; i < iter; i++) {
+           HMAC(md, password, password_len, tmpcksum, checksumsize,
+                tmpcksum, &hmacsize);
+
+           for (j = 0; j < len; j++)
+               p[j] ^= tmpcksum[j];
+       }
+
+       p += len;
+       leftofkey -= len;
+       keypart++;
+    }
+
+    free(tmpcksum);
+
+    return 1;
+}
diff --git a/src/external/heimdal/hcrypto/rand-egd.c b/src/external/heimdal/hcrypto/rand-egd.c
new file mode 100644 (file)
index 0000000..dd2d3e1
--- /dev/null
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#ifdef HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <assert.h>
+
+#include <rand.h>
+#include <randi.h>
+
+#include <roken.h>
+
+static const char *egd_path = "/var/run/egd-pool";
+
+#define MAX_EGD_DATA 255
+
+static int
+connect_egd(const char *path)
+{
+    struct sockaddr_un addr;
+    int fd;
+
+    memset(&addr, 0, sizeof(addr));
+
+    if (strlen(path) > sizeof(addr.sun_path))
+       return -1;
+
+    addr.sun_family = AF_UNIX;
+    strlcpy(addr.sun_path, path, sizeof(addr.sun_path));
+
+    fd = socket(AF_UNIX, SOCK_STREAM, 0);
+    if (fd < 0)
+       return -1;
+
+    rk_cloexec(fd);
+
+    if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
+       close(fd);
+       return -1;
+    }
+
+    return fd;
+}
+
+static int
+get_entropy(int fd, void *data, size_t len)
+{
+    unsigned char msg[2];
+
+    assert(len <= MAX_EGD_DATA);
+
+    msg[0] = 0x02; /* read blocking data */
+    msg[1] = len; /* wanted length */
+
+    if (net_write(fd, msg, sizeof(msg)) != sizeof(msg))
+       return 0;
+
+    if (net_read(fd, data, len) != len)
+       return 0;
+
+    return 1;
+}
+
+static int
+put_entropy(int fd, const void *data, size_t len)
+{
+    unsigned char msg[4];
+
+    assert (len <= MAX_EGD_DATA);
+
+    msg[0] = 0x03; /* write data */
+    msg[1] = 0; /* dummy */
+    msg[2] = 0; /* entropy */
+    msg[3] = len; /* length */
+
+    if (net_write(fd, msg, sizeof(msg)) != sizeof(msg))
+       return 0;
+    if (net_write(fd, data, len) != len)
+       return 0;
+
+    return 1;
+}
+
+/*
+ *
+ */
+
+static void
+egd_seed(const void *indata, int size)
+{
+    size_t len;
+    int fd, ret = 1;
+
+    fd = connect_egd(egd_path);
+    if (fd < 0)
+       return;
+
+    while(size) {
+       len = size;
+       if (len > MAX_EGD_DATA)
+           len = MAX_EGD_DATA;
+       ret = put_entropy(fd, indata, len);
+       if (ret != 1)
+           break;
+       indata = ((unsigned char *)indata) + len;
+       size -= len;
+    }
+    close(fd);
+}
+
+static int
+get_bytes(const char *path, unsigned char *outdata, int size)
+{
+    size_t len;
+    int fd, ret = 1;
+
+    if (path == NULL)
+       path = egd_path;
+
+    fd = connect_egd(path);
+    if (fd < 0)
+       return 0;
+
+    while(size) {
+       len = size;
+       if (len > MAX_EGD_DATA)
+           len = MAX_EGD_DATA;
+       ret = get_entropy(fd, outdata, len);
+       if (ret != 1)
+           break;
+       outdata += len;
+       size -= len;
+    }
+    close(fd);
+
+    return ret;
+}
+
+static int
+egd_bytes(unsigned char *outdata, int size)
+{
+    return get_bytes(NULL, outdata, size);
+}
+
+static void
+egd_cleanup(void)
+{
+}
+
+static void
+egd_add(const void *indata, int size, double entropi)
+{
+    egd_seed(indata, size);
+}
+
+static int
+egd_pseudorand(unsigned char *outdata, int size)
+{
+    return get_bytes(NULL, outdata, size);
+}
+
+static int
+egd_status(void)
+{
+    int fd;
+    fd = connect_egd(egd_path);
+    if (fd < 0)
+       return 0;
+    close(fd);
+    return 1;
+}
+
+const RAND_METHOD hc_rand_egd_method = {
+    egd_seed,
+    egd_bytes,
+    egd_cleanup,
+    egd_add,
+    egd_pseudorand,
+    egd_status
+};
+
+const RAND_METHOD *
+RAND_egd_method(void)
+{
+    return &hc_rand_egd_method;
+}
+
+
+int
+RAND_egd(const char *filename)
+{
+    return RAND_egd_bytes(filename, 128);
+}
+
+int
+RAND_egd_bytes(const char *filename, int size)
+{
+    void *data;
+    int ret;
+
+    if (size <= 0)
+       return 0;
+
+    data = malloc(size);
+    if (data == NULL)
+       return 0;
+
+    ret = get_bytes(filename, data, size);
+    if (ret != 1) {
+       free(data);
+       return ret;
+    }
+
+    RAND_seed(data, size);
+
+    memset(data, 0, size);
+    free(data);
+
+    return 1;
+}
diff --git a/src/external/heimdal/hcrypto/rand-fortuna.c b/src/external/heimdal/hcrypto/rand-fortuna.c
new file mode 100644 (file)
index 0000000..11027b4
--- /dev/null
@@ -0,0 +1,655 @@
+/*
+ * fortuna.c
+ *             Fortuna-like PRNG.
+ *
+ * Copyright (c) 2005 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.     IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ *
+ * $PostgreSQL: pgsql/contrib/pgcrypto/fortuna.c,v 1.8 2006/10/04 00:29:46 momjian Exp $
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <rand.h>
+#include <heim_threads.h>
+
+#ifdef KRB5
+#include <krb5-types.h>
+#endif
+#include <roken.h>
+
+#include "randi.h"
+#include "aes.h"
+#include "sha.h"
+
+/*
+ * Why Fortuna-like: There does not seem to be any definitive reference
+ * on Fortuna in the net.  Instead this implementation is based on
+ * following references:
+ *
+ * http://en.wikipedia.org/wiki/Fortuna_(PRNG)
+ *      - Wikipedia article
+ * http://jlcooke.ca/random/
+ *      - Jean-Luc Cooke Fortuna-based /dev/random driver for Linux.
+ */
+
+/*
+ * There is some confusion about whether and how to carry forward
+ * the state of the pools.     Seems like original Fortuna does not
+ * do it, resetting hash after each request.  I guess expecting
+ * feeding to happen more often that requesting.   This is absolutely
+ * unsuitable for pgcrypto, as nothing asynchronous happens here.
+ *
+ * J.L. Cooke fixed this by feeding previous hash to new re-initialized
+ * hash context.
+ *
+ * Fortuna predecessor Yarrow requires ability to query intermediate
+ * 'final result' from hash, without affecting it.
+ *
+ * This implementation uses the Yarrow method - asking intermediate
+ * results, but continuing with old state.
+ */
+
+
+/*
+ * Algorithm parameters
+ */
+
+#define NUM_POOLS              32
+
+/* in microseconds */
+#define RESEED_INTERVAL 100000 /* 0.1 sec */
+
+/* for one big request, reseed after this many bytes */
+#define RESEED_BYTES   (1024*1024)
+
+/*
+ * Skip reseed if pool 0 has less than this many
+ * bytes added since last reseed.
+ */
+#define POOL0_FILL             (256/8)
+
+/*
+ * Algorithm constants
+ */
+
+/* Both cipher key size and hash result size */
+#define BLOCK                  32
+
+/* cipher block size */
+#define CIPH_BLOCK             16
+
+/* for internal wrappers */
+#define MD_CTX                 SHA256_CTX
+#define CIPH_CTX               AES_KEY
+
+struct fortuna_state
+{
+    unsigned char      counter[CIPH_BLOCK];
+    unsigned char      result[CIPH_BLOCK];
+    unsigned char      key[BLOCK];
+    MD_CTX             pool[NUM_POOLS];
+    CIPH_CTX           ciph;
+    unsigned           reseed_count;
+    struct timeval     last_reseed_time;
+    unsigned           pool0_bytes;
+    unsigned           rnd_pos;
+    int                        tricks_done;
+    pid_t              pid;
+};
+typedef struct fortuna_state FState;
+
+
+/*
+ * Use our own wrappers here.
+ * - Need to get intermediate result from digest, without affecting it.
+ * - Need re-set key on a cipher context.
+ * - Algorithms are guaranteed to exist.
+ * - No memory allocations.
+ */
+
+static void
+ciph_init(CIPH_CTX * ctx, const unsigned char *key, int klen)
+{
+    AES_set_encrypt_key(key, klen * 8, ctx);
+}
+
+static void
+ciph_encrypt(CIPH_CTX * ctx, const unsigned char *in, unsigned char *out)
+{
+    AES_encrypt(in, out, ctx);
+}
+
+static void
+md_init(MD_CTX * ctx)
+{
+    SHA256_Init(ctx);
+}
+
+static void
+md_update(MD_CTX * ctx, const unsigned char *data, int len)
+{
+    SHA256_Update(ctx, data, len);
+}
+
+static void
+md_result(MD_CTX * ctx, unsigned char *dst)
+{
+    SHA256_CTX tmp;
+
+    memcpy(&tmp, ctx, sizeof(*ctx));
+    SHA256_Final(dst, &tmp);
+    memset(&tmp, 0, sizeof(tmp));
+}
+
+/*
+ * initialize state
+ */
+static void
+init_state(FState * st)
+{
+    int                        i;
+
+    memset(st, 0, sizeof(*st));
+    for (i = 0; i < NUM_POOLS; i++)
+       md_init(&st->pool[i]);
+    st->pid = getpid();
+}
+
+/*
+ * Endianess does not matter.
+ * It just needs to change without repeating.
+ */
+static void
+inc_counter(FState * st)
+{
+    uint32_t   *val = (uint32_t *) st->counter;
+
+    if (++val[0])
+       return;
+    if (++val[1])
+       return;
+    if (++val[2])
+       return;
+    ++val[3];
+}
+
+/*
+ * This is called 'cipher in counter mode'.
+ */
+static void
+encrypt_counter(FState * st, unsigned char *dst)
+{
+    ciph_encrypt(&st->ciph, st->counter, dst);
+    inc_counter(st);
+}
+
+
+/*
+ * The time between reseed must be at least RESEED_INTERVAL
+ * microseconds.
+ */
+static int
+enough_time_passed(FState * st)
+{
+    int                        ok;
+    struct timeval tv;
+    struct timeval *last = &st->last_reseed_time;
+
+    gettimeofday(&tv, NULL);
+
+    /* check how much time has passed */
+    ok = 0;
+    if (tv.tv_sec > last->tv_sec + 1)
+       ok = 1;
+    else if (tv.tv_sec == last->tv_sec + 1)
+    {
+       if (1000000 + tv.tv_usec - last->tv_usec >= RESEED_INTERVAL)
+           ok = 1;
+    }
+    else if (tv.tv_usec - last->tv_usec >= RESEED_INTERVAL)
+       ok = 1;
+
+    /* reseed will happen, update last_reseed_time */
+    if (ok)
+       memcpy(last, &tv, sizeof(tv));
+
+    memset(&tv, 0, sizeof(tv));
+
+    return ok;
+}
+
+/*
+ * generate new key from all the pools
+ */
+static void
+reseed(FState * st)
+{
+    unsigned   k;
+    unsigned   n;
+    MD_CTX             key_md;
+    unsigned char      buf[BLOCK];
+
+    /* set pool as empty */
+    st->pool0_bytes = 0;
+
+    /*
+     * Both #0 and #1 reseed would use only pool 0. Just skip #0 then.
+     */
+    n = ++st->reseed_count;
+
+    /*
+     * The goal: use k-th pool only 1/(2^k) of the time.
+     */
+    md_init(&key_md);
+    for (k = 0; k < NUM_POOLS; k++)
+    {
+       md_result(&st->pool[k], buf);
+       md_update(&key_md, buf, BLOCK);
+
+       if (n & 1 || !n)
+           break;
+       n >>= 1;
+    }
+
+    /* add old key into mix too */
+    md_update(&key_md, st->key, BLOCK);
+
+    /* add pid to make output diverse after fork() */
+    md_update(&key_md, (const unsigned char *)&st->pid, sizeof(st->pid));
+
+    /* now we have new key */
+    md_result(&key_md, st->key);
+
+    /* use new key */
+    ciph_init(&st->ciph, st->key, BLOCK);
+
+    memset(&key_md, 0, sizeof(key_md));
+    memset(buf, 0, BLOCK);
+}
+
+/*
+ * Pick a random pool. This uses key bytes as random source.
+ */
+static unsigned
+get_rand_pool(FState * st)
+{
+    unsigned   rnd;
+
+    /*
+     * This slightly prefers lower pools - thats OK.
+     */
+    rnd = st->key[st->rnd_pos] % NUM_POOLS;
+
+    st->rnd_pos++;
+    if (st->rnd_pos >= BLOCK)
+       st->rnd_pos = 0;
+
+    return rnd;
+}
+
+/*
+ * update pools
+ */
+static void
+add_entropy(FState * st, const unsigned char *data, unsigned len)
+{
+    unsigned           pos;
+    unsigned char      hash[BLOCK];
+    MD_CTX             md;
+
+    /* hash given data */
+    md_init(&md);
+    md_update(&md, data, len);
+    md_result(&md, hash);
+
+    /*
+     * Make sure the pool 0 is initialized, then update randomly.
+     */
+    if (st->reseed_count == 0)
+       pos = 0;
+    else
+       pos = get_rand_pool(st);
+    md_update(&st->pool[pos], hash, BLOCK);
+
+    if (pos == 0)
+       st->pool0_bytes += len;
+
+    memset(hash, 0, BLOCK);
+    memset(&md, 0, sizeof(md));
+}
+
+/*
+ * Just take 2 next blocks as new key
+ */
+static void
+rekey(FState * st)
+{
+    encrypt_counter(st, st->key);
+    encrypt_counter(st, st->key + CIPH_BLOCK);
+    ciph_init(&st->ciph, st->key, BLOCK);
+}
+
+/*
+ * Hide public constants. (counter, pools > 0)
+ *
+ * This can also be viewed as spreading the startup
+ * entropy over all of the components.
+ */
+static void
+startup_tricks(FState * st)
+{
+    int                        i;
+    unsigned char      buf[BLOCK];
+
+    /* Use next block as counter. */
+    encrypt_counter(st, st->counter);
+
+    /* Now shuffle pools, excluding #0 */
+    for (i = 1; i < NUM_POOLS; i++)
+    {
+       encrypt_counter(st, buf);
+       encrypt_counter(st, buf + CIPH_BLOCK);
+       md_update(&st->pool[i], buf, BLOCK);
+    }
+    memset(buf, 0, BLOCK);
+
+    /* Hide the key. */
+    rekey(st);
+
+    /* This can be done only once. */
+    st->tricks_done = 1;
+}
+
+static void
+extract_data(FState * st, unsigned count, unsigned char *dst)
+{
+    unsigned   n;
+    unsigned   block_nr = 0;
+    pid_t      pid = getpid();
+
+    /* Should we reseed? */
+    if (st->pool0_bytes >= POOL0_FILL || st->reseed_count == 0)
+       if (enough_time_passed(st))
+           reseed(st);
+
+    /* Do some randomization on first call */
+    if (!st->tricks_done)
+       startup_tricks(st);
+
+    /* If we forked, force a reseed again */
+    if (pid != st->pid) {
+       st->pid = pid;
+       reseed(st);
+    }
+
+    while (count > 0)
+    {
+       /* produce bytes */
+       encrypt_counter(st, st->result);
+
+       /* copy result */
+       if (count > CIPH_BLOCK)
+           n = CIPH_BLOCK;
+       else
+           n = count;
+       memcpy(dst, st->result, n);
+       dst += n;
+       count -= n;
+
+       /* must not give out too many bytes with one key */
+       block_nr++;
+       if (block_nr > (RESEED_BYTES / CIPH_BLOCK))
+       {
+           rekey(st);
+           block_nr = 0;
+       }
+    }
+    /* Set new key for next request. */
+    rekey(st);
+}
+
+/*
+ * public interface
+ */
+
+static FState  main_state;
+static int     init_done;
+static int     have_entropy;
+#define FORTUNA_RESEED_BYTE    10000
+static unsigned        resend_bytes;
+
+/*
+ * This mutex protects all of the above static elements from concurrent
+ * access by multiple threads
+ */
+static HEIMDAL_MUTEX fortuna_mutex = HEIMDAL_MUTEX_INITIALIZER;
+
+/*
+ * Try our best to do an inital seed
+ */
+#define INIT_BYTES     128
+
+/*
+ * fortuna_mutex must be held across calls to this function
+ */
+
+static int
+fortuna_reseed(void)
+{
+    int entropy_p = 0;
+
+    if (!init_done)
+       abort();
+
+#ifndef NO_RAND_UNIX_METHOD
+    {
+       unsigned char buf[INIT_BYTES];
+       if ((*hc_rand_unix_method.bytes)(buf, sizeof(buf)) == 1) {
+           add_entropy(&main_state, buf, sizeof(buf));
+           entropy_p = 1;
+           memset(buf, 0, sizeof(buf));
+       }
+    }
+#endif
+#ifdef HAVE_ARC4RANDOM
+    {
+       uint32_t buf[INIT_BYTES / sizeof(uint32_t)];
+       int i;
+
+       for (i = 0; i < sizeof(buf)/sizeof(buf[0]); i++)
+           buf[i] = arc4random();
+       add_entropy(&main_state, (void *)buf, sizeof(buf));
+       entropy_p = 1;
+    }
+#endif
+#ifndef NO_RAND_EGD_METHOD
+    /*
+     * Only to get egd entropy if /dev/random or arc4rand failed since
+     * it can be horribly slow to generate new bits.
+     */
+    if (!entropy_p) {
+       unsigned char buf[INIT_BYTES];
+       if ((*hc_rand_egd_method.bytes)(buf, sizeof(buf)) == 1) {
+           add_entropy(&main_state, buf, sizeof(buf));
+           entropy_p = 1;
+           memset(buf, 0, sizeof(buf));
+       }
+    }
+#endif
+    /*
+     * Fall back to gattering data from timer and secret files, this
+     * is really the last resort.
+     */
+    if (!entropy_p) {
+       /* to save stackspace */
+       union {
+           unsigned char buf[INIT_BYTES];
+           unsigned char shad[1001];
+       } u;
+       int fd;
+
+       /* add timer info */
+       if ((*hc_rand_timer_method.bytes)(u.buf, sizeof(u.buf)) == 1)
+           add_entropy(&main_state, u.buf, sizeof(u.buf));
+       /* add /etc/shadow */
+       fd = open("/etc/shadow", O_RDONLY, 0);
+       if (fd >= 0) {
+           ssize_t n;
+           rk_cloexec(fd);
+           /* add_entropy will hash the buf */
+           while ((n = read(fd, (char *)u.shad, sizeof(u.shad))) > 0)
+               add_entropy(&main_state, u.shad, sizeof(u.shad));
+           close(fd);
+       }
+
+       memset(&u, 0, sizeof(u));
+
+       entropy_p = 1; /* sure about this ? */
+    }
+    {
+       pid_t pid = getpid();
+       add_entropy(&main_state, (void *)&pid, sizeof(pid));
+    }
+    {
+       struct timeval tv;
+       gettimeofday(&tv, NULL);
+       add_entropy(&main_state, (void *)&tv, sizeof(tv));
+    }
+#ifdef HAVE_GETUID
+    {
+       uid_t u = getuid();
+       add_entropy(&main_state, (void *)&u, sizeof(u));
+    }
+#endif
+    return entropy_p;
+}
+
+/*
+ * fortuna_mutex must be held by callers of this function
+ */
+static int
+fortuna_init(void)
+{
+    if (!init_done)
+    {
+       init_state(&main_state);
+       init_done = 1;
+    }
+    if (!have_entropy)
+       have_entropy = fortuna_reseed();
+    return (init_done && have_entropy);
+}
+
+
+
+static void
+fortuna_seed(const void *indata, int size)
+{
+    HEIMDAL_MUTEX_lock(&fortuna_mutex);
+
+    fortuna_init();
+    add_entropy(&main_state, indata, size);
+    if (size >= INIT_BYTES)
+       have_entropy = 1;
+
+    HEIMDAL_MUTEX_unlock(&fortuna_mutex);
+}
+
+static int
+fortuna_bytes(unsigned char *outdata, int size)
+{
+    int ret = 0;
+
+    HEIMDAL_MUTEX_lock(&fortuna_mutex);
+
+    if (!fortuna_init())
+       goto out;
+
+    resend_bytes += size;
+    if (resend_bytes > FORTUNA_RESEED_BYTE || resend_bytes < size) {
+       resend_bytes = 0;
+       fortuna_reseed();
+    }
+    extract_data(&main_state, size, outdata);
+    ret = 1;
+
+out:
+    HEIMDAL_MUTEX_unlock(&fortuna_mutex);
+
+    return ret;
+}
+
+static void
+fortuna_cleanup(void)
+{
+    HEIMDAL_MUTEX_lock(&fortuna_mutex);
+
+    init_done = 0;
+    have_entropy = 0;
+    memset(&main_state, 0, sizeof(main_state));
+
+    HEIMDAL_MUTEX_unlock(&fortuna_mutex);
+}
+
+static void
+fortuna_add(const void *indata, int size, double entropi)
+{
+    fortuna_seed(indata, size);
+}
+
+static int
+fortuna_pseudorand(unsigned char *outdata, int size)
+{
+    return fortuna_bytes(outdata, size);
+}
+
+static int
+fortuna_status(void)
+{
+    int result;
+
+    HEIMDAL_MUTEX_lock(&fortuna_mutex);
+    result = fortuna_init();
+    HEIMDAL_MUTEX_unlock(&fortuna_mutex);
+
+    return result ? 1 : 0;
+}
+
+const RAND_METHOD hc_rand_fortuna_method = {
+    fortuna_seed,
+    fortuna_bytes,
+    fortuna_cleanup,
+    fortuna_add,
+    fortuna_pseudorand,
+    fortuna_status
+};
+
+const RAND_METHOD *
+RAND_fortuna_method(void)
+{
+    return &hc_rand_fortuna_method;
+}
diff --git a/src/external/heimdal/hcrypto/rand-timer.c b/src/external/heimdal/hcrypto/rand-timer.c
new file mode 100644 (file)
index 0000000..994c321
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1999, 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <rand.h>
+
+#include <roken.h>
+
+#include "randi.h"
+
+#ifndef WIN32 /* don't bother with this on windows */
+
+static volatile int counter;
+static volatile unsigned char *gdata; /* Global data */
+static volatile int igdata;    /* Index into global data */
+static int gsize;
+
+static
+RETSIGTYPE
+sigALRM(int sig)
+{
+    if (igdata < gsize)
+       gdata[igdata++] ^= counter & 0xff;
+
+#ifndef HAVE_SIGACTION
+    signal(SIGALRM, sigALRM); /* Reinstall SysV signal handler */
+#endif
+    SIGRETURN(0);
+}
+
+#ifndef HAVE_SETITIMER
+static void
+pacemaker(struct timeval *tv)
+{
+    fd_set fds;
+    pid_t pid;
+    pid = getppid();
+    while(1){
+       FD_ZERO(&fds);
+       FD_SET(0, &fds);
+       select(1, &fds, NULL, NULL, tv);
+       kill(pid, SIGALRM);
+    }
+}
+#endif
+
+#ifdef HAVE_SIGACTION
+/* XXX ugly hack, should perhaps use function from roken */
+static RETSIGTYPE
+(*fake_signal(int sig, RETSIGTYPE (*f)(int)))(int)
+{
+    struct sigaction sa, osa;
+    sa.sa_handler = f;
+    sa.sa_flags = 0;
+    sigemptyset(&sa.sa_mask);
+    sigaction(sig, &sa, &osa);
+    return osa.sa_handler;
+}
+#define signal(S, F) fake_signal((S), (F))
+#endif
+
+#endif /* WIN32*/
+
+/*
+ *
+ */
+
+static void
+timer_seed(const void *indata, int size)
+{
+}
+
+static int
+timer_bytes(unsigned char *outdata, int size)
+{
+#ifdef WIN32
+    return 0;
+#else /* WIN32 */
+    struct itimerval tv, otv;
+    RETSIGTYPE (*osa)(int);
+    int i, j;
+#ifndef HAVE_SETITIMER
+    RETSIGTYPE (*ochld)(int);
+    pid_t pid;
+#endif
+
+    gdata = outdata;
+    gsize = size;
+    igdata = 0;
+
+    osa = signal(SIGALRM, sigALRM);
+
+    /* Start timer */
+    tv.it_value.tv_sec = 0;
+    tv.it_value.tv_usec = 10 * 1000; /* 10 ms */
+    tv.it_interval = tv.it_value;
+#ifdef HAVE_SETITIMER
+    setitimer(ITIMER_REAL, &tv, &otv);
+#else
+    ochld = signal(SIGCHLD, SIG_IGN);
+    pid = fork();
+    if(pid == -1){
+       signal(SIGCHLD, ochld != SIG_ERR ? ochld : SIG_DFL);
+       des_not_rand_data(data, size);
+       return;
+    }
+    if(pid == 0)
+       pacemaker(&tv.it_interval);
+#endif
+
+    for(i = 0; i < 4; i++) {
+       for (igdata = 0; igdata < size;) /* igdata++ in sigALRM */
+           counter++;
+       for (j = 0; j < size; j++) /* Only use 2 bits each lap */
+           gdata[j] = (gdata[j]>>2) | (gdata[j]<<6);
+    }
+#ifdef HAVE_SETITIMER
+    setitimer(ITIMER_REAL, &otv, 0);
+#else
+    kill(pid, SIGKILL);
+    while(waitpid(pid, NULL, 0) != pid);
+    signal(SIGCHLD, ochld != SIG_ERR ? ochld : SIG_DFL);
+#endif
+    signal(SIGALRM, osa != SIG_ERR ? osa : SIG_DFL);
+
+    return 1;
+#endif
+}
+
+static void
+timer_cleanup(void)
+{
+}
+
+static void
+timer_add(const void *indata, int size, double entropi)
+{
+}
+
+static int
+timer_pseudorand(unsigned char *outdata, int size)
+{
+    return timer_bytes(outdata, size);
+}
+
+static int
+timer_status(void)
+{
+#ifdef WIN32
+    return 0;
+#else
+    return 1;
+#endif
+}
+
+const RAND_METHOD hc_rand_timer_method = {
+    timer_seed,
+    timer_bytes,
+    timer_cleanup,
+    timer_add,
+    timer_pseudorand,
+    timer_status
+};
+
+const RAND_METHOD *
+RAND_timer_method(void)
+{
+    return &hc_rand_timer_method;
+}
diff --git a/src/external/heimdal/hcrypto/rand-unix.c b/src/external/heimdal/hcrypto/rand-unix.c
new file mode 100644 (file)
index 0000000..c52155b
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <rand.h>
+#include <heim_threads.h>
+
+#include <roken.h>
+
+#include "randi.h"
+
+/*
+ * Unix /dev/random
+ */
+
+int
+_hc_unix_device_fd(int flags, const char **fn)
+{
+    static const char *rnd_devices[] = {
+       "/dev/urandom",
+       "/dev/random",
+       "/dev/srandom",
+       "/dev/arandom",
+       NULL
+    };
+    const char **p;
+
+    for(p = rnd_devices; *p; p++) {
+       int fd = open(*p, flags | O_NDELAY);
+       if(fd >= 0) {
+           if (fn)
+               *fn = *p;
+           rk_cloexec(fd);
+           return fd;
+       }
+    }
+    return -1;
+}
+
+static void
+unix_seed(const void *indata, int size)
+{
+    int fd;
+
+    if (size <= 0)
+       return;
+
+    fd = _hc_unix_device_fd(O_WRONLY, NULL);
+    if (fd < 0)
+       return;
+
+    write(fd, indata, size);
+    close(fd);
+
+}
+
+
+static int
+unix_bytes(unsigned char *outdata, int size)
+{
+    ssize_t count;
+    int fd;
+
+    if (size < 0)
+       return 0;
+    else if (size == 0)
+       return 1;
+
+    fd = _hc_unix_device_fd(O_RDONLY, NULL);
+    if (fd < 0)
+       return 0;
+
+    while (size > 0) {
+       count = read(fd, outdata, size);
+       if (count < 0 && errno == EINTR)
+           continue;
+       else if (count <= 0) {
+           close(fd);
+           return 0;
+       }
+       outdata += count;
+       size -= count;
+    }
+    close(fd);
+
+    return 1;
+}
+
+static void
+unix_cleanup(void)
+{
+}
+
+static void
+unix_add(const void *indata, int size, double entropi)
+{
+    unix_seed(indata, size);
+}
+
+static int
+unix_pseudorand(unsigned char *outdata, int size)
+{
+    return unix_bytes(outdata, size);
+}
+
+static int
+unix_status(void)
+{
+    int fd;
+
+    fd = _hc_unix_device_fd(O_RDONLY, NULL);
+    if (fd < 0)
+       return 0;
+    close(fd);
+
+    return 1;
+}
+
+const RAND_METHOD hc_rand_unix_method = {
+    unix_seed,
+    unix_bytes,
+    unix_cleanup,
+    unix_add,
+    unix_pseudorand,
+    unix_status
+};
+
+const RAND_METHOD *
+RAND_unix_method(void)
+{
+    return &hc_rand_unix_method;
+}
diff --git a/src/external/heimdal/hcrypto/rand.c b/src/external/heimdal/hcrypto/rand.c
new file mode 100644 (file)
index 0000000..b02f938
--- /dev/null
@@ -0,0 +1,383 @@
+/*
+ * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <rand.h>
+#include <randi.h>
+
+#include <roken.h>
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+/**
+ * @page page_rand RAND - random number
+ *
+ * See the library functions here: @ref hcrypto_rand
+ */
+
+const static RAND_METHOD *selected_meth = NULL;
+static ENGINE *selected_engine = NULL;
+
+static void
+init_method(void)
+{
+    if (selected_meth != NULL)
+       return;
+#if defined(_WIN32)
+    selected_meth = &hc_rand_w32crypto_method;
+#elif defined(__APPLE__)
+    selected_meth = &hc_rand_unix_method;
+#else
+    selected_meth = &hc_rand_fortuna_method;
+#endif
+}
+
+/**
+ * Seed that random number generator. Secret material can securely be
+ * feed into the function, they will never be returned.
+ *
+ * @param indata seed data
+ * @param size length seed data
+ *
+ * @ingroup hcrypto_rand
+ */
+
+void
+RAND_seed(const void *indata, size_t size)
+{
+    init_method();
+    (*selected_meth->seed)(indata, size);
+}
+
+/**
+ * Get a random block from the random generator, can be used for key material.
+ *
+ * @param outdata random data
+ * @param size length random data
+ *
+ * @return 1 on success, 0 on failure.
+ *
+ * @ingroup hcrypto_rand
+ */
+int
+RAND_bytes(void *outdata, size_t size)
+{
+    if (size == 0)
+       return 1;
+    init_method();
+    return (*selected_meth->bytes)(outdata, size);
+}
+
+/**
+ * Reset and free memory used by the random generator.
+ *
+ * @ingroup hcrypto_rand
+ */
+
+void
+RAND_cleanup(void)
+{
+    const RAND_METHOD *meth = selected_meth;
+    ENGINE *engine = selected_engine;
+
+    selected_meth = NULL;
+    selected_engine = NULL;
+
+    if (meth)
+       (*meth->cleanup)();
+    if (engine)
+       ENGINE_finish(engine);
+}
+
+/**
+ * Seed that random number generator. Secret material can securely be
+ * feed into the function, they will never be returned.
+ *
+ * @param indata the input data.
+ * @param size size of in data.
+ * @param entropi entropi in data.
+ *
+ *
+ * @ingroup hcrypto_rand
+ */
+
+void
+RAND_add(const void *indata, size_t size, double entropi)
+{
+    init_method();
+    (*selected_meth->add)(indata, size, entropi);
+}
+
+/**
+ * Get a random block from the random generator, should NOT be used for key material.
+ *
+ * @param outdata random data
+ * @param size length random data
+ *
+ * @return 1 on success, 0 on failure.
+ *
+ * @ingroup hcrypto_rand
+ */
+
+int
+RAND_pseudo_bytes(void *outdata, size_t size)
+{
+    init_method();
+    return (*selected_meth->pseudorand)(outdata, size);
+}
+
+/**
+ * Return status of the random generator
+ *
+ * @return 1 if the random generator can deliver random data.
+ *
+ * @ingroup hcrypto_rand
+ */
+
+int
+RAND_status(void)
+{
+    init_method();
+    return (*selected_meth->status)();
+}
+
+/**
+ * Set the default random method.
+ *
+ * @param meth set the new default method.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_rand
+ */
+
+int
+RAND_set_rand_method(const RAND_METHOD *meth)
+{
+    const RAND_METHOD *old = selected_meth;
+    selected_meth = meth;
+    if (old)
+       (*old->cleanup)();
+    if (selected_engine) {
+       ENGINE_finish(selected_engine);
+       selected_engine = NULL;
+    }
+    return 1;
+}
+
+/**
+ * Get the default random method.
+ *
+ * @ingroup hcrypto_rand
+ */
+
+const RAND_METHOD *
+RAND_get_rand_method(void)
+{
+    init_method();
+    return selected_meth;
+}
+
+/**
+ * Set the default random method from engine.
+ *
+ * @param engine use engine, if NULL is passed it, old method and engine is cleared.
+ *
+ * @return 1 on success, 0 on failure.
+ *
+ * @ingroup hcrypto_rand
+ */
+
+int
+RAND_set_rand_engine(ENGINE *engine)
+{
+    const RAND_METHOD *meth, *old = selected_meth;
+
+    if (engine) {
+       ENGINE_up_ref(engine);
+       meth = ENGINE_get_RAND(engine);
+       if (meth == NULL) {
+           ENGINE_finish(engine);
+           return 0;
+       }
+    } else {
+       meth = NULL;
+    }
+
+    if (old)
+       (*old->cleanup)();
+
+    if (selected_engine)
+       ENGINE_finish(selected_engine);
+
+    selected_engine = engine;
+    selected_meth = meth;
+
+    return 1;
+}
+
+#define RAND_FILE_SIZE 1024
+
+/**
+ * Load a a file and feed it into RAND_seed().
+ *
+ * @param filename name of file to read.
+ * @param size minimum size to read.
+ *
+ * @ingroup hcrypto_rand
+ */
+
+int
+RAND_load_file(const char *filename, size_t size)
+{
+    unsigned char buf[128];
+    size_t len;
+    ssize_t slen;
+    int fd;
+
+    fd = open(filename, O_RDONLY | O_BINARY, 0600);
+    if (fd < 0)
+       return 0;
+    rk_cloexec(fd);
+    len = 0;
+    while(len < size) {
+       slen = read(fd, buf, sizeof(buf));
+       if (slen <= 0)
+           break;
+       RAND_seed(buf, slen);
+       len += slen;
+    }
+    close(fd);
+
+    return len ? 1 : 0;
+}
+
+/**
+ * Write of random numbers to a file to store for later initiation with RAND_load_file().
+ *
+ * @param filename name of file to write.
+ *
+ * @return 1 on success and non-one on failure.
+ * @ingroup hcrypto_rand
+ */
+
+int
+RAND_write_file(const char *filename)
+{
+    unsigned char buf[128];
+    size_t len;
+    int res = 0, fd;
+
+    fd = open(filename, O_WRONLY | O_CREAT | O_BINARY, 0600);
+    if (fd < 0)
+       return 0;
+    rk_cloexec(fd);
+
+    len = 0;
+    while(len < RAND_FILE_SIZE) {
+       res = RAND_bytes(buf, sizeof(buf));
+       if (res != 1)
+           break;
+       if (write(fd, buf, sizeof(buf)) != sizeof(buf)) {
+           res = 0;
+           break;
+       }
+       len += sizeof(buf);
+    }
+
+    close(fd);
+
+    return res;
+}
+
+/**
+ * Return the default random state filename for a user to use for
+ * RAND_load_file(), and RAND_write_file().
+ *
+ * @param filename buffer to hold file name.
+ * @param size size of buffer filename.
+ *
+ * @return the buffer filename or NULL on failure.
+ *
+ * @ingroup hcrypto_rand
+ */
+
+const char *
+RAND_file_name(char *filename, size_t size)
+{
+    const char *e = NULL;
+    int pathp = 0, ret;
+
+    if (!issuid()) {
+       e = getenv("RANDFILE");
+       if (e == NULL)
+           e = getenv("HOME");
+       if (e)
+           pathp = 1;
+    }
+    /*
+     * Here we really want to call getpwuid(getuid()) but this will
+     * cause recursive lookups if the nss library uses
+     * gssapi/krb5/hcrypto to authenticate to the ldap servers.
+     *
+     * So at least return the unix /dev/random if we have one
+     */
+#ifndef _WIN32
+    if (e == NULL) {
+       int fd;
+
+       fd = _hc_unix_device_fd(O_RDONLY, &e);
+       if (fd >= 0)
+           close(fd);
+    }
+#endif
+    if (e == NULL)
+       return NULL;
+
+    if (pathp)
+       ret = snprintf(filename, size, "%s/.rnd", e);
+    else
+       ret = snprintf(filename, size, "%s", e);
+
+    if (ret <= 0 || ret >= size)
+       return NULL;
+
+    return filename;
+}
diff --git a/src/external/heimdal/hcrypto/rand.h b/src/external/heimdal/hcrypto/rand.h
new file mode 100644 (file)
index 0000000..923d4ad
--- /dev/null
@@ -0,0 +1,108 @@
+
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _HEIM_RAND_H
+#define _HEIM_RAND_H 1
+
+typedef struct RAND_METHOD RAND_METHOD;
+
+#include <hcrypto/engine.h>
+
+/* symbol renaming */
+#define RAND_bytes hc_RAND_bytes
+#define RAND_pseudo_bytes hc_RAND_pseudo_bytes
+#define RAND_seed hc_RAND_seed
+#define RAND_cleanup hc_RAND_cleanup
+#define RAND_add hc_RAND_add
+#define RAND_set_rand_method hc_RAND_set_rand_method
+#define RAND_get_rand_method hc_RAND_get_rand_method
+#define RAND_set_rand_engine hc_RAND_set_rand_engine
+#define RAND_file_name hc_RAND_file_name
+#define RAND_load_file hc_RAND_load_file
+#define RAND_write_file hc_RAND_write_file
+#define RAND_status hc_RAND_status
+#define RAND_egd hc_RAND_egd
+#define RAND_egd_bytes hc_RAND_egd_bytes
+#define RAND_fortuna_method hc_RAND_fortuna_method
+#define RAND_egd_method hc_RAND_egd_method
+#define RAND_unix_method hc_RAND_unix_method
+#define RAND_w32crypto_method hc_RAND_w32crypto_method
+
+/*
+ *
+ */
+
+struct RAND_METHOD
+{
+    void (*seed)(const void *, int);
+    int (*bytes)(unsigned char *, int);
+    void (*cleanup)(void);
+    void (*add)(const void *, int, double);
+    int (*pseudorand)(unsigned char *, int);
+    int (*status)(void);
+};
+
+/*
+ *
+ */
+
+int    RAND_bytes(void *, size_t num);
+int    RAND_pseudo_bytes(void *, size_t);
+void   RAND_seed(const void *, size_t);
+void   RAND_cleanup(void);
+void   RAND_add(const void *, size_t, double);
+
+int    RAND_set_rand_method(const RAND_METHOD *);
+const RAND_METHOD *
+       RAND_get_rand_method(void);
+int    RAND_set_rand_engine(ENGINE *);
+
+const char *
+       RAND_file_name(char *, size_t);
+int    RAND_load_file(const char *, size_t);
+int    RAND_write_file(const char *);
+int    RAND_status(void);
+int    RAND_egd(const char *);
+int    RAND_egd_bytes(const char *, int);
+
+
+const RAND_METHOD *    RAND_fortuna_method(void);
+const RAND_METHOD *    RAND_unix_method(void);
+const RAND_METHOD *    RAND_egd_method(void);
+
+#endif /* _HEIM_RAND_H */
diff --git a/src/external/heimdal/hcrypto/randi.h b/src/external/heimdal/hcrypto/randi.h
new file mode 100644 (file)
index 0000000..fe021a8
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _HEIM_RANDI_H
+#define _HEIM_RANDI_H 1
+
+extern const RAND_METHOD hc_rand_fortuna_method;
+extern const RAND_METHOD hc_rand_unix_method;
+extern const RAND_METHOD hc_rand_egd_method;
+extern const RAND_METHOD hc_rand_timer_method;
+extern const RAND_METHOD hc_rand_w32crypto_method;
+
+const RAND_METHOD * RAND_timer_method(void);
+int _hc_unix_device_fd(int, const char **);
+
+#endif /* _HEIM_RANDI_H */
diff --git a/src/external/heimdal/hcrypto/rc2.c b/src/external/heimdal/hcrypto/rc2.c
new file mode 100644 (file)
index 0000000..63bd3da
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+#include <config.h>
+
+#include "rc2.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+ * Implemented from Peter Gutmann's "Specification for Ron Rivests Cipher No.2"
+ * rfc2268 and "On the Design and Security of RC2" was also useful.
+ */
+
+static unsigned int Sbox[256] = {
+    0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed,
+    0x28, 0xe9, 0xfd, 0x79, 0x4a, 0xa0, 0xd8, 0x9d,
+    0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e,
+    0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2,
+    0x17, 0x9a, 0x59, 0xf5, 0x87, 0xb3, 0x4f, 0x13,
+    0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32,
+    0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b,
+    0xf0, 0x95, 0x21, 0x22, 0x5c, 0x6b, 0x4e, 0x82,
+    0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c,
+    0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc,
+    0x12, 0x75, 0xca, 0x1f, 0x3b, 0xbe, 0xe4, 0xd1,
+    0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26,
+    0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57,
+    0x27, 0xf2, 0x1d, 0x9b, 0xbc, 0x94, 0x43, 0x03,
+    0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7,
+    0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7,
+    0x08, 0xe8, 0xea, 0xde, 0x80, 0x52, 0xee, 0xf7,
+    0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a,
+    0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74,
+    0x4b, 0x9f, 0xd0, 0x5e, 0x04, 0x18, 0xa4, 0xec,
+    0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc,
+    0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39,
+    0x99, 0x7c, 0x3a, 0x85, 0x23, 0xb8, 0xb4, 0x7a,
+    0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31,
+    0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae,
+    0x05, 0xdf, 0x29, 0x10, 0x67, 0x6c, 0xba, 0xc9,
+    0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c,
+    0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9,
+    0x0d, 0x38, 0x34, 0x1b, 0xab, 0x33, 0xff, 0xb0,
+    0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e,
+    0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77,
+    0x0a, 0xa6, 0x20, 0x68, 0xfe, 0x7f, 0xc1, 0xad
+};
+
+void
+RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits)
+{
+    unsigned char k[128];
+    int j, T8, TM;
+
+    if (len <= 0)
+       abort();
+    if (len > 128)
+       len = 128;
+    if (bits <= 0 || bits > 1024)
+       bits = 1024;
+
+    for (j = 0; j < len; j++)
+       k[j] = data[j];
+    for (; j < 128; j++)
+       k[j] = Sbox[(k[j - len] + k[j - 1]) & 0xff];
+
+    T8 = (bits + 7) / 8;
+    j = (8*T8 - bits);
+    TM = 0xff >> j;
+
+    k[128 - T8] = Sbox[k[128 - T8] & TM];
+
+    for (j = 127 - T8; j >= 0; j--)
+       k[j] = Sbox[k[j + 1] ^ k[j + T8]];
+
+    for (j = 0; j < 64; j++)
+       key->data[j] = k[(j * 2) + 0] | (k[(j * 2) + 1] << 8);
+    memset(k, 0, sizeof(k));
+}
+
+#define ROT16L(w,n)  ((w<<n)|(w>>(16-n)))
+#define ROT16R(w,n)  ((w>>n)|(w<<(16-n)))
+
+void
+RC2_encryptc(unsigned char *in, unsigned char *out, const RC2_KEY *key)
+{
+    int i, j;
+    int w0, w1, w2, w3;
+    int t0, t1, t2, t3;
+
+    w0 = in[0] | (in[1] << 8);
+    w1 = in[2] | (in[3] << 8);
+    w2 = in[4] | (in[5] << 8);
+    w3 = in[6] | (in[7] << 8);
+
+    for (i = 0; i < 16; i++) {
+       j = i * 4;
+       t0 = (w0 + (w1 & ~w3) + (w2 & w3) + key->data[j + 0]) & 0xffff;
+       w0 = ROT16L(t0, 1);
+       t1 = (w1 + (w2 & ~w0) + (w3 & w0) + key->data[j + 1]) & 0xffff;
+       w1 = ROT16L(t1, 2);
+       t2 = (w2 + (w3 & ~w1) + (w0 & w1) + key->data[j + 2]) & 0xffff;
+       w2 = ROT16L(t2, 3);
+       t3 = (w3 + (w0 & ~w2) + (w1 & w2) + key->data[j + 3]) & 0xffff;
+       w3 = ROT16L(t3, 5);
+       if(i == 4 || i == 10) {
+           w0 += key->data[w3 & 63];
+           w1 += key->data[w0 & 63];
+           w2 += key->data[w1 & 63];
+           w3 += key->data[w2 & 63];
+       }
+    }
+
+    out[0] = w0 & 0xff;
+    out[1] = (w0 >> 8) & 0xff;
+    out[2] = w1 & 0xff;
+    out[3] = (w1 >> 8) & 0xff;
+    out[4] = w2 & 0xff;
+    out[5] = (w2 >> 8) & 0xff;
+    out[6] = w3 & 0xff;
+    out[7] = (w3 >> 8) & 0xff;
+}
+
+void
+RC2_decryptc(unsigned char *in, unsigned char *out, const RC2_KEY *key)
+{
+    int i, j;
+    int w0, w1, w2, w3;
+    int t0, t1, t2, t3;
+
+    w0 = in[0] | (in[1] << 8);
+    w1 = in[2] | (in[3] << 8);
+    w2 = in[4] | (in[5] << 8);
+    w3 = in[6] | (in[7] << 8);
+
+    for (i = 15; i >= 0; i--) {
+       j = i * 4;
+
+       if(i == 4 || i == 10) {
+           w3 = (w3 - key->data[w2 & 63]) & 0xffff;
+           w2 = (w2 - key->data[w1 & 63]) & 0xffff;
+           w1 = (w1 - key->data[w0 & 63]) & 0xffff;
+           w0 = (w0 - key->data[w3 & 63]) & 0xffff;
+       }
+
+       t3 = ROT16R(w3, 5);
+       w3 = (t3 - (w0 & ~w2) - (w1 & w2) - key->data[j + 3]) & 0xffff;
+       t2 = ROT16R(w2, 3);
+       w2 = (t2 - (w3 & ~w1) - (w0 & w1) - key->data[j + 2]) & 0xffff;
+       t1 = ROT16R(w1, 2);
+       w1 = (t1 - (w2 & ~w0) - (w3 & w0) - key->data[j + 1]) & 0xffff;
+       t0 = ROT16R(w0, 1);
+       w0 = (t0 - (w1 & ~w3) - (w2 & w3) - key->data[j + 0]) & 0xffff;
+
+    }
+    out[0] = w0 & 0xff;
+    out[1] = (w0 >> 8) & 0xff;
+    out[2] = w1 & 0xff;
+    out[3] = (w1 >> 8) & 0xff;
+    out[4] = w2 & 0xff;
+    out[5] = (w2 >> 8) & 0xff;
+    out[6] = w3 & 0xff;
+    out[7] = (w3 >> 8) & 0xff;
+}
+
+void
+RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long size,
+               RC2_KEY *key, unsigned char *iv, int forward_encrypt)
+{
+    unsigned char tmp[RC2_BLOCK_SIZE];
+    int i;
+
+    if (forward_encrypt) {
+       while (size >= RC2_BLOCK_SIZE) {
+           for (i = 0; i < RC2_BLOCK_SIZE; i++)
+               tmp[i] = in[i] ^ iv[i];
+           RC2_encryptc(tmp, out, key);
+           memcpy(iv, out, RC2_BLOCK_SIZE);
+           size -= RC2_BLOCK_SIZE;
+           in += RC2_BLOCK_SIZE;
+           out += RC2_BLOCK_SIZE;
+       }
+       if (size) {
+           for (i = 0; i < size; i++)
+               tmp[i] = in[i] ^ iv[i];
+           for (i = size; i < RC2_BLOCK_SIZE; i++)
+               tmp[i] = iv[i];
+           RC2_encryptc(tmp, out, key);
+           memcpy(iv, out, RC2_BLOCK_SIZE);
+       }
+    } else {
+       while (size >= RC2_BLOCK_SIZE) {
+           memcpy(tmp, in, RC2_BLOCK_SIZE);
+           RC2_decryptc(tmp, out, key);
+           for (i = 0; i < RC2_BLOCK_SIZE; i++)
+               out[i] ^= iv[i];
+           memcpy(iv, tmp, RC2_BLOCK_SIZE);
+           size -= RC2_BLOCK_SIZE;
+           in += RC2_BLOCK_SIZE;
+           out += RC2_BLOCK_SIZE;
+       }
+       if (size) {
+           memcpy(tmp, in, RC2_BLOCK_SIZE);
+           RC2_decryptc(tmp, out, key);
+           for (i = 0; i < size; i++)
+               out[i] ^= iv[i];
+           memcpy(iv, tmp, RC2_BLOCK_SIZE);
+       }
+    }
+}
diff --git a/src/external/heimdal/hcrypto/rc2.h b/src/external/heimdal/hcrypto/rc2.h
new file mode 100644 (file)
index 0000000..5e479fb
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+/* $Id$ */
+
+/* symbol renaming */
+#define RC2_set_key hc_RC2_set_key
+#define RC2_encryptc hc_RC2_encryptc
+#define RC2_decryptc hc_RC2_decryptc
+#define RC2_cbc_encrypt hc_RC2_cbc_encrypt
+
+/*
+ *
+ */
+
+#define RC2_ENCRYPT    1
+#define RC2_DECRYPT    0
+
+#define RC2_BLOCK_SIZE 8
+#define RC2_BLOCK      RC2_BLOCK_SIZE
+#define RC2_KEY_LENGTH 16
+
+typedef struct rc2_key {
+    unsigned int data[64];
+} RC2_KEY;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void RC2_set_key(RC2_KEY *, int, const unsigned char *,int);
+
+void RC2_encryptc(unsigned char *, unsigned char *, const RC2_KEY *);
+void RC2_decryptc(unsigned char *, unsigned char *, const RC2_KEY *);
+
+void RC2_cbc_encrypt(const unsigned char *, unsigned char *, long,
+                    RC2_KEY *, unsigned char *, int);
+
+#ifdef  __cplusplus
+}
+#endif
diff --git a/src/external/heimdal/hcrypto/rc4.c b/src/external/heimdal/hcrypto/rc4.c
new file mode 100644 (file)
index 0000000..988c424
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+/* implemented from description in draft-kaukonen-cipher-arcfour-03.txt */
+
+#include "config.h"
+
+#include <rc4.h>
+
+#define SWAP(k,x,y)                            \
+{ unsigned int _t;                             \
+  _t = k->state[x];                            \
+  k->state[x] = k->state[y];                   \
+  k->state[y] = _t;                            \
+}
+
+void
+RC4_set_key(RC4_KEY *key, const int len, const unsigned char *data)
+{
+    int i, j;
+
+    for (i = 0; i < 256; i++)
+       key->state[i] = i;
+    for (i = 0, j = 0; i < 256; i++) {
+       j = (j + key->state[i] + data[i % len]) % 256;
+       SWAP(key, i, j);
+    }
+    key->x = key->y = 0;
+}
+
+void
+RC4(RC4_KEY *key, const int len, const unsigned char *in, unsigned char *out)
+{
+    int i, t;
+    unsigned x, y;
+
+    x = key->x;
+    y = key->y;
+    for (i = 0; i < len; i++) {
+       x = (x + 1) % 256;
+       y = (y + key->state[x]) % 256;
+       SWAP(key, x, y);
+       t = (key->state[x] + key->state[y]) % 256;
+       *out++ = key->state[t] ^ *in++;
+    }
+    key->x = x;
+    key->y = y;
+}
diff --git a/src/external/heimdal/hcrypto/rc4.h b/src/external/heimdal/hcrypto/rc4.h
new file mode 100644 (file)
index 0000000..f93482f
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+ */
+
+/* $Id$ */
+
+/* symbol renaming */
+#define RC4_set_key hc_RC4_set_key
+#define RC4 hc_RC4
+
+typedef struct rc4_key {
+    unsigned int x, y;
+    unsigned int state[256];
+} RC4_KEY;
+
+void RC4_set_key(RC4_KEY *, const int, const unsigned char *);
+void RC4(RC4_KEY *, const int, const unsigned char *, unsigned char *);
diff --git a/src/external/heimdal/hcrypto/rijndael-alg-fst.c b/src/external/heimdal/hcrypto/rijndael-alg-fst.c
new file mode 100644 (file)
index 0000000..a44b525
--- /dev/null
@@ -0,0 +1,1229 @@
+/*     $NetBSD: rijndael-alg-fst.c,v 1.5 2001/11/13 01:40:10 lukem Exp $       */
+/*     $KAME: rijndael-alg-fst.c,v 1.10 2003/07/15 10:47:16 itojun Exp $       */
+/**
+ * rijndael-alg-fst.c
+ *
+ * @version 3.0 (December 2000)
+ *
+ * Optimised ANSI C code for the Rijndael cipher (now AES)
+ *
+ * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ * @author Paulo Barreto <paulo.barreto@terra.com.br>
+ *
+ * This code is hereby placed in the public domain.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN 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.
+ */
+
+/* "$NetBSD: rijndael-alg-fst.c,v 1.5 2001/11/13 01:40:10 lukem Exp $" */
+
+#include "config.h"
+
+
+#include <stdlib.h>
+#ifdef KRB5
+#include <krb5-types.h>
+#endif
+
+#include "rijndael-alg-fst.h"
+
+/* the file should not be used from outside */
+typedef uint8_t                        u8;
+typedef uint16_t               u16;
+typedef uint32_t               u32;
+
+/*
+Te0[x] = S [x].[02, 01, 01, 03];
+Te1[x] = S [x].[03, 02, 01, 01];
+Te2[x] = S [x].[01, 03, 02, 01];
+Te3[x] = S [x].[01, 01, 03, 02];
+Te4[x] = S [x].[01, 01, 01, 01];
+
+Td0[x] = Si[x].[0e, 09, 0d, 0b];
+Td1[x] = Si[x].[0b, 0e, 09, 0d];
+Td2[x] = Si[x].[0d, 0b, 0e, 09];
+Td3[x] = Si[x].[09, 0d, 0b, 0e];
+Td4[x] = Si[x].[01, 01, 01, 01];
+*/
+
+static const u32 Te0[256] = {
+    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
+    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
+    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
+    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
+    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
+    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
+    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
+    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
+    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
+    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
+    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
+    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
+    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
+    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
+    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
+    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
+    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
+    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
+    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
+    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
+    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
+    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
+    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
+    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
+    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
+    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
+    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
+    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
+    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
+    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
+    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
+    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
+    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
+    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
+    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
+    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
+    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
+    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
+    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
+    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
+    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
+    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
+    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
+    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
+    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
+    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
+    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
+    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
+    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
+    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
+    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
+    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
+    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
+    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
+    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
+    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
+    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
+    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
+    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
+    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
+    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
+    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
+    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
+    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
+};
+static const u32 Te1[256] = {
+    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
+    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
+    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
+    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
+    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
+    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
+    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
+    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
+    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
+    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
+    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
+    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
+    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
+    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
+    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
+    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
+    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
+    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
+    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
+    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
+    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
+    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
+    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
+    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
+    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
+    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
+    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
+    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
+    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
+    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
+    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
+    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
+    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
+    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
+    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
+    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
+    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
+    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
+    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
+    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
+    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
+    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
+    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
+    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
+    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
+    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
+    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
+    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
+    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
+    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
+    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
+    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
+    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
+    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
+    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
+    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
+    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
+    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
+    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
+    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
+    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
+    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
+    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
+    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
+};
+static const u32 Te2[256] = {
+    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
+    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
+    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
+    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
+    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
+    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
+    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
+    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
+    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
+    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
+    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
+    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
+    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
+    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
+    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
+    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
+    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
+    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
+    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
+    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
+    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
+    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
+    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
+    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
+    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
+    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
+    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
+    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
+    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
+    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
+    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
+    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
+    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
+    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
+    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
+    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
+    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
+    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
+    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
+    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
+    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
+    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
+    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
+    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
+    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
+    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
+    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
+    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
+    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
+    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
+    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
+    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
+    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
+    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
+    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
+    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
+    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
+    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
+    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
+    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
+    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
+    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
+    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
+    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
+};
+static const u32 Te3[256] = {
+
+    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
+    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
+    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
+    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
+    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
+    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
+    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
+    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
+    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
+    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
+    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
+    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
+    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
+    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
+    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
+    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
+    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
+    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
+    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
+    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
+    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
+    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
+    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
+    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
+    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
+    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
+    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
+    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
+    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
+    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
+    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
+    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
+    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
+    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
+    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
+    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
+    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
+    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
+    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
+    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
+    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
+    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
+    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
+    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
+    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
+    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
+    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
+    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
+    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
+    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
+    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
+    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
+    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
+    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
+    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
+    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
+    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
+    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
+    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
+    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
+    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
+    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
+    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
+    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
+};
+static const u32 Te4[256] = {
+    0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
+    0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
+    0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
+    0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
+    0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
+    0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
+    0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
+    0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
+    0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
+    0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
+    0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
+    0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
+    0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
+    0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
+    0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
+    0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
+    0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
+    0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
+    0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
+    0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
+    0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
+    0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
+    0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
+    0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
+    0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
+    0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
+    0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
+    0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
+    0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
+    0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
+    0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
+    0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
+    0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
+    0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
+    0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7