📄 crypt.c
字号:
register char *encp; register int i; register int t; int salt; int num_iter, salt_size; C_block keyblock, rsltblock; for (i = 0; i < 8; i++) { if ((t = 2*(unsigned char)(*key)) != 0) key++; keyblock.b[i] = t; } if (des_setkey((char *)keyblock.b)) /* also initializes "a64toi" */ return (NULL); encp = &cryptresult[0]; switch (*setting) { default: num_iter = 25; salt_size = 2; } salt = 0; for (i = salt_size; --i >= 0; ) { if ((t = (unsigned char)setting[i]) == '\0') t = '.'; encp[i] = t; salt = (salt<<6) | a64toi[t]; } encp += salt_size; if (des_cipher((char *)&constdatablock, (char *)&rsltblock, salt, num_iter)) return (NULL); /* * Encode the 64 cipher bits as 11 ascii characters. */ i = ((int)((rsltblock.b[0]<<8) | rsltblock.b[1])<<8) | rsltblock.b[2]; encp[3] = itoa64[i&0x3f]; i >>= 6; encp[2] = itoa64[i&0x3f]; i >>= 6; encp[1] = itoa64[i&0x3f]; i >>= 6; encp[0] = itoa64[i]; encp += 4; i = ((int)((rsltblock.b[3]<<8) | rsltblock.b[4])<<8) | rsltblock.b[5]; encp[3] = itoa64[i&0x3f]; i >>= 6; encp[2] = itoa64[i&0x3f]; i >>= 6; encp[1] = itoa64[i&0x3f]; i >>= 6; encp[0] = itoa64[i]; encp += 4; i = ((int)((rsltblock.b[6])<<8) | rsltblock.b[7])<<2; encp[2] = itoa64[i&0x3f]; i >>= 6; encp[1] = itoa64[i&0x3f]; i >>= 6; encp[0] = itoa64[i]; encp[3] = 0; return (cryptresult);}/* * The Key Schedule, filled in by des_setkey() or setkey(). */#define KS_SIZE 16static C_block KS[KS_SIZE];/* * Set up the key schedule from the key. */STATIC int des_setkey(key) register const char *key;{ register DCL_BLOCK(K, K0, K1); register C_block *ptabp; register int i; static int des_ready = 0; if (!des_ready) { init_des(); des_ready = 1; } PERM6464(K,K0,K1,(unsigned char *)key,(C_block *)PC1ROT); key = (char *)&KS[0]; STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key); for (i = 1; i < 16; i++) { key += sizeof(C_block); STORE(K,K0,K1,*(C_block *)key); ptabp = (C_block *)PC2ROT[Rotates[i]-1]; PERM6464(K,K0,K1,(unsigned char *)key,ptabp); STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key); } return (0);}/* * Encrypt (or decrypt if num_iter < 0) the 8 chars at "in" with abs(num_iter) * iterations of DES, using the the given 24-bit salt and the pre-computed key * schedule, and store the resulting 8 chars at "out" (in == out is permitted). * * NOTE: the performance of this routine is critically dependent on your * compiler and machine architecture. */STATIC int des_cipher(in, out, salt, num_iter) const char *in; char *out; long salt; int num_iter;{ /* variables that we want in registers, most important first */#if defined(pdp11) register int j;#endif register int L0, L1, R0, R1, k; register C_block *kp; register int ks_inc, loop_count; C_block B; L0 = salt; TO_SIX_BIT(salt, L0); /* convert to 4*(6+2) format */#if defined(vax) || defined(pdp11) salt = ~salt; /* "x &~ y" is faster than "x & y". */#define SALT (~salt)#else#define SALT salt#endif#if defined(MUST_ALIGN) B.b[0] = in[0]; B.b[1] = in[1]; B.b[2] = in[2]; B.b[3] = in[3]; B.b[4] = in[4]; B.b[5] = in[5]; B.b[6] = in[6]; B.b[7] = in[7]; LOAD(L,L0,L1,B);#else LOAD(L,L0,L1,*(C_block *)in);#endif LOADREG(R,R0,R1,L,L0,L1); L0 &= 0x55555555L; L1 &= 0x55555555L; L0 = (L0 << 1) | L1; /* L0 is the even-numbered input bits */ R0 &= 0xaaaaaaaaL; R1 = (R1 >> 1) & 0x55555555L; L1 = R0 | R1; /* L1 is the odd-numbered input bits */ STORE(L,L0,L1,B); PERM3264(L,L0,L1,B.b, (C_block *)IE3264); /* even bits */ PERM3264(R,R0,R1,B.b+4,(C_block *)IE3264); /* odd bits */ if (num_iter >= 0) { /* encryption */ kp = &KS[0]; ks_inc = sizeof(*kp); } else { /* decryption */ num_iter = -num_iter; kp = &KS[KS_SIZE-1]; ks_inc = -(long)sizeof(*kp); } while (--num_iter >= 0) { loop_count = 8; do {#define SPTAB(t, i) \ (*(int*)((unsigned char *)t + i*(sizeof(int)/4)))#if defined(gould) /* use this if B.b[i] is evaluated just once ... */#define DOXOR(x,y,i) x^=SPTAB(SPE[0][i],B.b[i]); y^=SPTAB(SPE[1][i],B.b[i]);#else#if defined(pdp11) /* use this if your "long" int indexing is slow */#define DOXOR(x,y,i) j=B.b[i]; x^=SPTAB(SPE[0][i],j); y^=SPTAB(SPE[1][i],j);#else /* use this if "k" is allocated to a register ... */#define DOXOR(x,y,i) k=B.b[i]; x^=SPTAB(SPE[0][i],k); y^=SPTAB(SPE[1][i],k);#endif#endif#define CRUNCH(p0, p1, q0, q1) \ k = (q0 ^ q1) & SALT; \ B.b32.i0 = k ^ q0 ^ kp->b32.i0; \ B.b32.i1 = k ^ q1 ^ kp->b32.i1; \ kp = (C_block *)((char *)kp+ks_inc); \ \ DOXOR(p0, p1, 0); \ DOXOR(p0, p1, 1); \ DOXOR(p0, p1, 2); \ DOXOR(p0, p1, 3); \ DOXOR(p0, p1, 4); \ DOXOR(p0, p1, 5); \ DOXOR(p0, p1, 6); \ DOXOR(p0, p1, 7); CRUNCH(L0, L1, R0, R1); CRUNCH(R0, R1, L0, L1); } while (--loop_count != 0); kp = (C_block *)((char *)kp-(ks_inc*KS_SIZE)); /* swap L and R */ L0 ^= R0; L1 ^= R1; R0 ^= L0; R1 ^= L1; L0 ^= R0; L1 ^= R1; } /* store the encrypted (or decrypted) result */ L0 = ((L0 >> 3) & 0x0f0f0f0fL) | ((L1 << 1) & 0xf0f0f0f0L); L1 = ((R0 >> 3) & 0x0f0f0f0fL) | ((R1 << 1) & 0xf0f0f0f0L); STORE(L,L0,L1,B); PERM6464(L,L0,L1,B.b, (C_block *)CF6464);#if defined(MUST_ALIGN) STORE(L,L0,L1,B); out[0] = B.b[0]; out[1] = B.b[1]; out[2] = B.b[2]; out[3] = B.b[3]; out[4] = B.b[4]; out[5] = B.b[5]; out[6] = B.b[6]; out[7] = B.b[7];#else STORE(L,L0,L1,*(C_block *)out);#endif return (0);}/* * Initialize various tables. This need only be done once. It could even be * done at compile time, if the compiler were capable of that sort of thing. */STATICvoidinit_des(){ register int i, j; register int k; register int tableno; static unsigned char perm[64], tmp32[32]; /* "static" for speed */ /* * table that converts chars "./0-9A-Za-z"to integers 0-63. */ for (i = 0; i < 64; i++) a64toi[itoa64[i]] = i; /* * PC1ROT - bit reverse, then PC1, then Rotate, then PC2. */ for (i = 0; i < 64; i++) perm[i] = 0; for (i = 0; i < 64; i++) { if ((k = PC2[i]) == 0) continue; k += Rotates[0]-1; if ((k%28) < Rotates[0]) k -= 28; k = PC1[k]; if (k > 0) { k--; k = (k|07) - (k&07); k++; } perm[i] = k; }#ifdef DEBUG prtab("pc1tab", perm, 8);#endif init_perm(PC1ROT, perm, 8, 8); /* * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2. */ for (j = 0; j < 2; j++) { unsigned char pc2inv[64]; for (i = 0; i < 64; i++) perm[i] = pc2inv[i] = 0; for (i = 0; i < 64; i++) { if ((k = PC2[i]) == 0) continue; pc2inv[k-1] = i+1; } for (i = 0; i < 64; i++) { if ((k = PC2[i]) == 0) continue; k += j; if ((k%28) <= j) k -= 28; perm[i] = pc2inv[k]; }#ifdef DEBUG prtab("pc2tab", perm, 8);#endif init_perm(PC2ROT[j], perm, 8, 8); } /* * Bit reverse, then initial permutation, then expansion. */ for (i = 0; i < 8; i++) { for (j = 0; j < 8; j++) { k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1]; if (k > 32) k -= 32; else if (k > 0) k--; if (k > 0) { k--; k = (k|07) - (k&07); k++; } perm[i*8+j] = k; } }#ifdef DEBUG prtab("ietab", perm, 8);#endif init_perm(IE3264, perm, 4, 8); /* * Compression, then final permutation, then bit reverse. */ for (i = 0; i < 64; i++) { k = IP[CIFP[i]-1]; if (k > 0) { k--; k = (k|07) - (k&07); k++; } perm[k-1] = i+1; }#ifdef DEBUG prtab("cftab", perm, 8);#endif init_perm(CF6464, perm, 8, 8); /* * SPE table */ for (i = 0; i < 48; i++) perm[i] = P32Tr[ExpandTr[i]-1]; for (tableno = 0; tableno < 8; tableno++) { for (j = 0; j < 64; j++) { k = (((j >> 0) &01) << 5)| (((j >> 1) &01) << 3)| (((j >> 2) &01) << 2)| (((j >> 3) &01) << 1)| (((j >> 4) &01) << 0)| (((j >> 5) &01) << 4); k = S[tableno][k]; k = (((k >> 3)&01) << 0)| (((k >> 2)&01) << 1)| (((k >> 1)&01) << 2)| (((k >> 0)&01) << 3); for (i = 0; i < 32; i++) tmp32[i] = 0; for (i = 0; i < 4; i++) tmp32[4 * tableno + i] = (k >> i) & 01; k = 0; for (i = 24; --i >= 0; ) k = (k<<1) | tmp32[perm[i]-1]; TO_SIX_BIT(SPE[0][tableno][j], k); k = 0; for (i = 24; --i >= 0; ) k = (k<<1) | tmp32[perm[i+24]-1]; TO_SIX_BIT(SPE[1][tableno][j], k); } }}/* * Initialize "perm" to represent transformation "p", which rearranges * (perhaps with expansion and/or contraction) one packed array of bits * (of size "chars_in" characters) into another array (of size "chars_out" * characters). * * "perm" must be all-zeroes on entry to this routine. */STATICvoidinit_perm(perm, p, chars_in, chars_out) C_block perm[64/CHUNKBITS][1<<CHUNKBITS]; unsigned char p[64]; int chars_in, chars_out;{ register int i, j, k, l; for (k = 0; k < chars_out*8; k++) { /* each output bit position */ l = p[k] - 1; /* where this bit comes from */ if (l < 0) continue; /* output bit is always 0 */ i = l>>LGCHUNKBITS; /* which chunk this bit comes from */ l = 1<<(l&(CHUNKBITS-1)); /* mask for this bit */ for (j = 0; j < (1<<CHUNKBITS); j++) { /* each chunk value */ if ((j & l) != 0) perm[i][j].b[k>>3] |= 1<<(k&07); } }}/* * "setkey" routine (for backwards compatibility) */int setkey(key) register const char *key;{ register int i, j, k; C_block keyblock; for (i = 0; i < 8; i++) { k = 0; for (j = 0; j < 8; j++) { k <<= 1; k |= (unsigned char)*key++; } keyblock.b[i] = k; } return (des_setkey((char *)keyblock.b));}/* * "encrypt" routine (for backwards compatibility) */int encrypt(block, flag) register char *block; int flag;{ register int i, j, k; C_block cblock; for (i = 0; i < 8; i++) { k = 0; for (j = 0; j < 8; j++) { k <<= 1; k |= (unsigned char)*block++; } cblock.b[i] = k; } if (des_cipher((char *)&cblock, (char *)&cblock, 0L, (flag ? -1: 1))) return (1); for (i = 7; i >= 0; i--) { k = cblock.b[i]; for (j = 7; j >= 0; j--) { *--block = k&01; k >>= 1; } } return (0);}#ifdef DEBUGSTATICvoidprtab(s, t, num_rows) char *s; unsigned char *t; int num_rows;{ register int i, j; (void)printf("%s:\n", s); for (i = 0; i < num_rows; i++) { for (j = 0; j < 8; j++) { (void)printf("%3d", t[i*8+j]); } (void)printf("\n"); } (void)printf("\n");}#endif/********************************************************************************* cryptRtnInit - install cryptographic authentication routine into hook** RETURNS: N/A** NOMANUAL*/void cryptRtnInit ( FUNCPTR *cryptRtnHook ) { *cryptRtnHook = (FUNCPTR) crypt; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -