Annotation of rsaref/source/desc.c, revision 1.1.1.2

1.1       root        1: /* DESC.C - Data Encryption Standard routines for RSAREF
1.1.1.2 ! root        2:      Based on "Karn/Hoey/Outerbridge" implementation (KHODES)
1.1       root        3:  */
                      4: 
                      5: #include "global.h"
                      6: #include "rsaref.h"
                      7: #include "des.h"
                      8: 
1.1.1.2 ! root        9: static UINT2 BYTE_BIT[8] = {
        !            10:   0200, 0100, 040, 020, 010, 04, 02, 01
1.1       root       11: };
                     12: 
1.1.1.2 ! root       13: static UINT4 BIG_BYTE[24] = {
        !            14:   0x800000L, 0x400000L, 0x200000L, 0x100000L,
        !            15:   0x80000L,  0x40000L,  0x20000L,  0x10000L,
        !            16:   0x8000L,   0x4000L,   0x2000L,   0x1000L,
        !            17:   0x800L,    0x400L,    0x200L,    0x100L,
        !            18:   0x80L,     0x40L,     0x20L,     0x10L,
        !            19:   0x8L,      0x4L,      0x2L,      0x1L
1.1       root       20: };
                     21: 
1.1.1.2 ! root       22: static unsigned char PC1[56] = {
        !            23:   56, 48, 40, 32, 24, 16,  8,      0, 57, 49, 41, 33, 25, 17,
        !            24:    9,  1, 58, 50, 42, 34, 26,     18, 10,  2, 59, 51, 43, 35,
        !            25:   62, 54, 46, 38, 30, 22, 14,      6, 61, 53, 45, 37, 29, 21,
        !            26:   13,  5, 60, 52, 44, 36, 28,     20, 12,  4, 27, 19, 11,  3
1.1       root       27: };
                     28: 
1.1.1.2 ! root       29: static unsigned char TOTAL_ROTATIONS[16] = {
        !            30:   1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28
1.1       root       31: };
                     32: 
1.1.1.2 ! root       33: static unsigned char PC2[48] = {
        !            34:   13, 16, 10, 23,  0,  4,  2, 27, 14,  5, 20,  9,
        !            35:   22, 18, 11,  3, 25,  7, 15,  6, 26, 19, 12,  1,
        !            36:   40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
        !            37:   43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
1.1       root       38: };
                     39: 
1.1.1.2 ! root       40: static UINT4 SP1[64] = {
        !            41:   0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
        !            42:   0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
        !            43:   0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
        !            44:   0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
        !            45:   0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
        !            46:   0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
        !            47:   0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
        !            48:   0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
        !            49:   0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
        !            50:   0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
        !            51:   0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
        !            52:   0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
        !            53:   0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
        !            54:   0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
        !            55:   0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
        !            56:   0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L
1.1       root       57: };
                     58: 
1.1.1.2 ! root       59: static UINT4 SP2[64] = {
        !            60:   0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
        !            61:   0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
        !            62:   0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
        !            63:   0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
        !            64:   0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
        !            65:   0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
        !            66:   0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
        !            67:   0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
        !            68:   0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
        !            69:   0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
        !            70:   0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
        !            71:   0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
        !            72:   0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
        !            73:   0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
        !            74:   0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
        !            75:   0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L
1.1       root       76: };
                     77: 
1.1.1.2 ! root       78: static UINT4 SP3[64] = {
        !            79:   0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
        !            80:   0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
        !            81:   0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
        !            82:   0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
        !            83:   0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
        !            84:   0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
        !            85:   0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
        !            86:   0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
        !            87:   0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
        !            88:   0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
        !            89:   0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
        !            90:   0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
        !            91:   0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
        !            92:   0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
        !            93:   0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
        !            94:   0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L
1.1       root       95: };
                     96: 
1.1.1.2 ! root       97: static UINT4 SP4[64] = {
        !            98:   0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
        !            99:   0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
        !           100:   0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
        !           101:   0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
        !           102:   0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
        !           103:   0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
        !           104:   0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
        !           105:   0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
        !           106:   0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
        !           107:   0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
        !           108:   0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
        !           109:   0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
        !           110:   0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
        !           111:   0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
        !           112:   0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
        !           113:   0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L
        !           114: };
        !           115: 
        !           116: static UINT4 SP5[64] = {
        !           117:   0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
        !           118:   0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
        !           119:   0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
        !           120:   0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
        !           121:   0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
        !           122:   0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
        !           123:   0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
        !           124:   0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
        !           125:   0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
        !           126:   0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
        !           127:   0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
        !           128:   0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
        !           129:   0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
        !           130:   0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
        !           131:   0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
        !           132:   0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L
        !           133: };
        !           134: 
        !           135: static UINT4 SP6[64] = {
        !           136:   0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
        !           137:   0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
        !           138:   0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
        !           139:   0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
        !           140:   0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
        !           141:   0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
        !           142:   0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
        !           143:   0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
        !           144:   0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
        !           145:   0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
        !           146:   0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
        !           147:   0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
        !           148:   0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
        !           149:   0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
        !           150:   0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
        !           151:   0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L
        !           152: };
        !           153: 
        !           154: static UINT4 SP7[64] = {
        !           155:   0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
        !           156:   0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
        !           157:   0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
        !           158:   0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
        !           159:   0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
        !           160:   0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
        !           161:   0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
        !           162:   0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
        !           163:   0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
        !           164:   0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
        !           165:   0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
        !           166:   0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
        !           167:   0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
        !           168:   0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
        !           169:   0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
        !           170:   0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L
        !           171: };
        !           172: 
        !           173: static UINT4 SP8[64] = {
        !           174:   0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
        !           175:   0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
        !           176:   0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
        !           177:   0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
        !           178:   0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
        !           179:   0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
        !           180:   0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
        !           181:   0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
        !           182:   0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
        !           183:   0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
        !           184:   0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
        !           185:   0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
        !           186:   0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
        !           187:   0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
        !           188:   0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
        !           189:   0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L
        !           190: };
1.1       root      191: 
1.1.1.2 ! root      192: static void Unpack PROTO_LIST ((unsigned char *, UINT4 *));
        !           193: static void Pack PROTO_LIST ((UINT4 *, unsigned char *));
        !           194: static void DESKey PROTO_LIST ((UINT4 *, unsigned char *, int));
        !           195: static void CookKey PROTO_LIST ((UINT4 *, UINT4 *, int));
        !           196: static void DESFunction PROTO_LIST ((UINT4 *, UINT4 *));
        !           197: 
        !           198: /* Initialize context.  Caller must zeroize the context when finished.
1.1       root      199:  */
                    200: void DES_CBCInit (context, key, iv, encrypt)
1.1.1.2 ! root      201: DES_CBC_CTX *context;                                            /* context */
        !           202: unsigned char key[8];                                                /* key */
        !           203: unsigned char iv[8];                                 /* initializing vector */
1.1       root      204: int encrypt;                     /* encrypt flag (1 = encrypt, 0 = decrypt) */
1.1.1.2 ! root      205: {  
1.1       root      206:   /* Copy encrypt flag to context.
                    207:    */
                    208:   context->encrypt = encrypt;
                    209: 
1.1.1.2 ! root      210:   /* Pack initializing vector into context.
1.1       root      211:    */
1.1.1.2 ! root      212:   Pack (context->iv, iv);
1.1       root      213: 
1.1.1.2 ! root      214:   /* Save the IV for use in Restart */
        !           215:   context->originalIV[0] = context->iv[0];
        !           216:   context->originalIV[1] = context->iv[1];
1.1       root      217: 
1.1.1.2 ! root      218:   /* Precompute key schedule
1.1       root      219:    */
1.1.1.2 ! root      220:   DESKey (context->subkeys, key, encrypt);
1.1       root      221: }
                    222: 
                    223: /* DES-CBC block update operation. Continues a DES-CBC encryption
                    224:    operation, processing eight-byte message blocks, and updating
                    225:    the context.
                    226:  */
                    227: int DES_CBCUpdate (context, output, input, len)
