www.gusucode.com > 一些VC++加密算法+实例源码源码程序 > 一些VC++加密算法+实例源码/优化后的加密注册模块/优化后的加密注册模块/inventory(optimized)/Encry.cpp
//**************************************************** //* Arko Information Technology Co.,Ltd. * //**************************************************** //*encry.cpp Version: 1.3 * //*Copyright: This is a part of the Arko Source Code * //**************************************************** //*Programmmer: YL * //*Date: 2000-11-19 * //**************************************************** /*#################################################### this is main encryption functions including DES arithmetic and MD5 arithmetic ####################################################*/ #include "stdafx.h" #include "Encry.h" #include "module.h" /*des*/ #include <stdlib.h> #include <fcntl.h> #include <string.h> #include <mbstring.h> #include <time.h> /*md5*/ #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <math.h> //begin fo globle functions /* Caller must ASCII encode the encrypted keys if required. */ /* If type is zero, simply print the task string, otherwise convert the type to a string and print task and type. */ #ifndef USE_ANSI /* Secure memset routine */ #ifndef USEASM void R_memset(POINTER output,int value,unsigned int len) //POINTER output; /* output block */ //int value; /* value */ //unsigned int len; /* length of block */ { if(len != 0) { do { *output++ = (unsigned char)value; } while(--len != 0); } } /* Secure memcpy routine */ void R_memcpy(POINTER output,POINTER input,unsigned int len) //POINTER output; /* output block */ //POINTER input; /* input block */ //unsigned int len; /* length of blocks */ { if (len != 0) { do { *output++ = *input++; }while (--len != 0); } } /* Secure memcmp routine */ int R_memcmp(POINTER Block1,POINTER Block2,unsigned int len) //POINTER Block1; /* first block */ //POINTER Block2; /* second block */ //unsigned int len; /* length of blocks */ { if(len != 0) { /* little trick in declaring vars */ register const unsigned char *p1 = Block1, *p2 = Block2; do { if(*p1++ != *p2++) return(*--p1 - *--p2); }while(--len != 0); } return(0); } #endif /* USEASM */ #endif /* USE_ANSI */ void scrunch (UINT4 *into, unsigned char *outof) //UINT4 *into; //unsigned char *outof; { *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); } void unscrunch(unsigned char *into, UINT4 *outof) //unsigned char *into; //UINT4 *outof; { *into++ = (unsigned char)((*outof >> 24) & 0xffL); *into++ = (unsigned char)((*outof >> 16) & 0xffL); *into++ = (unsigned char)((*outof >> 8) & 0xffL); *into++ = (unsigned char)( *outof++ & 0xffL); *into++ = (unsigned char)((*outof >> 24) & 0xffL); *into++ = (unsigned char)((*outof >> 16) & 0xffL); *into++ = (unsigned char)((*outof >> 8) & 0xffL); *into = (unsigned char)( *outof & 0xffL); } //end of globle functions /////////////////////////////////////////////////////////////////////////////////////////////// //Here is the des core algorism /////////////////////////////////////////////////////////////////////////////////////////////// UINT2 bytebit[8] = { 0200, 0100, 040, 020, 010, 04, 02, 01 }; UINT4 bigbyte[24] = { 0x800000L, 0x400000L, 0x200000L, 0x100000L, 0x80000L, 0x40000L, 0x20000L, 0x10000L, 0x8000L, 0x4000L, 0x2000L, 0x1000L, 0x800L, 0x400L, 0x200L, 0x100L, 0x80L, 0x40L, 0x20L, 0x10L, 0x8L, 0x4L, 0x2L, 0x1L }; unsigned char totrot[16] = { 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 }; unsigned char pc1[56] = { 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 }; unsigned char pc2[48] = { 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 }; unsigned char *PADDING_OPEN[] = { (unsigned char *)"", (unsigned char *)"\01", (unsigned char *)"\02\02", (unsigned char *)"\03\03\03", (unsigned char *)"\04\04\04\04", (unsigned char *)"\05\05\05\05\05", (unsigned char *)"\06\06\06\06\06\06", (unsigned char *)"\07\07\07\07\07\07\07", (unsigned char *)"\010\010\010\010\010\010\010\010" }; #ifndef DES386 UINT4 Spbox[8][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, 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, 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, 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, 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, 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, 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, 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 }; #else /* S box tables for assembler desfunc */ unsigned long Spbox[8][64] = { 0x04041000,0x00000000,0x00040000,0x04041010, 0x04040010,0x00041010,0x00000010,0x00040000, 0x00001000,0x04041000,0x04041010,0x00001000, 0x04001010,0x04040010,0x04000000,0x00000010, 0x00001010,0x04001000,0x04001000,0x00041000, 0x00041000,0x04040000,0x04040000,0x04001010, 0x00040010,0x04000010,0x04000010,0x00040010, 0x00000000,0x00001010,0x00041010,0x04000000, 0x00040000,0x04041010,0x00000010,0x04040000, 0x04041000,0x04000000,0x04000000,0x00001000, 0x04040010,0x00040000,0x00041000,0x04000010, 0x00001000,0x00000010,0x04001010,0x00041010, 0x04041010,0x00040010,0x04040000,0x04001010, 0x04000010,0x00001010,0x00041010,0x04041000, 0x00001010,0x04001000,0x04001000,0x00000000, 0x00040010,0x00041000,0x00000000,0x04040010, 0x00420082,0x00020002,0x00020000,0x00420080, 0x00400000,0x00000080,0x00400082,0x00020082, 0x00000082,0x00420082,0x00420002,0x00000002, 0x00020002,0x00400000,0x00000080,0x00400082, 0x00420000,0x00400080,0x00020082,0x00000000, 0x00000002,0x00020000,0x00420080,0x00400002, 0x00400080,0x00000082,0x00000000,0x00420000, 0x00020080,0x00420002,0x00400002,0x00020080, 0x00000000,0x00420080,0x00400082,0x00400000, 0x00020082,0x00400002,0x00420002,0x00020000, 0x00400002,0x00020002,0x00000080,0x00420082, 0x00420080,0x00000080,0x00020000,0x00000002, 0x00020080,0x00420002,0x00400000,0x00000082, 0x00400080,0x00020082,0x00000082,0x00400080, 0x00420000,0x00000000,0x00020002,0x00020080, 0x00000002,0x00400082,0x00420082,0x00420000, 0x00000820,0x20080800,0x00000000,0x20080020, 0x20000800,0x00000000,0x00080820,0x20000800, 0x00080020,0x20000020,0x20000020,0x00080000, 0x20080820,0x00080020,0x20080000,0x00000820, 0x20000000,0x00000020,0x20080800,0x00000800, 0x00080800,0x20080000,0x20080020,0x00080820, 0x20000820,0x00080800,0x00080000,0x20000820, 0x00000020,0x20080820,0x00000800,0x20000000, 0x20080800,0x20000000,0x00080020,0x00000820, 0x00080000,0x20080800,0x20000800,0x00000000, 0x00000800,0x00080020,0x20080820,0x20000800, 0x20000020,0x00000800,0x00000000,0x20080020, 0x20000820,0x00080000,0x20000000,0x20080820, 0x00000020,0x00080820,0x00080800,0x20000020, 0x20080000,0x20000820,0x00000820,0x20080000, 0x00080820,0x00000020,0x20080020,0x00080800, 0x02008004,0x00008204,0x00008204,0x00000200, 0x02008200,0x02000204,0x02000004,0x00008004, 0x00000000,0x02008000,0x02008000,0x02008204, 0x00000204,0x00000000,0x02000200,0x02000004, 0x00000004,0x00008000,0x02000000,0x02008004, 0x00000200,0x02000000,0x00008004,0x00008200, 0x02000204,0x00000004,0x00008200,0x02000200, 0x00008000,0x02008200,0x02008204,0x00000204, 0x02000200,0x02000004,0x02008000,0x02008204, 0x00000204,0x00000000,0x00000000,0x02008000, 0x00008200,0x02000200,0x02000204,0x00000004, 0x02008004,0x00008204,0x00008204,0x00000200, 0x02008204,0x00000204,0x00000004,0x00008000, 0x02000004,0x00008004,0x02008200,0x02000204, 0x00008004,0x00008200,0x02000000,0x02008004, 0x00000200,0x02000000,0x00008000,0x02008200, 0x00000400,0x08200400,0x08200000,0x08000401, 0x00200000,0x00000400,0x00000001,0x08200000, 0x00200401,0x00200000,0x08000400,0x00200401, 0x08000401,0x08200001,0x00200400,0x00000001, 0x08000000,0x00200001,0x00200001,0x00000000, 0x00000401,0x08200401,0x08200401,0x08000400, 0x08200001,0x00000401,0x00000000,0x08000001, 0x08200400,0x08000000,0x08000001,0x00200400, 0x00200000,0x08000401,0x00000400,0x08000000, 0x00000001,0x08200000,0x08000401,0x00200401, 0x08000400,0x00000001,0x08200001,0x08200400, 0x00200401,0x00000400,0x08000000,0x08200001, 0x08200401,0x00200400,0x08000001,0x08200401, 0x08200000,0x00000000,0x00200001,0x08000001, 0x00200400,0x08000400,0x00000401,0x00200000, 0x00000000,0x00200001,0x08200400,0x00000401, 0x80000040,0x81000000,0x00010000,0x81010040, 0x81000000,0x00000040,0x81010040,0x01000000, 0x80010000,0x01010040,0x01000000,0x80000040, 0x01000040,0x80010000,0x80000000,0x00010040, 0x00000000,0x01000040,0x80010040,0x00010000, 0x01010000,0x80010040,0x00000040,0x81000040, 0x81000040,0x00000000,0x01010040,0x81010000, 0x00010040,0x01010000,0x81010000,0x80000000, 0x80010000,0x00000040,0x81000040,0x01010000, 0x81010040,0x01000000,0x00010040,0x80000040, 0x01000000,0x80010000,0x80000000,0x00010040, 0x80000040,0x81010040,0x01010000,0x81000000, 0x01010040,0x81010000,0x00000000,0x81000040, 0x00000040,0x00010000,0x81000000,0x01010040, 0x00010000,0x01000040,0x80010040,0x00000000, 0x81010000,0x80000000,0x01000040,0x80010040, 0x00800000,0x10800008,0x10002008,0x00000000, 0x00002000,0x10002008,0x00802008,0x10802000, 0x10802008,0x00800000,0x00000000,0x10000008, 0x00000008,0x10000000,0x10800008,0x00002008, 0x10002000,0x00802008,0x00800008,0x10002000, 0x10000008,0x10800000,0x10802000,0x00800008, 0x10800000,0x00002000,0x00002008,0x10802008, 0x00802000,0x00000008,0x10000000,0x00802000, 0x10000000,0x00802000,0x00800000,0x10002008, 0x10002008,0x10800008,0x10800008,0x00000008, 0x00800008,0x10000000,0x10002000,0x00800000, 0x10802000,0x00002008,0x00802008,0x10802000, 0x00002008,0x10000008,0x10802008,0x10800000, 0x00802000,0x00000000,0x00000008,0x10802008, 0x00000000,0x00802008,0x10800000,0x00002000, 0x10000008,0x10002000,0x00002000,0x00800008, 0x40004100,0x00004000,0x00100000,0x40104100, 0x40000000,0x40004100,0x00000100,0x40000000, 0x00100100,0x40100000,0x40104100,0x00104000, 0x40104000,0x00104100,0x00004000,0x00000100, 0x40100000,0x40000100,0x40004000,0x00004100, 0x00104000,0x00100100,0x40100100,0x40104000, 0x00004100,0x00000000,0x00000000,0x40100100, 0x40000100,0x40004000,0x00104100,0x00100000, 0x00104100,0x00100000,0x40104000,0x00004000, 0x00000100,0x40100100,0x00004000,0x00104100, 0x40004000,0x00000100,0x40000100,0x40100000, 0x40100100,0x40000000,0x00100000,0x40004100, 0x00000000,0x40104100,0x00100100,0x40000100, 0x40100000,0x40004000,0x40004100,0x00000000, 0x40104100,0x00104000,0x00104000,0x00004100, 0x00004100,0x00100100,0x40000000,0x40104000, }; #endif void cookey(UINT4 *subkeys, UINT4 *kn,int encrypt) //UINT4 *subkeys; //UINT4 *kn; //int encrypt; { UINT4 *cooked, *raw0, *raw1; int increment; unsigned int i; raw1 = kn; cooked = encrypt ? subkeys : &subkeys[30]; increment = encrypt ? 1 : -3; for (i = 0; i < 16; i++, raw1++) { raw0 = raw1++; *cooked = (*raw0 & 0x00fc0000L) << 6; *cooked |= (*raw0 & 0x00000fc0L) << 10; *cooked |= (*raw1 & 0x00fc0000L) >> 10; *cooked++ |= (*raw1 & 0x00000fc0L) >> 6; *cooked = (*raw0 & 0x0003f000L) << 12; *cooked |= (*raw0 & 0x0000003fL) << 16; *cooked |= (*raw1 & 0x0003f000L) >> 4; *cooked |= (*raw1 & 0x0000003fL); cooked += increment; } } /* Compute DES Subkeys */ void deskey(UINT4 subkeys[32], unsigned char *key,int encrypt) //UINT4 subkeys[32]; //unsigned char key[8]; //int encrypt; { UINT4 kn[32]; int i, j, l, m, n; unsigned char pc1m[56], pcr[56]; for(j = 0; j < 56; j++) { l = pc1[j]; m = l & 07; pc1m[j] = (unsigned char)((key[l >> 3] & bytebit[m]) ? 1 : 0); } for(i = 0; i < 16; i++) { 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(subkeys, kn, encrypt); #ifdef DES386 for(i=0;i < 32;i++) subkeys[i] <<= 2; #endif R_memset((POINTER)pc1m, 0, sizeof(pc1m)); R_memset((POINTER)pcr, 0, sizeof(pcr)); R_memset((POINTER)kn, 0, sizeof(kn)); } #ifndef DES386 /* ignore C version in favor of 386 ONLY desfunc */ #define Desf(l,r,key) \ {\ work = ((r >> 4) | (r << 28)) ^ *key;\ l ^= Spbox[6][work & 0x3f];\ l ^= Spbox[4][(work >> 8) & 0x3f];\ l ^= Spbox[2][(work >> 16) & 0x3f];\ l ^= Spbox[0][(work >> 24) & 0x3f];\ work = r ^ *(key+1);\ l ^= Spbox[7][work & 0x3f];\ l ^= Spbox[5][(work >> 8) & 0x3f];\ l ^= Spbox[3][(work >> 16) & 0x3f];\ l ^= Spbox[1][(work >> 24) & 0x3f];\ } /* This desfunc code is marginally quicker than that uses in RSAREF(tm) */ void desfunc(UINT4 *block,UINT4 *ks) //UINT4 *block; /* Data block */ //UINT4 *ks; /* Key schedule */ { unsigned long left,right,work; left = block[0]; right = block[1]; work = ((left >> 4) ^ right) & 0x0f0f0f0f; right ^= work; left ^= work << 4; work = ((left >> 16) ^ right) & 0xffff; right ^= work; left ^= work << 16; work = ((right >> 2) ^ left) & 0x33333333; left ^= work; right ^= (work << 2); work = ((right >> 8) ^ left) & 0xff00ff; left ^= work; right ^= (work << 8); right = (right << 1) | (right >> 31); work = (left ^ right) & 0xaaaaaaaa; left ^= work; right ^= work; left = (left << 1) | (left >> 31); /* Now do the 16 rounds */ Desf(left,right,&ks[0]); Desf(right,left,&ks[2]); Desf(left,right,&ks[4]); Desf(right,left,&ks[6]); Desf(left,right,&ks[8]); Desf(right,left,&ks[10]); Desf(left,right,&ks[12]); Desf(right,left,&ks[14]); Desf(left,right,&ks[16]); Desf(right,left,&ks[18]); Desf(left,right,&ks[20]); Desf(right,left,&ks[22]); Desf(left,right,&ks[24]); Desf(right,left,&ks[26]); Desf(left,right,&ks[28]); Desf(right,left,&ks[30]); right = (right << 31) | (right >> 1); work = (left ^ right) & 0xaaaaaaaa; left ^= work; right ^= work; left = (left >> 1) | (left << 31); work = ((left >> 8) ^ right) & 0xff00ff; right ^= work; left ^= work << 8; work = ((left >> 2) ^ right) & 0x33333333; right ^= work; left ^= work << 2; work = ((right >> 16) ^ left) & 0xffff; left ^= work; right ^= work << 16; work = ((right >> 4) ^ left) & 0x0f0f0f0f; left ^= work; right ^= work << 4; *block++ = right; *block = left; } #endif /* DES386 endif */ /////////////////////////////////////////////////////////////////////////////////////////////// //Here is the end of Des Core Algorithm /////////////////////////////////////////////////////////////////////////////////////////////// //begin fo md5 block /* Constants for MD5Transform routine. */ #define S11 7 #define S12 12 #define S13 17 #define S14 22 #define S21 5 #define S22 9 #define S23 14 #define S24 20 #define S31 4 #define S32 11 #define S33 16 #define S34 23 #define S41 6 #define S42 10 #define S43 15 #define S44 21 /* ROTATE_LEFT rotates x left n bits. */ #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) unsigned char PADDING[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* F, G, H and I are basic MD5 functions. */ #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | (~z))) /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. Rotation is separate from addition to prevent recomputation. */ #define FF(a, b, c, d, x, s, ac) { \ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define GG(a, b, c, d, x, s, ac) { \ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define HH(a, b, c, d, x, s, ac) { \ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define II(a, b, c, d, x, s, ac) { \ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } /* MD5 initialization. Begins an MD5 operation, writing a new context. */ void MD5Init (MD5_CTX *context) //MD5_CTX *context; /* context */ { context->count[0] = context->count[1] = 0; /* Load magic initialization constants. */ context->state[0] = 0x67452301; context->state[1] = 0xefcdab89; context->state[2] = 0x98badcfe; context->state[3] = 0x10325476; } /* Encodes input (UINT4) into output (unsigned char). Assumes len is a multiple of 4. */ void Encode(unsigned char *output, UINT4 *input,unsigned int len) //unsigned char *output; //UINT4 *input; //unsigned int len; { unsigned int i, j; for(i = 0, j = 0; j < len; i++, j += 4) { output[j] = (unsigned char)(input[i] & 0xff); output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); } } void Decode(UINT4 *output, unsigned char *input,unsigned int len) //UINT4 *output; //unsigned char *input; //unsigned int len; { unsigned int i, j; for(i = 0, j = 0; j < len; i++, j += 4) output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); } void MD5Transform (UINT4 state[4], unsigned char block[64]) //UINT4 state[4]; //unsigned char block[64]; { UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; Decode(x, block, 64); /* Round 1 */ FF(a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ FF(d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ FF(c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ FF(b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ FF(a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ FF(d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ FF(c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ FF(b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ FF(a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ FF(d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ /* Round 2 */ GG(a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ GG(d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ GG(b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ GG(a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */ GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ GG(b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ GG(a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ GG(c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ GG(b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ GG(d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ GG(c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ /* Round 3 */ HH(a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ HH(d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ HH(a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ HH(d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ HH(c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ HH(d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ HH(c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ HH(b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ HH(a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ HH(b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ /* Round 4 */ II(a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ II(d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ II(b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ II(d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ II(b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ II(a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ II(c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ II(a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ II(c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ II(b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ state[0] += a; state[1] += b; state[2] += c; state[3] += d; /* Zeroize sensitive information. */ R_memset((POINTER)x, 0, sizeof(x)); } /* MD5 block update operation. Continues an MD5 message-digest operation, processing another message block, and updating the context. */ void MD5Update(MD5_CTX *context, unsigned char *input,unsigned int inputLen) //MD5_CTX *context; /* context */ //unsigned char *input; /* input block */ //unsigned int inputLen; /* length of input block */ { unsigned int i, index, partLen; /* Compute number of bytes mod 64 */ index = (unsigned int)((context->count[0] >> 3) & 0x3F); /* Update number of bits */ if((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3)) context->count[1]++; context->count[1] += ((UINT4)inputLen >> 29); partLen = 64 - index; /* Transform as many times as possible. */ if(inputLen >= partLen) { R_memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen); MD5Transform(context->state, context->buffer); for(i = partLen; i + 63 < inputLen; i += 64) MD5Transform(context->state, &input[i]); index = 0; } else i = 0; /* Buffer remaining input */ R_memcpy((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i); } /* MD5 finalization. Ends an MD5 message-digest operation, writing the the message digest and zeroizing the context. */ void MD5Final (unsigned char digest[16],MD5_CTX *context) //unsigned char digest[16]; /* message digest */ //MD5_CTX *context; /* context */ { unsigned char bits[8]; unsigned int index, padLen; /* Save number of bits */ Encode(bits, context->count, 8); /* Pad out to 56 mod 64. */ index = (unsigned int)((context->count[0] >> 3) & 0x3f); padLen = (index < 56) ? (56 - index) : (120 - index); MD5Update(context, PADDING, padLen); /* Append length (before padding) */ MD5Update(context, bits, 8); /* Store state in digest */ Encode(digest, context->state, 16); /* Zeroize sensitive information. */ R_memset((POINTER)context, 0, sizeof(*context)); } //end of md5 block //begin of random functions int R_RandomUpdate(R_RANDOM_STRUCT *random, unsigned char *block,unsigned int len) //R_RANDOM_STRUCT *random; /* random structure */ //unsigned char *block; /* block of values to mix in */ //unsigned int len; /* length of block */ { MD5_CTX context; BYTE digest[16]; unsigned int i, j; MD5Init(&context); MD5Update(&context, block, len); MD5Final(digest, &context); /* add digest to state */ for(j = 0, i = 16; i > 0; i--) { j += random->state[i-1] + digest[i-1]; random->state[i-1] = (BYTE)j; j >>= 8; } if(random->bytesNeeded < len) random->bytesNeeded = 0; else random->bytesNeeded -= len; /* Clear sensitive information. */ R_memset((POINTER)digest, 0, sizeof (digest)); j = 0; return(R_IDOK); } /* Get the number of seed byte still required by the object */ int R_GetRandomBytesNeeded(unsigned int *bytesNeeded, R_RANDOM_STRUCT *random) //unsigned int *bytesNeeded; /* number of mix-in bytes needed */ //R_RANDOM_STRUCT *random; /* random structure */ { *bytesNeeded = random->bytesNeeded; return(R_IDOK); } void R_RandomCreate(R_RANDOM_STRUCT *random) //R_RANDOM_STRUCT *random; /* random structure */ { // unsigned int bytes; clock_t cnow; time_t t; struct tm *gmt; /* clear and setup object for seeding */ R_memset((POINTER)random->state, 0, sizeof(random->state)); random->outputAvailable = 0; random->bytesNeeded = RANDOM_BYTES_RQINT; /* using internal value */ /* Add data to random object */ while(random->bytesNeeded) { t = time(NULL); /* use for seed data */ gmt = gmtime(&t); cnow = clock(); R_RandomUpdate(random, (POINTER)gmt, sizeof(struct tm)); R_RandomUpdate(random, (POINTER)&cnow, sizeof(clock_t)); } /* Clean Up time data */ R_memset((POINTER)gmt, 0, sizeof(struct tm)); cnow = 0; t = 0; } int R_GenerateBytes(unsigned char *block,unsigned int len, R_RANDOM_STRUCT *random) //unsigned char *block; /* block */ //unsigned int len; /* length of block */ //R_RANDOM_STRUCT *random; /* random structure */ { MD5_CTX context; unsigned int avail, i; if(random->bytesNeeded) return(RE_NEED_RANDOM); avail = random->outputAvailable; while(avail < len) { R_memcpy((POINTER)block, (POINTER)&random->output[16-avail], avail); len -= avail; block += avail; /* generate new output */ MD5Init(&context); MD5Update(&context, random->state, 16); MD5Final(random->output, &context); avail = 16; /* increment state */ for(i = 16; i > 0; i--) if(random->state[i-1]++) break; } R_memcpy((POINTER)block, (POINTER)&random->output[16-avail], len); random->outputAvailable = avail - len; return(R_IDOK); } //end of random functions /////////////////////////////////////////////////////////////////////////////////////////////// //Here is the begin of four des encrypt /////////////////////////////////////////////////////////////////////////////////////////////// /* Initialize context. Caller must zeroize the context when finished. */ void DES_CBCInit(DES_CBC_CTX *context, unsigned char *key, unsigned char *iv,int encrypt) //DES_CBC_CTX *context; /* context */ //unsigned char *key; /* key */ //unsigned char *iv; /* initializing vector */ //int encrypt; /* encrypt flag (1 = encrypt, 0 = decrypt) */ { /* Save encrypt flag to context. */ context->encrypt = encrypt; /* Pack initializing vector into context. */ scrunch(context->iv, iv); scrunch(context->originalIV, iv); /* Precompute key schedule */ deskey(context->subkeys, key, encrypt); } /* DES-CBC block update operation. Continues a DES-CBC encryption operation, processing eight-byte message blocks, and updating the context. This requires len to be a multiple of 8. */ int DES_CBCUpdate(DES_CBC_CTX *context, unsigned char *output, unsigned char *input, unsigned int len) //DES_CBC_CTX *context; /* context */ //unsigned char *output; /* output block */ //unsigned char *input; /* input block */ //unsigned int len; /* length of input and output blocks */ { UINT4 inputBlock[2], work[2]; unsigned int i; if(len % 8) /* block size check */ return(RE_LEN); for(i = 0; i < len/8; i++) { scrunch(inputBlock, &input[8*i]); /* Chain if encrypting. */ if(context->encrypt == 0) { *work = *inputBlock; *(work+1) = *(inputBlock+1); }else{ *work = *inputBlock ^ *context->iv; *(work+1) = *(inputBlock+1) ^ *(context->iv+1); } desfunc(work, context->subkeys); /* Chain if decrypting, then update IV. */ if(context->encrypt == 0) { *work ^= *context->iv; *(work+1) ^= *(context->iv+1); *context->iv = *inputBlock; *(context->iv+1) = *(inputBlock+1); }else{ *context->iv = *work; *(context->iv+1) = *(work+1); } unscrunch (&output[8*i], work); } /* Clear sensitive information. */ R_memset((POINTER)inputBlock, 0, sizeof(inputBlock)); R_memset((POINTER)work, 0, sizeof(work)); return(R_IDOK); } void DES_CBCRestart(DES_CBC_CTX *context) //DES_CBC_CTX *context; /* context */ { /* Restore the original IV */ *context->iv = *context->originalIV; *(context->iv+1) = *(context->originalIV+1); } /* Initialize context. Caller should clear the context when finished. The key has the DES key, input whitener and output whitener concatenated. This is the RSADSI special DES implementation. */ /*void DESX_CBCInit(DESX_CBC_CTX *context, unsigned char *key, unsigned char *iv, int encrypt) //DESX_CBC_CTX *context; /* context */ //unsigned char *key; /* DES key and whiteners */ //unsigned char *iv; /* DES initializing vector */ //int encrypt; /* encrypt flag (1 = encrypt, 0 = decrypt) */ /* { context->encrypt = encrypt; scrunch(context->iv, iv); scrunch(context->inputWhitener, key + 8); scrunch(context->outputWhitener, key + 16); scrunch(context->originalIV, iv); deskey (context->subkeys, key, encrypt); } */ /* DESX-CBC block update operation. Continues a DESX-CBC encryption operation, processing eight-byte message blocks, and updating the context. This is the RSADSI special DES implementation. Requires len to a multiple of 8. */ //int DESX_CBCUpdate (DESX_CBC_CTX *context, unsigned char *output, unsigned char *input, // unsigned int len) //DESX_CBC_CTX *context; /* context */ //unsigned char *output; /* output block */ //unsigned char *input; /* input block */ //unsigned int len; /* length of input and output blocks */ /* { UINT4 inputBlock[2], work[2]; unsigned int i; if(len % 8) return(RE_LEN); for(i = 0; i < len/8; i++) { scrunch(inputBlock, &input[8*i]); if(context->encrypt == 0) { *work = *inputBlock ^ *context->outputWhitener; *(work+1) = *(inputBlock+1) ^ *(context->outputWhitener+1); }else{ *work = *inputBlock ^ *context->iv ^ *context->inputWhitener; *(work+1) = *(inputBlock+1) ^ *(context->iv+1) ^ *(context->inputWhitener+1); } desfunc(work, context->subkeys); */ /* Xor with whitener, chain if decrypting, then update IV. */ /* if(context->encrypt == 0) { *work ^= *context->iv ^ *context->inputWhitener; *(work+1) ^= *(context->iv+1) ^ *(context->inputWhitener+1); *(context->iv) = *inputBlock; *(context->iv+1) = *(inputBlock+1); }else{ *work ^= *context->outputWhitener; *(work+1) ^= *(context->outputWhitener+1); *context->iv = *work; *(context->iv+1) = *(work+1); } unscrunch(&output[8*i], work); } R_memset((POINTER)inputBlock, 0, sizeof(inputBlock)); R_memset((POINTER)work, 0, sizeof(work)); return(R_IDOK); } */ /*void DESX_CBCRestart(DESX_CBC_CTX *context) //DESX_CBC_CTX *context; /* context */ /*{ *context->iv = *context->originalIV; *(context->iv+1) = *(context->originalIV+1); } */ /* Initialize context. Caller must zeroize the context when finished. */ /*void DES3_CBCInit(DES3_CBC_CTX *context, unsigned char *key, unsigned char *iv,int encrypt) //DES3_CBC_CTX *context; /* context */ //unsigned char *key; /* key */ //unsigned char *iv; /* initializing vector */ //int encrypt; /* encrypt flag (1 = encrypt, 0 = decrypt) */ /*{ /* Copy encrypt flag to context. */ // context->encrypt = encrypt; /* Pack initializing vector into context. */ // scrunch(context->iv, iv); /* Save the IV for use in Restart */ // scrunch(context->originalIV, iv); /* Precompute key schedules. */ // deskey(context->subkeys[0], encrypt ? key : &key[16], encrypt); // deskey(context->subkeys[1], &key[8], !encrypt); // deskey(context->subkeys[2], encrypt ? &key[16] : key, encrypt); //} //int DES3_CBCUpdate(DES3_CBC_CTX *context,unsigned char *output, unsigned char *input, // unsigned int len) //DES3_CBC_CTX *context; /* context */ //unsigned char *output; /* output block */ //unsigned char *input; /* input block */ //unsigned int len; /* length of input and output blocks */ //{ // UINT4 inputBlock[2], work[2]; // unsigned int i; // // if(len % 8) /* length check */ // return(RE_LEN); // for(i = 0; i < len/8; i++) { // scrunch(inputBlock, &input[8*i]); /* Chain if encrypting. */ // if(context->encrypt == 0) { // *work = *inputBlock; // *(work+1) = *(inputBlock+1); // } // else { /* *work = *inputBlock ^ *context->iv; *(work+1) = *(inputBlock+1) ^ *(context->iv+1); } desfunc(work, context->subkeys[0]); desfunc(work, context->subkeys[1]); desfunc(work, context->subkeys[2]); /* Chain if decrypting, then update IV. */ /* if(context->encrypt == 0) { *work ^= *context->iv; *(work+1) ^= *(context->iv+1); *context->iv = *inputBlock; *(context->iv+1) = *(inputBlock+1); } else { *context->iv = *work; *(context->iv+1) = *(work+1); } unscrunch(&output[8*i], work); } R_memset((POINTER)inputBlock, 0, sizeof(inputBlock)); R_memset((POINTER)work, 0, sizeof(work)); return (0); } void DES3_CBCRestart (DES3_CBC_CTX *context) //DES3_CBC_CTX *context; /* context */ //{ /* Restore the original IV */ // *context->iv = *context->originalIV; // *(context->iv+1) = *(context->originalIV+1); //} /* Assume len is a multiple of 8.*/ void EncryptBlk(R_ENVELOPE_CTX *context, unsigned char *output, unsigned char * input,unsigned int len) //R_ENVELOPE_CTX *context; //unsigned char *output; //unsigned char *input; //unsigned int len; { // switch(context->encryptionAlgorithm) { // case EA_DES_CBC: DES_CBCUpdate (&context->cipherContext.des, output, input, len); // break; /* case EA_DESX_CBC: DESX_CBCUpdate (&context->cipherContext.desx, output, input, len); break; case EA_DES_EDE2_CBC: case EA_DES_EDE3_CBC: DES3_CBCUpdate (&context->cipherContext.des3, output, input, len); } */ } ////////////////////////////////////////////////////////////////////////////////////////////// //Here is the end of four des encrypt ////////////////////////////////////////////////////////////////////////////////////////////// //begin fo cipher functions int CipherInit(R_ENVELOPE_CTX *context,int encryptionAlgorithm, unsigned char *key, unsigned char *iv,int encrypt) //################################## //encrypt = 1 加密 encrypt = 0 解密 //################################## //R_ENVELOPE_CTX *context; //int encryptionAlgorithm; //unsigned char *key; //unsigned char *iv; //int encrypt; { // switch(encryptionAlgorithm) // { // case EA_DES_CBC: DES_CBCInit (&context->cipherContext.des, key, iv, encrypt); /* break; case EA_DESX_CBC: DESX_CBCInit (&context->cipherContext.desx, key, iv, encrypt); break; case EA_DES_EDE2_CBC: case EA_DES_EDE3_CBC: DES3_CBCInit (&context->cipherContext.des3, key, iv, encrypt); break; default: return (RE_ENCRYPTION_ALGORITHM); } */ return(R_IDOK); } void RestartCipher(R_ENVELOPE_CTX *context) //R_ENVELOPE_CTX *context; { // switch(context->encryptionAlgorithm) { // case EA_DES_CBC: DES_CBCRestart (&context->cipherContext.des); /* break; case EA_DESX_CBC: DESX_CBCRestart (&context->cipherContext.desx); break; case EA_DES_EDE2_CBC: case EA_DES_EDE3_CBC: DES3_CBCRestart (&context->cipherContext.des3); } */ } //end of cipher functions /*######################################################### ingore rsa encrypt DES keys #########################################################*/ /////////////////////////////////////////////////////////////////////////////////////////////// //Begin of rsa functions int RSAPublicEncrypt(unsigned char *output, unsigned int *outputLen, unsigned char *input, unsigned int *inputLen, R_RANDOM_STRUCT *randomStruct) //unsigned char *output; /* output block */ //unsigned int *outputLen; /* length of output block */ //unsigned char *input; /* input block */ //unsigned int inputLen; /* length of input block */ //R_RSA_PUBLIC_KEY *publicKey; /* RSA public key */ //R_RANDOM_STRUCT *randomStruct; /* random structure */ { output=input; *outputLen=*inputLen; return 0; } int RSAPrivateDecrypt(unsigned char *output, unsigned int *outputLen, unsigned char *input, unsigned int inputLen) //unsigned char *output; /* output block */ //unsigned int *outputLen; /* length of output block */ //unsigned char *input; /* input block */ //unsigned int inputLen; /* length of input block */ //R_RSA_PRIVATE_KEY *privateKey; /* RSA private key */ { output=input; *outputLen=inputLen; return 0; } /////////////////////////////////////////////////////////////////////////////////////////////// //begin of seal functions /* int R_SealInit(R_ENVELOPE_CTX *context, unsigned char **encryptedKeys, unsigned int *encryptedKeyLens, unsigned char iv[8], unsigned int publicKeyCount, int encryptionAlgorithm, R_RANDOM_STRUCT *randomStruct) */ //R_ENVELOPE_CTX *context; /* new context */ //unsigned char **encryptedKeys; /* encrypted keys */ //unsigned int *encryptedKeyLens; /* lengths of encrypted keys */ //unsigned char iv[8]; /* initialization vector */ //unsigned int publicKeyCount; /* number of public keys */ //R_RSA_PUBLIC_KEY **publicKeys; /* public keys */ //int encryptionAlgorithm; /* data encryption algorithm */ //R_RANDOM_STRUCT *randomStruct; /* random structure */ /* { int status; unsigned char key[24]; unsigned int keyLen, i,keylentmp; context->encryptionAlgorithm = encryptionAlgorithm; keyLen = (encryptionAlgorithm == EA_DES_CBC) ? 8 : 24; { if((status = R_GenerateBytes (iv, 8, randomStruct)) == 0) { // if(encryptionAlgorithm == EA_DES_EDE2_CBC) */ /* Make both E keys the same */ // R_memcpy ((POINTER)(key + 16), (POINTER)key, 8); /* if((status = CipherInit (context, encryptionAlgorithm, key, iv, 1)) == 0) { for(i = 0; i < publicKeyCount; ++i) { if(RSAPublicEncrypt(encryptedKeys[i], &keylentmp, key, &keyLen, randomStruct)) { status = RE_PUBLIC_KEY; break; } *encryptedKeyLens=keylentmp; } } if(status == 0) context->bufferLen = 0; } } */ /* Clear sensitive information. */ /* R_memset(key, 0, sizeof(key)); return(status); } */ /* partOut buffer should be at least partInLen + 7 */ int R_SealUpdate (R_ENVELOPE_CTX *context, unsigned char *partOut, unsigned int *partOutLen, unsigned char *partIn, unsigned int partInLen) //R_ENVELOPE_CTX *context; /* context */ //unsigned char *partOut; /* next encrypted data part */ //unsigned int *partOutLen; /* length of next encrypted data part */ //unsigned char *partIn; /* next data part */ //unsigned int partInLen; /* length of next data part */ { unsigned int temp; temp = 8 - context->bufferLen; if(partInLen < temp) { /* Just accumulate into buffer. */ *partOutLen = 0; R_memcpy((POINTER)(context->buffer + context->bufferLen), (POINTER)partIn, partInLen); context->bufferLen += partInLen; /* Bug Fix - 02/09/95, SK */ return(R_IDOK); } /* Fill the buffer and encrypt. */ R_memcpy((POINTER)(context->buffer + context->bufferLen), (POINTER)partIn, temp); EncryptBlk(context, partOut, context->buffer, 8); partOut += 8; *partOutLen = 8; partIn += temp; partInLen -= temp; /* Encrypt as many 8-byte blocks as possible. */ temp = 8 * (partInLen / 8); EncryptBlk(context, partOut, partIn, temp); *partOutLen += temp; partIn += temp; partInLen -= temp; /* Length now less than 8, so copy remainder to buffer for next time. */ R_memcpy((POINTER)context->buffer, partIn, context->bufferLen = partInLen); return(R_IDOK); } /* Assume partOut buffer is at least 8 bytes. */ int R_SealFinal(R_ENVELOPE_CTX *context, unsigned char *partOut, unsigned int *partOutLen) //R_ENVELOPE_CTX *context; /* context */ //unsigned char *partOut; /* last encrypted data part */ //unsigned int *partOutLen; /* length of last encrypted data part */ { unsigned int padLen; /* Pad and encrypt final block. */ padLen = 8 - context->bufferLen; /* little trick to pad the block */ R_memset((POINTER)(context->buffer + context->bufferLen), (int)padLen, padLen); EncryptBlk(context, partOut, context->buffer, 8); *partOutLen = 8; /* Restart the context. */ RestartCipher(context); context->bufferLen = 0; return(R_IDOK); } //end of seal functions //begin of read or write functions /* Read a block of up to length maxPartOutLen bytes from file, storing it in partOut and returning its length in partOutLen. Return 0 on success or 1 if error or end of file. */ /* Write block of length partOutLen to a file. Return 0 on success or 1 if error. */ int R_OpenInit(R_ENVELOPE_CTX *context,int encryptionAlgorithm, unsigned char *encryptedKey, unsigned int encryptedKeyLen,unsigned char iv[8],int flag) //R_ENVELOPE_CTX *context; /* new context */ //int encryptionAlgorithm; /* data encryption algorithm */ //unsigned char *encryptedKey; /* encrypted data encryption key */ //unsigned int encryptedKeyLen; /* length of encrypted key */ //unsigned char iv[8]; /* initialization vector */ //R_RSA_PRIVATE_KEY *privateKey; /* recipient's RSA private key */ { int status; unsigned char key[MAX_ENCRYPTED_KEY_LEN]; unsigned int keyLen; if(encryptedKeyLen > MAX_ENCRYPTED_KEY_LEN) return(RE_LEN); context->encryptionAlgorithm = encryptionAlgorithm; if(RSAPrivateDecrypt(key, &keyLen, encryptedKey, encryptedKeyLen)) { status = RE_PRIVATE_KEY; }else { if(encryptionAlgorithm == EA_DES_CBC) { if(keyLen != 8) status = RE_PRIVATE_KEY; else { if((status = CipherInit (context, encryptionAlgorithm, key, iv, flag)) == 0) context->bufferLen = 0; } }else{ if(keyLen != 24) status = RE_PRIVATE_KEY; else { if((status = CipherInit (context, encryptionAlgorithm, key, iv, flag)) == 0) context->bufferLen = 0; } } } /* Clear sensitive information. */ R_memset(key, 0, sizeof(key)); return(status); } int R_OpenUpdate(R_ENVELOPE_CTX *context, unsigned char *partOut, unsigned int *partOutLen, unsigned char *partIn, unsigned int partInLen) //R_ENVELOPE_CTX *context; /* context */ //unsigned char *partOut; /* next recovered data part */ //unsigned int *partOutLen; /* length of next recovered data part */ //unsigned char *partIn; /* next encrypted data part */ //unsigned int partInLen; /* length of next encrypted data part */ { unsigned int tempLen; tempLen = 8 - context->bufferLen; if (partInLen <= tempLen) { /* Just accumulate into buffer. */ *partOutLen = 0; R_memcpy((POINTER)(context->buffer + context->bufferLen), partIn, partInLen); context->bufferLen += partInLen; return(R_IDOK); } /* Fill the buffer and decrypt. We know that there will be more left in partIn after decrypting the buffer. */ R_memcpy((POINTER)(context->buffer + context->bufferLen), partIn, tempLen); EncryptBlk (context, partOut, context->buffer, 8); partOut += 8; *partOutLen = 8; partIn += tempLen; partInLen -= tempLen; /* Decrypt as many 8 byte blocks as possible, leaving at least one byte in partIn. */ tempLen = 8 * ((partInLen - 1) / 8); EncryptBlk (context, partOut, partIn, tempLen); partIn += tempLen; *partOutLen += tempLen; partInLen -= tempLen; /* Length is between 1 and 8, so copy into buffer. */ R_memcpy((POINTER)context->buffer, partIn, context->bufferLen = partInLen); return (R_IDOK); } /* Assume partOut buffer is at least 7 bytes. */ int R_OpenFinal(R_ENVELOPE_CTX *context, unsigned char *partOut, unsigned int *partOutLen) //R_ENVELOPE_CTX *context; /* context */ //unsigned char *partOut; /* last recovered data part */ //unsigned int *partOutLen; /* length of last recovered data part */ { int status; unsigned char lastPart[8]; unsigned int padLen; status = 0; if(context->bufferLen == 0) /* There was no input data to decrypt */ *partOutLen = 0; else { if(context->bufferLen != 8) { status = RE_KEY; }else{ /* Decrypt and strip any padding from the final block. */ EncryptBlk (context, lastPart, context->buffer, 8); padLen = lastPart[7]; if(padLen == 0 || padLen > 8) status = RE_KEY; else{ if(R_memcmp((POINTER)&lastPart[8 - padLen], PADDING_OPEN[padLen], padLen) != 0) status = RE_KEY; else R_memcpy (partOut, lastPart, *partOutLen = 8 - padLen); } /* Restart the context. */ if(status == 0) { RestartCipher(context); context->bufferLen = 0; } } } /* Clear sensitive information. */ R_memset(lastPart, 0, sizeof(lastPart)); return (status); } //end of read or write block functions /////////////////////////////////////////////////////////////////////////////////////////////// //Begin of output des functions /////////////////////////////////////////////////////////////////////////////////////////////// int DesEncrypt(unsigned char *inchar, unsigned int inlen, unsigned char *outchar, unsigned int * outlen, unsigned char keystore[8]) //by yaoliang 2000.11.14 { if ( (inlen >= *outlen) && ( *outlen != 0) ) return E_Length ; //not enough out length lstrcpy((char *)outchar,""); //by yaoliang initial output char R_ENVELOPE_CTX context; int status; unsigned char encryptedKey[MAX_ENCRYPTED_KEY_LEN], *encryptedKeys[1], iv[8], partIn[24], partOut[31]; unsigned int encryptedKeyLen, partInLen, partOutLen, AllInLen=0, AllOutLen=0,i; R_RANDOM_STRUCT *randomStruct, a; R_RandomCreate(&a); randomStruct=&a; status = 0; int encryptionAlgorithm=EA_DES_CBC; encryptedKeys[0] = encryptedKey; encryptedKeyLen = 8; for ( int k = 0 ; k < 8 ; k++ ) iv[k]=keystore[k]; if((status = R_OpenInit(&context, encryptionAlgorithm, encryptedKey, encryptedKeyLen, iv,1)) == 0) //encrypt = 1 加密 encrypt = 0 解密 // if((status = R_SealInit(&context, encryptedKeys, &encryptedKeyLen, iv,1,encryptionAlgorithm, randomStruct)) == 0) //by yaoliang { while( AllInLen < inlen ) { if (( inlen - AllInLen ) > 24 ) partInLen = 24; else partInLen = inlen - AllInLen; for (i=0;i<partInLen;i++) partIn[i]=inchar[AllInLen+i]; // _mbsnbcpy(partIn,( inchar + AllInLen ),partInLen); if ((status = R_SealUpdate(&context, partOut, &partOutLen,partIn, partInLen)) != 0) break; for (i=0;i<partOutLen;i++) outchar[i+AllOutLen]=partOut[i]; AllInLen += partInLen; AllOutLen += partOutLen; // _mbsnbcat(outchar, partOut,partOutLen); } if(!status) { if((status = R_SealFinal (&context, partOut, &partOutLen)) == 0) { for (i=0;i<partOutLen;i++) outchar[i+AllOutLen]=partOut[i]; // _mbsnbcat(outchar, partOut,partOutLen); AllOutLen += partOutLen; } // for ( int k = 0 ; k < 8 ; k++ ) keystore[k]=iv[k]; } } R_memset((POINTER)&context, 0, sizeof(context)); R_memset((POINTER)partIn, 0, sizeof(partIn)); R_memset((POINTER)iv, 0, sizeof(iv)); R_memset((POINTER)partOut, 0, sizeof(partOut)); *outlen = AllOutLen; if (status) return E_Error; else return 0; } /*extern "C" _declspec(dllexport)*/ int DesDecrypt(unsigned char *inchar, unsigned int inlen, unsigned char *outchar, unsigned int * outlen, unsigned char keystore[8]) //by yaoliang 2000.11.14 { if ( (inlen - 8 >= *outlen) && ( *outlen != 0) ) return E_Length ; //not enough out length lstrcpy((char *)outchar,""); R_ENVELOPE_CTX context; int status; unsigned char encryptedKey[MAX_ENCRYPTED_KEY_LEN], iv[8], partIn[24], partOut[31]; unsigned int encryptedKeyLen, partInLen, partOutLen, AllInLen=0, AllOutLen=0,i; status = 0; int encryptionAlgorithm=EA_DES_CBC; encryptedKeyLen = 8 ; for ( int k = 0 ; k < 8 ; k++ ) iv[k]=keystore[k]; if((status = R_OpenInit(&context, encryptionAlgorithm, encryptedKey, encryptedKeyLen, iv,0)) == 0) //encrypt = 1 加密 encrypt = 0 解密 { while ( AllInLen < inlen ) { if (( inlen - AllInLen ) > 24 ) partInLen = 24; else partInLen = inlen - AllInLen; for (i=0;i<partInLen;i++) partIn[i]=inchar[AllInLen+i]; // _mbsnbcpy(partIn,( inchar + AllInLen ),partInLen); if((status = R_OpenUpdate(&context, partOut, &partOutLen, partIn, partInLen)) != 0) break; for (i=0;i<partOutLen;i++) outchar[i+AllOutLen]=partOut[i]; AllInLen += partInLen; AllOutLen += partOutLen; // _mbsnbcat(outchar, partOut,partOutLen); } if((status = R_OpenFinal(&context, partOut, &partOutLen)) == 0) { for (i=0;i<partOutLen;i++) outchar[i+AllOutLen]=partOut[i]; // _mbsnbcat(outchar, partOut,partOutLen); AllOutLen += partOutLen; } } R_memset((POINTER)&context, 0, sizeof(context)); R_memset((POINTER)partOut, 0, sizeof(partOut)); R_memset((POINTER)iv, 0, sizeof(iv)); R_memset((POINTER)partIn, 0, sizeof(partIn)); *outlen = AllOutLen; if (status) return E_Error; else return 0; } /*外部必须已经分配足够的内存空间outbstrlen必须大于((inbstrlen / 8 + 1 )* 8 )*/ int DesBSTREncrypt (BSTR inbstr, unsigned int inbstrlen, BSTR outbstr, unsigned int * outbstrlen, unsigned char DesKey[8]) //by yaoliang 2000.11.14 { unsigned inlen = inbstrlen * 2; unsigned outlen = *outbstrlen * 2; unsigned char * inchar = (unsigned char *)inbstr; unsigned char * outchar = (unsigned char *)outbstr; int statue = DesEncrypt(inchar, inlen, outchar, &outlen, DesKey); *outbstrlen = outlen / 2; return statue; } /*外部必须已经分配足够的内存空间outbstrlen必须大于(inbstrlen - 8 )*/ int DesBSTRDecrypt (BSTR inbstr, unsigned int inbstrlen, BSTR outbstr, unsigned int * outbstrlen, unsigned char DesKey[8]) //by yaoliang 2000.11.14 { unsigned inlen = inbstrlen * 2; unsigned outlen = *outbstrlen * 2; unsigned char * inchar = (unsigned char *)inbstr; unsigned char * outchar = (unsigned char *)outbstr; int statue = DesDecrypt(inchar, inlen, outchar, &outlen, DesKey); *outbstrlen = outlen / 2; return 0; } /////////////////////////////////////////////////////////////////////////////////////////////// //End of output des functions /////////////////////////////////////////////////////////////////////////////////////////////// /* Constants for MD5Transform routine. */ /* #define S11 7 #define S12 12 #define S13 17 #define S14 22 #define S21 5 #define S22 9 #define S23 14 #define S24 20 #define S31 4 #define S32 11 #define S33 16 #define S34 23 #define S41 6 #define S42 10 #define S43 15 #define S44 21 /* F, G, H and I are basic MD5 functions. #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | (~z))) /* ROTATE_LEFT rotates x left n bits. #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. Rotation is separate from addition to prevent recomputation. #define FF(a, b, c, d, x, s, ac) { \ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define GG(a, b, c, d, x, s, ac) { \ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define HH(a, b, c, d, x, s, ac) { \ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define II(a, b, c, d, x, s, ac) { \ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } */ /* MD5 initialization. Begins an MD5 operation, writing a new context. */ //begin of output fuctions //generate key int KeyGenerate(unsigned char DesKey[8]) //by yaoliang 2000.11.14 { int status,i; R_ENVELOPE_CTX context; R_RANDOM_STRUCT randomStruct; unsigned char key[24]; int flag = 1 ; int encryptionAlgorithm = EA_DES_CBC; context.encryptionAlgorithm = encryptionAlgorithm; do { R_RandomCreate(&randomStruct); if((status = R_GenerateBytes (DesKey, 8, &randomStruct)) != 0) return status ; if (status = CipherInit (&context, encryptionAlgorithm, key, DesKey, 1) != 0) return status; for (i = 0 ; i < 8 ; i++) { if (DesKey[i] == 0) flag = 1 ; } } while ( flag ) ; return 0; } /*外部必须已经分配足够的内存空间strlen(outputchar)长度必须大于( 16 + 1 )*/ int md5hash(unsigned char *inputchar,int inlen,unsigned char *outputchar) //by yaoliang 2000.8.14 { MD5_CTX *md5ctx; unsigned int j; md5ctx=(MD5_CTX *)malloc(sizeof(MD5_CTX)); MD5Init (md5ctx); MD5Update (md5ctx, inputchar,inlen/*lstrlen((char *)inputchar)*/); //by yaoliang lstrlen((char *)inputchar) return only 4 !!! MD5Final (outputchar, md5ctx); free (md5ctx); div_t div_result; for (j=0;j<16;j++) { div_result = div( outputchar[j] , 62); outputchar[j]=div_result.rem; if (outputchar[j] < 10) outputchar[j]+=('0'-0); else if ((outputchar[j] > 9)&&(outputchar[j] < 36)) outputchar[j]+=('a'-10); else if (outputchar[j] > 35) outputchar[j]+=('A'-36); outputchar[16]='\0'; } return 0; } /*外部必须已经分配足够的内存空间strlen(outchar)长度必须大于((strlen(inlen) / 8 + 1 )* 9 + 2 +1 )*/ int DesBSTREn (BSTR inbstr , BSTR * outbstr , unsigned char DesKey[8]) //by yaoliang 2000.12.02 { if ( wcslen(inbstr) == 0 ) //if input is "", return "",not NULL { wcscpy ( (*outbstr) , L"") ; return 0 ; } unsigned int inlen , outlen ,i; LPTSTR tmp1; char * inchar = new char [wcslen(inbstr)*2+1] ; unsigned char * outchar = (unsigned char *) (*outbstr) ; BSTR_to_LPTSTR (&tmp1, inbstr); strcpy ((char *)inchar,tmp1); LocalFree (tmp1); inlen = strlen ((char *)inchar); outlen = (inlen / 8 + 1 ) * 8; int statue = DesEncrypt((unsigned char *)inchar, inlen, outchar+2, &outlen, DesKey); if (statue) return statue ; for ( i = 0 ; i < (inlen / 8 +1) ; i++ ) outchar [2+outlen+i] = 255 ; for (i = 0 ; i < outlen ; i++ ) { if (( outchar [i+2] == 0 ) || ( outchar [i+2] == 39 ) || ( outchar [i+2] == 34 )) { if ( outchar [i+2] == 0 ) outchar [i+2] = 255 ; if ( outchar [i+2] == 34 ) outchar [i+2] = 254 ; if ( outchar [i+2] == 39 ) outchar [i+2] = 253 ; outchar [i/8+2+outlen] = outchar [i/8+2+outlen] & ( ~ ( 1 << ( i % 8 ))) ; } } if ((inlen / 8 + 1) % 2) { outchar [outlen/8*9+2] = 255 ; outchar [outlen/8*9+2+1] = 0 ; outchar [outlen/8*9+2+2] = 0 ; outlen = outlen / 8 * 9 + 2 + 1 + 2 ; } else { outchar [outlen/8*9+2] = 0 ; outchar [outlen/8*9+2+1] = 0 ; outlen = outlen / 8 * 9 + 2 + 2 ; } outchar [0] = outlen / 255 ; outchar [1] = outlen % 255 ; outchar [0] = outchar [0] << 4 ; outchar [0] = outchar [0] + 8 ; if ( outchar [1] == 39 ) { outchar [1] = 253 ; outchar [0] += 1 ; return 0 ; } if ( outchar [1] == 34 ) { outchar [1] = 254 ; outchar [0] += 2 ; return 0 ; } if ( outchar [1] == 0 ) { outchar [1] = 255 ; outchar [0] += 4 ; return 0 ; } free (inchar); return 0 ; } /*外部必须已经分配足够的内存空间strlen(outchar)长度必须大于((strlen(inlen) - 2 - 1 ) / 9 * 8 )*/ int DesBSTRDe (BSTR inbstr , BSTR * outbstr , unsigned char DesKey[8]) //by yaoliang 2000.12.02 { if ( wcslen(inbstr) == 0 ) //if input is "",return "",not NULL !!! { wcscpy ( (*outbstr) , L"") ; return 0 ; } BSTR intmp = SysAllocStringByteLen (NULL,wcslen(inbstr)*2+2); wcscpy (intmp,inbstr); unsigned int i , j ; unsigned int inlen , outlen ; LPOLESTR tmp1; unsigned char * inchar = (unsigned char *) inbstr ; if ((inchar[0] & 0x07) == 4) inchar[1] = 0 ; if ((inchar[0] & 0x07) == 2) inchar[1] = 34 ; if ((inchar[0] & 0x07) == 1) inchar[1] = 39 ; inchar [0] >>= 4 ; outlen = (inchar [0]) * 255 + inchar [1] ; if ((outlen - 2 - 2) % 9) inlen = ((outlen - 2 - 2 - 1) / 9 ) * 8 ; else inlen = ((outlen - 2 - 2) / 9 ) * 8 ; char * outchar = new char [inlen] ; outlen = inlen ; for (i = 0 ; i < inlen / 8 ; i++ ) { for (j = 0 ; j < 8 ; j++) { if (!(inchar [2+inlen+i] & 1)) { if ( inchar [i*8+j+2] == 255 ) inchar [i*8+j+2] = 0 ; if ( inchar [i*8+j+2] == 254 ) inchar [i*8+j+2] = 34 ; if ( inchar [i*8+j+2] == 253 ) inchar [i*8+j+2] = 39 ; } inchar [2+inlen+i] = inchar [2+inlen+i] >> 1 ; } } int statue = DesDecrypt (inchar + 2 , inlen , (unsigned char *)outchar , &outlen, DesKey); if ( statue ) return statue ; outchar [outlen] = 0 ; AnsiToUnicode((LPCSTR)outchar,&tmp1); *outbstr = SysAllocString(tmp1); wcscpy (inbstr,intmp) ; SysFreeString (intmp) ; CoTaskMemFree (tmp1); free (outchar); return 0; } /*外部必须已经分配足够的内存空间strlen(outchar)长度必须大于((strlen(inlen) / 8 + 1 )* 9 + 2 +1 )*/ int DesStrEn (unsigned char * inchar , unsigned char * outchar , unsigned char DesKey[8]) //by yaoliang 2000.12.02 { if ( strlen((char *)inchar) == 0 ) //if retrun is "",return "",not NULL!!! { strcpy ((char *)outchar,"") ; return 0 ; } unsigned int i; unsigned int inlen = strlen ((char *)inchar); unsigned int outlen = (inlen / 8 + 1 ) * 8; // char * outtmp = new char [(inlen / 8 + 1 )* 9 + 2 +1 ]; /*默认外部已经分配足够的内存空间*/ // if ( (inlen >= *outlen) && ( *outlen != 0) ) return E_Length ; //not enough out length int statue = DesEncrypt (inchar , inlen , outchar +2 , &outlen, DesKey); if ( statue ) return statue ; for ( i = 0 ; i < (inlen / 8 +1) ; i++ ) outchar [2+outlen+i] = 255 ; for (i = 0 ; i < outlen ; i++ ) { if (( outchar [i+2] == 0 ) || ( outchar [i+2] == 39 ) || ( outchar [i+2] == 34 )) { if ( outchar [i+2] == 0 ) outchar [i+2] = 255 ; if ( outchar [i+2] == 34 ) outchar [i+2] = 254 ; if ( outchar [i+2] == 39 ) outchar [i+2] = 253 ; outchar [i/8+2+outlen] = outchar [i/8+2+outlen] & ( ~ ( 1 << ( i % 8 ))) ; } } outchar [outlen/8*9+2] = 0 ; outlen = outlen / 8 * 9 + 2 + 1 ; outchar [0] = outlen / 255 ; outchar [1] = outlen % 255 ; outchar [0] = outchar [0] << 4 ; outchar [0] = outchar [0] + 8 ; if ( outchar [1] == 39 ) { outchar [1] = 253 ; outchar [0] += 1 ; return 0 ; } if ( outchar [1] == 34 ) { outchar [1] = 254 ; outchar [0] += 2 ; return 0 ; } if ( outchar [1] == 0 ) { outchar [1] = 255 ; outchar [0] += 4 ; return 0 ; } return 0; } /*外部必须已经分配足够的内存空间strlen(outchar)长度必须大于((strlen(inlen) - 2 - 1 ) / 9 * 8 )*/ int DesStrDe (unsigned char * inchar , unsigned char * outchar , unsigned char DesKey[8]) //by yaoliang 2000.12.02 { if ( strlen((char *)inchar) == 0 ) //if input is "",return "",not NULL!!! { strcpy ((char *)outchar,"") ; return 0 ; } unsigned int i,j; unsigned int inlen ; unsigned int outlen ; // char * outtmp = new char [(inlen / 8 + 1 )* 9 + 2 +1 ]; unsigned char * intmp = (unsigned char *) new char [strlen((char *)inchar)+1] ; //keep input into tmp strcpy ((char *)intmp , (char *)inchar) ; if ((inchar[0] & 0x07) == 4) inchar[1] = 0 ; if ((inchar[0] & 0x07) == 2) inchar[1] = 34 ; if ((inchar[0] & 0x07) == 1) inchar[1] = 39 ; inchar [0] >>= 4 ; outlen = (inchar [0]) * 255 + inchar [1] ; inlen = ((outlen - 2 - 1) / 9 ) * 8 ; /*默认外部已经分配足够的内存空间*/ // if ( (inlen >= *outlen) && ( *outlen != 0) ) return E_Length ; //not enough out length for (i = 0 ; i < inlen / 8 ; i++ ) { for (j = 0 ; j < 8 ; j++) { if (!(inchar [2+inlen+i] & 1)) { if ( inchar [i*8+j+2] == 255 ) inchar [i*8+j+2] = 0 ; if ( inchar [i*8+j+2] == 254 ) inchar [i*8+j+2] = 34 ; if ( inchar [i*8+j+2] == 253 ) inchar [i*8+j+2] = 39 ; } inchar [2+inlen+i] = inchar [2+inlen+i] >> 1 ; } } int statue = DesDecrypt (inchar + 2 , inlen , outchar , &outlen, DesKey); if ( statue ) return statue ; outchar [outlen] = 0 ; strcpy ((char *)inchar , (char *)intmp) ; //keep input as origin free (intmp); return 0; } //end of output fuctions