summaryrefslogtreecommitdiffabout
path: root/pwmanager
Side-by-side diff
Diffstat (limited to 'pwmanager') (more/less context) (ignore whitespace changes)
-rw-r--r--pwmanager/libcrypt/cipher/serpent.c4
-rw-r--r--pwmanager/pwmanager/binentrygen.cpp5
-rw-r--r--pwmanager/pwmanager/binentrygen.h2
-rw-r--r--pwmanager/pwmanager/blowfish.cpp2
-rw-r--r--pwmanager/pwmanager/blowfish.h4
-rw-r--r--pwmanager/pwmanager/genpasswd.cpp1
-rw-r--r--pwmanager/pwmanager/libgcryptif.h4
-rw-r--r--pwmanager/pwmanager/pwmexception.h3
-rw-r--r--pwmanager/pwmanager/randomizer.h1
9 files changed, 17 insertions, 9 deletions
diff --git a/pwmanager/libcrypt/cipher/serpent.c b/pwmanager/libcrypt/cipher/serpent.c
index d606d9f..fb5df20 100644
--- a/pwmanager/libcrypt/cipher/serpent.c
+++ b/pwmanager/libcrypt/cipher/serpent.c
@@ -1,979 +1,979 @@
/* serpent.c - Implementation of the Serpent encryption algorithm.
* Copyright (C) 2003 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser general Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include <config.h>
#include <string.h>
#include <stdio.h>
#include "types.h"
#include "g10lib.h"
#include "cipher.h"
#include "bithelp.h"
/* Number of rounds per Serpent encrypt/decrypt operation. */
#define ROUNDS 32
/* Magic number, used during generating of the subkeys. */
#define PHI 0x9E3779B9
/* Internal types. */
typedef byte byte_t;
typedef u32 u32_t;
/* Serpent works on 128 bit blocks. */
typedef u32_t serpent_block_t[4];
/* Serpent key, provided by the user. If the original key is shorter
than 256 bits, it is padded. */
typedef u32_t serpent_key_t[8];
/* The key schedule consists of 33 128 bit subkeys. */
typedef u32_t serpent_subkeys_t[ROUNDS + 1][4];
/* A Serpent context. */
typedef struct serpent_context
{
serpent_subkeys_t keys; /* Generated subkeys. */
} serpent_context_t;
#define byte_swap_32(x) \
(0 \
| (((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) \
| (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24));
/* These are the S-Boxes of Serpent. They are copied from Serpents
reference implementation (the optimized one, contained in
`floppy2') and are therefore:
Copyright (C) 1998 Ross Anderson, Eli Biham, Lars Knudsen.
To quote the Serpent homepage
(http://www.cl.cam.ac.uk/~rja14/serpent.html):
"Serpent is now completely in the public domain, and we impose no
restrictions on its use. This was announced on the 21st August at
the First AES Candidate Conference. The optimised implementations
in the submission package are now under the GNU PUBLIC LICENSE
(GPL), although some comments in the code still say otherwise. You
are welcome to use Serpent for any application." */
#define SBOX0(a, b, c, d, w, x, y, z) \
{ \
register unsigned long t02, t03, t05, t06, t07, t08, t09; \
register unsigned long t11, t12, t13, t14, t15, t17, t01; \
t01 = b ^ c ; \
t02 = a | d ; \
t03 = a ^ b ; \
z = t02 ^ t01; \
t05 = c | z ; \
t06 = a ^ d ; \
t07 = b | c ; \
t08 = d & t05; \
t09 = t03 & t07; \
y = t09 ^ t08; \
t11 = t09 & y ; \
t12 = c ^ d ; \
t13 = t07 ^ t11; \
t14 = b & t06; \
t15 = t06 ^ t13; \
w = ~ t15; \
t17 = w ^ t14; \
x = t12 ^ t17; \
}
#define SBOX0_INVERSE(a, b, c, d, w, x, y, z) \
{ \
register unsigned long t02, t03, t04, t05, t06, t08, t09, t10; \
register unsigned long t12, t13, t14, t15, t17, t18, t01; \
t01 = c ^ d ; \
t02 = a | b ; \
t03 = b | c ; \
t04 = c & t01; \
t05 = t02 ^ t01; \
t06 = a | t04; \
y = ~ t05; \
t08 = b ^ d ; \
t09 = t03 & t08; \
t10 = d | y ; \
x = t09 ^ t06; \
t12 = a | t05; \
t13 = x ^ t12; \
t14 = t03 ^ t10; \
t15 = a ^ c ; \
z = t14 ^ t13; \
t17 = t05 & t13; \
t18 = t14 | t17; \
w = t15 ^ t18; \
}
#define SBOX1(a, b, c, d, w, x, y, z) \
{ \
register unsigned long t02, t03, t04, t05, t06, t07, t08; \
register unsigned long t10, t11, t12, t13, t16, t17, t01; \
t01 = a | d ; \
t02 = c ^ d ; \
t03 = ~ b ; \
t04 = a ^ c ; \
t05 = a | t03; \
t06 = d & t04; \
t07 = t01 & t02; \
t08 = b | t06; \
y = t02 ^ t05; \
t10 = t07 ^ t08; \
t11 = t01 ^ t10; \
t12 = y ^ t11; \
t13 = b & d ; \
z = ~ t10; \
x = t13 ^ t12; \
t16 = t10 | x ; \
t17 = t05 & t16; \
w = c ^ t17; \
}
#define SBOX1_INVERSE(a, b, c, d, w, x, y, z) \
{ \
register unsigned long t02, t03, t04, t05, t06, t07, t08; \
register unsigned long t09, t10, t11, t14, t15, t17, t01; \
t01 = a ^ b ; \
t02 = b | d ; \
t03 = a & c ; \
t04 = c ^ t02; \
t05 = a | t04; \
t06 = t01 & t05; \
t07 = d | t03; \
t08 = b ^ t06; \
t09 = t07 ^ t06; \
t10 = t04 | t03; \
t11 = d & t08; \
y = ~ t09; \
x = t10 ^ t11; \
t14 = a | y ; \
t15 = t06 ^ x ; \
z = t01 ^ t04; \
t17 = c ^ t15; \
w = t14 ^ t17; \
}
#define SBOX2(a, b, c, d, w, x, y, z) \
{ \
register unsigned long t02, t03, t05, t06, t07, t08; \
register unsigned long t09, t10, t12, t13, t14, t01; \
t01 = a | c ; \
t02 = a ^ b ; \
t03 = d ^ t01; \
w = t02 ^ t03; \
t05 = c ^ w ; \
t06 = b ^ t05; \
t07 = b | t05; \
t08 = t01 & t06; \
t09 = t03 ^ t07; \
t10 = t02 | t09; \
x = t10 ^ t08; \
t12 = a | d ; \
t13 = t09 ^ x ; \
t14 = b ^ t13; \
z = ~ t09; \
y = t12 ^ t14; \
}
#define SBOX2_INVERSE(a, b, c, d, w, x, y, z) \
{ \
register unsigned long t02, t03, t04, t06, t07, t08, t09; \
register unsigned long t10, t11, t12, t15, t16, t17, t01; \
t01 = a ^ d ; \
t02 = c ^ d ; \
t03 = a & c ; \
t04 = b | t02; \
w = t01 ^ t04; \
t06 = a | c ; \
t07 = d | w ; \
t08 = ~ d ; \
t09 = b & t06; \
t10 = t08 | t03; \
t11 = b & t07; \
t12 = t06 & t02; \
z = t09 ^ t10; \
x = t12 ^ t11; \
t15 = c & z ; \
t16 = w ^ x ; \
t17 = t10 ^ t15; \
y = t16 ^ t17; \
}
#define SBOX3(a, b, c, d, w, x, y, z) \
{ \
register unsigned long t02, t03, t04, t05, t06, t07, t08; \
register unsigned long t09, t10, t11, t13, t14, t15, t01; \
t01 = a ^ c ; \
t02 = a | d ; \
t03 = a & d ; \
t04 = t01 & t02; \
t05 = b | t03; \
t06 = a & b ; \
t07 = d ^ t04; \
t08 = c | t06; \
t09 = b ^ t07; \
t10 = d & t05; \
t11 = t02 ^ t10; \
z = t08 ^ t09; \
t13 = d | z ; \
t14 = a | t07; \
t15 = b & t13; \
y = t08 ^ t11; \
w = t14 ^ t15; \
x = t05 ^ t04; \
}
#define SBOX3_INVERSE(a, b, c, d, w, x, y, z) \
{ \
register unsigned long t02, t03, t04, t05, t06, t07, t09; \
register unsigned long t11, t12, t13, t14, t16, t01; \
t01 = c | d ; \
t02 = a | d ; \
t03 = c ^ t02; \
t04 = b ^ t02; \
t05 = a ^ d ; \
t06 = t04 & t03; \
t07 = b & t01; \
y = t05 ^ t06; \
t09 = a ^ t03; \
w = t07 ^ t03; \
t11 = w | t05; \
t12 = t09 & t11; \
t13 = a & y ; \
t14 = t01 ^ t05; \
x = b ^ t12; \
t16 = b | t13; \
z = t14 ^ t16; \
}
#define SBOX4(a, b, c, d, w, x, y, z) \
{ \
register unsigned long t02, t03, t04, t05, t06, t08, t09; \
register unsigned long t10, t11, t12, t13, t14, t15, t16, t01; \
t01 = a | b ; \
t02 = b | c ; \
t03 = a ^ t02; \
t04 = b ^ d ; \
t05 = d | t03; \
t06 = d & t01; \
z = t03 ^ t06; \
t08 = z & t04; \
t09 = t04 & t05; \
t10 = c ^ t06; \
t11 = b & c ; \
t12 = t04 ^ t08; \
t13 = t11 | t03; \
t14 = t10 ^ t09; \
t15 = a & t05; \
t16 = t11 | t12; \
y = t13 ^ t08; \
x = t15 ^ t16; \
w = ~ t14; \
}
#define SBOX4_INVERSE(a, b, c, d, w, x, y, z) \
{ \
register unsigned long t02, t03, t04, t05, t06, t07, t09; \
register unsigned long t10, t11, t12, t13, t15, t01; \
t01 = b | d ; \
t02 = c | d ; \
t03 = a & t01; \
t04 = b ^ t02; \
t05 = c ^ d ; \
t06 = ~ t03; \
t07 = a & t04; \
x = t05 ^ t07; \
t09 = x | t06; \
t10 = a ^ t07; \
t11 = t01 ^ t09; \
t12 = d ^ t04; \
t13 = c | t10; \
z = t03 ^ t12; \
t15 = a ^ t04; \
y = t11 ^ t13; \
w = t15 ^ t09; \
}
#define SBOX5(a, b, c, d, w, x, y, z) \
{ \
register unsigned long t02, t03, t04, t05, t07, t08, t09; \
register unsigned long t10, t11, t12, t13, t14, t01; \
t01 = b ^ d ; \
t02 = b | d ; \
t03 = a & t01; \
t04 = c ^ t02; \
t05 = t03 ^ t04; \
w = ~ t05; \
t07 = a ^ t01; \
t08 = d | w ; \
t09 = b | t05; \
t10 = d ^ t08; \
t11 = b | t07; \
t12 = t03 | w ; \
t13 = t07 | t10; \
t14 = t01 ^ t11; \
y = t09 ^ t13; \
x = t07 ^ t08; \
z = t12 ^ t14; \
}
#define SBOX5_INVERSE(a, b, c, d, w, x, y, z) \
{ \
register unsigned long t02, t03, t04, t05, t07, t08, t09; \
register unsigned long t10, t12, t13, t15, t16, t01; \
t01 = a & d ; \
t02 = c ^ t01; \
t03 = a ^ d ; \
t04 = b & t02; \
t05 = a & c ; \
w = t03 ^ t04; \
t07 = a & w ; \
t08 = t01 ^ w ; \
t09 = b | t05; \
t10 = ~ b ; \
x = t08 ^ t09; \
t12 = t10 | t07; \
t13 = w | x ; \
z = t02 ^ t12; \
t15 = t02 ^ t13; \
t16 = b ^ d ; \
y = t16 ^ t15; \
}
#define SBOX6(a, b, c, d, w, x, y, z) \
{ \
register unsigned long t02, t03, t04, t05, t07, t08, t09, t10; \
register unsigned long t11, t12, t13, t15, t17, t18, t01; \
t01 = a & d ; \
t02 = b ^ c ; \
t03 = a ^ d ; \
t04 = t01 ^ t02; \
t05 = b | c ; \
x = ~ t04; \
t07 = t03 & t05; \
t08 = b & x ; \
t09 = a | c ; \
t10 = t07 ^ t08; \
t11 = b | d ; \
t12 = c ^ t11; \
t13 = t09 ^ t10; \
y = ~ t13; \
t15 = x & t03; \
z = t12 ^ t07; \
t17 = a ^ b ; \
t18 = y ^ t15; \
w = t17 ^ t18; \
}
#define SBOX6_INVERSE(a, b, c, d, w, x, y, z) \
{ \
register unsigned long t02, t03, t04, t05, t06, t07, t08, t09; \
register unsigned long t12, t13, t14, t15, t16, t17, t01; \
t01 = a ^ c ; \
t02 = ~ c ; \
t03 = b & t01; \
t04 = b | t02; \
t05 = d | t03; \
t06 = b ^ d ; \
t07 = a & t04; \
t08 = a | t02; \
t09 = t07 ^ t05; \
x = t06 ^ t08; \
w = ~ t09; \
t12 = b & w ; \
t13 = t01 & t05; \
t14 = t01 ^ t12; \
t15 = t07 ^ t13; \
t16 = d | t02; \
t17 = a ^ x ; \
z = t17 ^ t15; \
y = t16 ^ t14; \
}
#define SBOX7(a, b, c, d, w, x, y, z) \
{ \
register unsigned long t02, t03, t04, t05, t06, t08, t09, t10; \
register unsigned long t11, t13, t14, t15, t16, t17, t01; \
t01 = a & c ; \
t02 = ~ d ; \
t03 = a & t02; \
t04 = b | t01; \
t05 = a & b ; \
t06 = c ^ t04; \
z = t03 ^ t06; \
t08 = c | z ; \
t09 = d | t05; \
t10 = a ^ t08; \
t11 = t04 & z ; \
x = t09 ^ t10; \
t13 = b ^ x ; \
t14 = t01 ^ x ; \
t15 = c ^ t05; \
t16 = t11 | t13; \
t17 = t02 | t14; \
w = t15 ^ t17; \
y = a ^ t16; \
}
#define SBOX7_INVERSE(a, b, c, d, w, x, y, z) \
{ \
register unsigned long t02, t03, t04, t06, t07, t08, t09; \
register unsigned long t10, t11, t13, t14, t15, t16, t01; \
t01 = a & b ; \
t02 = a | b ; \
t03 = c | t01; \
t04 = d & t02; \
z = t03 ^ t04; \
t06 = b ^ t04; \
t07 = d ^ z ; \
t08 = ~ t07; \
t09 = t06 | t08; \
t10 = b ^ d ; \
t11 = a | d ; \
x = a ^ t09; \
t13 = c ^ t06; \
t14 = c & t11; \
t15 = d | x ; \
t16 = t01 | t10; \
w = t13 ^ t15; \
y = t14 ^ t16; \
}
/* XOR BLOCK1 into BLOCK0. */
#define BLOCK_XOR(block0, block1) \
{ \
block0[0] ^= block1[0]; \
block0[1] ^= block1[1]; \
block0[2] ^= block1[2]; \
block0[3] ^= block1[3]; \
}
/* Copy BLOCK_SRC to BLOCK_DST. */
#define BLOCK_COPY(block_dst, block_src) \
{ \
block_dst[0] = block_src[0]; \
block_dst[1] = block_src[1]; \
block_dst[2] = block_src[2]; \
block_dst[3] = block_src[3]; \
}
/* Apply SBOX number WHICH to to the block found in ARRAY0 at index
INDEX, writing the output to the block found in ARRAY1 at index
INDEX. */
#define SBOX(which, array0, array1, index) \
SBOX##which (array0[index + 0], array0[index + 1], \
array0[index + 2], array0[index + 3], \
array1[index + 0], array1[index + 1], \
array1[index + 2], array1[index + 3]);
/* Apply inverse SBOX number WHICH to to the block found in ARRAY0 at
index INDEX, writing the output to the block found in ARRAY1 at
index INDEX. */
#define SBOX_INVERSE(which, array0, array1, index) \
SBOX##which##_INVERSE (array0[index + 0], array0[index + 1], \
array0[index + 2], array0[index + 3], \
array1[index + 0], array1[index + 1], \
array1[index + 2], array1[index + 3]);
/* Apply the linear transformation to BLOCK. */
#define LINEAR_TRANSFORMATION(block) \
{ \
block[0] = rol (block[0], 13); \
block[2] = rol (block[2], 3); \
block[1] = block[1] ^ block[0] ^ block[2]; \
block[3] = block[3] ^ block[2] ^ (block[0] << 3); \
block[1] = rol (block[1], 1); \
block[3] = rol (block[3], 7); \
block[0] = block[0] ^ block[1] ^ block[3]; \
block[2] = block[2] ^ block[3] ^ (block[1] << 7); \
block[0] = rol (block[0], 5); \
block[2] = rol (block[2], 22); \
}
/* Apply the inverse linear transformation to BLOCK. */
#define LINEAR_TRANSFORMATION_INVERSE(block) \
{ \
block[2] = ror (block[2], 22); \
block[0] = ror (block[0] , 5); \
block[2] = block[2] ^ block[3] ^ (block[1] << 7); \
block[0] = block[0] ^ block[1] ^ block[3]; \
block[3] = ror (block[3], 7); \
block[1] = ror (block[1], 1); \
block[3] = block[3] ^ block[2] ^ (block[0] << 3); \
block[1] = block[1] ^ block[0] ^ block[2]; \
block[2] = ror (block[2], 3); \
block[0] = ror (block[0], 13); \
}
/* Apply a Serpent round to BLOCK, using the SBOX number WHICH and the
subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary storage.
This macro increments `round'. */
#define ROUND(which, subkeys, block, block_tmp) \
{ \
BLOCK_XOR (block, subkeys[round]); \
round++; \
SBOX (which, block, block_tmp, 0); \
LINEAR_TRANSFORMATION (block_tmp); \
BLOCK_COPY (block, block_tmp); \
}
/* Apply the last Serpent round to BLOCK, using the SBOX number WHICH
and the subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary
storage. The result will be stored in BLOCK_TMP. This macro
increments `round'. */
#define ROUND_LAST(which, subkeys, block, block_tmp) \
{ \
BLOCK_XOR (block, subkeys[round]); \
round++; \
SBOX (which, block, block_tmp, 0); \
BLOCK_XOR (block_tmp, subkeys[round]); \
round++; \
}
/* Apply an inverse Serpent round to BLOCK, using the SBOX number
WHICH and the subkeys contained in SUBKEYS. Use BLOCK_TMP as
temporary storage. This macro increments `round'. */
#define ROUND_INVERSE(which, subkey, block, block_tmp) \
{ \
LINEAR_TRANSFORMATION_INVERSE (block); \
SBOX_INVERSE (which, block, block_tmp, 0); \
BLOCK_XOR (block_tmp, subkey[round]); \
round--; \
BLOCK_COPY (block, block_tmp); \
}
/* Apply the first Serpent round to BLOCK, using the SBOX number WHICH
and the subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary
storage. The result will be stored in BLOCK_TMP. This macro
increments `round'. */
#define ROUND_FIRST_INVERSE(which, subkeys, block, block_tmp) \
{ \
BLOCK_XOR (block, subkeys[round]); \
round--; \
SBOX_INVERSE (which, block, block_tmp, 0); \
BLOCK_XOR (block_tmp, subkeys[round]); \
round--; \
}
/* Convert the user provided key KEY of KEY_LENGTH bytes into the
internally used format. */
static void
serpent_key_prepare (const byte_t *key, unsigned int key_length,
serpent_key_t key_prepared)
{
int i;
/* Copy key. */
for (i = 0; i < key_length / 4; i++)
{
#ifdef WORDS_BIGENDIAN
key_prepared[i] = byte_swap_32 (((u32_t *) key)[i]);
#else
key_prepared[i] = ((u32_t *) key)[i];
#endif
}
if (i < 8)
{
/* Key must be padded according to the Serpent
specification. */
key_prepared[i] = 0x00000001;
for (i++; i < 8; i++)
key_prepared[i] = 0;
}
}
/* Derive the 33 subkeys from KEY and store them in SUBKEYS. */
static void
serpent_subkeys_generate (serpent_key_t key, serpent_subkeys_t subkeys)
{
u32_t w_real[140]; /* The `prekey'. */
u32_t k[132];
u32_t *w = &w_real[8];
int i, j;
/* Initialize with key values. */
for (i = 0; i < 8; i++)
w[i - 8] = key[i];
/* Expand to intermediate key using the affine recurrence. */
for (i = 0; i < 132; i++)
w[i] = rol (w[i - 8] ^ w[i - 5] ^ w[i - 3] ^ w[i - 1] ^ PHI ^ i, 11);
/* Calculate subkeys via S-Boxes, in bitslice mode. */
SBOX (3, w, k, 0);
SBOX (2, w, k, 4);
SBOX (1, w, k, 8);
SBOX (0, w, k, 12);
SBOX (7, w, k, 16);
SBOX (6, w, k, 20);
SBOX (5, w, k, 24);
SBOX (4, w, k, 28);
SBOX (3, w, k, 32);
SBOX (2, w, k, 36);
SBOX (1, w, k, 40);
SBOX (0, w, k, 44);
SBOX (7, w, k, 48);
SBOX (6, w, k, 52);
SBOX (5, w, k, 56);
SBOX (4, w, k, 60);
SBOX (3, w, k, 64);
SBOX (2, w, k, 68);
SBOX (1, w, k, 72);
SBOX (0, w, k, 76);
SBOX (7, w, k, 80);
SBOX (6, w, k, 84);
SBOX (5, w, k, 88);
SBOX (4, w, k, 92);
SBOX (3, w, k, 96);
SBOX (2, w, k, 100);
SBOX (1, w, k, 104);
SBOX (0, w, k, 108);
SBOX (7, w, k, 112);
SBOX (6, w, k, 116);
SBOX (5, w, k, 120);
SBOX (4, w, k, 124);
SBOX (3, w, k, 128);
/* Renumber subkeys. */
for (i = 0; i < ROUNDS + 1; i++)
for (j = 0; j < 4; j++)
subkeys[i][j] = k[4 * i + j];
}
/* Initialize CONTEXT with the key KEY of KEY_LENGTH bits. */
static void
serpent_setkey_internal (serpent_context_t *context,
const byte_t *key, unsigned int key_length)
{
serpent_key_t key_prepared;
serpent_key_prepare (key, key_length, key_prepared);
serpent_subkeys_generate (key_prepared, context->keys);
_gcry_burn_stack (272 * sizeof (u32_t));
}
-
+ static const char *serpent_test (void);
/* Initialize CTX with the key KEY of KEY_LENGTH bytes. */
static gcry_err_code_t
serpent_setkey (void *ctx,
const byte_t *key, unsigned int key_length)
{
serpent_context_t *context = ctx;
static const char *serpent_test_ret;
static int serpent_init_done;
gcry_err_code_t ret = GPG_ERR_NO_ERROR;
if (! serpent_init_done)
{
/* Execute a self-test the first time, Serpent is used. */
- static const char *serpent_test (void);
+
serpent_test_ret = serpent_test ();
if (serpent_test_ret)
log_error ("Serpent test failure: %s\n", serpent_test_ret);
serpent_init_done = 1;
}
if (serpent_test_ret)
ret = GPG_ERR_SELFTEST_FAILED;
else
{
serpent_setkey_internal (context, key, key_length);
_gcry_burn_stack (sizeof (serpent_key_t));
}
return ret;
}
static void
serpent_encrypt_internal (serpent_context_t *context,
const serpent_block_t input, serpent_block_t output)
{
serpent_block_t b, b_next;
int round = 0;
#ifdef WORDS_BIGENDIAN
b[0] = byte_swap_32 (input[0]);
b[1] = byte_swap_32 (input[1]);
b[2] = byte_swap_32 (input[2]);
b[3] = byte_swap_32 (input[3]);
#else
b[0] = input[0];
b[1] = input[1];
b[2] = input[2];
b[3] = input[3];
#endif
ROUND (0, context->keys, b, b_next);
ROUND (1, context->keys, b, b_next);
ROUND (2, context->keys, b, b_next);
ROUND (3, context->keys, b, b_next);
ROUND (4, context->keys, b, b_next);
ROUND (5, context->keys, b, b_next);
ROUND (6, context->keys, b, b_next);
ROUND (7, context->keys, b, b_next);
ROUND (0, context->keys, b, b_next);
ROUND (1, context->keys, b, b_next);
ROUND (2, context->keys, b, b_next);
ROUND (3, context->keys, b, b_next);
ROUND (4, context->keys, b, b_next);
ROUND (5, context->keys, b, b_next);
ROUND (6, context->keys, b, b_next);
ROUND (7, context->keys, b, b_next);
ROUND (0, context->keys, b, b_next);
ROUND (1, context->keys, b, b_next);
ROUND (2, context->keys, b, b_next);
ROUND (3, context->keys, b, b_next);
ROUND (4, context->keys, b, b_next);
ROUND (5, context->keys, b, b_next);
ROUND (6, context->keys, b, b_next);
ROUND (7, context->keys, b, b_next);
ROUND (0, context->keys, b, b_next);
ROUND (1, context->keys, b, b_next);
ROUND (2, context->keys, b, b_next);
ROUND (3, context->keys, b, b_next);
ROUND (4, context->keys, b, b_next);
ROUND (5, context->keys, b, b_next);
ROUND (6, context->keys, b, b_next);
ROUND_LAST (7, context->keys, b, b_next);
#ifdef WORDS_BIGENDIAN
output[0] = byte_swap_32 (b_next[0]);
output[1] = byte_swap_32 (b_next[1]);
output[2] = byte_swap_32 (b_next[2]);
output[3] = byte_swap_32 (b_next[3]);
#else
output[0] = b_next[0];
output[1] = b_next[1];
output[2] = b_next[2];
output[3] = b_next[3];
#endif
}
static void
serpent_decrypt_internal (serpent_context_t *context,
const serpent_block_t input, serpent_block_t output)
{
serpent_block_t b, b_next;
int round = ROUNDS;
#ifdef WORDS_BIGENDIAN
b_next[0] = byte_swap_32 (input[0]);
b_next[1] = byte_swap_32 (input[1]);
b_next[2] = byte_swap_32 (input[2]);
b_next[3] = byte_swap_32 (input[3]);
#else
b_next[0] = input[0];
b_next[1] = input[1];
b_next[2] = input[2];
b_next[3] = input[3];
#endif
ROUND_FIRST_INVERSE (7, context->keys, b_next, b);
ROUND_INVERSE (6, context->keys, b, b_next);
ROUND_INVERSE (5, context->keys, b, b_next);
ROUND_INVERSE (4, context->keys, b, b_next);
ROUND_INVERSE (3, context->keys, b, b_next);
ROUND_INVERSE (2, context->keys, b, b_next);
ROUND_INVERSE (1, context->keys, b, b_next);
ROUND_INVERSE (0, context->keys, b, b_next);
ROUND_INVERSE (7, context->keys, b, b_next);
ROUND_INVERSE (6, context->keys, b, b_next);
ROUND_INVERSE (5, context->keys, b, b_next);
ROUND_INVERSE (4, context->keys, b, b_next);
ROUND_INVERSE (3, context->keys, b, b_next);
ROUND_INVERSE (2, context->keys, b, b_next);
ROUND_INVERSE (1, context->keys, b, b_next);
ROUND_INVERSE (0, context->keys, b, b_next);
ROUND_INVERSE (7, context->keys, b, b_next);
ROUND_INVERSE (6, context->keys, b, b_next);
ROUND_INVERSE (5, context->keys, b, b_next);
ROUND_INVERSE (4, context->keys, b, b_next);
ROUND_INVERSE (3, context->keys, b, b_next);
ROUND_INVERSE (2, context->keys, b, b_next);
ROUND_INVERSE (1, context->keys, b, b_next);
ROUND_INVERSE (0, context->keys, b, b_next);
ROUND_INVERSE (7, context->keys, b, b_next);
ROUND_INVERSE (6, context->keys, b, b_next);
ROUND_INVERSE (5, context->keys, b, b_next);
ROUND_INVERSE (4, context->keys, b, b_next);
ROUND_INVERSE (3, context->keys, b, b_next);
ROUND_INVERSE (2, context->keys, b, b_next);
ROUND_INVERSE (1, context->keys, b, b_next);
ROUND_INVERSE (0, context->keys, b, b_next);
#ifdef WORDS_BIGENDIAN
output[0] = byte_swap_32 (b_next[0]);
output[1] = byte_swap_32 (b_next[1]);
output[2] = byte_swap_32 (b_next[2]);
output[3] = byte_swap_32 (b_next[3]);
#else
output[0] = b_next[0];
output[1] = b_next[1];
output[2] = b_next[2];
output[3] = b_next[3];
#endif
}
static void
serpent_encrypt (void *ctx, byte_t *buffer_out, const byte_t *buffer_in)
{
serpent_context_t *context = ctx;
serpent_encrypt_internal (context,
(const u32_t *) buffer_in, (u32_t *) buffer_out);
_gcry_burn_stack (2 * sizeof (serpent_block_t));
}
static void
serpent_decrypt (void *ctx, byte *buffer_out, const byte *buffer_in)
{
serpent_context_t *context = ctx;
serpent_decrypt_internal (context,
(const u32_t *) buffer_in,
(u32_t *) buffer_out);
_gcry_burn_stack (2 * sizeof (serpent_block_t));
}
/* Serpent test. */
static const char *
serpent_test (void)
{
serpent_context_t context;
unsigned char scratch[16];
unsigned int i;
static struct test
{
int key_length;
unsigned char key[32];
unsigned char text_plain[16];
unsigned char text_cipher[16];
} test_data[] =
{
{
16,
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
"\xD2\x9D\x57\x6F\xCE\xA3\xA3\xA7\xED\x90\x99\xF2\x92\x73\xD7\x8E",
"\xB2\x28\x8B\x96\x8A\xE8\xB0\x86\x48\xD1\xCE\x96\x06\xFD\x99\x2D"
},
{
24,
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00",
"\xD2\x9D\x57\x6F\xCE\xAB\xA3\xA7\xED\x98\x99\xF2\x92\x7B\xD7\x8E",
"\x13\x0E\x35\x3E\x10\x37\xC2\x24\x05\xE8\xFA\xEF\xB2\xC3\xC3\xE9"
},
{
32,
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
"\xD0\x95\x57\x6F\xCE\xA3\xE3\xA7\xED\x98\xD9\xF2\x90\x73\xD7\x8E",
"\xB9\x0E\xE5\x86\x2D\xE6\x91\x68\xF2\xBD\xD5\x12\x5B\x45\x47\x2B"
},
{
32,
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
"\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00",
"\x20\x61\xA4\x27\x82\xBD\x52\xEC\x69\x1E\xC3\x83\xB0\x3B\xA7\x7C"
},
{
0
},
};
for (i = 0; test_data[i].key_length; i++)
{
serpent_setkey_internal (&context, test_data[i].key,
test_data[i].key_length);
serpent_encrypt_internal (&context,
(const u32_t *) test_data[i].text_plain,
(u32_t *) scratch);
if (memcmp (scratch, test_data[i].text_cipher, sizeof (serpent_block_t)))
switch (test_data[i].key_length)
{
case 16:
return "Serpent-128 test encryption failed.";
case 24:
return "Serpent-192 test encryption failed.";
case 32:
return "Serpent-256 test encryption failed.";
}
serpent_decrypt_internal (&context,
(const u32_t *) test_data[i].text_cipher,
(u32_t *) scratch);
if (memcmp (scratch, test_data[i].text_plain, sizeof (serpent_block_t)))
switch (test_data[i].key_length)
{
case 16:
return "Serpent-128 test decryption failed.";
case 24:
return "Serpent-192 test decryption failed.";
case 32:
return "Serpent-256 test decryption failed.";
}
}
return NULL;
}
/* "SERPENT" is an alias for "SERPENT128". */
static const char *cipher_spec_serpent128_aliases[] =
{
"SERPENT",
NULL,
};
gcry_cipher_spec_t _gcry_cipher_spec_serpent128 =
{
"SERPENT128", cipher_spec_serpent128_aliases, NULL, 16, 128,
sizeof (serpent_context_t),
serpent_setkey, serpent_encrypt, serpent_decrypt,
};
gcry_cipher_spec_t _gcry_cipher_spec_serpent192 =
{
"SERPENT192", NULL, NULL, 16, 192,
sizeof (serpent_context_t),
serpent_setkey, serpent_encrypt, serpent_decrypt,
};
gcry_cipher_spec_t _gcry_cipher_spec_serpent256 =
{
"SERPENT256", NULL, NULL, 16, 256,
sizeof (serpent_context_t),
serpent_setkey, serpent_encrypt, serpent_decrypt,
};
diff --git a/pwmanager/pwmanager/binentrygen.cpp b/pwmanager/pwmanager/binentrygen.cpp
index 7d5ae45..f156a5e 100644
--- a/pwmanager/pwmanager/binentrygen.cpp
+++ b/pwmanager/pwmanager/binentrygen.cpp
@@ -1,71 +1,72 @@
/***************************************************************************
* *
* copyright (C) 2004 by Michael Buesch *
* email: mbuesch@freenet.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 *
* as published by the Free Software Foundation. *
* *
***************************************************************************/
/***************************************************************************
* copyright (C) 2004 by Ulf Schenk
* This file is originaly based on version 1.0.1 of pwmanager
* and was modified to run on embedded devices that run microkde
*
* $Id$
**************************************************************************/
-
#include "binentrygen.h"
#include "base64.h"
-#include "pwmexception.h"
+#include "pwmexception.h"
+#include "globalstuff.h"
void BinEntryGen::encode(const QByteArray &data,
PwMDataItem *ret,
DataType type)
{
ret->clear();
ret->name = tostr(static_cast<int>(type));
ret->binary = true;
if (data.size() == 0)
return;
Base64 b64;
string d(data.data(), data.size());
ret->pw = b64.encode(d);
}
void BinEntryGen::decode(const PwMDataItem &data,
QByteArray *ret,
DataType *type)
{
BUG_ON(!data.binary);
int t = strtol(data.name.c_str(), 0, 10);
*type = static_cast<DataType>(t);
switch (*type) {
case None:
case KWalletMap:
case KWalletStream:
break;
default:
*type = None;
}
if (data.pw == "") {
ret->fill(0);
ret->resize(0);
return;
}
Base64 b64;
string d(b64.decode(data.pw));
ret->duplicate(d.c_str(), d.length());
}
BinEntryGen::DataType BinEntryGen::binType(const PwMDataItem &data)
{
if (!data.binary)
return None;
int type = strtol(data.name.c_str(), 0, 10);
return (static_cast<DataType>(type));
}
+
diff --git a/pwmanager/pwmanager/binentrygen.h b/pwmanager/pwmanager/binentrygen.h
index a58cd42..49288aa 100644
--- a/pwmanager/pwmanager/binentrygen.h
+++ b/pwmanager/pwmanager/binentrygen.h
@@ -1,65 +1,65 @@
/***************************************************************************
* *
* copyright (C) 2004 by Michael Buesch *
* email: mbuesch@freenet.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 *
* as published by the Free Software Foundation. *
* *
***************************************************************************/
/***************************************************************************
* copyright (C) 2004 by Ulf Schenk
* This file is originaly based on version 1.0.1 of pwmanager
* and was modified to run on embedded devices that run microkde
*
* $Id$
**************************************************************************/
#ifndef __BINENTRYGEN_H
#define __BINENTRYGEN_H
-#include "pwmdoc.h"
#include <qcstring.h>
+#include "pwmdoc.h"
/** Binary entry generator.
* This generator generates a normal struct PwMDataItem
* from binary data (using base64 encoding).
* This mechanism is used to support the binary interface functions
* of the KWallet emulation, for example.
*
* The format of the encoded binary data as a PwMDataItem is as follows:
*
* PwMDataItem::desc contains the normal description string for
* this entry. Nothing surprising.
* PwMDataItem::name contains the "DataType" number in ascii format.
* PwMDataItem::pw contains the base64 encoded data stream.
* PwMDataItem::binary is always true for binary entries.
* All other PwMDataItems are currently unused by BinEntryGen.
*/
class BinEntryGen
{
public:
enum DataType
{
None = 0,
KWalletMap,
KWalletStream
};
public:
BinEntryGen() { }
/** Encode the binary "data" and return it in "ret" */
void encode(const QByteArray &data, PwMDataItem *ret, DataType type);
/** Decode the "data" and return it as binary "ret" */
void decode(const PwMDataItem &data, QByteArray *ret, DataType *type);
/** Return the data type for this binary data item */
DataType binType(const PwMDataItem &data);
};
#endif // __BINENTRYGEN_H
diff --git a/pwmanager/pwmanager/blowfish.cpp b/pwmanager/pwmanager/blowfish.cpp
index 2ca58ce..ee29756 100644
--- a/pwmanager/pwmanager/blowfish.cpp
+++ b/pwmanager/pwmanager/blowfish.cpp
@@ -1,579 +1,579 @@
/* 2003.05.02: Derived from libgcrypt-1.1.12 by Michael Buesch */
/* blowfish.c - Blowfish encryption
* Copyright (C) 1998, 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser general Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* For a description of the algorithm, see:
* Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
* ISBN 0-471-11709-9. Pages 336 ff.
*/
/* Test values:
* key "abcdefghijklmnopqrstuvwxyz";
* plain "BLOWFISH"
* cipher 32 4E D0 FE F4 13 A2 03
*
*/
/***************************************************************************
* copyright (C) 2004 by Ulf Schenk
* This file is originaly based on version 1.0.1 of pwmanager
* and was modified to run on embedded devices that run microkde
*
* $Id$
**************************************************************************/
#include <string.h>
#include <stdlib.h>
-#include "blowfish.h"
#include "globalstuff.h"
+#include "blowfish.h"
/* precomputed S boxes */
static const uint32_t ks0[256] = {
0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96,
0xBA7C9045, 0xF12C7F99, 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16,
0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, 0x0D95748F, 0x728EB658,
0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013,
0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, 0x8E79DCB0, 0x603A180E,
0x6C9E0E8B, 0xB01E8A3E, 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60,
0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, 0x55CA396A, 0x2AAB10B6,
0xB4CC5C34, 0x1141E8CE, 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, 0xAFD6BA33, 0x6C24CF5C,
0x7A325381, 0x28958677, 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193,
0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032, 0xEF845D5D, 0xE98575B1,
0xDC262302, 0xEB651B88, 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239,
0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, 0x21C66842, 0xF6E96C9A,
0x670C9C61, 0xABD388F0, 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3,
0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, 0xA1F1651D, 0x39AF0176,
0x66CA593E, 0x82430E88, 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, 0x4ED3AA62, 0x363F7706,
0x1BFEDF72, 0x429B023D, 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B,
0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, 0xE3FE501A, 0xB6794C3B,
0x976CE0BD, 0x04C006BA, 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463,
0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, 0x6DFC511F, 0x9B30952C,
0xCC814544, 0xAF5EBD09, 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3,
0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, 0x5579C0BD, 0x1A60320A,
0xD6A100C6, 0x402C7279, 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, 0x323DB5FA, 0xFD238760,
0x53317B48, 0x3E00DF82, 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB,
0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, 0x695B27B0, 0xBBCA58C8,
0xE1FFA35D, 0xB8F011A0, 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B,
0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, 0xE1DDF2DA, 0xA4CB7E33,
0x62FB1341, 0xCEE4C6E8, 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4,
0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, 0xD08ED1D0, 0xAFC725E0,
0x8E3C5B2F, 0x8E7594B7, 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, 0x2F2F2218, 0xBE0E1777,
0xEA752DFE, 0x8B021FA1, 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299,
0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9, 0x165FA266, 0x80957705,
0x93CC7314, 0x211A1477, 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF,
0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, 0x00250E2D, 0x2071B35E,
0x226800BB, 0x57B8E0AF, 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA,
0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, 0x83260376, 0x6295CFA9,
0x11C81968, 0x4E734A41, 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, 0x08BA6FB5, 0x571BE91F,
0xF296EC6B, 0x2A0DD915, 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664,
0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A
};
static const uint32_t ks1[256] = {
0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, 0xAD6EA6B0, 0x49A7DF7D,
0x9CEE60B8, 0x8FEDB266, 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1,
0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, 0x3F54989A, 0x5B429D65,
0x6B8FE4D6, 0x99F73FD6, 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1,
0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, 0x09686B3F, 0x3EBAEFC9,
0x3C971814, 0x6B6A70A1, 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737,
0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, 0xB03ADA37, 0xF0500C0D,
0xF01C1F04, 0x0200B3FF, 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, 0x3AE5E581, 0x37C2DADC,
0xC8B57634, 0x9AF3DDA7, 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41,
0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331, 0x4E548B38, 0x4F6DB908,
0x6F420D03, 0xF60A04BF, 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, 0x5512721F, 0x2E6B7124,
0x501ADDE6, 0x9F84CD87, 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C,
0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, 0xEF1C1847, 0x3215D908,
0xDD433B37, 0x24C2BA16, 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, 0x043556F1, 0xD7A3C76B,
0x3C11183B, 0x5924A509, 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E,
0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3, 0x771FE71C, 0x4E3D06FA,
0x2965DCB9, 0x99E71D0F, 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A,
0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, 0xF2F74EA7, 0x361D2B3D,
0x1939260F, 0x19C27960, 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66,
0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, 0xC332DDEF, 0xBE6C5AA5,
0x65582185, 0x68AB9802, 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, 0x13CCA830, 0xEB61BD96,
0x0334FE1E, 0xAA0363CF, 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14,
0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E, 0x648B1EAF, 0x19BDF0CA,
0xA02369B9, 0x655ABB50, 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7,
0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, 0xF837889A, 0x97E32D77,
0x11ED935F, 0x16681281, 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99,
0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, 0xCDB30AEB, 0x532E3054,
0x8FD948E4, 0x6DBC3128, 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, 0x45EEE2B6, 0xA3AAABEA,
0xDB6C4F15, 0xFACB4FD0, 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105,
0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250, 0xCF62A1F2, 0x5B8D2646,
0xFC8883A0, 0xC1C7B6A3, 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285,
0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, 0x58428D2A, 0x0C55F5EA,
0x1DADF43E, 0x233F7061, 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB,
0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, 0xA6078084, 0x19F8509E,
0xE8EFD855, 0x61D99735, 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, 0xDB73DBD3, 0x105588CD,
0x675FDA79, 0xE3674340, 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20,
0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7
};
static const uint32_t ks2[256] = {
0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, 0x411520F7, 0x7602D4F7,
0xBCF46B2E, 0xD4A20068, 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF,
0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, 0x4D95FC1D, 0x96B591AF,
0x70F4DDD3, 0x66A02F45, 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504,
0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, 0x28507825, 0x530429F4,
0x0A2C86DA, 0xE9B66DFB, 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE,
0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, 0xAACE1E7C, 0xD3375FEC,
0xCE78A399, 0x406B2A42, 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, 0x3A6EFA74, 0xDD5B4332,
0x6841E7F7, 0xCA7820FB, 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527,
0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B, 0x55A867BC, 0xA1159A58,
0xCCA92963, 0x99E1DB33, 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, 0x95C11548, 0xE4C66D22,
0x48C1133F, 0xC70F86DC, 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17,
0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, 0x257B7834, 0x602A9C60,
0xDFF8E8A3, 0x1F636C1B, 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, 0x85B2A20E, 0xE6BA0D99,
0xDE720C8C, 0x2DA2F728, 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0,
0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, 0x0A476341, 0x992EFF74,
0x3A6F6EAB, 0xF4F8FD37, 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D,
0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, 0xF1290DC7, 0xCC00FFA3,
0xB5390F92, 0x690FED0B, 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3,
0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, 0x37392EB3, 0xCC115979,
0x8026E297, 0xF42E312D, 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, 0x1A6B1018, 0x11CAEDFA,
0x3D25BDD8, 0xE2E1C3C9, 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A,
0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, 0x9DBC8057, 0xF0F7C086,
0x60787BF8, 0x6003604D, 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC,
0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, 0x77A057BE, 0xBDE8AE24,
0x55464299, 0xBF582E61, 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2,
0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, 0x7AEB2661, 0x8B1DDF84,
0x846A0E79, 0x915F95E2, 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, 0xB77F19B6, 0xE0A9DC09,
0x662D09A1, 0xC4324633, 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10,
0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169, 0xDCB7DA83, 0x573906FE,
0xA1E2CE9B, 0x4FCD7F52, 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027,
0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, 0xF0177A28, 0xC0F586E0,
0x006058AA, 0x30DC7D62, 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634,
0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, 0x6F05E409, 0x4B7C0188,
0x39720A3D, 0x7C927C24, 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, 0x1E50EF5E, 0xB161E6F8,
0xA28514D9, 0x6C51133C, 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837,
0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0
};
static const uint32_t ks3[256] = {
0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, 0x5CB0679E, 0x4FA33742,
0xD3822740, 0x99BC9BBE, 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B,
0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, 0x5748AB2F, 0xBC946E79,
0xC6A376D2, 0x6549C2C8, 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6,
0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, 0xA1FAD5F0, 0x6A2D519A,
0x63EF8CE2, 0x9A86EE22, 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4,
0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, 0x2826A2F9, 0xA73A3AE1,
0x4BA99586, 0xEF5562E9, 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, 0xE990FD5A, 0x9E34D797,
0x2CF0B7D9, 0x022B8B51, 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28,
0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C, 0xE029AC71, 0xE019A5E6,
0x47B0ACFD, 0xED93FA9B, 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28,
0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, 0x15056DD4, 0x88F46DBA,
0x03A16125, 0x0564F0BD, 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A,
0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, 0x7533D928, 0xB155FDF5,
0x03563482, 0x8ABA3CBB, 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, 0xEA7A90C2, 0xFB3E7BCE,
0x5121CE64, 0x774FBE32, 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680,
0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, 0xB39A460A, 0x6445C0DD,
0x586CDECF, 0x1C20C8AE, 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB,
0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, 0x72EACEA8, 0xFA6484BB,
0x8D6612AE, 0xBF3C6F47, 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370,
0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, 0x4040CB08, 0x4EB4E2CC,
0x34D2466A, 0x0115AF84, 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, 0x611560B1, 0xE7933FDC,
0xBB3A792B, 0x344525BD, 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9,
0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, 0x1A908749, 0xD44FBD9A,
0xD0DADECB, 0xD50ADA38, 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F,
0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, 0xBF97222C, 0x15E6FC2A,
0x0F91FC71, 0x9B941525, 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1,
0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, 0xE0EC6E0E, 0x1698DB3B,
0x4C98A0BE, 0x3278E964, 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, 0xDF359F8D, 0x9B992F2E,
0xE60B6F47, 0x0FE3F11D, 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F,
0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299, 0xF523F357, 0xA6327623,
0x93A83531, 0x56CCCD02, 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, 0xE6C6C7BD, 0x327A140A,
0x45E1D006, 0xC3F27B9A, 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6,
0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, 0x53113EC0, 0x1640E3D3,
0x38ABBD60, 0x2547ADF0, 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, 0x1948C25C, 0x02FB8A8C,
0x01C36AE4, 0xD6EBE1F9, 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6
};
static const uint32_t ps[BLOWFISH_ROUNDS + 2] = {
0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0,
0x082EFA98, 0xEC4E6C89, 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, 0x9216D5D9, 0x8979FB1B
};
void Blowfish::burn_stack(int bytes)
{
char buf[64];
memset(buf, 0, sizeof buf);
bytes -= sizeof buf;
if (bytes > 0)
burn_stack(bytes);
}
void Blowfish::do_encrypt(uint32_t * ret_xl, uint32_t * ret_xr)
{
#if BLOWFISH_ROUNDS == 16
uint32_t xl, xr, *s0, *s1, *s2, *s3, *p;
xl = *ret_xl;
xr = *ret_xr;
p = bc.p;
s0 = bc.s0;
s1 = bc.s1;
s2 = bc.s2;
s3 = bc.s3;
R(xl, xr, 0, p, s0, s1, s2, s3);
R(xr, xl, 1, p, s0, s1, s2, s3);
R(xl, xr, 2, p, s0, s1, s2, s3);
R(xr, xl, 3, p, s0, s1, s2, s3);
R(xl, xr, 4, p, s0, s1, s2, s3);
R(xr, xl, 5, p, s0, s1, s2, s3);
R(xl, xr, 6, p, s0, s1, s2, s3);
R(xr, xl, 7, p, s0, s1, s2, s3);
R(xl, xr, 8, p, s0, s1, s2, s3);
R(xr, xl, 9, p, s0, s1, s2, s3);
R(xl, xr, 10, p, s0, s1, s2, s3);
R(xr, xl, 11, p, s0, s1, s2, s3);
R(xl, xr, 12, p, s0, s1, s2, s3);
R(xr, xl, 13, p, s0, s1, s2, s3);
R(xl, xr, 14, p, s0, s1, s2, s3);
R(xr, xl, 15, p, s0, s1, s2, s3);
xl ^= p[BLOWFISH_ROUNDS];
xr ^= p[BLOWFISH_ROUNDS + 1];
*ret_xl = xr;
*ret_xr = xl;
#else
uint32_t xl, xr, temp, *p;
int i;
xl = *ret_xl;
xr = *ret_xr;
p = bc.p;
for (i = 0; i < BLOWFISH_ROUNDS; i++) {
xl ^= p[i];
xr ^= function_F(xl);
temp = xl;
xl = xr;
xr = temp;
}
temp = xl;
xl = xr;
xr = temp;
xr ^= p[BLOWFISH_ROUNDS];
xl ^= p[BLOWFISH_ROUNDS + 1];
*ret_xl = xl;
*ret_xr = xr;
#endif
}
void Blowfish::do_decrypt(uint32_t * ret_xl, uint32_t * ret_xr)
{
#if BLOWFISH_ROUNDS == 16
uint32_t xl, xr, *s0, *s1, *s2, *s3, *p;
xl = *ret_xl;
xr = *ret_xr;
p = bc.p;
s0 = bc.s0;
s1 = bc.s1;
s2 = bc.s2;
s3 = bc.s3;
R(xl, xr, 17, p, s0, s1, s2, s3);
R(xr, xl, 16, p, s0, s1, s2, s3);
R(xl, xr, 15, p, s0, s1, s2, s3);
R(xr, xl, 14, p, s0, s1, s2, s3);
R(xl, xr, 13, p, s0, s1, s2, s3);
R(xr, xl, 12, p, s0, s1, s2, s3);
R(xl, xr, 11, p, s0, s1, s2, s3);
R(xr, xl, 10, p, s0, s1, s2, s3);
R(xl, xr, 9, p, s0, s1, s2, s3);
R(xr, xl, 8, p, s0, s1, s2, s3);
R(xl, xr, 7, p, s0, s1, s2, s3);
R(xr, xl, 6, p, s0, s1, s2, s3);
R(xl, xr, 5, p, s0, s1, s2, s3);
R(xr, xl, 4, p, s0, s1, s2, s3);
R(xl, xr, 3, p, s0, s1, s2, s3);
R(xr, xl, 2, p, s0, s1, s2, s3);
xl ^= p[1];
xr ^= p[0];
*ret_xl = xr;
*ret_xr = xl;
#else
uint32_t xl, xr, temp, *p;
int i;
xl = *ret_xl;
xr = *ret_xr;
p = bc.p;
for (i = BLOWFISH_ROUNDS + 1; i > 1; i--) {
xl ^= p[i];
xr ^= function_F(xl);
temp = xl;
xl = xr;
xr = temp;
}
temp = xl;
xl = xr;
xr = temp;
xr ^= p[1];
xl ^= p[0];
*ret_xl = xl;
*ret_xr = xr;
#endif
}
void Blowfish::do_encrypt_block(byte * outbuf, byte * inbuf)
{
uint32_t d1, d2;
d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
do_encrypt(&d1, &d2);
outbuf[0] = (d1 >> 24) & 0xff;
outbuf[1] = (d1 >> 16) & 0xff;
outbuf[2] = (d1 >> 8) & 0xff;
outbuf[3] = d1 & 0xff;
outbuf[4] = (d2 >> 24) & 0xff;
outbuf[5] = (d2 >> 16) & 0xff;
outbuf[6] = (d2 >> 8) & 0xff;
outbuf[7] = d2 & 0xff;
}
void Blowfish::encrypt_block(byte * outbuf, byte * inbuf)
{
do_encrypt_block(outbuf, inbuf);
burn_stack(64);
}
void Blowfish::do_decrypt_block(byte * outbuf, byte * inbuf)
{
uint32_t d1, d2;
d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
do_decrypt(&d1, &d2);
outbuf[0] = (d1 >> 24) & 0xff;
outbuf[1] = (d1 >> 16) & 0xff;
outbuf[2] = (d1 >> 8) & 0xff;
outbuf[3] = d1 & 0xff;
outbuf[4] = (d2 >> 24) & 0xff;
outbuf[5] = (d2 >> 16) & 0xff;
outbuf[6] = (d2 >> 8) & 0xff;
outbuf[7] = d2 & 0xff;
}
void Blowfish::decrypt_block(byte * outbuf, byte * inbuf)
{
do_decrypt_block(outbuf, inbuf);
burn_stack(64);
}
bool Blowfish::selfTest()
{
byte plain1[] = "BLOWFISH";
byte key1[] = "abcdefghijklmnopqrstuvwxyz";
byte cipher1[] = "\x32\x4E\xD0\xFE\xF4\x13\xA2\x03";
byte plain2[] = "\xFE\xDC\xBA\x98\x76\x54\x32\x10";
byte key2[] = "\x41\x79\x6E\xA0\x52\x61\x6E\xE4";
byte cipher2[] = "\xE1\x13\xF4\x10\x2C\xFC\xCE\x43";
byte buffer[8];
Blowfish blowfish;
blowfish.bf_setkey(key1, array_size(key1) - 1);
blowfish.bf_encrypt(buffer, plain1, array_size(plain1) - 1);
if (unlikely(memcmp(buffer, cipher1, array_size(cipher1) - 1)))
return false;
blowfish.bf_decrypt(buffer, buffer, array_size(buffer));
if (unlikely(memcmp(buffer, plain1, array_size(plain1) - 1)))
return false;
blowfish.bf_setkey(key2, array_size(key2) - 1);
blowfish.bf_encrypt(buffer, plain2, array_size(plain2) - 1);
if (unlikely(memcmp(buffer, cipher2, array_size(cipher2) - 1)))
return false;
blowfish.bf_decrypt(buffer, buffer, array_size(buffer));
if (unlikely(memcmp(buffer, plain2, array_size(plain2) - 1)))
return false;
return true;
}
int Blowfish::do_bf_setkey(byte * key, unsigned int keylen)
{
int i, j;
uint32_t data, datal, datar;
for (i = 0; i < BLOWFISH_ROUNDS + 2; ++i)
bc.p[i] = ps[i];
for (i = 0; i < 256; ++i) {
bc.s0[i] = ks0[i];
bc.s1[i] = ks1[i];
bc.s2[i] = ks2[i];
bc.s3[i] = ks3[i];
}
for (i = j = 0; i < BLOWFISH_ROUNDS + 2; ++i) {
#ifdef BIG_ENDIAN_HOST
((byte *) & data)[0] = key[j];
((byte *) & data)[1] = key[(j + 1) % keylen];
((byte *) & data)[2] = key[(j + 2) % keylen];
((byte *) & data)[3] = key[(j + 3) % keylen];
#else
((byte *) & data)[3] = key[j];
((byte *) & data)[2] = key[(j + 1) % keylen];
((byte *) & data)[1] = key[(j + 2) % keylen];
((byte *) & data)[0] = key[(j + 3) % keylen];
#endif
bc.p[i] ^= data;
j = (j + 4) % keylen;
}
datal = datar = 0;
for (i = 0; i < BLOWFISH_ROUNDS + 2; i += 2) {
do_encrypt(&datal, &datar);
bc.p[i] = datal;
bc.p[i + 1] = datar;
}
for (i = 0; i < 256; i += 2) {
do_encrypt(&datal, &datar);
bc.s0[i] = datal;
bc.s0[i + 1] = datar;
}
for (i = 0; i < 256; i += 2) {
do_encrypt(&datal, &datar);
bc.s1[i] = datal;
bc.s1[i + 1] = datar;
}
for (i = 0; i < 256; i += 2) {
do_encrypt(&datal, &datar);
bc.s2[i] = datal;
bc.s2[i + 1] = datar;
}
for (i = 0; i < 256; i += 2) {
do_encrypt(&datal, &datar);
bc.s3[i] = datal;
bc.s3[i + 1] = datar;
}
/* Check for weak key. A weak key is a key in which a value in */
/* the P-array (here c) occurs more than once per table. */
for (i = 0; i < 255; ++i) {
for (j = i + 1; j < 256; ++j) {
if ((bc.s0[i] == bc.s0[j]) || (bc.s1[i] == bc.s1[j]) ||
(bc.s2[i] == bc.s2[j]) || (bc.s3[i] == bc.s3[j]))
return 1;
}
}
return 0;
}
int Blowfish::bf_setkey(byte * key, unsigned int keylen)
{
int rc = do_bf_setkey(key, keylen);
burn_stack(64);
return rc;
}
int Blowfish::bf_encrypt(byte * outbuf, byte * inbuf, unsigned int inbuf_len)
{
if (unlikely(inbuf_len % 8))
return 1;
unsigned int i = 0;
while (i < inbuf_len) {
encrypt_block(outbuf + i, inbuf + i);
i += 8;
}
return 0;
}
int Blowfish::bf_decrypt(byte * outbuf, byte * inbuf, unsigned int inbuf_len)
{
if (unlikely(inbuf_len % 8))
return 1;
unsigned int i = 0;
while (i < inbuf_len) {
decrypt_block(outbuf + i, inbuf + i);
i += 8;
}
return 0;
}
void Blowfish::padNull(string *buf)
{
buf->append(1, (char)0x01);
string::size_type append_null = 8 - (buf->length() % 8);
buf->append(append_null, (char)0x00);
}
bool Blowfish::unpadNull(string *buf)
{
if (unlikely(buf->size() % 8))
return false;
string::size_type pos = buf->length() - 1;
while ((*buf)[pos] != (char)0x01) {
if (unlikely(pos == 0))
return false;
--pos;
}
buf->erase(pos, buf->length() - pos);
return true;
}
diff --git a/pwmanager/pwmanager/blowfish.h b/pwmanager/pwmanager/blowfish.h
index 5129eab..862cccb 100644
--- a/pwmanager/pwmanager/blowfish.h
+++ b/pwmanager/pwmanager/blowfish.h
@@ -1,129 +1,131 @@
/***************************************************************************
* *
* copyright (C) 2003, 2004 by Michael Buesch *
* email: mbuesch@freenet.de *
* *
* blowfish.c - Blowfish encryption *
* Copyright (C) 1998, 2001, 2002 Free Software Foundation, Inc. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 *
* as published by the Free Software Foundation. *
* *
***************************************************************************/
/***************************************************************************
* copyright (C) 2004 by Ulf Schenk
* This file is originaly based on version 1.0.1 of pwmanager
* and was modified to run on embedded devices that run microkde
*
* $Id$
**************************************************************************/
#ifndef BLOWFISH_H
#define BLOWFISH_H
-#include "pwmexception.h"
+//#include "pwmexception.h"
#ifndef _WIN32_
#include <stdint.h>
#else
#endif
#include <string>
using std::string;
#define BLOWFISH_BLOCKSIZE 8
#define BLOWFISH_ROUNDS 16
#define CIPHER_ALGO_BLOWFISH 4 /* blowfish 128 bit key */
#ifndef _WIN32_
typedef uint8_t byte;
#else
#define uint8_t Q_UINT8
#define byte Q_UINT8
#define uint32_t Q_UINT32
#endif
+//#include "pwmexception.h"
+
/** blowfish encryption algorithm.
* Derived from libgcrypt-1.1.12
*/
class Blowfish
{
struct BLOWFISH_context
{
uint32_t s0[256];
uint32_t s1[256];
uint32_t s2[256];
uint32_t s3[256];
uint32_t p[BLOWFISH_ROUNDS+2];
};
public:
Blowfish() {}
static bool selfTest();
/** set key to encrypt. if return == 1, it is a weak key. */
int bf_setkey( byte *key, unsigned int keylen );
/** encrypt inbuf and return it in outbuf.
* inbuf and outbuf have to be: buf % 8 == 0
* You may check this with getPaddedLen() and pad with NULL.
*/
int bf_encrypt( byte *outbuf, byte *inbuf, unsigned int inbuf_len );
/** decrypt inbuf and return it in outbuf.
* inbuf and outbuf have to be: buf % 8 == 0
* You may check this with getPaddedLen() and pad with NULL.
*/
int bf_decrypt( byte *outbuf, byte *inbuf, unsigned int inbuf_len );
/** returns the length, the sting has to be padded to */
static unsigned int getPaddedLen(unsigned int inLen)
{ return ((8 - (inLen % 8)) + inLen); }
/** pad up to 8 bytes. */
static void padNull(string *buf);
/** remove padded data */
static bool unpadNull(string *buf);
protected:
#if BLOWFISH_ROUNDS != 16
uint32_t function_F( uint32_t x)
{
uint16_t a, b, c, d;
#ifdef BIG_ENDIAN_HOST
a = ((byte *) & x)[0];
b = ((byte *) & x)[1];
c = ((byte *) & x)[2];
d = ((byte *) & x)[3];
#else
a = ((byte *) & x)[3];
b = ((byte *) & x)[2];
c = ((byte *) & x)[1];
d = ((byte *) & x)[0];
#endif
return ((bc.s0[a] + bc.s1[b]) ^ bc.s2[c]) + bc.s3[d];
}
#endif
void R(uint32_t &l, uint32_t &r, uint32_t i, uint32_t *p,
uint32_t *s0, uint32_t *s1, uint32_t *s2, uint32_t *s3)
{
l ^= p[i];
#ifdef BIG_ENDIAN_HOST
r ^= (( s0[((byte*)&l)[0]] + s1[((byte*)&l)[1]])
^ s2[((byte*)&l)[2]]) + s3[((byte*)&l)[3]];
#else
r ^= (( s0[((byte*)&l)[3]] + s1[((byte*)&l)[2]])
^ s2[((byte*)&l)[1]]) + s3[((byte*)&l)[0]];
#endif
}
void encrypt_block(byte *outbuf, byte *inbuf);
void decrypt_block(byte *outbuf, byte *inbuf);
void burn_stack(int bytes);
void do_encrypt(uint32_t *ret_xl, uint32_t *ret_xr);
void do_decrypt(uint32_t *ret_xl, uint32_t *ret_xr);
void do_encrypt_block(byte *outbuf, byte *inbuf);
void do_decrypt_block(byte *outbuf, byte *inbuf);
int do_bf_setkey(byte *key, unsigned int keylen);
protected:
struct BLOWFISH_context bc;
};
#endif
diff --git a/pwmanager/pwmanager/genpasswd.cpp b/pwmanager/pwmanager/genpasswd.cpp
index b0cceff..41078b3 100644
--- a/pwmanager/pwmanager/genpasswd.cpp
+++ b/pwmanager/pwmanager/genpasswd.cpp
@@ -1,192 +1,193 @@
/***************************************************************************
* *
* copyright (C) 2004 by Michael Buesch *
* email: mbuesch@freenet.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 *
* as published by the Free Software Foundation. *
* *
***************************************************************************/
/***************************************************************************
* copyright (C) 2004 by Ulf Schenk
* This file is originaly based on version 1.0.1 of pwmanager
* and was modified to run on embedded devices that run microkde
*
* $Id$
**************************************************************************/
#include "genpasswd.h"
#include "pwmexception.h"
#include "randomizer.h"
+#include "globalstuff.h"
/* how often can a char of the same charset be reused in order */
#define FILTER_MAX_CHARSET_REUSE 3
/* re-randomize all charsets on every iteration (0/1) */
#define RERAND_CHARSET 0
struct staticCharsetStruct
{
const char *lower;
const char *upper;
const char *num;
const char *special;
const char *blank;
};
static struct staticCharsetStruct staticCharset = {
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
"0123456789",
"!\"§$%&/()=?,.-;:_+",
" "
};
GenPasswd::GenPasswd()
: length (8)
, useFilter (true)
{
dynCharset.setAutoDelete(true);
}
void GenPasswd::setCharset(bool lower,
bool upper,
bool num,
bool special,
bool blank,
QString user)
{
unsigned int sanityCheck = 0;
dynCharset_element *tmpElement;
dynCharset.clear();
if (lower) {
tmpElement = new dynCharset_element;
tmpElement->refCnt = 0;
tmpElement->data = staticCharset.lower;
dynCharset.append(tmpElement);
++sanityCheck;
}
if (upper) {
tmpElement = new dynCharset_element;
tmpElement->refCnt = 0;
tmpElement->data = staticCharset.upper;
dynCharset.append(tmpElement);
++sanityCheck;
}
if (num) {
tmpElement = new dynCharset_element;
tmpElement->refCnt = 0;
tmpElement->data = staticCharset.num;
dynCharset.append(tmpElement);
++sanityCheck;
}
if (special) {
tmpElement = new dynCharset_element;
tmpElement->refCnt = 0;
tmpElement->data = staticCharset.special;
dynCharset.append(tmpElement);
++sanityCheck;
}
if (blank) {
tmpElement = new dynCharset_element;
tmpElement->refCnt = 0;
tmpElement->data = staticCharset.blank;
dynCharset.append(tmpElement);
}
if (!user.isEmpty()) {
tmpElement = new dynCharset_element;
tmpElement->refCnt = 0;
tmpElement->data = user;
dynCharset.append(tmpElement);
if (likely(user.length() >= 2))
++sanityCheck;
}
BUG_ON(!sanityCheck);
rndDynCharset();
}
void GenPasswd::rndDynCharset()
{
QString tmpData;
int pos;
Randomizer *rnd = Randomizer::obj();
// QPtrList<dynCharset_element>::iterator is not available in QT-3.1
unsigned int i, cnt = dynCharset.count();
dynCharset_element *p;
for (i = 0; i < cnt; ++i) {
p = dynCharset.at(i);
PWM_ASSERT(p);
tmpData = QString::null;
while (p->data.length()) {
pos = rnd->genRndInt() % p->data.length();
tmpData.append(p->data.at(pos));
p->data.remove(pos, 1);
}
p->data = tmpData;
}
}
QString GenPasswd::gen()
{
BUG_ON(dynCharset.count() <= 0);
BUG_ON(length < 1);
dynCharset_element *curCharset;
QString ret;
int i;
for (i = 0; i < length; ++i) {
curCharset = selectNextCharset();
#if RERAND_CHARSET != 0
rndDynCharset();
#endif // RERAND_CHARSET
ret += genNewRandom(curCharset);
}
return ret;
}
GenPasswd::dynCharset_element * GenPasswd::selectNextCharset()
{
dynCharset_element *ret;
int numCharsets = dynCharset.count();
BUG_ON(numCharsets <= 0);
if (numCharsets == 1)
return dynCharset.at(0);
Randomizer *rnd = Randomizer::obj();
if (useFilter) {
// find out which charsets are allowed (filtering)
QPtrList<dynCharset_element> allowedCharsets;
// QPtrList<dynCharset_element>::iterator is not available in QT-3.1
unsigned int i, cnt = dynCharset.count();
dynCharset_element *p;
for (i = 0; i < cnt; ++i) {
p = dynCharset.at(i);
PWM_ASSERT(p);
if (p->refCnt < FILTER_MAX_CHARSET_REUSE) {
allowedCharsets.append(p);
} else {
p->refCnt = 0;
}
}
int numAllowedCharsets = allowedCharsets.count();
BUG_ON(numAllowedCharsets <= 0);
// now get a random charset out of the allowed
unsigned int randomPos = rnd->genRndUInt() % numAllowedCharsets;
ret = allowedCharsets.at(randomPos);
ret->refCnt++;
return ret;
}
// all charsets are allowed here (no filtering). Get a random.
unsigned int randomPos = rnd->genRndUInt() % numCharsets;
ret = dynCharset.at(randomPos);
return ret;
}
QChar GenPasswd::genNewRandom(const dynCharset_element *charset)
{
Randomizer *rnd = Randomizer::obj();
int pos = rnd->genRndInt() % charset->data.length();
return charset->data.at(pos);
}
diff --git a/pwmanager/pwmanager/libgcryptif.h b/pwmanager/pwmanager/libgcryptif.h
index 9a987a2..a08d678 100644
--- a/pwmanager/pwmanager/libgcryptif.h
+++ b/pwmanager/pwmanager/libgcryptif.h
@@ -1,177 +1,179 @@
/***************************************************************************
* *
* copyright (C) 2004 by Michael Buesch *
* email: mbuesch@freenet.de *
* *
* hashPassphrase() is derived from GnuPG and is *
* Copyright (C) 1998, 1999, 2000, 2001, 2003 *
* Free Software Foundation, Inc. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 *
* as published by the Free Software Foundation. *
* *
***************************************************************************/
/***************************************************************************
* copyright (C) 2004 by Ulf Schenk
* This file is originaly based on version 1.1 of pwmanager
* and was modified to run on embedded devices that run microkde
*
* $Id$
**************************************************************************/
#ifndef __LIBGCRYPTIF_H
#define __LIBGCRYPTIF_H
-#include "pwmexception.h"
//#undef CONFIG_PWMANAGER_GCRY // for debugging only.
#ifdef CONFIG_PWMANAGER_GCRY
#include <stddef.h>
#include <sys/types.h>
#ifndef _WIN32_
#include <stdint.h>
#else
#define uint8_t Q_UINT8
#define byte Q_UINT8
#define uint32_t Q_UINT32
#endif
#define STRING2KEY_SALTLEN 8
+#include "pwmexception.h"
+
+
/** interface class for the libgcrypt cipher and hash algorithms
* NOTE: Always allocate 1024 extra bytes for the inBuf (for padding)
*/
class LibGCryptIf
{
protected:
struct STRING2KEY
{
int mode;
int hash_algo;
uint8_t salt[STRING2KEY_SALTLEN];
uint32_t count;
};
struct DEK
{
size_t keylen;
uint8_t key[32]; // this is the largest used keylen (256 bit)
};
public:
LibGCryptIf() { }
/** is libgcrypt available? */
static bool available()
{ return true; }
/** encrypt data. _algo is the PWM_CRYPT_* ID
* of the algorithm.
*/
PwMerror encrypt(unsigned char **outBuf,
size_t *outBufLen,
unsigned char *inBuf,
size_t inBufLen,
const unsigned char *key,
size_t keylen,
char _algo,
char _hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
);
/** decrypt data. _algo is the PWM_CRYPT_* ID
* of the algorithm.
*/
PwMerror decrypt(unsigned char **outBuf,
size_t *outBufLen,
const unsigned char *inBuf,
size_t inBufLen,
const unsigned char *key,
size_t keylen,
char _algo,
char _hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
);
/** hash data. _algo is the PWM_HASH_* ID of the hash */
PwMerror hash(unsigned char **outBuf,
size_t *outBufLen,
const unsigned char *inBuf,
size_t inBufLen,
char _algo);
/** returns the length of the hash. _algo is the PWM_HASH_*
* id of the hash. returns 0 on error.
*/
unsigned int hashLength(char _algo);
protected:
/** returns the total buffer length */
size_t getBufLen(size_t inBufLen, size_t boundary)
{
return ((boundary - (inBufLen % boundary)) + inBufLen);
}
/** pad the data up to the given boundary.
* "buf" has to be big enough!
*/
void padData(unsigned char *buf,
size_t bufLen,
size_t boundary);
/** unpad the data */
void unpadData(const unsigned char *buf,
size_t *bufLen);
/** maps the PWM_CRYPT_* ID of an algorithm
* to the libgcrypt GCRY_CIPHER_* ID
*/
int mapCipherId(char algo);
/** maps the PWM_HASH_* ID of an algorithm
* to the libgcrypt GCRY_MD_* ID
*/
int mapHashId(char algo);
/** hash a passphrase to a cipher key */
bool hashPassphrase(const unsigned char *pw,
size_t pwlen,
unsigned char *salt,
unsigned char *key,
size_t keylen,
bool create,
char _hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
);
/** hash a passphrase to a cipher key */
bool doHashPassphrase(DEK *dek,
const unsigned char *pw,
size_t pwlen,
STRING2KEY *s2k,
bool create);
};
#else // CONFIG_PWMANAGER_GCRY
/** libgcrypt is not installed. This is a NOP wrapper. */
class LibGCryptIf
{
public:
LibGCryptIf() { }
static bool available()
{ return false; }
PwMerror encrypt(unsigned char **,
size_t *,
unsigned char *,
size_t,
const unsigned char *,
size_t,
char)
{ return e_cryptNotImpl; }
PwMerror decrypt(unsigned char **,
size_t *,
const unsigned char *,
size_t,
const unsigned char *,
size_t,
char)
{ return e_cryptNotImpl; }
PwMerror hash(unsigned char **,
size_t *,
const unsigned char *,
size_t,
char)
{ return e_hashNotImpl; }
unsigned int hashLength(char)
{ return 0; }
};
#endif // CONFIG_PWMANAGER_GCRY
#endif // __LIBGCRYPTIF_H
diff --git a/pwmanager/pwmanager/pwmexception.h b/pwmanager/pwmanager/pwmexception.h
index 301ebd7..7f5a3a6 100644
--- a/pwmanager/pwmanager/pwmexception.h
+++ b/pwmanager/pwmanager/pwmexception.h
@@ -1,217 +1,218 @@
/***************************************************************************
* *
* copyright (C) 2003, 2004 by Michael Buesch *
* email: mbuesch@freenet.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 *
* as published by the Free Software Foundation. *
* *
***************************************************************************/
/***************************************************************************
* copyright (C) 2004 by Ulf Schenk
* This file is originaly based on version 1.0.1 of pwmanager
* and was modified to run on embedded devices that run microkde
*
* $Id$
**************************************************************************/
#ifndef __PWMEXCEPTION_H
#define __PWMEXCEPTION_H
-#include "globalstuff.h"
+//#include "globalstuff.h"
#include <iostream>
#include <string>
using std::string;
using std::cerr;
using std::cout;
using std::endl;
/* This is an internal function to reduce code-overhead
* of the BUG(), WARN(), TOD0() and FiXME() macros. Please use
* these macros instead of calling this function directly.
*/
void pwmFatal(const char *id,
const char *file,
int line);
/** Use PWM_ASSERT(condition) for debugging assertions.
* "condition" is eaten up and replaced with a NOP
* when debugging is disabled.
*
* PWM_ASSERT_NOEAT(condition) is the same as PWM_ASSERT(condition),
* but it does _not_ eat up "condition" and ensures that
* condition is always evaluated.
*/
#ifdef PWM_ASSERT
# undef PWM_ASSERT
#endif
#ifdef PWM_ASSERT_NOEAT
# undef PWM_ASSERT_NOEAT
#endif
#ifdef PWM_DEBUG
# define PWM_ASSERT(x) do { \
if (unlikely(!(x))) { \
cerr << "PWM_ASSERT failed: (" << #x \
<< ") in " << __FILE__ \
<< ":" << __LINE__ \
<< endl; \
} \
} while (0)
# define PWM_ASSERT_NOEAT(x) do { PWM_ASSERT(x); } while (0)
#else // PWM_DEBUG
# define PWM_ASSERT(x) do { } while (0)
# define PWM_ASSERT_NOEAT(x) do { if (x) ; } while (0)
#endif // PWM_DEBUG
/** Insert a BUG() into code paths which clearly show
* a bug in the code and which should, under normal
* circumstances, never execute.
*/
#ifdef BUG
# undef BUG
#endif
#define BUG() do { pwmFatal("BUG", __FILE__, __LINE__); } while (0)
/** Use BUG_ON(condition) to print a bug-message if "condition"
* is true. This is also enabled in non-debugging code.
*/
#ifdef BUG_ON
# undef BUG_ON
#endif
#define BUG_ON(x) do { if (unlikely(x)) BUG(); } while (0)
/** Insert a WARN() into code-paths which should not
* execute normally, but if they do it's non-fatal.
*/
#ifdef WARN
# undef WARN
#endif
#define WARN() do { pwmFatal("badness", __FILE__, __LINE__); } while (0)
/** Same as BUG_ON() but prints a warning-message */
#ifdef WARN_ON
# undef WARN_ON
#endif
#define WARN_ON(x) do { if (unlikely(x)) WARN(); } while (0)
/** Insert this into code which is incomplete */
#ifdef TODO
# undef TODO
#endif
#define TODO() do { pwmFatal("TODO", __FILE__, __LINE__); } while (0)
/** Insert this into code which likely contains bugs */
#ifdef FIXME
# undef FIXME
#endif
#define FIXME() do { pwmFatal("FIXME", __FILE__, __LINE__); } while (0)
/** PwM error codes */
enum PwMerror {
e_success = 0,
// file access errors
e_filename,
e_readFile,
e_writeFile,
e_openFile,
e_accessFile, // permission error, etc...
e_fileGeneric,
e_alreadyOpen,
// other file errors
e_fileVer,
e_fileFormat, // format error
e_unsupportedFormat, // completely unsupported format
e_setFilePointer,
e_fileBackup,
e_fileCorrupt, // file data has correct format,
// but is corrupt (checksum error, etc)
// password errors
e_wrongPw,
e_getPw,
e_weakPw,
e_noPw,
// action not implemented errors
e_hashNotImpl,
e_cryptNotImpl,
// argument/parameter errors
e_incompleteArg,
e_invalidArg,
// misc
e_writeHeader,
e_serializeDta,
e_enc,
e_entryExists,
e_categoryExists,
e_maxAllowedEntr, // no more entries can be added.
e_outOfMem,
e_lock, // error while (un)locking
e_docNotSaved, // doc wasn't saved to a file, yet.
e_docIsEmpty,
e_binEntry,
e_normalEntry,
e_syncError,
e_generic
};
/** can be used for general exception faults */
class PwMException
{
public:
enum exceptionId
{
EX_GENERIC = 0,
EX_OPEN,
EX_CLOSE,
EX_READ,
EX_WRITE,
EX_LOAD_MODULE,
EX_PARSE
};
public:
PwMException(exceptionId id = EX_GENERIC,
const char *message = "")
{
exId = id;
exMsg = message;
}
exceptionId getId()
{ return exId; }
const char* getMessage()
{ return exMsg; }
protected:
/** ID of this exception */
exceptionId exId;
/** additional error-message for this exception */
const char *exMsg;
};
void __printInfo(const string &msg);
void __printWarn(const string &msg);
void __printError(const string &msg);
#ifdef PWM_DEBUG
void __printDebug(const string &msg);
# define printDebug(x) __printDebug(x)
#else
# define printDebug(x) do { } while (0)
#endif
#define printInfo(x) __printInfo(x)
#define printWarn(x) __printWarn(x)
#define printError(x) __printError(x)
+#include "globalstuff.h"
#endif // __PWMEXCEPTION_H
diff --git a/pwmanager/pwmanager/randomizer.h b/pwmanager/pwmanager/randomizer.h
index f2a6015..44cc28e 100644
--- a/pwmanager/pwmanager/randomizer.h
+++ b/pwmanager/pwmanager/randomizer.h
@@ -1,86 +1,87 @@
/***************************************************************************
* *
* copyright (C) 2003, 2004 by Michael Buesch *
* email: mbuesch@freenet.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 *
* as published by the Free Software Foundation. *
* *
***************************************************************************/
/***************************************************************************
* copyright (C) 2004 by Ulf Schenk
* This file is originaly based on version 1.1 of pwmanager
* and was modified to run on embedded devices that run microkde
*
* $Id$
**************************************************************************/
#ifndef __RANDOMIZER_H
#define __RANDOMIZER_H
#include "pwmexception.h"
+#include "globalstuff.h"
#ifndef PWM_EMBEDDED
#include <qmutex.h>
#endif
#include <string>
using std::string;
class QFile;
/** Randomizer to get random values.
* This class is thread-safe.
* You should always use the instance returned by
* obj() to use it.
*/
class Randomizer
{
public:
Randomizer();
~Randomizer();
static Randomizer * obj()
{
PWM_ASSERT(rndObj);
return rndObj;
}
static void init()
{
PWM_ASSERT(!rndObj);
rndObj = new Randomizer;
}
static void cleanup()
{
delete_ifnot_null(rndObj);
}
/** generate random char */
char genRndChar();
/** generate random int */
int genRndInt();
/** generate a random unsigned int */
unsigned int genRndUInt();
/** returns a buffer with random data */
string genRndBuf(size_t len);
/** returns a buffer with random data */
void genRndBuf(unsigned char *buf, size_t len);
protected:
/** random-device-node (if available. Otherwise NULL) */
QFile *rndDev;
#ifndef PWM_EMBEDDED
/** mutex for accessing the public functions thread-save */
QMutex mutex;
#endif
/** seed value for fallback - rand_r() */
unsigned int seed;
/** static Randomizer object returned by obj() */
static Randomizer *rndObj;
};
#endif // __RANDOMIZER_H