/* * convert the key to a bit pattern * obuf bit pattern * inbuf the key itself */ void expand_des_key(char *obuf, char *inbuf) { int i, j; /* counter in a for loop */ int nbuf[64]; /* used for hex/key translation */ /* * leading '0x' or '0X' == hex key */ if (inbuf[0] == '0' && (inbuf[1] == 'x' || inbuf[1] == 'X')) { inbuf = &inbuf[2]; /* * now translate it, bombing on any illegal hex digit */ for (i = 0; inbuf[i] && i < 16; i++) if ((nbuf[i] = hex_to_binary((int) inbuf[i], 16)) == -1) des_error("bad hex digit in key"); while (i < 16) nbuf[i++] = 0; for (i = 0; i < 8; i++) obuf[i] = ((nbuf[2*i]&0xf)<<4) | (nbuf[2*i+1]&0xf); /* preserve parity bits */ pflag = 1; return; } /* * leading '0b' or '0B' == binary key */ if (inbuf[0] == '0' && (inbuf[1] == 'b' || inbuf[1] == 'B')) { inbuf = &inbuf[2]; /* * now translate it, bombing on any illegal binary digit */ for (i = 0; inbuf[i] && i < 16; i++) if ((nbuf[i] = hex_to_binary((int) inbuf[i], 2)) == -1) des_error("bad binary digit in key"); while (i < 64) nbuf[i++] = 0; for (i = 0; i < 8; i++) for (j = 0; j < 8; j++) obuf[i] = (obuf[i]<<1)|nbuf[8*i+j]; /* preserve parity bits */ pflag = 1; return; } /* * no special leader -- ASCII */ strncpy(obuf, inbuf, 8); }
/* * This decrypts using the Cipher Block Chaining mode of DES * msgbuf I/O buffer * fp input file descriptor */ int cbc_decode(char *msgbuf, FILE *fp) { DES_cblock inbuf; /* temp buffer for initialization vector */ int n; /* number of bytes actually read */ int c; /* used to test for EOF */ int inverse = 1; /* 0 to encrypt, 1 to decrypt */ if ((n = READ(msgbuf, 8, fp)) == 8) { /* * do the transformation */ MEMCPY(inbuf, msgbuf, 8); DES_XFORM((DES_cblock *)msgbuf); for (c = 0; c < 8; c++) msgbuf[c] ^= ivec[c]; MEMCPY(ivec, inbuf, 8); /* * if the last one, handle it specially */ if ((c = fgetc(fp)) == EOF) { n = msgbuf[7]; if (n < 0 || n > 7) { des_error("decryption failed (block corrupted)"); return EOF; } } else ungetc(c, fp); return n; } if (n > 0) des_error("decryption failed (incomplete block)"); else if (n < 0) des_error("cannot read file"); return EOF; }
/* * This decrypts using the Cipher Block Chaining mode of DES * msgbuf I/O buffer * fp input file descriptor */ int cbc_decode(char *msgbuf, FILE *fp) { Desbuf tbuf; /* temp buffer for initialization vector */ int n; /* number of bytes actually read */ int c; /* used to test for EOF */ int inverse = 1; /* 0 to encrypt, 1 to decrypt */ if ((n = READ(BUFFER(msgbuf), 8, fp)) == 8) { /* * do the transformation */ MEMCPY(BUFFER(tbuf), BUFFER(msgbuf), 8); DES_XFORM(UBUFFER(msgbuf)); for (c = 0; c < 8; c++) UCHAR(msgbuf, c) ^= UCHAR(ivec, c); MEMCPY(BUFFER(ivec), BUFFER(tbuf), 8); /* * if the last one, handle it specially */ if ((c = fgetc(fp)) == EOF) { n = CHAR(msgbuf, 7); if (n < 0 || n > 7) { des_error("decryption failed (block corrupted)"); return EOF; } } else (void)ungetc(c, fp); return n; } if (n > 0) des_error("decryption failed (incomplete block)"); else if (n < 0) des_error("cannot read file"); return EOF; }