/* ***************************************************************************** * * File: cipher_funcs.c * * Author: Damien S. Stuart * * Purpose: Cipher functions used by fwknop * * Copyright 2009-2010 Damien Stuart (dstuart@dstuart.org) * * License (GNU Public License): * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * 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 #ifdef WIN32 #include #include #include #else #include #endif #include "cipher_funcs.h" #include "digest.h" #ifndef WIN32 #ifndef RAND_FILE #define RAND_FILE "/dev/urandom" #endif #endif /* Get random data. */ void get_random_data(unsigned char *data, size_t len) { uint32_t i; #ifdef WIN32 int rnum; struct _timeb tb; _ftime_s(&tb); srand((uint32_t)(tb.time*1000)+tb.millitm); 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, 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. */ rij_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. */ size_t rij_encrypt(unsigned char *in, size_t in_len, 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); } /***EOF***/