9 static const char rcsid[] __attribute__((used)) =
"$Id: Crypt.cpp 1653 2016-02-28 19:54:59Z sella $";
12 #include "CommonMacro.h"
14 #include "../Exception.h"
19 #include <mutils/mhash.h>
25 using namespace sella::util;
27 Crypt::Crypt(
const char *algo,
const char *mode,
int keylen, uint32_t seed) : init(false), password(NULL), salt(NULL), key(NULL), iv(NULL), algo(algo), mode(mode) {
28 td = mcrypt_module_open((
char*) algo, NULL, (
char*) mode, NULL);
30 if (mcrypt_enc_is_block_algorithm(td) == 1 && mcrypt_enc_is_block_mode(td) == 1) {
31 THROW(Exception,
"Crypt does not support block algorithm or block modes");
37 setFlipSeed((uint32_t) Time::gettimeofday_usec());
42 setPassword(CRYPT_PASSWORD_DEF, CRYPT_SALT_DEF);
45 Crypt::Crypt(
const Crypt &other) :
48 password(strdup(other.password)),
49 salt(strdup(other.salt)),
50 key((unsigned char *)malloc(other.keylen)),
56 memcpy(this->key, other.key, this->keylen);
58 this->td = mcrypt_module_open((
char*) this->algo.c_str(), NULL, (
char*) this->mode.c_str(), NULL);
64 mcrypt_module_close(td);
67 Crypt& Crypt::operator=(
const Crypt &other)
throw () {
72 this->seed = other.seed;
73 this->password = strdup(other.password);
74 this->salt = strdup(other.salt);
76 this->keylen = other.keylen;
77 this->algo = other.algo;
78 this->mode = other.mode;
80 key = (
unsigned char *)malloc(this->keylen);
81 memcpy(this->key, other.key, this->keylen);
83 this->td = mcrypt_module_open((
char*) this->algo.c_str(), NULL, (
char*) this->mode.c_str(), NULL);
89 void Crypt::clear(
void) {
90 int iv_size = mcrypt_enc_get_iv_size(td);
96 memset(this->iv, 0, iv_size);
101 memset(this->key, 0, this->keylen);
102 SAFE_FREE(this->key);
106 memset(this->salt, 0, strlen(this->salt));
107 SAFE_FREE(this->salt);
110 if (this->password) {
111 memset(this->password, 0, strlen(this->password));
112 SAFE_FREE(this->password);
116 void Crypt::setSeed(uint32_t seed) {
121 int iv_size = mcrypt_enc_get_iv_size(td);
123 memset(this->iv, 0, iv_size);
128 void Crypt::setFlipSeed(uint32_t seed, uint32_t pattern) {
129 setSeed((~seed) ^ pattern);
132 uint32_t Crypt::getSeed(
void)
const {
136 bool Crypt::setPassword(
const char *password,
const char *salt) {
138 int passlen, saltlen;
139 unsigned char* key = NULL;
141 assert(password != NULL);
142 assert(salt != NULL);
146 memset(this->key, 0, this->keylen);
147 SAFE_FREE(this->key);
151 memset(this->salt, 0, strlen(this->salt));
152 SAFE_FREE(this->salt);
155 if (this->password) {
156 memset(this->password, 0, strlen(this->password));
157 SAFE_FREE(this->password);
160 if (password == NULL || salt == NULL) {
164 if ((key = (
unsigned char*) calloc(1, keylen)) == NULL) {
168 if ((saltlen = mhash_get_keygen_salt_size(KEYGEN_MCRYPT)) == 0) {
169 saltlen = strlen(salt);
170 }
else if (saltlen > (
int) strlen(salt)) {
171 saltlen = strlen(salt);
174 data.hash_algorithm[0] = MHASH_MD5;
176 data.salt = (
void*) salt;
177 data.salt_size = saltlen;
178 passlen = strlen(password);
180 if (mhash_keygen_ext(KEYGEN_MCRYPT, data, key, keylen, (
unsigned char*) password, passlen) < 0) {
185 this->password = strndup(password, passlen);
186 this->salt = strndup(salt, saltlen);
189 printf(
"key(%d): 0x", keylen);
190 for (
int i = 0; i < keylen; i++) {
191 printf(
"%.2x", this->key[i]);
200 memset(key, 0, this->keylen);
207 const char* Crypt::getPassword(
void) {
211 const unsigned char* Crypt::getKey(
void) {
215 void Crypt::setKeyLen(
int bits) {
216 int maxlen = mcrypt_enc_get_key_size(td);
219 if (keylen > maxlen) {
221 }
else if (keylen < 1) {
222 keylen = CRYPT_KEYLEN_DEF;
226 if (password && salt) {
227 char *tpassword = strdup(password);
228 char *tsalt = strdup(salt);
230 setPassword(password, salt);
233 memset(tpassword, 0, strlen(tpassword));
234 SAFE_FREE(tpassword);
236 memset(tsalt, 0, strlen(tsalt));
241 int Crypt::getKeyLen(
void)
const {
245 bool Crypt::encrypt(
char *plaintext,
int len) {
246 if (!plaintext || len < 1) {
254 return !mcrypt_generic(td, plaintext, len);
257 bool Crypt::decrypt(
char *ciphertext,
int len) {
258 if (!ciphertext || len < 1) {
266 return !mdecrypt_generic(td, ciphertext, len);
269 bool Crypt::check(
const char *ciphertext,
int len) {
273 if ((tmp = malloc(len)) == NULL) {
277 memcpy(tmp, ciphertext, len);
279 retval = decrypt((
char*) tmp, len);
287 bool Crypt::initialize(
void) {
288 if (!deinitialize()) {
298 if (mcrypt_generic_init(td, key, keylen, iv) >= 0) {
307 bool Crypt::deinitialize(
void) {
311 if (mcrypt_generic_deinit(td) < 0) {
319 bool Crypt::generateIV(
void) {
320 struct drand48_data state;
322 int iv_size = mcrypt_enc_get_iv_size(td);
325 memset(this->iv, 0, iv_size);
329 if ((this->iv = (
unsigned char*) malloc(iv_size)) == NULL) {
333 srand48_r(seed, &state);
334 for (
int i = 0; i < iv_size; i++) {
335 lrand48_r(&state, &result);
336 this->iv[i] = (
unsigned char) result;
340 printf(
"iv(%d)[seed: %lu]: 0x", iv_size, seed);
341 for (
int i = 0; i < iv_size; i++) {
342 printf(
"%.1x", this->iv[i]);