From e9ba420cfc46b61eb8ea96f360b6e08850cf6b6f Mon Sep 17 00:00:00 2001 From: "Marshall T. Vandegrift" Date: Sat, 26 Jul 2008 14:19:26 -0400 Subject: [PATCH 1/4] Converted DES decryption to a Python/C module --- setup.py | 6 +- src/calibre/__init__.py | 2 +- src/calibre/ebooks/lit/reader.py | 9 +- src/calibre/utils/msdes/d3des.h | 156 ++++++ src/calibre/utils/msdes/des.c | 693 ++++++++++++++++++++++++++ src/calibre/utils/msdes/msdesmodule.c | 98 ++++ src/calibre/utils/msdes/spr.h | 202 ++++++++ 7 files changed, 1160 insertions(+), 6 deletions(-) create mode 100644 src/calibre/utils/msdes/d3des.h create mode 100644 src/calibre/utils/msdes/des.c create mode 100644 src/calibre/utils/msdes/msdesmodule.c create mode 100644 src/calibre/utils/msdes/spr.h diff --git a/setup.py b/setup.py index 03cd53efe5..9150a28b90 100644 --- a/setup.py +++ b/setup.py @@ -53,7 +53,11 @@ if __name__ == '__main__': ext_modules = [Extension('calibre.plugins.lzx', sources=['src/calibre/utils/lzx/lzxmodule.c', 'src/calibre/utils/lzx/lzxd.c'], - include_dirs=['src/calibre/utils/lzx'])] + include_dirs=['src/calibre/utils/lzx']), + Extension('calibre.plugins.msdes', + sources=['src/calibre/utils/msdes/msdesmodule.c', + 'src/calibre/utils/msdes/des.c'], + include_dirs=['src/calibre/utils/msdes'])] if iswindows: ext_modules.append(Extension('calibre.plugins.winutil', sources=['src/calibre/utils/windows/winutil.c'], diff --git a/src/calibre/__init__.py b/src/calibre/__init__.py index 65f1151e46..be12f3d102 100644 --- a/src/calibre/__init__.py +++ b/src/calibre/__init__.py @@ -61,7 +61,7 @@ if iswindows and getattr(sys, 'frozen', False): plugins = {} -for plugin in ['pictureflow', 'lzx'] + \ +for plugin in ['pictureflow', 'lzx', 'msdes'] + \ (['winutil'] if iswindows else []) + \ (['usbobserver'] if isosx else []): try: diff --git a/src/calibre/ebooks/lit/reader.py b/src/calibre/ebooks/lit/reader.py index 683f8d8dad..4fb5280a4d 100644 --- a/src/calibre/ebooks/lit/reader.py +++ b/src/calibre/ebooks/lit/reader.py @@ -13,9 +13,9 @@ import re from calibre.ebooks.lit import LitError from calibre.ebooks.lit.maps import OPF_MAP, HTML_MAP import calibre.ebooks.lit.mssha1 as mssha1 -import calibre.ebooks.lit.msdes as msdes from calibre import plugins lzx, lxzerror = plugins['lzx'] +msdes, msdeserror = plugins['msdes'] OPF_DECL = """ > 3] & bytebit[m]) ? 1 : 0; + } + for( i = 0; i < 16; i++ ) { + if( edf == DE1 ) m = (15 - i) << 1; + else m = i << 1; + n = m + 1; + kn[m] = kn[n] = 0L; + for( j = 0; j < 28; j++ ) { + l = j + totrot[i]; + if( l < 28 ) pcr[j] = pc1m[l]; + else pcr[j] = pc1m[l - 28]; + } + for( j = 28; j < 56; j++ ) { + l = j + totrot[i]; + if( l < 56 ) pcr[j] = pc1m[l]; + else pcr[j] = pc1m[l - 28]; + } + for( j = 0; j < 24; j++ ) { + if( pcr[pc2[j]] ) kn[m] |= bigbyte[j]; + if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j]; + } + } + cookey(kn); + return; + } + +static void cookey(raw1) +unsigned long *raw1; +{ + unsigned long *cook, *raw0; + unsigned long dough[32]; + int i; + + cook = dough; + for( i = 0; i < 16; i++, raw1++ ) { + raw0 = raw1++; + *cook = (*raw0 & 0x00fc0000L) << 6; + *cook |= (*raw0 & 0x00000fc0L) << 10; + *cook |= (*raw1 & 0x00fc0000L) >> 10; + *cook++ |= (*raw1 & 0x00000fc0L) >> 6; + *cook = (*raw0 & 0x0003f000L) << 12; + *cook |= (*raw0 & 0x0000003fL) << 16; + *cook |= (*raw1 & 0x0003f000L) >> 4; + *cook++ |= (*raw1 & 0x0000003fL); + } + usekey(dough); + return; + } + +void cpkey(into) +unsigned long *into; +{ + unsigned long *from, *endp; + + from = KnL, endp = &KnL[32]; + while( from < endp ) *into++ = *from++; + return; + } + +void usekey(from) +unsigned long *from; +{ + unsigned long *to, *endp; + + to = KnL, endp = &KnL[32]; + while( to < endp ) *to++ = *from++; + return; + } + +void des(inblock, outblock) +unsigned char *inblock, *outblock; +{ + unsigned long work[2]; + + scrunch(inblock, work); + desfunc(work, KnL); + unscrun(work, outblock); + return; + } + + +static void scrunch(outof, into) +unsigned char *outof; +unsigned long *into; +{ + *into = (*outof++ & 0xffL) << 24; + *into |= (*outof++ & 0xffL) << 16; + *into |= (*outof++ & 0xffL) << 8; + *into++ |= (*outof++ & 0xffL); + *into = (*outof++ & 0xffL) << 24; + *into |= (*outof++ & 0xffL) << 16; + *into |= (*outof++ & 0xffL) << 8; + *into |= (*outof & 0xffL); + return; + } + + +static void unscrun(outof, into) +unsigned long *outof; +unsigned char *into; +{ + *into++ = (*outof >> 24) & 0xffL; + *into++ = (*outof >> 16) & 0xffL; + *into++ = (*outof >> 8) & 0xffL; + *into++ = *outof++ & 0xffL; + *into++ = (*outof >> 24) & 0xffL; + *into++ = (*outof >> 16) & 0xffL; + *into++ = (*outof >> 8) & 0xffL; + *into = *outof & 0xffL; + return; + } + +#include "spr.h" +/* +static unsigned long SP1[64] = { + 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L, + 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L, + 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L, + 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L, + 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L, + 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L, + 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L, + 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L, + 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L, + 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L, + 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L, + 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L, + 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L, + 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L, + 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L, + 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L }; + +static unsigned long SP2[64] = { + 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L, + 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L, + 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L, + 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L, + 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L, + 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L, + 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L, + 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L, + 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L, + 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L, + 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L, + 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L, + 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L, + 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L, + 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L, + 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L }; + +static unsigned long SP3[64] = { + 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L, + 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L, + 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L, + 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L, + 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L, + 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L, + 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L, + 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L, + 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L, + 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L, + 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L, + 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L, + 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L, + 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L, + 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L, + 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L }; + +static unsigned long SP4[64] = { + 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, + 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L, + 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L, + 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L, + 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L, + 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L, + 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L, + 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L, + 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L, + 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L, + 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L, + 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, + 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L, + 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L, + 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L, + 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L }; + +static unsigned long SP5[64] = { + 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L, + 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L, + 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L, + 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L, + 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L, + 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L, + 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L, + 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L, + 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L, + 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L, + 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L, + 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L, + 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L, + 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L, + 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L, + 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L }; + +static unsigned long SP6[64] = { + 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L, + 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L, + 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L, + 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L, + 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L, + 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L, + 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L, + 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L, + 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L, + 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L, + 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L, + 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L, + 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L, + 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L, + 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L, + 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L }; + +static unsigned long SP7[64] = { + 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L, + 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L, + 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L, + 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L, + 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L, + 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L, + 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L, + 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L, + 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L, + 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L, + 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L, + 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L, + 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L, + 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L, + 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L, + 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L }; + +static unsigned long SP8[64] = { + 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L, + 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L, + 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L, + 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L, + 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L, + 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L, + 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L, + 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L, + 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L, + 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L, + 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L, + 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L, + 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L, + 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L, + 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L, + 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L }; +*/ + + +static void desfunc(block, keys) +unsigned long *block, *keys; +{ + unsigned long fval, work, right, leftt; + int round; + + leftt = block[0]; + right = block[1]; + work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; + right ^= work; + leftt ^= (work << 4); + work = ((leftt >> 16) ^ right) & 0x0000ffffL; + right ^= work; + leftt ^= (work << 16); + work = ((right >> 2) ^ leftt) & 0x33333333L; + leftt ^= work; + right ^= (work << 2); + work = ((right >> 8) ^ leftt) & 0x00ff00ffL; + leftt ^= work; + right ^= (work << 8); + right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL; + work = (leftt ^ right) & 0xaaaaaaaaL; + leftt ^= work; + right ^= work; + leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL; + + for( round = 0; round < 8; round++ ) { + work = (right << 28) | (right >> 4); + work ^= *keys++; + fval = SP7[ work & 0x3fL]; + fval |= SP5[(work >> 8) & 0x3fL]; + fval |= SP3[(work >> 16) & 0x3fL]; + fval |= SP1[(work >> 24) & 0x3fL]; + work = right ^ *keys++; + fval |= SP8[ work & 0x3fL]; + fval |= SP6[(work >> 8) & 0x3fL]; + fval |= SP4[(work >> 16) & 0x3fL]; + fval |= SP2[(work >> 24) & 0x3fL]; + leftt ^= fval; + work = (leftt << 28) | (leftt >> 4); + work ^= *keys++; + fval = SP7[ work & 0x3fL]; + fval |= SP5[(work >> 8) & 0x3fL]; + fval |= SP3[(work >> 16) & 0x3fL]; + fval |= SP1[(work >> 24) & 0x3fL]; + work = leftt ^ *keys++; + fval |= SP8[ work & 0x3fL]; + fval |= SP6[(work >> 8) & 0x3fL]; + fval |= SP4[(work >> 16) & 0x3fL]; + fval |= SP2[(work >> 24) & 0x3fL]; + right ^= fval; + } + + right = (right << 31) | (right >> 1); + work = (leftt ^ right) & 0xaaaaaaaaL; + leftt ^= work; + right ^= work; + leftt = (leftt << 31) | (leftt >> 1); + work = ((leftt >> 8) ^ right) & 0x00ff00ffL; + right ^= work; + leftt ^= (work << 8); + work = ((leftt >> 2) ^ right) & 0x33333333L; + right ^= work; + leftt ^= (work << 2); + work = ((right >> 16) ^ leftt) & 0x0000ffffL; + leftt ^= work; + right ^= (work << 16); + work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL; + leftt ^= work; + right ^= (work << 4); + *block++ = right; + *block = leftt; + return; + } + +#ifdef D2_DES + +void des2key(hexkey, mode) /* stomps on Kn3 too */ +unsigned char *hexkey; /* unsigned char[16] */ +short mode; +{ + short revmod; + + revmod = (mode == EN0) ? DE1 : EN0; + deskey(&hexkey[8], revmod); + cpkey(KnR); + deskey(hexkey, mode); + cpkey(Kn3); /* Kn3 = KnL */ + return; + } + +void Ddes(from, into) +unsigned char *from, *into; /* unsigned char[8] */ +{ + unsigned long work[2]; + + scrunch(from, work); + desfunc(work, KnL); + desfunc(work, KnR); + desfunc(work, Kn3); + unscrun(work, into); + return; + } + +void D2des(from, into) +unsigned char *from; /* unsigned char[16] */ +unsigned char *into; /* unsigned char[16] */ +{ + unsigned long *right, *l1, swap; + unsigned long leftt[2], bufR[2]; + + right = bufR; + l1 = &leftt[1]; + scrunch(from, leftt); + scrunch(&from[8], right); + desfunc(leftt, KnL); + desfunc(right, KnL); + swap = *l1; + *l1 = *right; + *right = swap; + desfunc(leftt, KnR); + desfunc(right, KnR); + swap = *l1; + *l1 = *right; + *right = swap; + desfunc(leftt, Kn3); + desfunc(right, Kn3); + unscrun(leftt, into); + unscrun(right, &into[8]); + return; + } + +void makekey(aptr, kptr) +char *aptr; /* NULL-terminated */ +unsigned char *kptr; /* unsigned char[8] */ +{ + unsigned char *store; + int first, i; + unsigned long savek[96]; + + cpDkey(savek); + des2key(Df_Key, EN0); + for( i = 0; i < 8; i++ ) kptr[i] = Df_Key[i]; + first = 1; + while( (*aptr != '\0') || first ) { + store = kptr; + for( i = 0; i < 8 && (*aptr != '\0'); i++ ) { + *store++ ^= *aptr & 0x7f; + *aptr++ = '\0'; + } + Ddes(kptr, kptr); + first = 0; + } + useDkey(savek); + return; + } + +void make2key(aptr, kptr) +char *aptr; /* NULL-terminated */ +unsigned char *kptr; /* unsigned char[16] */ +{ + unsigned char *store; + int first, i; + unsigned long savek[96]; + + cpDkey(savek); + des2key(Df_Key, EN0); + for( i = 0; i < 16; i++ ) kptr[i] = Df_Key[i]; + first = 1; + while( (*aptr != '\0') || first ) { + store = kptr; + for( i = 0; i < 16 && (*aptr != '\0'); i++ ) { + *store++ ^= *aptr & 0x7f; + *aptr++ = '\0'; + } + D2des(kptr, kptr); + first = 0; + } + useDkey(savek); + return; + } + +#ifndef D3_DES /* D2_DES only */ + +void cp2key(into) +unsigned long *into; /* unsigned long[64] */ +{ + unsigned long *from, *endp; + + cpkey(into); + into = &into[32]; + from = KnR, endp = &KnR[32]; + while( from < endp ) *into++ = *from++; + return; + } + +void use2key(from) /* stomps on Kn3 too */ +unsigned long *from; /* unsigned long[64] */ +{ + unsigned long *to, *endp; + + usekey(from); + from = &from[32]; + to = KnR, endp = &KnR[32]; + while( to < endp ) *to++ = *from++; + cpkey(Kn3); /* Kn3 = KnL */ + return; + } + +#else /* D3_DES too */ + +void des3key(hexkey, mode) +unsigned char *hexkey; /* unsigned char[24] */ +short mode; +{ + unsigned char *first, *third; + short revmod; + + if( mode == EN0 ) { + revmod = DE1; + first = hexkey; + third = &hexkey[16]; + } + else { + revmod = EN0; + first = &hexkey[16]; + third = hexkey; + } + deskey(&hexkey[8], revmod); + cpkey(KnR); + deskey(third, mode); + cpkey(Kn3); + deskey(first, mode); + return; + } + +void cp3key(into) +unsigned long *into; /* unsigned long[96] */ +{ + unsigned long *from, *endp; + + cpkey(into); + into = &into[32]; + from = KnR, endp = &KnR[32]; + while( from < endp ) *into++ = *from++; + from = Kn3, endp = &Kn3[32]; + while( from < endp ) *into++ = *from++; + return; + } + +void use3key(from) +unsigned long *from; /* unsigned long[96] */ +{ + unsigned long *to, *endp; + + usekey(from); + from = &from[32]; + to = KnR, endp = &KnR[32]; + while( to < endp ) *to++ = *from++; + to = Kn3, endp = &Kn3[32]; + while( to < endp ) *to++ = *from++; + return; + } + +static void D3des(unsigned char *, unsigned char *); + +static void D3des(from, into) /* amateur theatrics */ +unsigned char *from; /* unsigned char[24] */ +unsigned char *into; /* unsigned char[24] */ +{ + unsigned long swap, leftt[2], middl[2], right[2]; + + scrunch(from, leftt); + scrunch(&from[8], middl); + scrunch(&from[16], right); + desfunc(leftt, KnL); + desfunc(middl, KnL); + desfunc(right, KnL); + swap = leftt[1]; + leftt[1] = middl[0]; + middl[0] = swap; + swap = middl[1]; + middl[1] = right[0]; + right[0] = swap; + desfunc(leftt, KnR); + desfunc(middl, KnR); + desfunc(right, KnR); + swap = leftt[1]; + leftt[1] = middl[0]; + middl[0] = swap; + swap = middl[1]; + middl[1] = right[0]; + right[0] = swap; + desfunc(leftt, Kn3); + desfunc(middl, Kn3); + desfunc(right, Kn3); + unscrun(leftt, into); + unscrun(middl, &into[8]); + unscrun(right, &into[16]); + return; + } + +void make3key(aptr, kptr) +char *aptr; /* NULL-terminated */ +unsigned char *kptr; /* unsigned char[24] */ +{ + unsigned char *store; + int first, i; + unsigned long savek[96]; + + cp3key(savek); + des3key(Df_Key, EN0); + for( i = 0; i < 24; i++ ) kptr[i] = Df_Key[i]; + first = 1; + while( (*aptr != '\0') || first ) { + store = kptr; + for( i = 0; i < 24 && (*aptr != '\0'); i++ ) { + *store++ ^= *aptr & 0x7f; + *aptr++ = '\0'; + } + D3des(kptr, kptr); + first = 0; + } + use3key(savek); + return; + } + +#endif /* D3_DES */ +#endif /* D2_DES */ + +/* Validation sets: + * + * Single-length key, single-length plaintext - + * Key : 0123 4567 89ab cdef + * Plain : 0123 4567 89ab cde7 + * Cipher : c957 4425 6a5e d31d + * + * Double-length key, single-length plaintext - + * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 + * Plain : 0123 4567 89ab cde7 + * Cipher : 7f1d 0a77 826b 8aff + * + * Double-length key, double-length plaintext - + * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 + * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff + * Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7 + * + * Triple-length key, single-length plaintext - + * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567 + * Plain : 0123 4567 89ab cde7 + * Cipher : de0b 7c06 ae5e 0ed5 + * + * Triple-length key, double-length plaintext - + * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567 + * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff + * Cipher : ad0d 1b30 ac17 cf07 0ed1 1c63 81e4 4de5 + * + * d3des V5.09 rwo 9208.04 20:31 Graven Imagery + **********************************************************************/ + diff --git a/src/calibre/utils/msdes/msdesmodule.c b/src/calibre/utils/msdes/msdesmodule.c new file mode 100644 index 0000000000..27ca46ffcb --- /dev/null +++ b/src/calibre/utils/msdes/msdesmodule.c @@ -0,0 +1,98 @@ +/* __license__ = 'GPL v3' + * __copyright__ = '2008, Marshall T. Vandegrift ' + * + * Python module C glue code. + */ + + +#include + +#include + +static char msdes_doc[] = +"Provide LIT-specific DES en/decryption."; + +static PyObject *MsDesError = NULL; + +static PyObject * +msdes_deskey(PyObject *self, PyObject *args) +{ + unsigned char *key = NULL; + unsigned int len = 0; + short int edf = 0; + + if (!PyArg_ParseTuple(args, "s#h", &key, &len, &edf)) { + return NULL; + } + + if (len != 8) { + PyErr_SetString(MsDesError, "Key length incorrect"); + return NULL; + } + + if ((edf != EN0) && (edf != DE1)) { + PyErr_SetString(MsDesError, "En/decryption direction invalid"); + return NULL; + } + + deskey(key, edf); + + Py_RETURN_NONE; +} + +static PyObject * +msdes_des(PyObject *self, PyObject *args) +{ + unsigned char *inbuf = NULL; + unsigned char *outbuf = NULL; + unsigned int len = 0; + unsigned int off = 0; + PyObject *retval = NULL; + + if (!PyArg_ParseTuple(args, "s#", &inbuf, &len)) { + return NULL; + } + + if ((len == 0) || ((len % 8) != 0)) { + PyErr_SetString(MsDesError, + "Input length not a multiple of the block size"); + return NULL; + } + + retval = PyString_FromStringAndSize(NULL, len); + if (retval == NULL) { + return NULL; + } + outbuf = (unsigned char *)PyString_AS_STRING(retval); + + for (off = 0; off < len; off += 8) { + des((inbuf + off), (outbuf + off)); + } + + return retval; +} + +static PyMethodDef msdes_methods[] = { + { "deskey", &msdes_deskey, METH_VARARGS, "Provide a new key for DES en/decryption." }, + { "des", &msdes_des, METH_VARARGS, "Perform DES en/decryption." }, + { NULL, NULL } +}; + +PyMODINIT_FUNC +initmsdes(void) +{ + PyObject *m; + + m = Py_InitModule3("msdes", msdes_methods, msdes_doc); + if (m == NULL) { + return; + } + + MsDesError = PyErr_NewException("msdes.MsDesError", NULL, NULL); + Py_INCREF(MsDesError); + PyModule_AddObject(m, "MsDesError", MsDesError); + PyModule_AddObject(m, "EN0", PyInt_FromLong(EN0)); + PyModule_AddObject(m, "DE1", PyInt_FromLong(DE1)); + + return; +} diff --git a/src/calibre/utils/msdes/spr.h b/src/calibre/utils/msdes/spr.h new file mode 100644 index 0000000000..fdcf5e3e46 --- /dev/null +++ b/src/calibre/utils/msdes/spr.h @@ -0,0 +1,202 @@ +/* crypto/des/spr.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 OR CONTRIBUTORS 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. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +static unsigned long SP1[64] = { +0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L, +0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L, +0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L, +0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L, +0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L, +0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L, +0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L, +0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L, +0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L, +0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L, +0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L, +0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L, +0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L, +0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L, +0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L, +0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L +}; +static unsigned long SP2[64] = { +0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L, +0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L, +0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L, +0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L, +0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L, +0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L, +0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L, +0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L, +0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L, +0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L, +0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L, +0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L, +0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L, +0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L, +0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L, +0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L +}; +static unsigned long SP3[64] = { +0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L, +0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L, +0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L, +0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L, +0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L, +0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L, +0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L, +0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L, +0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L, +0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L, +0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L, +0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L, +0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L, +0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L, +0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L, +0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L +}; +static unsigned long SP4[64] = { +0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L, +0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L, +0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L, +0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L, +0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L, +0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L, +0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L, +0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L, +0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L, +0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L, +0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L, +0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L, +0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L, +0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L, +0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L, +0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L +}; +static unsigned long SP5[64] = { +0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L, +0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L, +0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L, +0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L, +0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L, +0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L, +0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L, +0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L, +0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L, +0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L, +0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L, +0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L, +0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L, +0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L, +0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L, +0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L +}; +static unsigned long SP6[64] = { +0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L, +0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L, +0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L, +0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L, +0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L, +0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L, +0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L, +0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L, +0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L, +0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L, +0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L, +0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L, +0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L, +0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L, +0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L, +0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L, +}; +static unsigned long SP7[64] = { +0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L, +0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L, +0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L, +0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L, +0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L, +0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L, +0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L, +0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L, +0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L, +0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L, +0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L, +0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L, +0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L, +0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L, +0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L, +0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L, +}; +static unsigned long SP8[64] = { +0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L, +0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L, +0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L, +0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L, +0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L, +0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L, +0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L, +0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L, +0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L, +0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L, +0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L, +0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L, +0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L, +0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L, +0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L, +0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L, +}; From ac819eec9d600cc2687cb2e86d0cefd8d7f6d0ea Mon Sep 17 00:00:00 2001 From: "Marshall T. Vandegrift" Date: Sat, 26 Jul 2008 14:56:07 -0400 Subject: [PATCH 2/4] Convert some range()s to xrange()s --- src/calibre/ebooks/lit/reader.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/calibre/ebooks/lit/reader.py b/src/calibre/ebooks/lit/reader.py index 4fb5280a4d..cb33505d75 100644 --- a/src/calibre/ebooks/lit/reader.py +++ b/src/calibre/ebooks/lit/reader.py @@ -85,7 +85,7 @@ def read_utf8_char(bytes, pos): if elsize + pos > len(bytes): raise LitError('Invalid UTF8 character: %s' % repr(bytes[pos])) c &= (mask - 1) - for i in range(1, elsize): + for i in xrange(1, elsize): b = ord(bytes[pos+i]) if (b & 0xC0) != 0x80: raise LitError( @@ -475,7 +475,7 @@ class LitReader(object): def _read_header_pieces(self): src = self.header[self.hdr_len:] - for i in range(self.num_pieces): + for i in xrange(self.num_pieces): piece = src[i * self.PIECE_SIZE:(i + 1) * self.PIECE_SIZE] if u32(piece[4:]) != 0 or u32(piece[12:]) != 0: raise LitError('Piece %s has 64bit value' % repr(piece)) @@ -542,7 +542,7 @@ class LitReader(object): self.num_sections = u16(raw[2:pos]) self.section_names = [""]*self.num_sections self.section_data = [None]*self.num_sections - for section in range(self.num_sections): + for section in xrange(self.num_sections): size = u16(raw[pos:pos+2]) pos += 2 size = size*2 + 2 From 97b5fc46ba58d20e0ad919cd9a8d2c8e9160efc2 Mon Sep 17 00:00:00 2001 From: "Marshall T. Vandegrift" Date: Sat, 26 Jul 2008 15:53:26 -0400 Subject: [PATCH 3/4] Use pysco when UnBinarying, if available --- src/calibre/ebooks/lit/reader.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/calibre/ebooks/lit/reader.py b/src/calibre/ebooks/lit/reader.py index cb33505d75..d9924a2454 100644 --- a/src/calibre/ebooks/lit/reader.py +++ b/src/calibre/ebooks/lit/reader.py @@ -797,5 +797,12 @@ def main(args=sys.argv): print _('OEB ebook created in'), opts.output_dir return 0 +try: + import psyco + psyco.bind(read_utf8_char) + psyco.bind(UnBinary.binary_to_text) +except ImportError: + pass + if __name__ == '__main__': sys.exit(main()) From 49e8e8b4b280b200ac56cc18dd71a9d4114c9fc0 Mon Sep 17 00:00:00 2001 From: "Marshall T. Vandegrift" Date: Sat, 26 Jul 2008 16:00:37 -0400 Subject: [PATCH 4/4] Removed pure-Python LIT-specific DES code --- src/calibre/ebooks/lit/msdes.py | 489 -------------------------------- 1 file changed, 489 deletions(-) delete mode 100644 src/calibre/ebooks/lit/msdes.py diff --git a/src/calibre/ebooks/lit/msdes.py b/src/calibre/ebooks/lit/msdes.py deleted file mode 100644 index de980f8c3d..0000000000 --- a/src/calibre/ebooks/lit/msdes.py +++ /dev/null @@ -1,489 +0,0 @@ -# Re-modified for use in MS LIT decryption. Un-reversed the bytebit[] array. -# Substituted Microsoft's absurd modified S-boxes. Modified the -# encrypt/decrypt methods to handle more than one block at a time. Added a few -# speed-ups supported by modern versions of Python. Added option 'psyco' use. -# -# And lo, all the previous notices follow: - -# Modified DES encryption for VNC password authentication. -# Ported from realvnc's java viewer by -# I chose this package name because it is not compatible with the -# original DES algorithm, e.g. found pycrypto. -# -# (C) 2003 chris -# Released as free software under the Python License. -# -# You're free to use it for commercial and noncommercial -# application, modify and redistribute it as long as the -# copyright notices are intact. There are no warranties, not -# even that it does what it says to do ;-) -# -# Original notice following: - -# This DES class has been extracted from package Acme.Crypto for use in VNC. -# The bytebit[] array has been reversed so that the most significant bit -# in each byte of the key is ignored, not the least significant. Also the -# unnecessary odd parity code has been removed. -# -# These changes are: -# Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. -# -# This software 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. -# - -# DesCipher - the DES encryption method -# -# The meat of this code is by Dave Zimmerman , and is: -# -# Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved. -# -# Permission to use, copy, modify, and distribute this software -# and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and -# without fee is hereby granted, provided that this copyright notice is kept -# intact. -# -# WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY -# OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -# TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -# PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE -# FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR -# DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. -# -# THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE -# CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE -# PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT -# NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE -# SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE -# SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE -# PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET WORKSHOP -# SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR -# HIGH RISK ACTIVITIES. -# -# -# The rest is: -# -# Copyright (C) 1996 by Jef Poskanzer . 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. -# -# Visit the ACME Labs Java page for up-to-date versions of this and other -# fine Java utilities: http://www.acme.com/java/ - - -#/ The DES encryption method. -#

-# This is surprisingly fast, for pure Java. On a SPARC 20, wrapped -# in Acme.Crypto.EncryptedOutputStream or Acme.Crypto.EncryptedInputStream, -# it does around 7000 bytes/second. -#

-# Most of this code is by Dave Zimmerman , and is -# Copyright (c) 1996 Widget Workshop, Inc. See the source file for details. -#

-# Fetch the software.
-# Fetch the entire Acme package. -#

-# @see Des3Cipher -# @see EncryptedOutputStream -# @see EncryptedInputStream - -import struct - -class DesCipher: - # Constructor, byte-array key. - def __init__(self, key): - self.setKey(key) - - #/ Set the key. - def setKey(self, key): - self.encryptKeys = self.deskey([ord(x) for x in key], 1) - self.decryptKeys = self.deskey([ord(x) for x in key], 0) - - # Turn an 8-byte key into internal keys. - def deskey(self, keyBlock, encrypting): - #~ int i, j, l, m, n; - pc1m = [0]*56 #new int[56]; - pcr = [0]*56 #new int[56]; - kn = [0]*32 #new int[32]; - - for j in xrange(56): - l = pc1[j] - m = l & 07 - pc1m[j] = ((keyBlock[l >> 3] & bytebit[m]) != 0) - for i in xrange(16): - if encrypting: - m = i << 1 - else: - m = (15-i) << 1 - n = m + 1 - kn[m] = kn[n] = 0 - for j in xrange(28): - l = j + totrot[i] - if l < 28: - pcr[j] = pc1m[l] - else: - pcr[j] = pc1m[l - 28] - for j in xrange(28, 56): - l = j + totrot[i] - if l < 56: - pcr[j] = pc1m[l] - else: - pcr[j] = pc1m[l - 28] - for j in xrange(24): - if pcr[pc2[j]] != 0: - kn[m] |= bigbyte[j] - if pcr[pc2[j+24]] != 0: - kn[n] |= bigbyte[j] - return self.cookey(kn) - - def cookey(self, raw): - #~ int raw0, raw1; - #~ int rawi, KnLi; - #~ int i; - KnL = [0]*32 - - rawi = 0 - KnLi = 0 - for i in xrange(16): - raw0 = raw[rawi] - rawi += 1 - raw1 = raw[rawi] - rawi += 1 - KnL[KnLi] = (raw0 & 0x00fc0000L) << 6 - KnL[KnLi] |= (raw0 & 0x00000fc0L) << 10 - KnL[KnLi] |= (raw1 & 0x00fc0000L) >> 10 - KnL[KnLi] |= (raw1 & 0x00000fc0L) >> 6 - KnLi += 1 - KnL[KnLi] = (raw0 & 0x0003f000L) << 12 - KnL[KnLi] |= (raw0 & 0x0000003fL) << 16 - KnL[KnLi] |= (raw1 & 0x0003f000L) >> 4 - KnL[KnLi] |= (raw1 & 0x0000003fL) - KnLi += 1 - return KnL - - # Block encryption routines. - - #/ Encrypt a block of eight bytes. - def encrypt(self, clearText): - if len(clearText) % 8 != 0: - raise TypeError, "length must be multiple of block size" - result = [] - for base in xrange(0, len(clearText), 8): - result.append(struct.pack( - ">LL", *self.des(struct.unpack(">LL", clearText[base:base+8]), - self.encryptKeys))) - return ''.join(result) - - #/ Decrypt a block of eight bytes. - def decrypt(self, cipherText): - if len(cipherText) % 8 != 0: - raise TypeError, "length must be multiple of block size" - result = [] - for base in xrange(0, len(cipherText), 8): - result.append(struct.pack( - ">LL", *self.des(struct.unpack(">LL", cipherText[base:base+8]), - self.decryptKeys))) - return ''.join(result) - - # The DES function. - def des(self, (leftt, right), keys): - #~ int fval, work, right, leftt; - #~ int round - keysi = 0 - - work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL - right ^= work - leftt ^= (work << 4) & 0xffffffffL - - work = ((leftt >> 16) ^ right) & 0x0000ffffL - right ^= work - leftt ^= (work << 16) & 0xffffffffL - - work = ((right >> 2) ^ leftt) & 0x33333333L - leftt ^= work - right ^= (work << 2) & 0xffffffffL - - work = ((right >> 8) ^ leftt) & 0x00ff00ffL - leftt ^= work - right ^= (work << 8) & 0xffffffffL - right = ((right << 1) | ((right >> 31) & 1)) & 0xffffffffL - - work = (leftt ^ right) & 0xaaaaaaaaL - leftt ^= work - right ^= work - leftt = ((leftt << 1) | ((leftt >> 31) & 1)) & 0xffffffffL - - for round in xrange(8): - work = ((right << 28) | (right >> 4)) & 0xffffffffL - work ^= keys[keysi] - keysi += 1 - fval = SP7[ work & 0x0000003fL ] - fval |= SP5[(work >> 8) & 0x0000003fL ] - fval |= SP3[(work >> 16) & 0x0000003fL ] - fval |= SP1[(work >> 24) & 0x0000003fL ] - work = right ^ keys[keysi] - keysi += 1 - fval |= SP8[ work & 0x0000003fL ] - fval |= SP6[(work >> 8) & 0x0000003fL ] - fval |= SP4[(work >> 16) & 0x0000003fL ] - fval |= SP2[(work >> 24) & 0x0000003fL ] - leftt ^= fval - work = ((leftt << 28) | (leftt >> 4)) & 0xffffffffL - work ^= keys[keysi] - keysi += 1 - fval = SP7[ work & 0x0000003fL ] - fval |= SP5[(work >> 8) & 0x0000003fL ] - fval |= SP3[(work >> 16) & 0x0000003fL ] - fval |= SP1[(work >> 24) & 0x0000003fL ] - work = leftt ^ keys[keysi] - keysi += 1 - fval |= SP8[ work & 0x0000003fL ] - fval |= SP6[(work >> 8) & 0x0000003fL ] - fval |= SP4[(work >> 16) & 0x0000003fL ] - fval |= SP2[(work >> 24) & 0x0000003fL ] - right ^= fval - - right = ((right << 31) | (right >> 1)) & 0xffffffffL - work = (leftt ^ right) & 0xaaaaaaaaL - leftt ^= work - right ^= work - leftt = ((leftt << 31) | (leftt >> 1)) & 0xffffffffL - work = ((leftt >> 8) ^ right) & 0x00ff00ffL - right ^= work - leftt ^= (work << 8) & 0xffffffffL - work = ((leftt >> 2) ^ right) & 0x33333333L - right ^= work - leftt ^= (work << 2) & 0xffffffffL - work = ((right >> 16) ^ leftt) & 0x0000ffffL - leftt ^= work - right ^= (work << 16) & 0xffffffffL - work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL - leftt ^= work - right ^= (work << 4) & 0xffffffffL - return right, leftt - -# Tables, permutations, S-boxes, etc. - -bytebit = [0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01] - -bigbyte = [ - 0x800000, 0x400000, 0x200000, 0x100000, - 0x080000, 0x040000, 0x020000, 0x010000, - 0x008000, 0x004000, 0x002000, 0x001000, - 0x000800, 0x000400, 0x000200, 0x000100, - 0x000080, 0x000040, 0x000020, 0x000010, - 0x000008, 0x000004, 0x000002, 0x000001 -] - -pc1 = [ - 56, 48, 40, 32, 24, 16, 8, - 0, 57, 49, 41, 33, 25, 17, - 9, 1, 58, 50, 42, 34, 26, - 18, 10, 2, 59, 51, 43, 35, - 62, 54, 46, 38, 30, 22, 14, - 6, 61, 53, 45, 37, 29, 21, - 13, 5, 60, 52, 44, 36, 28, - 20, 12, 4, 27, 19, 11, 3 -] - -totrot = [ - 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 -] - -pc2 = [ - 13, 16, 10, 23, 0, 4, - 2, 27, 14, 5, 20, 9, - 22, 18, 11, 3 , 25, 7, - 15, 6, 26, 19, 12, 1, - 40, 51, 30, 36, 46, 54, - 29, 39, 50, 44, 32, 47, - 43, 48, 38, 55, 33, 52, - 45, 41, 49, 35, 28, 31, -] - -# Microsoft's modified S-boxes for LIT file encryption -SP1 = [ -0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L, -0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L, -0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L, -0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L, -0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L, -0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L, -0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L, -0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L, -0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L, -0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L, -0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L, -0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L, -0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L, -0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L, -0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L, -0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L -] -SP2 = [ -0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L, -0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L, -0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L, -0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L, -0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L, -0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L, -0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L, -0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L, -0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L, -0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L, -0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L, -0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L, -0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L, -0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L, -0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L, -0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L -] -SP3 = [ -0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L, -0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L, -0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L, -0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L, -0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L, -0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L, -0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L, -0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L, -0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L, -0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L, -0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L, -0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L, -0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L, -0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L, -0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L, -0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L -] -SP4 = [ -0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L, -0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L, -0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L, -0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L, -0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L, -0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L, -0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L, -0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L, -0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L, -0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L, -0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L, -0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L, -0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L, -0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L, -0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L, -0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L -] -SP5 = [ -0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L, -0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L, -0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L, -0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L, -0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L, -0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L, -0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L, -0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L, -0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L, -0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L, -0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L, -0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L, -0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L, -0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L, -0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L, -0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L -] -SP6 = [ -0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L, -0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L, -0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L, -0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L, -0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L, -0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L, -0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L, -0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L, -0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L, -0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L, -0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L, -0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L, -0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L, -0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L, -0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L, -0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L, -] -SP7 = [ -0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L, -0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L, -0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L, -0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L, -0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L, -0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L, -0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L, -0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L, -0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L, -0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L, -0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L, -0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L, -0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L, -0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L, -0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L, -0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L, -] -SP8 = [ -0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L, -0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L, -0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L, -0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L, -0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L, -0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L, -0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L, -0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L, -0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L, -0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L, -0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L, -0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L, -0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L, -0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L, -0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L, -0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L, -] - -def new(key): - return DesCipher(key) - -block_size = 8 -key_size = 8 - -try: - import psyco - psyco.bind(DesCipher.deskey) - psyco.bind(DesCipher.cookey) - psyco.bind(DesCipher.des) -except ImportError: - pass - -#test only: -if __name__ == '__main__': - des = DesCipher("\x01\x23\x45\x67\x89\xab\xcd\xef") - print ''.join( - "%02x" % ord(x) for x in des.encrypt("Now is t")) -