/* The main puzzle struct type */
typedef struct {
- char chars[MAX_PUZZLE_SIZE][MAX_PUZZLE_SIZE];
+ char chars[MAX_PUZZLE_SIZE+1][MAX_PUZZLE_SIZE+1];
int start_across_word[MAX_PUZZLE_SIZE][MAX_PUZZLE_SIZE];
int start_down_word[MAX_PUZZLE_SIZE][MAX_PUZZLE_SIZE];
String clue_across[MAX_PUZZLE_SIZE][MAX_PUZZLE_SIZE];
Puzzle puzzle;
char filename[65535];
bool is_loaded;
- char char_ans[MAX_PUZZLE_SIZE][MAX_PUZZLE_SIZE];
+ char char_ans[MAX_PUZZLE_SIZE+1][MAX_PUZZLE_SIZE+1];
int cur_row;
int cur_col;
bool solution_revealed;
exit (2);
}
-/* encode the binary data to readable text format using OpenSSL */
-void encode_binary (char *encoded, unsigned char *binary_data, unsigned int len)
+/* encode the binary data to readable text format using OpenSSL - also call
+ OPENSSL_free if the binary data was allocated by OpenSSL */
+void encode_binary (char *encoded, unsigned char *binary_data, unsigned int len,
+ bool free_openssl_data)
{
EVP_EncodeBlock ((unsigned char*)encoded,
(const unsigned char*)binary_data, len);
- OPENSSL_free (binary_data);
+ if (free_openssl_data)
+ OPENSSL_free (binary_data);
+}
+
+/* decode the binary data from the textual representation using OpenSSL */
+void decode_binary (char *bin_data, char *encoded)
+{
+ EVP_DecodeBlock ((unsigned char*)bin_data,
+ (const unsigned char*)encoded, strlen (encoded));
+}
+
+/* encrypt a block of text using password/passphrase with OpenSSL and
+ also encode it to textual representation */
+void encrypt_data (char *enc_data, const char *data, const char *password)
+{
+ EVP_CIPHER_CTX *ctx;
+ int len, cipher_len;
+ ctx = EVP_CIPHER_CTX_new ();
+ if (! ctx) goto err;
+
+ unsigned char encrypted[256] = { '\0' };
+
+ unsigned char key[EVP_MAX_KEY_LENGTH] = { '\0'};
+ unsigned char iv[EVP_MAX_IV_LENGTH] = { '\0' };
+
+ if (! EVP_BytesToKey (EVP_aes_256_cbc(), EVP_md5(), NULL,
+ (unsigned char*)password, strlen(password),
+ 10, key, iv))
+ goto err;
+
+ if (1 != EVP_EncryptInit_ex (ctx, EVP_aes_256_cbc(), NULL, key, iv))
+ goto err;
+
+ if (1 != EVP_EncryptUpdate (ctx, (unsigned char*) encrypted, &len,
+ (unsigned char*) data, strlen (data) ))
+ goto err;
+ cipher_len = len;
+
+ if (1 != EVP_EncryptFinal_ex (ctx, encrypted + len, &len))
+ goto err;
+
+ cipher_len += len;
+ EVP_CIPHER_CTX_free (ctx);
+
+ EVP_EncodeBlock ((unsigned char*) enc_data, (unsigned char*) encrypted,
+ cipher_len);
+ return;
+ err:
+ ERR_print_errors_fp (stderr);
+ EVP_CIPHER_CTX_free (ctx);
+ exit (2);
+}
+
+/* decrypt a block of text using password/passphrase with OpenSSL */
+void decrypt_data (char *dec_data, const char *data, const char *password)
+{
+ EVP_CIPHER_CTX *ctx;
+ int len, text_len;
+ ctx = EVP_CIPHER_CTX_new ();
+ if (! ctx) goto err;
+
+ char enc_data[256] = { '\0' };
+
+ unsigned char key[EVP_MAX_KEY_LENGTH] = { '\0'};
+ unsigned char iv[EVP_MAX_IV_LENGTH] = { '\0' };
+
+
+ if (! EVP_BytesToKey (EVP_aes_256_cbc(), EVP_md5(), NULL,
+ (unsigned char*)password, strlen(password),
+ 10, key, iv))
+ goto err;
+
+ int r = EVP_DecodeBlock ((unsigned char*)enc_data,
+ (const unsigned char*) data, strlen (data));
+ if (-1 == r)
+ goto err;
+
+
+ if (1 != EVP_DecryptInit_ex (ctx, EVP_aes_256_cbc(), NULL, key, iv))
+ goto err;
+
+ if (1 != EVP_DecryptUpdate (ctx, (unsigned char*) dec_data, &len,
+ (unsigned char*) enc_data, r - (r % 16) ))
+ goto err;
+ text_len = len;
+
+ if (1 != EVP_DecryptFinal_ex (ctx, (unsigned char *)dec_data + len, &len))
+ goto err;
+
+ text_len += len;
+ EVP_CIPHER_CTX_free (ctx);
+
+ dec_data[text_len] = '\0';
+
+ return;
+ err:
+ ERR_print_errors_fp (stderr);
+ EVP_CIPHER_CTX_free (ctx);
+ exit (2);
}
/* get a number from the user */
digest_message ((const unsigned char *)password, strlen(password),
&hashed_sol_password, &len);
char hashed_hex_pwd[256] = { '\0' };
- encode_binary (hashed_hex_pwd, hashed_sol_password, len);
+ encode_binary (hashed_hex_pwd, hashed_sol_password, len, true);
if (strcmp (p->hashed_solution_password, hashed_hex_pwd) == 0)
return true;
digest_message ((const unsigned char *)password, strlen(password),
&hashed_mas_password, &len);
char hashed_hex_pwd[256] = { '\0' };
- encode_binary (hashed_hex_pwd, hashed_mas_password, len);
+ encode_binary (hashed_hex_pwd, hashed_mas_password, len, true);
if (strcmp (p->hashed_master_password, hashed_hex_pwd) == 0)
return true;
/* the hashedpwd contains binary data - we will convert it to
hexadecimal data and store in file */
- encode_binary (p->hashed_solution_password, hashedpwd, len);
+ encode_binary (p->hashed_solution_password, hashedpwd, len, true);
}
}
/* the hashedpwd contains binary data - we will convert it to
hexadecimal data and store in file */
- encode_binary (p->hashed_master_password, hashedpwd, len);
+ encode_binary (p->hashed_master_password, hashedpwd, len, true);
}
}
/* the hashed_solution_password */
fprintf (outfile, "%s\n", puzzle->hashed_solution_password);
- /* First output the grid characters columns/rows */
+ /* First output the grid characters columns/rows as encrypted */
for (int i = 0; i < puzzle->grid_size; i ++)
{
- for (int j = 0; j < puzzle->grid_size; j ++)
- fprintf (outfile, "%c", puzzle->chars[i][j]);
+ char encrypted[256] = { '\0' };
+ encrypt_data (encrypted, puzzle->chars[i],
+ puzzle->hashed_master_password);
+
+ fprintf (outfile, "%s", encrypted);
fprintf (outfile, "\n");
}
/* read each character of the grid */
for (int i = 0; i < p.grid_size; i ++ )
{
- fgets (line, MAX_CLUE_LENGTH + 10, infile);
+ char encoded[256];
+ fgets (encoded, MAX_CLUE_LENGTH + 10, infile);
+ decrypt_data (line, encoded, p.hashed_master_password);
for (int j = 0; j < p.grid_size; j ++)
p.chars[i][j] = line[j];
+
}
/* read the word numbers */
for (int i = 0; i < p.grid_size; i ++)