/* $Id$ ***************************************************************************** * * File: cipher_funcs.c * * Author: Damien S. Stuart * * Purpose: Cipher functions used by fwknop * * License (GNU Public License): * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #include #include #include #include "cipher_funcs.h" #include "digest.h" #ifndef RAND_FILE #define RAND_FILE "/dev/urandom" #endif /* Get random data. */ void get_random_data(unsigned char *data, int len) { FILE *rfd; struct timeval tv; int i; /* Attempt to read seed data from /dev/urandom. If that does not * work, then fall back to a time-based method (less secure, but * probably more portable). */ if((rfd = fopen(RAND_FILE, "r")) == NULL) { /* Seed based on time (current usecs). */ gettimeofday(&tv, NULL); srand(tv.tv_usec); for(i=0; isalt, (data+8), 8); } else { /* Generate a random 8-byte salt. */ get_random_data(ctx->salt, 8); } /* Now generate the key and initialization vector. * (again it is the perl Crypt::CBC way, with a touch of * fwknop). */ memcpy(tmp_buf+16, pw_buf, 16); memcpy(tmp_buf+32, ctx->salt, 8); while(kiv_len < sizeof(kiv_buf)) { if(kiv_len == 0) md5(md5_buf, tmp_buf+16, 24); else md5(md5_buf, tmp_buf, 40); memcpy(tmp_buf, md5_buf, 16); memcpy(kiv_buf + kiv_len, md5_buf, 16); kiv_len += 16; } memcpy(ctx->key, kiv_buf, 32); memcpy(ctx->iv, kiv_buf+32, 16); } /* Initialization entry point. */ void rijndael_init(RIJNDAEL_context *ctx, const char *pass, unsigned char *data) { /* Use ECB mode to be compatible with the Crypt::CBC perl module. */ ctx->mode = MODE_ECB; /* Generate the salt and initialization vector. */ salt_and_iv(ctx, pass, data); /* Intialize our rinjdael context. */ rijndael_setup(ctx, 32, ctx->key); } /* Take a chunk of data, encrypt it in the same way the perl Crypt::CBC * module would. */ int fko_encrypt(unsigned char *in, int in_len, const char *pass, unsigned char *out) { RIJNDAEL_context ctx; unsigned char plaintext[16]; unsigned char mixtext[16]; unsigned char ciphertext[16]; int i, pad_val; unsigned char *ondx = out; rijndael_init(&ctx, pass, NULL); /* Prepend the salt... */ memcpy(ondx, "Salted__", 8); ondx+=8; memcpy(ondx, ctx.salt, 8); ondx+=8; /* Now iterate of the input data and encrypt in 16-byte chunks. */ while(in_len) { for(i=0; i= 0 && pad_val <= 16) { pad_s = ondx - pad_val; for(i=0; i < (ondx-pad_s); i++) { if(*(pad_s+i) != pad_val) pad_err++; } if(pad_err == 0) ondx -= pad_val; } *ondx = '\0'; return(ondx - out); } /* void hex_dump(unsigned char *data, int size) { int ln, i, j = 0; char ascii_str[17] = {0}; for(i=0; i 0x7e) ? '.' : data[i]; if(j == 8) printf(" "); } // Remainder... ln = strlen(ascii_str); if(ln > 0) { for(i=0; i < 16-ln; i++) printf(" "); printf(" %s\n\n", ascii_str); } } */ /***EOF***/