1.1.1.2 ! root      228: DES_CBC_CTX *context;                                            /* context */
1.1       root      229: unsigned char *output;                                      /* output block */
                    230: unsigned char *input;                                        /* input block */
                    231: unsigned int len;                      /* length of input and output blocks */
                    232: {
1.1.1.2 ! root      233:   UINT4 inputBlock[2], work[2];
        !           234:   unsigned int i;
1.1       root      235:   
                    236:   if (len % 8)
                    237:     return (RE_LEN);
1.1.1.2 ! root      238: 
1.1       root      239:   for (i = 0; i < len/8; i++) {
1.1.1.2 ! root      240:     Pack (inputBlock, &input[8*i]);
        !           241:         
        !           242:     /* Chain if encrypting.
        !           243:      */
        !           244:     if (context->encrypt) {
        !           245:       work[0] = inputBlock[0] ^ context->iv[0];
        !           246:       work[1] = inputBlock[1] ^ context->iv[1];
        !           247:     }
        !           248:     else {
        !           249:       work[0] = inputBlock[0];
        !           250:       work[1] = inputBlock[1];         
        !           251:     }
1.1       root      252: 
1.1.1.2 ! root      253:     DESFunction (work, context->subkeys);
        !           254: 
        !           255:     /* Chain if decrypting, then update IV.
1.1       root      256:      */
1.1.1.2 ! root      257:     if (context->encrypt) {
        !           258:       context->iv[0] = work[0];
        !           259:       context->iv[1] = work[1];
        !           260:     }
        !           261:     else {
        !           262:       work[0] ^= context->iv[0];
        !           263:       work[1] ^= context->iv[1];
        !           264:       context->iv[0] = inputBlock[0];
        !           265:       context->iv[1] = inputBlock[1];
        !           266:     }
        !           267:     Unpack (&output[8*i], work);
        !           268:   }
1.1       root      269:   
1.1.1.2 ! root      270:   /* Zeroize sensitive information.
        !           271:    */
        !           272:   R_memset ((POINTER)inputBlock, 0, sizeof (inputBlock));
        !           273:   R_memset ((POINTER)work, 0, sizeof (work));
1.1       root      274:   
1.1.1.2 ! root      275:   return (0);
        !           276: }
        !           277: 
        !           278: void DES_CBCRestart (context)
        !           279: DES_CBC_CTX *context;
        !           280: {
        !           281:   /* Reset to the original IV */
        !           282:   context->iv[0] = context->originalIV[0];
        !           283:   context->iv[1] = context->originalIV[1];
        !           284: }
        !           285: 
        !           286: /* Initialize context.  Caller must zeroize the context when finished.
        !           287:    The key has the DES key, input whitener and output whitener concatenated.
        !           288:  */
        !           289: void DESX_CBCInit (context, key, iv, encrypt)
        !           290: DESX_CBC_CTX *context;
        !           291: unsigned char key[24];                              /* DES key and whiteners */
        !           292: unsigned char iv[8];                              /* DES initializing vector */
        !           293: int encrypt;                      /* encrypt flag (1 = encrypt, 0 = decrypt) */
        !           294: {  
        !           295:   /* Copy encrypt flag to context.
        !           296:    */
        !           297:   context->encrypt = encrypt;
        !           298: 
        !           299:   /* Pack initializing vector and whiteners into context.
        !           300:    */
        !           301:   Pack (context->iv, iv);
        !           302:   Pack (context->inputWhitener, key + 8);
        !           303:   Pack (context->outputWhitener, key + 16);
        !           304: 
        !           305:   /* Save the IV for use in Restart */
        !           306:   context->originalIV[0] = context->iv[0];
        !           307:   context->originalIV[1] = context->iv[1];
        !           308: 
        !           309:   /* Precompute key schedule.
        !           310:    */
        !           311:   DESKey (context->subkeys, key, encrypt);
        !           312: }
        !           313: 
        !           314: /* DESX-CBC block update operation. Continues a DESX-CBC encryption
        !           315:    operation, processing eight-byte message blocks, and updating
        !           316:    the context.
        !           317:  */
        !           318: int DESX_CBCUpdate (context, output, input, len)
        !           319: DESX_CBC_CTX *context;                                           /* context */
        !           320: unsigned char *output;                                      /* output block */
        !           321: unsigned char *input;                                        /* input block */
        !           322: unsigned int len;                      /* length of input and output blocks */
        !           323: {
        !           324:   UINT4 inputBlock[2], work[2];
        !           325:   unsigned int i;
        !           326:   
        !           327:   if (len % 8)
        !           328:     return (RE_LEN);
        !           329: 
        !           330:   for (i = 0; i < len/8; i++)  {
        !           331:     Pack (inputBlock, &input[8*i]);
        !           332:         
        !           333:     /* Chain if encrypting, and xor with whitener.
1.1       root      334:      */
1.1.1.2 ! root      335:     if (context->encrypt) {
        !           336:       work[0] =
        !           337:         inputBlock[0] ^ context->iv[0] ^ context->inputWhitener[0];
        !           338:       work[1] =
        !           339:         inputBlock[1] ^ context->iv[1] ^ context->inputWhitener[1];
        !           340:     }
        !           341:     else {
        !           342:       work[0] = inputBlock[0] ^ context->outputWhitener[0];
        !           343:       work[1] = inputBlock[1] ^ context->outputWhitener[1];         
1.1       root      344:     }
                    345: 
1.1.1.2 ! root      346:     DESFunction (work, context->subkeys);
1.1       root      347: 
1.1.1.2 ! root      348:     /* Xor with whitener, chain if decrypting, then update IV.
1.1       root      349:      */
1.1.1.2 ! root      350:     if (context->encrypt) {
        !           351:       work[0] ^= context->outputWhitener[0];
        !           352:       work[1] ^= context->outputWhitener[1];
        !           353:       context->iv[0] = work[0];
        !           354:       context->iv[1] = work[1];
        !           355:     }
        !           356:     else {
        !           357:       work[0] ^= context->iv[0] ^ context->inputWhitener[0];
        !           358:       work[1] ^= context->iv[1] ^ context->inputWhitener[1];
        !           359:       context->iv[0] = inputBlock[0];
        !           360:       context->iv[1] = inputBlock[1];
        !           361:     }
        !           362:     Unpack (&output[8*i], work);
        !           363:   }
        !           364:   
        !           365:   /* Zeroize sensitive information.
        !           366:    */
        !           367:   R_memset ((POINTER)inputBlock, 0, sizeof (inputBlock));
        !           368:   R_memset ((POINTER)work, 0, sizeof (work));
        !           369:   
        !           370:   return (0);
        !           371: }
        !           372: 
        !           373: void DESX_CBCRestart (context)
        !           374: DESX_CBC_CTX *context;
        !           375: {
        !           376:   /* Reset to the original IV */
        !           377:   context->iv[0] = context->originalIV[0];
        !           378:   context->iv[1] = context->originalIV[1];
        !           379: }
1.1       root      380: 
1.1.1.2 ! root      381: /* Initialize context.  Caller must zeroize the context when finished.
        !           382:  */
        !           383: void DES3_CBCInit(context, key, iv, encrypt)
        !           384: DES3_CBC_CTX *context;                                           /* context */
        !           385: unsigned char key[24];                                               /* key */
        !           386: unsigned char iv[8];                                 /* initializing vector */
        !           387: int encrypt;                     /* encrypt flag (1 = encrypt, 0 = decrypt) */
        !           388: {  
        !           389:   /* Copy encrypt flag to context.
        !           390:    */
        !           391:   context->encrypt = encrypt;
        !           392: 
        !           393:   /* Pack initializing vector into context.
        !           394:    */
        !           395:   Pack (context->iv, iv);
        !           396: 
        !           397:   /* Save the IV for use in Restart */
        !           398:   context->originalIV[0] = context->iv[0];
        !           399:   context->originalIV[1] = context->iv[1];
        !           400: 
        !           401:   /* Precompute key schedules.
        !           402:    */
        !           403:   DESKey (context->subkeys[0], encrypt ? key : &key[16], encrypt);
        !           404:   DESKey (context->subkeys[1], &key[8], !encrypt);
        !           405:   DESKey (context->subkeys[2], encrypt ? &key[16] : key, encrypt);
        !           406: }
        !           407: 
        !           408: int DES3_CBCUpdate (context, output, input, len)
        !           409: DES3_CBC_CTX *context;                                           /* context */
        !           410: unsigned char *output;                                      /* output block */
        !           411: unsigned char *input;                                        /* input block */
        !           412: unsigned int len;                      /* length of input and output blocks */
        !           413: {
        !           414:   UINT4 inputBlock[2], work[2];
        !           415:   unsigned int i;
1.1       root      416:   
1.1.1.2 ! root      417:   if (len % 8)
        !           418:     return (RE_LEN);
        !           419: 
        !           420:   for (i = 0; i < len/8; i++) {
        !           421:     Pack (inputBlock, &input[8*i]);
        !           422:         
        !           423:     /* Chain if encrypting.
1.1       root      424:      */
1.1.1.2 ! root      425:     if (context->encrypt) {
        !           426:       work[0] = inputBlock[0] ^ context->iv[0];
        !           427:       work[1] = inputBlock[1] ^ context->iv[1];
        !           428:     }
        !           429:     else {
        !           430:       work[0] = inputBlock[0];
        !           431:       work[1] = inputBlock[1];         
        !           432:     }
        !           433: 
        !           434:     DESFunction (work, context->subkeys[0]);
        !           435:     DESFunction (work, context->subkeys[1]);
        !           436:     DESFunction (work, context->subkeys[2]);
        !           437: 
        !           438:     /* Chain if decrypting, then update IV.
        !           439:      */
        !           440:     if (context->encrypt) {
        !           441:       context->iv[0] = work[0];
        !           442:       context->iv[1] = work[1];
        !           443:     }
        !           444:     else {
        !           445:       work[0] ^= context->iv[0];
        !           446:       work[1] ^= context->iv[1];
        !           447:       context->iv[0] = inputBlock[0];
        !           448:       context->iv[1] = inputBlock[1];
        !           449:     }
        !           450:     Unpack (&output[8*i], work);
1.1       root      451:   }
                    452:   
                    453:   /* Zeroize sensitive information.
                    454:    */
1.1.1.2 ! root      455:   R_memset ((POINTER)inputBlock, 0, sizeof (inputBlock));
        !           456:   R_memset ((POINTER)work, 0, sizeof (work));
1.1       root      457:   
                    458:   return (0);
                    459: }
                    460: 
1.1.1.2 ! root      461: void DES3_CBCRestart (context)
        !           462: DES3_CBC_CTX *context;
        !           463: {
        !           464:   /* Reset to the original IV */
        !           465:   context->iv[0] = context->originalIV[0];
        !           466:   context->iv[1] = context->originalIV[1];
        !           467: }
        !           468: 
        !           469: static void Pack (into, outof)
        !           470: UINT4 *into;
        !           471: unsigned char *outof;
1.1       root      472: {
1.1.1.2 ! root      473:   *into    = (*outof++ & 0xffL) << 24;
        !           474:   *into   |= (*outof++ & 0xffL) << 16;
        !           475:   *into   |= (*outof++ & 0xffL) << 8;
        !           476:   *into++ |= (*outof++ & 0xffL);
        !           477:   *into    = (*outof++ & 0xffL) << 24;
        !           478:   *into   |= (*outof++ & 0xffL) << 16;
        !           479:   *into   |= (*outof++ & 0xffL) << 8;
        !           480:   *into   |= (*outof   & 0xffL);
1.1       root      481: }
                    482: 
1.1.1.2 ! root      483: static void Unpack (into, outof)
        !           484: unsigned char *into;
        !           485: UINT4 *outof;
1.1       root      486: {
1.1.1.2 ! root      487:   *into++ = (unsigned char)((*outof >> 24) & 0xffL);
        !           488:   *into++ = (unsigned char)((*outof >> 16) & 0xffL);
        !           489:   *into++ = (unsigned char)((*outof >>  8) & 0xffL);
        !           490:   *into++ = (unsigned char)( *outof++      & 0xffL);
        !           491:   *into++ = (unsigned char)((*outof >> 24) & 0xffL);
        !           492:   *into++ = (unsigned char)((*outof >> 16) & 0xffL);
        !           493:   *into++ = (unsigned char)((*outof >>  8) & 0xffL);
        !           494:   *into   = (unsigned char)( *outof        & 0xffL);
        !           495: }
