/* arctwo.c --- The RC2 cipher as described in RFC 2268.
- * Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010 Free Software
+ * Foundation, Inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* The implementation here is based on Peter Gutmann's RRC.2 paper.
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
+#include <config.h>
#include "arctwo.h"
+#include "bitrotate.h"
+
static const uint8_t arctwo_sbox[] = {
217, 120, 249, 196, 25, 221, 181, 237,
40, 233, 253, 121, 74, 160, 216, 157,
10, 166, 32, 104, 254, 127, 193, 173
};
-#define rotl16(x,n) (((x) << ((uint16_t)(n))) | ((x) >> (16 - (uint16_t)(n))))
-#define rotr16(x,n) (((x) >> ((uint16_t)(n))) | ((x) << (16 - (uint16_t)(n))))
-
/* C89 compliant way to cast 'char' to 'unsigned char'. */
static inline unsigned char
to_uchar (char ch)
void
arctwo_encrypt (arctwo_context *context, const char *inbuf,
- char *outbuf, size_t length)
+ char *outbuf, size_t length)
{
for (; length >= ARCTWO_BLOCK_SIZE; length -= ARCTWO_BLOCK_SIZE,
- inbuf += ARCTWO_BLOCK_SIZE, outbuf += ARCTWO_BLOCK_SIZE)
+ inbuf += ARCTWO_BLOCK_SIZE, outbuf += ARCTWO_BLOCK_SIZE)
{
size_t i, j;
uint16_t word0 = 0, word1 = 0, word2 = 0, word3 = 0;
word3 = (word3 << 8) | to_uchar (inbuf[6]);
for (i = 0; i < 16; i++)
- {
- j = i * 4;
- /* For some reason I cannot combine those steps. */
- word0 += (word1 & ~word3) + (word2 & word3) + context->S[j];
- word0 = rotl16 (word0, 1);
-
- word1 += (word2 & ~word0) + (word3 & word0) + context->S[j + 1];
- word1 = rotl16 (word1, 2);
-
- word2 += (word3 & ~word1) + (word0 & word1) + context->S[j + 2];
- word2 = rotl16 (word2, 3);
-
- word3 += (word0 & ~word2) + (word1 & word2) + context->S[j + 3];
- word3 = rotl16 (word3, 5);
-
- if (i == 4 || i == 10)
- {
- word0 += context->S[word3 & 63];
- word1 += context->S[word0 & 63];
- word2 += context->S[word1 & 63];
- word3 += context->S[word2 & 63];
- }
- }
+ {
+ j = i * 4;
+ /* For some reason I cannot combine those steps. */
+ word0 += (word1 & ~word3) + (word2 & word3) + context->S[j];
+ word0 = rotl16 (word0, 1);
+
+ word1 += (word2 & ~word0) + (word3 & word0) + context->S[j + 1];
+ word1 = rotl16 (word1, 2);
+
+ word2 += (word3 & ~word1) + (word0 & word1) + context->S[j + 2];
+ word2 = rotl16 (word2, 3);
+
+ word3 += (word0 & ~word2) + (word1 & word2) + context->S[j + 3];
+ word3 = rotl16 (word3, 5);
+
+ if (i == 4 || i == 10)
+ {
+ word0 += context->S[word3 & 63];
+ word1 += context->S[word0 & 63];
+ word2 += context->S[word1 & 63];
+ word3 += context->S[word2 & 63];
+ }
+ }
outbuf[0] = word0 & 255;
outbuf[1] = word0 >> 8;
void
arctwo_decrypt (arctwo_context *context, const char *inbuf,
- char *outbuf, size_t length)
+ char *outbuf, size_t length)
{
for (; length >= ARCTWO_BLOCK_SIZE; length -= ARCTWO_BLOCK_SIZE,
- inbuf += ARCTWO_BLOCK_SIZE, outbuf += ARCTWO_BLOCK_SIZE)
+ inbuf += ARCTWO_BLOCK_SIZE, outbuf += ARCTWO_BLOCK_SIZE)
{
size_t i, j;
uint16_t word0 = 0, word1 = 0, word2 = 0, word3 = 0;
word3 = (word3 << 8) | to_uchar (inbuf[6]);
for (i = 16; i > 0; i--)
- {
- j = (i - 1) * 4;
+ {
+ j = (i - 1) * 4;
- word3 = rotr16 (word3, 5);
- word3 -= (word0 & ~word2) + (word1 & word2) + context->S[j + 3];
+ word3 = rotr16 (word3, 5);
+ word3 -= (word0 & ~word2) + (word1 & word2) + context->S[j + 3];
- word2 = rotr16 (word2, 3);
- word2 -= (word3 & ~word1) + (word0 & word1) + context->S[j + 2];
+ word2 = rotr16 (word2, 3);
+ word2 -= (word3 & ~word1) + (word0 & word1) + context->S[j + 2];
- word1 = rotr16 (word1, 2);
- word1 -= (word2 & ~word0) + (word3 & word0) + context->S[j + 1];
+ word1 = rotr16 (word1, 2);
+ word1 -= (word2 & ~word0) + (word3 & word0) + context->S[j + 1];
- word0 = rotr16 (word0, 1);
- word0 -= (word1 & ~word3) + (word2 & word3) + context->S[j];
+ word0 = rotr16 (word0, 1);
+ word0 -= (word1 & ~word3) + (word2 & word3) + context->S[j];
- if (i == 6 || i == 12)
- {
- word3 = word3 - context->S[word2 & 63];
- word2 = word2 - context->S[word1 & 63];
- word1 = word1 - context->S[word0 & 63];
- word0 = word0 - context->S[word3 & 63];
- }
- }
+ if (i == 6 || i == 12)
+ {
+ word3 = word3 - context->S[word2 & 63];
+ word2 = word2 - context->S[word1 & 63];
+ word1 = word1 - context->S[word0 & 63];
+ word0 = word0 - context->S[word3 & 63];
+ }
+ }
outbuf[0] = word0 & 255;
outbuf[1] = word0 >> 8;
void
arctwo_setkey_ekb (arctwo_context *context,
- size_t keylen, const char *key, size_t effective_keylen)
+ size_t keylen, const char *key, size_t effective_keylen)
{
size_t i;
uint8_t *S, x;
S[i] = x;
while (i--)
- {
- x = arctwo_sbox[x ^ S[i + len]];
- S[i] = x;
- }
+ {
+ x = arctwo_sbox[x ^ S[i + len]];
+ S[i] = x;
+ }
}
/* Make the expanded key, endian independent. */