Module Name:    src
Committed By:   agc
Date:           Sat Oct 20 04:42:42 UTC 2012

Modified Files:
        src/crypto/external/bsd/netpgp/lib/cipher [agc-netpgp-standalone]:
            Makefile
Added Files:
        src/crypto/external/bsd/netpgp/dist/src/libcipher 
[agc-netpgp-standalone]:
            idea.c idea.h

Log Message:
Now that idea is out of jail, add it as a cipher - requested by christos.

For all intents and purposes, AES will be used these days, but idea may
be used in legacy things, so mainly for completeness.


To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1.2.1 \
    src/crypto/external/bsd/netpgp/dist/src/libcipher/idea.c \
    src/crypto/external/bsd/netpgp/dist/src/libcipher/idea.h
cvs rdiff -u -r1.1.2.1 -r1.1.2.2 \
    src/crypto/external/bsd/netpgp/lib/cipher/Makefile

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/crypto/external/bsd/netpgp/lib/cipher/Makefile
diff -u src/crypto/external/bsd/netpgp/lib/cipher/Makefile:1.1.2.1 src/crypto/external/bsd/netpgp/lib/cipher/Makefile:1.1.2.2
--- src/crypto/external/bsd/netpgp/lib/cipher/Makefile:1.1.2.1	Sun May  6 18:07:01 2012
+++ src/crypto/external/bsd/netpgp/lib/cipher/Makefile	Sat Oct 20 04:42:42 2012
@@ -1,6 +1,7 @@
 LIB=netpgpcipher
 SRCS= rijndael-alg-fst.c rijndael-api-fst.c rijndael.c
 SRCS+= cast.c
+SRCS+= idea.c
 SRCS+= modes.c
 SRCS+= camellia.c
 MAN=libnetpgpcipher.3
@@ -9,7 +10,7 @@ WARNS=4
 EXTDIST=	${.CURDIR}/../../dist
 .PATH:		${EXTDIST}/src/libcipher
 
-INCS=aes.h rijndael.h cast.h camellia.h
+INCS=aes.h rijndael.h cast.h camellia.h idea.h
 INCSDIR=/usr/include/netpgp
 
 .include <bsd.lib.mk>

Added files:

Index: src/crypto/external/bsd/netpgp/dist/src/libcipher/idea.c
diff -u /dev/null src/crypto/external/bsd/netpgp/dist/src/libcipher/idea.c:1.1.2.1
--- /dev/null	Sat Oct 20 04:42:42 2012
+++ src/crypto/external/bsd/netpgp/dist/src/libcipher/idea.c	Sat Oct 20 04:42:42 2012
@@ -0,0 +1,529 @@
+/* Paulo Barreto <pbarr...@unisys.com.br> 1996.01.17 */
+/*
+ *	idea.c - C source code for IDEA block cipher.
+ *	IDEA (International Data Encryption Algorithm), formerly known as 
+ *	IPES (Improved Proposed Encryption Standard).
+ *	Algorithm developed by Xuejia Lai and James L. Massey, of ETH Zurich.
+ *	This implementation modified and derived from original C code 
+ *	developed by Xuejia Lai.  
+ *	Zero-based indexing added, names changed from IPES to IDEA.
+ *	CFB functions added.  Random number routines added.
+ *
+ *	Extensively optimized and restructured by Colin Plumb.
+ *
+ *	The IDEA(tm) block cipher is covered by patents held by ETH and a
+ *	Swiss company called Ascom-Tech AG.  The Swiss patent number is
+ *	PCT/CH91/00117, the European patent number is EP 0 482 154 B1, and
+ *	the U.S. patent number is US005214703.  IDEA(tm) is a trademark of
+ *	Ascom-Tech AG.  There is no license fee required for noncommercial
+ *	use.  Commercial users may obtain licensing details from Dieter
+ *	Profos, Ascom Tech AG, Solothurn Lab, Postfach 151, 4502 Solothurn,
+ *	Switzerland, Tel +41 65 242885, Fax +41 65 235761.
+ *
+ *	The IDEA block cipher uses a 64-bit block size, and a 128-bit key 
+ *	size.  It breaks the 64-bit cipher block into four 16-bit words
+ *	because all of the primitive inner operations are done with 16-bit
+ *	arithmetic.  It likewise breaks the 128-bit cipher key into eight 
+ *	16-bit words.
+ *
+ *	For further information on the IDEA cipher, see the book:
+ *	  Xuejia Lai, "On the Design and Security of Block Ciphers",
+ *	  ETH Series on Information Processing (ed. J.L. Massey) Vol 1,
+ *	  Hartung-Gorre Verlag, Konstanz, Switzerland, 1992.  ISBN
+ *	  3-89191-573-X.
+ *
+ *	This code runs on arrays of bytes by taking pairs in big-endian
+ *	order to make the 16-bit words that IDEA uses internally.  This
+ *	produces the same result regardless of the byte order of the
+ *	native CPU.
+ */
+#include <inttypes.h>
+#include <string.h>
+
+#include "idea.h"
+
+#define OPTIMIZE 
+
+#define LOW16(x) ((x) & 0xFFFF)
+
+/*
+ * Compute the multiplicative inverse of x, modulo 65537, using Euclid's
+ * algorithm. It is unrolled twice to avoid swapping the registers each
+ * iteration, and some subtracts of t have been changed to adds.
+ */
+static __inline uint16_t
+mulInv(uint16_t x)     
+{
+	uint16_t t0, t1;
+	uint16_t q, y;
+
+	if (x <= 1)
+		return x;	/* 0 and 1 are self-inverse */
+	t1 = 0x10001 / x;	/* Since x >= 2, this fits into 16 bits */
+	y = 0x10001 % x;
+	if (y == 1)
+		return ( uint16_t ) LOW16(1-t1);
+	t0 = 1;
+	do {
+		q = x / y;
+		x = x % y;
+		t0 += q * t1;
+		if (x == 1)
+			return t0;
+		q = y / x;
+		y = y % x;
+		t1 += q * t0;
+	} while (y != 1);
+	return ( uint16_t ) LOW16(1-t1);
+}
+
+/*
+ * Expand a 128-bit user key to a working encryption key EK
+ */
+static void
+ideaExpandKey(const uint8_t *userkey, uint16_t *EK)
+{
+	unsigned i,j;
+
+	for (j=0; j<8; j++) {
+		EK[j] = (userkey[0]<<8) + userkey[1];
+		userkey += 2;
+	}
+	for (i=0; j < IDEA_KEYLEN; j++) {
+		i++;
+		EK[i+7] = (EK[i & 7] << 9) | (EK[(i + 1) & 7] >> 7);
+		EK += i & 8;
+		i &= 7;
+	}
+}
+
+#define NEG(x) (- (int) (x))
+
+/*
+ * Compute IDEA decryption key DK from an expanded IDEA encryption key EK
+ * Note that the input and output may be the same.  Thus, the key is
+ * inverted into an internal buffer, and then copied to the output.
+ */
+static void
+ideaInvertKey(const uint16_t *EK, uint16_t DK[IDEA_KEYLEN])
+{
+	uint16_t temp[IDEA_KEYLEN];
+#ifdef OPTIMIZE
+	register int k, p, r;
+
+	p = IDEA_KEYLEN;
+	temp [p-1] = mulInv (EK [3]);
+	temp [p-2] = NEG (EK [2]);
+	temp [p-3] = NEG (EK [1]);
+	temp [p-4] = mulInv (EK [0]);
+
+	k = 4; p -= 4;
+	for (r = IDEA_ROUNDS - 1; r > 0; r--) {
+		temp [p-1] = EK [k+1];
+		temp [p-2] = EK [k];
+		temp [p-3] = mulInv (EK [k+5]);
+		temp [p-4] = NEG (EK [k+3]);
+		temp [p-5] = NEG (EK [k+4]);
+		temp [p-6] = mulInv (EK [k+2]);
+		k += 6; p -= 6;
+	}
+	temp [p-1] = EK [k+1];
+	temp [p-2] = EK [k];
+	temp [p-3] = mulInv (EK [k+5]);
+	temp [p-4] = NEG (EK [k+4]);
+	temp [p-5] = NEG (EK [k+3]);
+	temp [p-6] = mulInv (EK [k+2]);
+#else  /* !OPTIMIZE */
+	int i;
+	uint16_t t1, t2, t3;
+	uint16_t *p = temp + IDEA_KEYLEN;
+
+	t1 = mulInv(*EK++);
+	t2 = - ( int ) *EK++;
+	t3 = - ( int ) *EK++;
+	*--p = mulInv(*EK++);
+	*--p = t3;
+	*--p = t2;
+	*--p = t1;
+
+	for (i = 0; i < IDEA_ROUNDS-1; i++) {
+		t1 = *EK++;
+		*--p = *EK++;
+		*--p = t1;
+
+		t1 = mulInv(*EK++);
+		t2 = - ( int ) *EK++;
+		t3 = - ( int ) *EK++;
+		*--p = mulInv(*EK++);
+		*--p = t2;
+		*--p = t3;
+		*--p = t1;
+	}
+	t1 = *EK++;
+	*--p = *EK++;
+	*--p = t1;
+
+	t1 = mulInv(*EK++);
+	t2 = - ( int ) *EK++;
+	t3 = - ( int ) *EK++;
+	*--p = mulInv(*EK++);
+	*--p = t3;
+	*--p = t2;
+	*--p = t1;
+#endif /* ?OPTIMIZE */
+/* Copy and destroy temp copy */
+	memcpy(DK, temp, sizeof(temp));
+	memset(temp, 0x0, sizeof(temp));
+}
+
+/*
+ * MUL(x,y) computes x = x*y, modulo 0x10001.  Requires two temps, 
+ * t16 and t32.  x is modified, and must me a side-effect-free lvalue.
+ * y may be anything, but unlike x, must be strictly 16 bits even if
+ * LOW16() is #defined.
+ * All of these are equivalent - see which is faster on your machine
+ */
+#define MUL(x,y) \
+	((t16 = (y)) ? \
+		(x=LOW16(x)) ? \
+			t32 = (uint32_t)x*t16, \
+			x = LOW16(t32), \
+			t16 = t32>>16, \
+			x = (x-t16)+(x<t16) \
+		: \
+			(x = 1-t16) \
+	: \
+		(x = 1-x))
+
+/*	IDEA encryption/decryption algorithm */
+/* Note that in and out can be the same buffer */
+static void
+ideaCipher(const uint8_t inbuf[8], uint8_t outbuf[8], const uint16_t *key)
+{
+	register uint16_t x1, x2, x3, x4, s2, s3;
+	const uint16_t *in;
+	uint16_t *out;
+	register uint16_t t16;	/* Temporaries needed by MUL macro */
+	register uint32_t t32;
+#ifndef OPTIMIZE
+	int r = IDEA_ROUNDS;
+#endif /* ?OPTIMIZE */
+	int	indian = 1;
+
+	in = (const uint16_t *)(const void *)inbuf;
+#ifdef OPTIMIZE
+	x1 = in[0];  x2 = in[1];
+	x3 = in[2];  x4 = in[3];
+#else  /* !OPTIMIZE */
+	x1 = *in++;  x2 = *in++;
+	x3 = *in++;  x4 = *in;
+#endif /* ?OPTIMIZE */
+	if (*(char *)(void *)&indian) {
+		/* little endian */
+		x1 = (x1>>8) | (x1<<8);
+		x2 = (x2>>8) | (x2<<8);
+		x3 = (x3>>8) | (x3<<8);
+		x4 = (x4>>8) | (x4<<8);
+	}
+
+#ifdef OPTIMIZE
+	/* round 1: */
+	MUL(x1,key[0]);
+	x2 += key[1];
+	x3 += key[2];
+	MUL(x4, key[3]);
+
+	s3 = x3;
+	x3 ^= x1;
+	MUL(x3, key[4]);
+	s2 = x2;
+	x2 ^= x4;
+	x2 += x3;
+	MUL(x2, key[5]);
+	x3 += x2;
+
+	x1 ^= x2;  x4 ^= x3;
+	x2 ^= s3;  x3 ^= s2;
+
+	/* round 2: */
+	MUL(x1,key[6]);
+	x2 += key[7];
+	x3 += key[8];
+	MUL(x4, key[9]);
+
+	s3 = x3;
+	x3 ^= x1;
+	MUL(x3, key[10]);
+	s2 = x2;
+	x2 ^= x4;
+	x2 += x3;
+	MUL(x2, key[11]);
+	x3 += x2;
+
+	x1 ^= x2;  x4 ^= x3;
+	x2 ^= s3;  x3 ^= s2;
+
+	/* round 3: */
+	MUL(x1,key[12]);
+	x2 += key[13];
+	x3 += key[14];
+	MUL(x4, key[15]);
+
+	s3 = x3;
+	x3 ^= x1;
+	MUL(x3, key[16]);
+	s2 = x2;
+	x2 ^= x4;
+	x2 += x3;
+	MUL(x2, key[17]);
+	x3 += x2;
+
+	x1 ^= x2;  x4 ^= x3;
+	x2 ^= s3;  x3 ^= s2;
+
+	/* round 4: */
+	MUL(x1,key[18]);
+	x2 += key[19];
+	x3 += key[20];
+	MUL(x4, key[21]);
+
+	s3 = x3;
+	x3 ^= x1;
+	MUL(x3, key[22]);
+	s2 = x2;
+	x2 ^= x4;
+	x2 += x3;
+	MUL(x2, key[23]);
+	x3 += x2;
+
+	x1 ^= x2;  x4 ^= x3;
+	x2 ^= s3;  x3 ^= s2;
+
+	/* round 5: */
+	MUL(x1,key[24]);
+	x2 += key[25];
+	x3 += key[26];
+	MUL(x4, key[27]);
+
+	s3 = x3;
+	x3 ^= x1;
+	MUL(x3, key[28]);
+	s2 = x2;
+	x2 ^= x4;
+	x2 += x3;
+	MUL(x2, key[29]);
+	x3 += x2;
+
+	x1 ^= x2;  x4 ^= x3;
+	x2 ^= s3;  x3 ^= s2;
+
+	/* round 6: */
+	MUL(x1,key[30]);
+	x2 += key[31];
+	x3 += key[32];
+	MUL(x4, key[33]);
+
+	s3 = x3;
+	x3 ^= x1;
+	MUL(x3, key[34]);
+	s2 = x2;
+	x2 ^= x4;
+	x2 += x3;
+	MUL(x2, key[35]);
+	x3 += x2;
+
+	x1 ^= x2;  x4 ^= x3;
+	x2 ^= s3;  x3 ^= s2;
+
+	/* round 7: */
+	MUL(x1,key[36]);
+	x2 += key[37];
+	x3 += key[38];
+	MUL(x4, key[39]);
+
+	s3 = x3;
+	x3 ^= x1;
+	MUL(x3, key[40]);
+	s2 = x2;
+	x2 ^= x4;
+	x2 += x3;
+	MUL(x2, key[41]);
+	x3 += x2;
+
+	x1 ^= x2;  x4 ^= x3;
+	x2 ^= s3;  x3 ^= s2;
+
+	/* round 8: */
+	MUL(x1,key[42]);
+	x2 += key[43];
+	x3 += key[44];
+	MUL(x4, key[45]);
+
+	s3 = x3;
+	x3 ^= x1;
+	MUL(x3, key[46]);
+	s2 = x2;
+	x2 ^= x4;
+	x2 += x3;
+	MUL(x2, key[47]);
+	x3 += x2;
+
+	x1 ^= x2;  x4 ^= x3;
+	x2 ^= s3;  x3 ^= s2;
+
+	/* final semiround: */
+	MUL(x1, key[48]);
+	x3 += key[49];
+	x2 += key[50];
+	MUL(x4, key[51]);
+
+#else  /* !OPTIMIZE */
+	do {
+		MUL(x1,*key++);
+		x2 += *key++;
+		x3 += *key++;
+		MUL(x4, *key++);
+
+		s3 = x3;
+		x3 ^= x1;
+		MUL(x3, *key++);
+		s2 = x2;
+		x2 ^= x4;
+		x2 += x3;
+		MUL(x2, *key++);
+		x3 += x2;
+
+		x1 ^= x2;  x4 ^= x3;
+
+		x2 ^= s3;  x3 ^= s2;
+	} while (--r);
+	MUL(x1, *key++);
+	x3 += *key++;
+	x2 += *key++;
+	MUL(x4, *key);
+#endif /* ?OPTIMIZE */
+
+	out = (uint16_t *)outbuf;
+	if (*(char *)(void *)&indian) {
+		/* little endian */
+#ifdef OPTIMIZE
+		out[0] = (x1>>8) | (x1<<8);
+		out[1] = (x3>>8) | (x3<<8);
+		out[2] = (x2>>8) | (x2<<8);
+		out[3] = (x4>>8) | (x4<<8);
+#else  /* !OPTIMIZE */
+		x1 = LOW16(x1);
+		x2 = LOW16(x2);
+		x3 = LOW16(x3);
+		x4 = LOW16(x4);
+		*out++ = (x1>>8) | (x1<<8);
+		*out++ = (x3>>8) | (x3<<8);
+		*out++ = (x2>>8) | (x2<<8);
+		*out   = (x4>>8) | (x4<<8);
+#endif /* ?OPTIMIZE */
+	} else {
+		/* big endian */
+		*out++ = x1;
+		*out++ = x3;
+		*out++ = x2;
+		*out = x4;
+	}
+}
+
+int
+idea_set_key(idea_context_t *ctx, uint8_t *key, unsigned keylen)
+{
+	ctx->have_decrypt_key = 0;
+	ideaExpandKey(key, ctx->enckey);
+	ideaInvertKey(ctx->enckey, ctx->deckey);
+	return 0;
+}
+
+void
+idea_encrypt_block(idea_context_t *ctx, uint8_t *out, uint8_t *in)
+{
+	ideaCipher(out, in, ctx->enckey);
+}
+
+void
+idea_decrypt_block(idea_context_t *ctx, uint8_t *out, uint8_t *in)
+{
+	if (!ctx->have_decrypt_key) {
+		ctx->have_decrypt_key = 1;
+		ideaInvertKey(ctx->enckey, ctx->deckey);
+	}
+	ideaCipher(out, in, ctx->deckey);
+}
+
+/*-------------------------------------------------------------*/
+
+#ifdef TEST
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+/*
+ * This is the number of Kbytes of test data to encrypt.
+ * It defaults to 1 MByte.
+ */
+#ifndef BLOCKS
+  #ifndef KBYTES
+	#define KBYTES 1024L
+  #endif
+  #define BLOCKS (64*KBYTES)
+#endif
+
+int
+main(void)
+{	/* Test driver for IDEA cipher */
+	idea_context_t	ctx;
+	int i, k;
+	uint8_t userkey[16];
+	uint8_t XX[8], YY[8], ZZ[8];
+	clock_t start, end;
+	long l;
+	float secs;
+
+	memset(&ctx, 0x0, sizeof(ctx));
+	/* Make a sample user key for testing... */
+	for(i=0; i<16; i++)
+		userkey[i] = i+1;
+
+	idea_set_key(&ctx, userkey, sizeof(userkey));
+
+	/* Make a sample plaintext pattern for testing... */
+	for (k=0; k<8; k++)
+		XX[k] = k;
+
+	printf("\nEncrypting %ld bytes (%ld blocks)...", BLOCKS*16, BLOCKS);
+	fflush(stdout);
+	start = clock();
+	memcpy(YY, XX, sizeof(YY));
+	for (l = 0; l < BLOCKS; l++)
+		idea_encrypt_block(&ctx, YY, YY);	/* repeated encryption */
+	memcpy(ZZ, YY, sizeof(ZZ));
+	for (l = 0; l < BLOCKS; l++)
+		idea_decrypt_block(&ctx, ZZ, ZZ);	/* repeated decryption */
+	end = clock() - start;
+	secs = (float) end / CLOCKS_PER_SEC;
+	printf("%.2f sec = %.0f bytes/sec.\n",
+		secs, (float) BLOCKS*16 / secs);
+
+	printf("\nX %3u  %3u  %3u  %3u  %3u  %3u  %3u %3u\n",
+	  XX[0], XX[1],  XX[2], XX[3], XX[4], XX[5],  XX[6], XX[7]);
+	printf("\nY %3u  %3u  %3u  %3u  %3u  %3u  %3u %3u\n",
+	  YY[0], YY[1],  YY[2], YY[3], YY[4], YY[5],  YY[6], YY[7]);
+	printf("\nZ %3u  %3u  %3u  %3u  %3u  %3u  %3u %3u\n",    
+	  ZZ[0], ZZ[1],  ZZ[2], ZZ[3], ZZ[4], ZZ[5],  ZZ[6], ZZ[7]);
+
+	/* Now decrypted ZZ should be same as original XX */
+	for (k=0; k<8; k++)
+		if (XX[k] != ZZ[k]) {
+			printf("\n\07Error!  Noninvertable encryption.\n");
+			exit(1);	/* error exit */ 
+		}
+	printf("\nNormal exit.\n");
+	return 0;	/* normal exit */
+}
+
+#endif /* TEST */
\ No newline at end of file
Index: src/crypto/external/bsd/netpgp/dist/src/libcipher/idea.h
diff -u /dev/null src/crypto/external/bsd/netpgp/dist/src/libcipher/idea.h:1.1.2.1
--- /dev/null	Sat Oct 20 04:42:42 2012
+++ src/crypto/external/bsd/netpgp/dist/src/libcipher/idea.h	Sat Oct 20 04:42:42 2012
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 2012 Alistair Crooks <a...@netbsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef IDEA_H_
+#define IDEA_H_
+
+#include <inttypes.h>
+
+#define IDEA_KEYSIZE	16
+#define IDEA_BLOCKSIZE	8
+#define IDEA_ROUNDS	8
+#define IDEA_KEYLEN	((6 * IDEA_ROUNDS) + 4)
+
+typedef struct idea_context_t {
+	uint16_t	enckey[IDEA_KEYLEN];
+	uint16_t	deckey[IDEA_KEYLEN];
+	uint8_t		have_decrypt_key;
+} idea_context_t;
+
+#ifndef __BEGIN_DECLS
+#  if defined(__cplusplus)
+#  define __BEGIN_DECLS           extern "C" {
+#  define __END_DECLS             }
+#  else
+#  define __BEGIN_DECLS
+#  define __END_DECLS
+#  endif
+#endif
+
+__BEGIN_DECLS
+
+int idea_set_key(idea_context_t */*ctx*/, uint8_t *key, unsigned /*size*/);
+void idea_encrypt_block(idea_context_t */*ctx*/, uint8_t */*out*/, uint8_t */*in*/);
+void idea_decrypt_block(idea_context_t */*ctx*/, uint8_t */*out*/, uint8_t */*in*/);
+
+__END_DECLS
+
+#endif

Reply via email to