1.1       root      496: 
1.1.1.2 ! root      497: static void DESKey (subkeys, key, encrypt)
        !           498: UINT4 subkeys[32];
        !           499: unsigned char key[8];
        !           500: int encrypt;
        !           501: {
        !           502:   UINT4 kn[32];
        !           503:   int i, j, l, m, n;
        !           504:   unsigned char pc1m[56], pcr[56];
        !           505: 
        !           506:   for (j = 0; j < 56; j++) {
        !           507:     l = PC1[j];
        !           508:     m = l & 07;
        !           509:     pc1m[j] = (unsigned char)((key[l >> 3] & BYTE_BIT[m]) ? 1 : 0);
1.1       root      510:   }
1.1.1.2 ! root      511:   for (i = 0; i < 16; i++) {
        !           512:     m = i << 1;
        !           513:     n = m + 1;
        !           514:     kn[m] = kn[n] = 0L;
        !           515:     for (j = 0; j < 28; j++) {
        !           516:       l = j + TOTAL_ROTATIONS[i];
        !           517:       if (l < 28)
        !           518:         pcr[j] = pc1m[l];
        !           519:       else
        !           520:         pcr[j] = pc1m[l - 28];
        !           521:     }
        !           522:     for (j = 28; j < 56; j++) {
        !           523:       l = j + TOTAL_ROTATIONS[i];
        !           524:       if (l < 56)
        !           525:         pcr[j] = pc1m[l];
        !           526:       else
        !           527:         pcr[j] = pc1m[l - 28];
        !           528:     }
        !           529:     for (j = 0; j < 24; j++) {
        !           530:       if (pcr[PC2[j]])
        !           531:         kn[m] |= BIG_BYTE[j];
        !           532:       if (pcr[PC2[j+24]])
        !           533:         kn[n] |= BIG_BYTE[j];
        !           534:     }
        !           535:   }
        !           536:   CookKey (subkeys, kn, encrypt);
        !           537: 
        !           538:   /* Zeroize sensitive information.
        !           539:    */
        !           540:   R_memset ((POINTER)pc1m, 0, sizeof (pc1m));
        !           541:   R_memset ((POINTER)pcr, 0, sizeof (pcr));
        !           542:   R_memset ((POINTER)kn, 0, sizeof (kn));
1.1       root      543: }
                    544: 
