/** * crypt.c: pseudo OO wrapper around libmcrypt. * Copyright (C) 2011 Georg Hopp * * This program 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 3 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, see . */ #include #include #include #include #include #include #include #include #include "token/cclass.h" #include "token/crypt.h" static void __construct(struct CRYPT * _this, va_list * params) { _this->algorithm = va_arg(* params, const char * const); _this->mode = va_arg(* params, const char * const); _this->mcrypt = mcrypt_module_open( (char *)_this->algorithm, NULL, (char *)_this->mode, NULL); _this->ivsize = mcrypt_enc_get_iv_size(_this->mcrypt); _this->keysize = mcrypt_enc_get_key_size(_this->mcrypt); } static void __destruct(struct CRYPT * _this) { if (_this->iv) { free(_this->iv); } mcrypt_module_close(_this->mcrypt); } static const struct CCLASS _crypt = { sizeof(struct CRYPT), (ctor)__construct, NULL, (dtor)__destruct, NULL }; const struct CCLASS * const CRYPT = &_crypt; void * crypt_createIv(struct CRYPT * _this) { int urandom; size_t rsize = 0; void * iv = NULL; iv = calloc(_this->ivsize, sizeof(char)); urandom = open("/dev/urandom", O_RDONLY); rsize = read(urandom, iv, _this->ivsize); if (_this->ivsize != rsize) { free(iv); iv = NULL; } return iv; } static void * createKey(struct CRYPT * _this, const char * const password) { void * key = NULL; key = calloc(_this->keysize, sizeof(char)); mhash_keygen( KEYGEN_MCRYPT, MHASH_SHA256, mhash_keygen_count(), key, _this->keysize, NULL, 0, (char *)password, // @TODO: bad karma...now this might change password. strlen(password)); return key; } void * crypt_encrypt( struct CRYPT * _this, const void * const data, const char * const password, size_t * length) { char * encrypted; void * iv; void * key; key = createKey(_this, password); if(_this->iv) { iv = _this->iv; } else { iv = crypt_createIv(_this); } mcrypt_generic_init(_this->mcrypt, key, _this->keysize, iv); encrypted = calloc(_this->ivsize + *length, sizeof(char)); memcpy(encrypted, iv, _this->ivsize); memcpy(encrypted + _this->ivsize, data, *length); mcrypt_generic(_this->mcrypt, encrypted + _this->ivsize, *length); mcrypt_generic_deinit(_this->mcrypt); *length += _this->ivsize; free(key); if (_this->iv != iv) { free(iv); } return encrypted; } void * crypt_decrypt( struct CRYPT * _this, const void * const data, const char * const password, size_t * length) { char * decrypted; void * iv; void * key; key = createKey(_this, password); iv = calloc(_this->ivsize, sizeof(char)); memcpy(iv, data, _this->ivsize); mcrypt_generic_init(_this->mcrypt, key, _this->keysize, iv); *length -= _this->ivsize; decrypted = calloc(*length, sizeof(char)); memcpy(decrypted, data + _this->ivsize, *length); mdecrypt_generic(_this->mcrypt, decrypted, *length); mcrypt_generic_deinit(_this->mcrypt); free(key); free(iv); return decrypted; } // vim: set et ts=4 sw=4: