summaryrefslogtreecommitdiff
path: root/utils/idea
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 21:39:35 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 21:39:35 +0000
commit74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a (patch)
treec6e220ba61db3a6ea4052e6841296d829654e664 /utils/idea
parent46439007cf417cbd9ac8049bb4122c890097a0fa (diff)
20060303
Diffstat (limited to 'utils/idea')
-rw-r--r--utils/idea/NOTICE27
-rw-r--r--utils/idea/idea.c254
-rw-r--r--utils/idea/mkfile13
3 files changed, 294 insertions, 0 deletions
diff --git a/utils/idea/NOTICE b/utils/idea/NOTICE
new file mode 100644
index 00000000..48e4162a
--- /dev/null
+++ b/utils/idea/NOTICE
@@ -0,0 +1,27 @@
+This copyright NOTICE applies to all files in this directory and
+subdirectories, unless another copyright notice appears in a given
+file or subdirectory. If you take substantial code from this software to use in
+other programs, you must somehow include with it an appropriate
+copyright notice that includes the copyright notice and the other
+notices below. It is fine (and often tidier) to do that in a separate
+file such as NOTICE, LICENCE or COPYING.
+
+ Copyright © 2002 Vita Nuova Holdings Limited (www.vitanuova.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/utils/idea/idea.c b/utils/idea/idea.c
new file mode 100644
index 00000000..0db0591c
--- /dev/null
+++ b/utils/idea/idea.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright © 2002 Vita Nuova Holdings Limited. All rights reserved.
+ */
+#include <lib9.h>
+#include <bio.h>
+
+/* CBC, ECB, integrate, SSL */
+
+#define KEYLEN 52
+
+#define MODA 0x10000
+#define MODM 0x10001
+#define MASKA (MODA-1)
+
+#define OP1(x, y) ((x) ^ (y))
+#define OP2(x, y) (((x) + (y)) & MASKA)
+#define OP3(x, y) mod(x, y)
+
+#define OP2INV(x) (-(x))
+#define OP3INV(x) inv(x)
+
+#define BIGEND(k, i) ((k[i]<<8)|k[i+1])
+#define MSB(x) ((x)>>8)
+#define LSB(x) ((x)&0xff)
+
+static ushort
+mod(ushort x, ushort y)
+{
+ ushort q, r;
+ uint z;
+
+ if (x == 0)
+ return 1-y;
+ if (y == 0)
+ return 1-x;
+ z = (uint)x*(uint)y;
+ q = z >> 16;
+ r = z & MASKA;
+ return r-q+(r<q);
+}
+
+static ushort
+inv(ushort x)
+{
+ int q, r0, r1, r2, v0, v1, v2;
+
+ if (x <= 1)
+ return x;
+ r0 = MODM;
+ r1 = x;
+ v0 = 0;
+ v1 = 1;
+ while (r1 != 0) {
+ q = r0/r1;
+ r2 = r0-q*r1;
+ v2 = v0-q*v1;
+ r0 = r1;
+ r1 = r2;
+ v0 = v1;
+ v1 = v2;
+ }
+ if (v0 < 0)
+ v0 += MODM;
+ return v0 & MASKA;
+}
+
+static void
+idea_key_setup_decrypt(ushort ek[KEYLEN], ushort dk[KEYLEN])
+{
+ int i;
+
+ for (i = 0; i < 54; i += 6) {
+ dk[i] = OP3INV(ek[48-i]);
+ dk[i+1] = OP2INV(ek[50-i]);
+ dk[i+2] = OP2INV(ek[49-i]);
+ dk[i+3] = OP3INV(ek[51-i]);
+ if (i < 48) {
+ dk[i+4] = ek[46-i];
+ dk[i+5] = ek[47-i];
+ }
+ }
+}
+
+void
+idea_key_setup(uchar key[16], ushort ek[2*KEYLEN])
+{
+ int i, j;
+ ushort tmp, *e = ek;
+
+ for (i = 0; i < 8; i++)
+ ek[i] = BIGEND(key, 2*i);
+ for (i = 8, j = 1; i < KEYLEN; i++, j++) {
+ ek[i] = (e[j&7]<<9)|(e[(j+1)&7]>>7);
+ if (((i+1) & 7) == 0)
+ e += 8;
+ }
+ tmp = ek[49];
+ ek[49] = ek[50];
+ ek[50] = tmp;
+ idea_key_setup_decrypt(ek, &ek[KEYLEN]);
+}
+
+void
+idea_cipher(ushort key[2*KEYLEN], uchar text[8], int decrypting)
+{
+ int i;
+ ushort *k;
+ ushort x[4];
+ ushort tmp, yout, zout;
+
+ k = decrypting ? &key[KEYLEN] : key;
+ for (i = 0; i < 4; i++)
+ x[i] = BIGEND(text, 2*i);
+ for (i = 0; i < 17; i++) {
+ if (!(i&1)) { /* odd round */
+ x[0] = OP3(x[0], k[3*i]);
+ tmp = OP2(x[2], k[3*i+2]);
+ x[2] = OP2(x[1], k[3*i+1]);
+ x[3] = OP3(x[3], k[3*i+3]);
+ x[1] = tmp;
+ }
+ else {
+ tmp = OP3(k[3*i+1], OP1(x[0], x[1]));
+ yout = OP3(OP2(tmp, OP1(x[2], x[3])), k[3*i+2]);
+ zout = OP2(tmp, yout);
+ x[0] = OP1(x[0], yout);
+ x[1] = OP1(x[1], yout);
+ x[2] = OP1(x[2], zout);
+ x[3] = OP1(x[3], zout);
+ }
+ }
+ for (i = 0; i < 4; i++) {
+ text[2*i] = MSB(x[i]);
+ text[2*i+1] = LSB(x[i]);
+ }
+}
+
+static void
+decerr(char *s)
+{
+ fprint(2, "decrypt error: %s (wrong password ?)\n", s);
+ exits("decrypt");
+}
+
+void
+main(int argc, char **argv)
+{
+/*
+ uchar key[] = { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
+ 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 };
+ uchar plain[] = { 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03 };
+ uchar cipher[] = { 0x11, 0xFB, 0xED, 0x2B, 0x01, 0x98, 0x6D, 0xE5 };
+ uchar tmp[8];
+*/
+ ushort edkey[2*KEYLEN];
+ uchar obuf[8], buf[8], key[16];
+ long i, m, n, om;
+ int dec, stdin = 0, stdout = 1;
+ Biobuf *bin, *bout;
+
+/*
+ memcpy(tmp, plain, 8);
+ idea_key_setup(key, edkey);
+ idea_cipher(edkey, tmp, 0);
+ if (memcmp(tmp, cipher, 8)) {
+ print("encrypt wrong\n");
+ exits("");
+ }
+ idea_cipher(edkey, tmp, 1);
+ if (memcmp(tmp, plain, 8)) {
+ print("decrypt wrong\n");
+ exits("");
+ }
+*/
+
+ if((argc != 3 && argc != 4) || (strcmp(argv[1], "-e") != 0 && strcmp(argv[1], "-d") != 0) || strlen(argv[2]) != 16){
+ fprint(2, "usage: idea -[e | d] <16 char key> [inputfile]\n");
+ exits("usage");
+ }
+ dec = strcmp(argv[1], "-d") == 0;
+ if(argc == 4){
+ char s[128];
+
+ stdin = open(argv[3], OREAD);
+ if(stdin < 0){
+ fprint(2, "cannot open %s\n", argv[3]);
+ exits("");
+ }
+ strcpy(s, argv[3]);
+ if(dec){
+ if(strcmp(s+strlen(s)-3, ".id") != 0){
+ fprint(2, "input file not a .id file\n");
+ exits("");
+ }
+ s[strlen(s)-3] = '\0';
+ }
+ else
+ strcat(s, ".id");
+ stdout = create(s, OWRITE, 0666);
+ if(stdout < 0){
+ fprint(2, "cannot create %s\n", s);
+ exits("");
+ }
+ }
+ for(i = 0; i < 16; i++)
+ key[i] = argv[2][i];
+ idea_key_setup(key, edkey);
+ m = om = 0;
+ bin = (Biobuf*)malloc(sizeof(Biobuf));
+ bout = (Biobuf*)malloc(sizeof(Biobuf));
+ Binit(bin, stdin, OREAD);
+ Binit(bout, stdout, OWRITE);
+ for(;;){
+ n = Bread(bin, &buf[m], 8-m);
+ if(n <= 0)
+ break;
+ m += n;
+ if(m == 8){
+ idea_cipher(edkey, buf, dec);
+ if(dec){ /* leave last block around */
+ if(om > 0)
+ Bwrite(bout, obuf, 8);
+ memcpy(obuf, buf, 8);
+ om = 8;
+ }
+ else
+ Bwrite(bout, buf, 8);
+ m = 0;
+ }
+ }
+ if(dec){
+ if(om != 8)
+ decerr("no last block");
+ if(m != 0)
+ decerr("last block not 8 bytes long");
+ m = obuf[7];
+ if(m < 0 || m > 7)
+ decerr("bad modulus");
+ for(i = m; i < 8-1; i++)
+ if(obuf[i] != 0)
+ decerr("byte not 0");
+ Bwrite(bout, obuf, m);
+ }
+ else{
+ for(i = m; i < 8; i++)
+ buf[i] = 0;
+ buf[7] = m;
+ idea_cipher(edkey, buf, dec);
+ Bwrite(bout, buf, 8);
+ }
+ Bflush(bout);
+ Bterm(bin);
+ Bterm(bout);
+}
diff --git a/utils/idea/mkfile b/utils/idea/mkfile
new file mode 100644
index 00000000..2721022f
--- /dev/null
+++ b/utils/idea/mkfile
@@ -0,0 +1,13 @@
+<../../mkconfig
+
+TARG=idea
+
+OFILES= idea.$O\
+
+HFILES=
+
+LIBS=bio 9 # libbio.a uses lib9.a so order matters.
+
+BIN=$ROOT/$OBJDIR/bin
+
+<$ROOT/mkfiles/mkone-$SHELLTYPE