1.1.1.2 ! root      545: static void CookKey (subkeys, kn, encrypt)
        !           546: UINT4 *subkeys;
        !           547: UINT4 *kn;
        !           548: int encrypt;
        !           549: {
        !           550:   UINT4 *cooked, *raw0, *raw1;
        !           551:   int increment;
        !           552:   unsigned int i;
        !           553: 
        !           554:   raw1 = kn;
        !           555:   cooked = encrypt ? subkeys : &subkeys[30];
        !           556:   increment = encrypt ? 1 : -3;
        !           557: 
        !           558:   for (i = 0; i < 16; i++, raw1++) {
        !           559:     raw0 = raw1++;
        !           560:     *cooked    = (*raw0 & 0x00fc0000L) << 6;
        !           561:     *cooked   |= (*raw0 & 0x00000fc0L) << 10;
        !           562:     *cooked   |= (*raw1 & 0x00fc0000L) >> 10;
        !           563:     *cooked++ |= (*raw1 & 0x00000fc0L) >> 6;
        !           564:     *cooked    = (*raw0 & 0x0003f000L) << 12;
        !           565:     *cooked   |= (*raw0 & 0x0000003fL) << 16;
        !           566:     *cooked   |= (*raw1 & 0x0003f000L) >> 4;
        !           567:     *cooked   |= (*raw1 & 0x0000003fL);
        !           568:     cooked += increment;
        !           569:   }
        !           570: }
        !           571: 
        !           572: static void DESFunction (block, subkeys)
        !           573: UINT4 *block;
        !           574: UINT4 *subkeys;
        !           575: {
        !           576:   register UINT4 fval, work, right, left;
        !           577:   register int round;
        !           578:   
        !           579:   left = block[0];
        !           580:   right = block[1];
        !           581:   work = ((left >> 4) ^ right) & 0x0f0f0f0fL;
        !           582:   right ^= work;
        !           583:   left ^= (work << 4);
        !           584:   work = ((left >> 16) ^ right) & 0x0000ffffL;
        !           585:   right ^= work;
        !           586:   left ^= (work << 16);
        !           587:   work = ((right >> 2) ^ left) & 0x33333333L;
        !           588:   left ^= work;
        !           589:   right ^= (work << 2);
        !           590:   work = ((right >> 8) ^ left) & 0x00ff00ffL;
        !           591:   left ^= work;
        !           592:   right ^= (work << 8);
        !           593:   right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL;
        !           594:   work = (left ^ right) & 0xaaaaaaaaL;
        !           595:   left ^= work;
        !           596:   right ^= work;
        !           597:   left = ((left << 1) | ((left >> 31) & 1L)) & 0xffffffffL;
        !           598:   
        !           599:   for (round = 0; round < 8; round++) {
        !           600:     work  = (right << 28) | (right >> 4);
        !           601:     work ^= *subkeys++;
        !           602:     fval  = SP7[ work        & 0x3fL];
        !           603:     fval |= SP5[(work >>  8) & 0x3fL];
        !           604:     fval |= SP3[(work >> 16) & 0x3fL];
        !           605:     fval |= SP1[(work >> 24) & 0x3fL];
        !           606:     work  = right ^ *subkeys++;
        !           607:     fval |= SP8[ work        & 0x3fL];
        !           608:     fval |= SP6[(work >>  8) & 0x3fL];
        !           609:     fval |= SP4[(work >> 16) & 0x3fL];
        !           610:     fval |= SP2[(work >> 24) & 0x3fL];
        !           611:     left ^= fval;
        !           612:     work  = (left << 28) | (left >> 4);
        !           613:     work ^= *subkeys++;
        !           614:     fval  = SP7[ work        & 0x3fL];
        !           615:     fval |= SP5[(work >>  8) & 0x3fL];
        !           616:     fval |= SP3[(work >> 16) & 0x3fL];
        !           617:     fval |= SP1[(work >> 24) & 0x3fL];
        !           618:     work  = left ^ *subkeys++;
        !           619:     fval |= SP8[ work        & 0x3fL];
        !           620:     fval |= SP6[(work >>  8) & 0x3fL];
        !           621:     fval |= SP4[(work >> 16) & 0x3fL];
        !           622:     fval |= SP2[(work >> 24) & 0x3fL];
        !           623:     right ^= fval;
1.1       root      624:   }
1.1.1.2 ! root      625:   
        !           626:   right = (right << 31) | (right >> 1);
        !           627:   work = (left ^ right) & 0xaaaaaaaaL;
        !           628:   left ^= work;
        !           629:   right ^= work;
        !           630:   left = (left << 31) | (left >> 1);
        !           631:   work = ((left >> 8) ^ right) & 0x00ff00ffL;
        !           632:   right ^= work;
        !           633:   left ^= (work << 8);
        !           634:   work = ((left >> 2) ^ right) & 0x33333333L;
        !           635:   right ^= work;
        !           636:   left ^= (work << 2);
        !           637:   work = ((right >> 16) ^ left) & 0x0000ffffL;
        !           638:   left ^= work;
        !           639:   right ^= (work << 16);
        !           640:   work = ((right >> 4) ^ left) & 0x0f0f0f0fL;
        !           641:   left ^= work;
        !           642:   right ^= (work << 4);
        !           643:   *block++ = right;
        !           644:   *block = left;
1.1       root      645: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.