-rw-r--r-- | pwmanager/libcrypt/cipher/serpent.c | 4 |
1 files changed, 2 insertions, 2 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 @@ -420,527 +420,527 @@ typedef struct serpent_context 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."; } } |