diff options
-rw-r--r-- | nettle/arctwo-meta.c | 24 | ||||
-rw-r--r-- | nettle/arctwo.c | 337 | ||||
-rw-r--r-- | nettle/arctwo.h | 34 | ||||
-rw-r--r-- | nettle/macros.h | 11 | ||||
-rw-r--r-- | nettle/nettle-meta.h | 7 |
5 files changed, 140 insertions, 273 deletions
diff --git a/nettle/arctwo-meta.c b/nettle/arctwo-meta.c index 839a58287c..b3a548e991 100644 --- a/nettle/arctwo-meta.c +++ b/nettle/arctwo-meta.c @@ -3,18 +3,17 @@ /* nettle, low-level cryptographics library * * Copyright (C) 2004 Simon Josefsson - * Copyright (C) 2002 Niels Möller * * The nettle library 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. - * + * * The nettle library 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 the nettle library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, @@ -29,11 +28,20 @@ #include "arctwo.h" +const struct nettle_cipher nettle_arctwo40 += _NETTLE_CIPHER (arctwo, ARCTWO, 40); + +const struct nettle_cipher nettle_arctwo64 += _NETTLE_CIPHER (arctwo, ARCTWO, 64); + const struct nettle_cipher nettle_arctwo128 -= _NETTLE_CIPHER(arctwo, ARCTWO, 128); += _NETTLE_CIPHER (arctwo, ARCTWO, 128); -const struct nettle_cipher nettle_arctwo40 -= _NETTLE_CIPHER(arctwo, ARCTWO, 40); +const struct nettle_cipher nettle_arctwo_gutmann40 += _NETTLE_CIPHER (arctwo_gutmann, ARCTWO, 40); + +const struct nettle_cipher nettle_arctwo_gutmann64 += _NETTLE_CIPHER (arctwo_gutmann, ARCTWO, 64); -const struct nettle_cipher nettle_gutmann_arctwo40 -= _NETTLE_CIPHER(gutmann_arctwo, ARCTWO, 40); +const struct nettle_cipher nettle_arctwo_gutmann128 += _NETTLE_CIPHER (arctwo_gutmann, ARCTWO, 128); diff --git a/nettle/arctwo.c b/nettle/arctwo.c index 9feb15c56f..8725f57117 100644 --- a/nettle/arctwo.c +++ b/nettle/arctwo.c @@ -78,126 +78,105 @@ static const uint8_t arctwo_sbox[] = { #define rotr16(x,n) (((x) >> ((uint16_t)(n))) | ((x) << (16 - (uint16_t)(n)))) void -arctwo_encrypt(struct arctwo_ctx *ctx, - unsigned length, uint8_t *dst, - const uint8_t *src) +arctwo_encrypt (struct arctwo_ctx *ctx, + unsigned length, uint8_t * dst, const uint8_t * src) { - FOR_BLOCKS(length, dst, src, ARCTWO_BLOCK_SIZE) - { - register int i, j; - uint16_t word0 = 0, word1 = 0, word2 = 0, word3 = 0; - - word0 = (word0 << 8) | src[1]; - word0 = (word0 << 8) | src[0]; - word1 = (word1 << 8) | src[3]; - word1 = (word1 << 8) | src[2]; - word2 = (word2 << 8) | src[5]; - word2 = (word2 << 8) | src[4]; - word3 = (word3 << 8) | src[7]; - word3 = (word3 << 8) | src[6]; - - for (i = 0; i < 16; i++) - { - j = i * 4; - /* For some reason I cannot combine those steps. */ - word0 += (word1 & ~word3) + (word2 & word3) + ctx->S[j]; - word0 = rotl16(word0, 1); - - word1 += (word2 & ~word0) + (word3 & word0) + ctx->S[j + 1]; - word1 = rotl16(word1, 2); - - word2 += (word3 & ~word1) + (word0 & word1) + ctx->S[j + 2]; - word2 = rotl16(word2, 3); - - word3 += (word0 & ~word2) + (word1 & word2) + ctx->S[j + 3]; - word3 = rotl16(word3, 5); - - if (i == 4 || i == 10) - { - word0 += ctx->S[word3 & 63]; - word1 += ctx->S[word0 & 63]; - word2 += ctx->S[word1 & 63]; - word3 += ctx->S[word2 & 63]; - } - } - - dst[0] = word0 & 255; - dst[1] = word0 >> 8; - dst[2] = word1 & 255; - dst[3] = word1 >> 8; - dst[4] = word2 & 255; - dst[5] = word2 >> 8; - dst[6] = word3 & 255; - dst[7] = word3 >> 8; - } + FOR_BLOCKS (length, dst, src, ARCTWO_BLOCK_SIZE) + { + register int i, j; + uint16_t word0 = 0, word1 = 0, word2 = 0, word3 = 0; + + word0 = LE_READ_UINT16 (&src[0]); + word1 = LE_READ_UINT16 (&src[2]); + word2 = LE_READ_UINT16 (&src[4]); + word3 = LE_READ_UINT16 (&src[6]); + + for (i = 0; i < 16; i++) + { + j = i * 4; + /* For some reason I cannot combine those steps. */ + word0 += (word1 & ~word3) + (word2 & word3) + ctx->S[j]; + word0 = rotl16 (word0, 1); + + word1 += (word2 & ~word0) + (word3 & word0) + ctx->S[j + 1]; + word1 = rotl16 (word1, 2); + + word2 += (word3 & ~word1) + (word0 & word1) + ctx->S[j + 2]; + word2 = rotl16 (word2, 3); + + word3 += (word0 & ~word2) + (word1 & word2) + ctx->S[j + 3]; + word3 = rotl16 (word3, 5); + + if (i == 4 || i == 10) + { + word0 += ctx->S[word3 & 63]; + word1 += ctx->S[word0 & 63]; + word2 += ctx->S[word1 & 63]; + word3 += ctx->S[word2 & 63]; + } + } + LE_WRITE_UINT16 (&dst[0], word0); + LE_WRITE_UINT16 (&dst[2], word1); + LE_WRITE_UINT16 (&dst[4], word2); + LE_WRITE_UINT16 (&dst[6], word3); + } } void -arctwo_decrypt(struct arctwo_ctx *ctx, - unsigned length, uint8_t *dst, - const uint8_t *src) +arctwo_decrypt (struct arctwo_ctx *ctx, + unsigned length, uint8_t * dst, const uint8_t * src) { - FOR_BLOCKS(length, dst, src, ARCTWO_BLOCK_SIZE) - { - register int i, j; - uint16_t word0 = 0, word1 = 0, word2 = 0, word3 = 0; - - word0 = (word0 << 8) | src[1]; - word0 = (word0 << 8) | src[0]; - word1 = (word1 << 8) | src[3]; - word1 = (word1 << 8) | src[2]; - word2 = (word2 << 8) | src[5]; - word2 = (word2 << 8) | src[4]; - word3 = (word3 << 8) | src[7]; - word3 = (word3 << 8) | src[6]; - - for (i = 15; i >= 0; i--) - { - j = i * 4; - - word3 = rotr16(word3, 5); - word3 -= (word0 & ~word2) + (word1 & word2) + ctx->S[j + 3]; - - word2 = rotr16(word2, 3); - word2 -= (word3 & ~word1) + (word0 & word1) + ctx->S[j + 2]; - - word1 = rotr16(word1, 2); - word1 -= (word2 & ~word0) + (word3 & word0) + ctx->S[j + 1]; - - word0 = rotr16(word0, 1); - word0 -= (word1 & ~word3) + (word2 & word3) + ctx->S[j]; - - if (i == 5 || i == 11) - { - word3 = word3 - ctx->S[word2 & 63]; - word2 = word2 - ctx->S[word1 & 63]; - word1 = word1 - ctx->S[word0 & 63]; - word0 = word0 - ctx->S[word3 & 63]; - } - - } - - dst[0] = word0 & 255; - dst[1] = word0 >> 8; - dst[2] = word1 & 255; - dst[3] = word1 >> 8; - dst[4] = word2 & 255; - dst[5] = word2 >> 8; - dst[6] = word3 & 255; - dst[7] = word3 >> 8; - } + FOR_BLOCKS (length, dst, src, ARCTWO_BLOCK_SIZE) + { + register int i, j; + uint16_t word0 = 0, word1 = 0, word2 = 0, word3 = 0; + + word0 = LE_READ_UINT16 (&src[0]); + word1 = LE_READ_UINT16 (&src[2]); + word2 = LE_READ_UINT16 (&src[4]); + word3 = LE_READ_UINT16 (&src[6]); + + for (i = 15; i >= 0; i--) + { + j = i * 4; + + word3 = rotr16 (word3, 5); + word3 -= (word0 & ~word2) + (word1 & word2) + ctx->S[j + 3]; + + word2 = rotr16 (word2, 3); + word2 -= (word3 & ~word1) + (word0 & word1) + ctx->S[j + 2]; + + word1 = rotr16 (word1, 2); + word1 -= (word2 & ~word0) + (word3 & word0) + ctx->S[j + 1]; + + word0 = rotr16 (word0, 1); + word0 -= (word1 & ~word3) + (word2 & word3) + ctx->S[j]; + + if (i == 5 || i == 11) + { + word3 = word3 - ctx->S[word2 & 63]; + word2 = word2 - ctx->S[word1 & 63]; + word1 = word1 - ctx->S[word0 & 63]; + word0 = word0 - ctx->S[word3 & 63]; + } + + } + LE_WRITE_UINT16 (&dst[0], word0); + LE_WRITE_UINT16 (&dst[2], word1); + LE_WRITE_UINT16 (&dst[4], word2); + LE_WRITE_UINT16 (&dst[6], word3); + } } static void -setkey_core(struct arctwo_ctx *ctx, - unsigned length, const uint8_t *key, - int with_phase2) +setkey_core (struct arctwo_ctx *ctx, + unsigned length, const uint8_t * key, int with_phase2) { unsigned i; uint8_t *S, x; - assert(length >= ARCTWO_MIN_KEY_SIZE); - assert(length <= ARCTWO_MAX_KEY_SIZE); + assert (length >= ARCTWO_MIN_KEY_SIZE); + assert (length <= ARCTWO_MAX_KEY_SIZE); S = (uint8_t *) ctx->S; @@ -231,152 +210,18 @@ setkey_core(struct arctwo_ctx *ctx, /* Make the expanded key, endian independent. */ for (i = 0; i < 64; i++) - ctx->S[i] = ( (uint16_t) S[i * 2] | (((uint16_t) S[i * 2 + 1]) << 8)); + ctx->S[i] = ((uint16_t) S[i * 2] | (((uint16_t) S[i * 2 + 1]) << 8)); } void -gutmann_arctwo_set_key(struct arctwo_ctx *ctx, - unsigned length, const uint8_t *key) +arctwo_gutmann_set_key (struct arctwo_ctx *ctx, + unsigned length, const uint8_t * key) { setkey_core (ctx, length, key, 0); } void -arctwo_set_key(struct arctwo_ctx *ctx, - unsigned length, const uint8_t *key) +arctwo_set_key (struct arctwo_ctx *ctx, unsigned length, const uint8_t * key) { setkey_core (ctx, length, key, 1); } - -#ifdef TEST - -#include <stdio.h> - -int main (void) -{ - struct arctwo_ctx ctx; - uint8_t scratch[16]; - - /* Test vectors from Peter Gutmann's paper. */ - static uint8_t key_1[] = - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - static uint8_t plaintext_1[] = - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - static const uint8_t ciphertext_1[] = - { 0x1C, 0x19, 0x8A, 0x83, 0x8D, 0xF0, 0x28, 0xB7 }; - - static uint8_t key_2[] = - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }; - static uint8_t plaintext_2[] = - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - static uint8_t ciphertext_2[] = - { 0x50, 0xDC, 0x01, 0x62, 0xBD, 0x75, 0x7F, 0x31 }; - - /* This one was checked against libmcrypt's RFC2268. */ - static uint8_t key_3[] = - { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - static uint8_t plaintext_3[] = - { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - static uint8_t ciphertext_3[] = - { 0x8f, 0xd1, 0x03, 0x89, 0x33, 0x6b, 0xf9, 0x5e }; - - /* Test vectors from RFC 2268. */ - static uint8_t key_4[] = - { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - static uint8_t plaintext_4[] = - { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - static const uint8_t ciphertext_4[] = - { 0x27, 0x8b, 0x27, 0xe4, 0x2e, 0x2f, 0x0d, 0x49 }; - - static uint8_t key_5[] = - { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - static uint8_t plaintext_5[] = - { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; - static const uint8_t ciphertext_5[] = - { 0x30, 0x64, 0x9e, 0xdf, 0x9b, 0xe7, 0xd2, 0xc2 }; - - static uint8_t key_6[] = - { 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f, - 0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2 }; - static uint8_t plaintext_6[] = - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - static const uint8_t ciphertext_6[] = - { 0x22, 0x69, 0x55, 0x2a, 0xb0, 0xf8, 0x5c, 0xa6 }; - - /* First test. */ - gutmann_arctwo_set_key (&ctx, sizeof(key_1), key_1); - arctwo_encrypt (&ctx, ARCTWO_BLOCK_SIZE, scratch, plaintext_1); - if (memcmp (scratch, ciphertext_1, sizeof(ciphertext_1))) - puts ("RFC2268 encryption test 1 failed."); - - gutmann_arctwo_set_key (&ctx, sizeof(key_1), key_1); - arctwo_decrypt (&ctx, ARCTWO_BLOCK_SIZE, scratch, scratch); - if (memcmp (scratch, plaintext_1, sizeof(plaintext_1))) - puts ("RFC2268 decryption test 1 failed."); - - /* Second test. */ - gutmann_arctwo_set_key (&ctx, sizeof(key_2), key_2); - arctwo_encrypt (&ctx, ARCTWO_BLOCK_SIZE, scratch, plaintext_2); - if (memcmp (scratch, ciphertext_2, sizeof(ciphertext_2))) - puts ("RFC2268 encryption test 2 failed."); - - gutmann_arctwo_set_key (&ctx, sizeof(key_2), key_2); - arctwo_decrypt (&ctx, ARCTWO_BLOCK_SIZE, scratch, scratch); - if (memcmp (scratch, plaintext_2, sizeof(plaintext_2))) - puts ("RFC2268 decryption test 2 failed."); - - /* Third test. */ - gutmann_arctwo_set_key(&ctx, sizeof(key_3), key_3); - arctwo_encrypt (&ctx, ARCTWO_BLOCK_SIZE, scratch, plaintext_3); - if (memcmp(scratch, ciphertext_3, sizeof(ciphertext_3))) - puts ("RFC2268 encryption test 3 failed."); - - gutmann_arctwo_set_key (&ctx, sizeof(key_3), key_3); - arctwo_decrypt (&ctx, ARCTWO_BLOCK_SIZE, scratch, scratch); - if (memcmp(scratch, plaintext_3, sizeof(plaintext_3))) - puts ("RFC2268 decryption test 3 failed."); - - /* Fourth test. */ - arctwo_set_key (&ctx, sizeof(key_4), key_4); - arctwo_encrypt (&ctx, ARCTWO_BLOCK_SIZE, scratch, plaintext_4); - if (memcmp (scratch, ciphertext_4, sizeof(ciphertext_4))) - puts ("RFC2268 encryption test 4 failed."); - - arctwo_set_key (&ctx, sizeof(key_4), key_4); - arctwo_decrypt (&ctx, ARCTWO_BLOCK_SIZE, scratch, scratch); - if (memcmp (scratch, plaintext_4, sizeof(plaintext_4))) - puts ("RFC2268 decryption test 4 failed."); - - /* Fifth test. */ - arctwo_set_key (&ctx, sizeof(key_5), key_5); - arctwo_encrypt (&ctx, ARCTWO_BLOCK_SIZE, scratch, plaintext_5); - if (memcmp (scratch, ciphertext_5, sizeof(ciphertext_5))) - puts ("RFC2268 encryption test 5 failed."); - - arctwo_set_key (&ctx, sizeof(key_5), key_5); - arctwo_decrypt (&ctx, ARCTWO_BLOCK_SIZE, scratch, scratch); - if (memcmp (scratch, plaintext_5, sizeof(plaintext_5))) - puts ("RFC2268 decryption test 5 failed."); - - /* Sixth test. */ - arctwo_set_key (&ctx, sizeof(key_6), key_6); - arctwo_encrypt (&ctx, ARCTWO_BLOCK_SIZE, scratch, plaintext_6); - if (memcmp (scratch, ciphertext_6, sizeof(ciphertext_6))) - puts ("RFC2268 encryption test 6 failed."); - - arctwo_set_key (&ctx, sizeof(key_6), key_6); - arctwo_decrypt (&ctx, ARCTWO_BLOCK_SIZE, scratch, scratch); - if (memcmp (scratch, plaintext_6, sizeof(plaintext_6))) - puts ("RFC2268 decryption test 6 failed."); - - puts ("Done"); - - return 0; -} -#endif /* TEST */ diff --git a/nettle/arctwo.h b/nettle/arctwo.h index b439e2399a..f94b98872b 100644 --- a/nettle/arctwo.h +++ b/nettle/arctwo.h @@ -7,23 +7,23 @@ * * Copyright (C) 2004 Simon Josefsson * Copyright (C) 2002 Niels Möller - * + * * The nettle library 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. - * + * * The nettle library 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 the nettle library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. */ - + #ifndef NETTLE_ARCTWO_H_INCLUDED #define NETTLE_ARCTWO_H_INCLUDED @@ -33,10 +33,13 @@ #define arctwo_set_key nettle_arctwo_set_key #define arctwo_encrypt nettle_arctwo_encrypt #define arctwo_decrypt nettle_arctwo_decrypt +#define arctwo_gutmann_set_key nettle_arctwo_gutmann_set_key -#define gutmann_arctwo_ctx arctwo_ctx -#define gutmann_arctwo_encrypt arctwo_encrypt -#define gutmann_arctwo_decrypt arctwo_decrypt +/* Map Gutmann variant. */ +#define arctwo_gutmann_ctx arctwo_ctx +#define arctwo_gutmann_encrypt arctwo_encrypt +#define arctwo_gutmann_decrypt arctwo_decrypt +#define arctwo_gutmann_ctx arctwo_ctx #define ARCTWO_BLOCK_SIZE 8 @@ -52,19 +55,16 @@ struct arctwo_ctx }; void -arctwo_set_key(struct arctwo_ctx *ctx, - unsigned length, const uint8_t *key); +arctwo_set_key (struct arctwo_ctx *ctx, unsigned length, const uint8_t * key); void -gutmann_arctwo_set_key(struct arctwo_ctx *ctx, - unsigned length, const uint8_t *key); +arctwo_gutmann_set_key (struct arctwo_ctx *ctx, + unsigned length, const uint8_t * key); void -arctwo_encrypt(struct arctwo_ctx *ctx, - unsigned length, uint8_t *dst, - const uint8_t *src); +arctwo_encrypt (struct arctwo_ctx *ctx, + unsigned length, uint8_t * dst, const uint8_t * src); void -arctwo_decrypt(struct arctwo_ctx *ctx, - unsigned length, uint8_t *dst, - const uint8_t *src); +arctwo_decrypt (struct arctwo_ctx *ctx, + unsigned length, uint8_t * dst, const uint8_t * src); #endif /* NETTLE_ARCTWO_H_INCLUDED */ diff --git a/nettle/macros.h b/nettle/macros.h index 89400c547b..b6c815c3a8 100644 --- a/nettle/macros.h +++ b/nettle/macros.h @@ -78,6 +78,17 @@ do { \ (p)[0] = (i) & 0xff; \ } while(0) +/* Analogous macros, for 16 bit numbers */ +#define LE_READ_UINT16(p) \ + ( (((uint32_t) (p)[1]) << 8) \ + | ((uint32_t) (p)[0])) + +#define LE_WRITE_UINT16(p, i) \ + do { \ + (p)[1] = ((i) >> 8) & 0xff; \ + (p)[0] = (i) & 0xff; \ + } while(0) + /* Macro to make it easier to loop over several blocks. */ #define FOR_BLOCKS(length, dst, src, blocksize) \ assert( !((length) % (blocksize))); \ diff --git a/nettle/nettle-meta.h b/nettle/nettle-meta.h index fa14c884ae..a78136cc72 100644 --- a/nettle/nettle-meta.h +++ b/nettle/nettle-meta.h @@ -115,9 +115,12 @@ extern const struct nettle_cipher nettle_twofish128; extern const struct nettle_cipher nettle_twofish192; extern const struct nettle_cipher nettle_twofish256; -extern const struct nettle_cipher nettle_arctwo128; extern const struct nettle_cipher nettle_arctwo40; -extern const struct nettle_cipher nettle_gutmann_arctwo40; +extern const struct nettle_cipher nettle_arctwo64; +extern const struct nettle_cipher nettle_arctwo128; +extern const struct nettle_cipher nettle_arctwo_gutmann40; +extern const struct nettle_cipher nettle_arctwo_gutmann64; +extern const struct nettle_cipher nettle_arctwo_gutmann128; /* Hash algorithms */ |