For the demo issue see function: test_encrypt()
* The sha2 functions appear to work.
Code: Select all
#include <irrlicht.h>
//#include "driverChoice.h"
#include <iostream>
#include <sstream> // u2hex
#include <iomanip> // u2hex
//using namespace std;
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif
#include "../../source/Irrlicht/aesGladman/aes.h"
#include "../../source/Irrlicht/aesGladman/hmac.h"
#include "../../source/Irrlicht/aesGladman/sha1.h"
#include "../../source/Irrlicht/aesGladman/pwd2key.h"
#include "../../source/Irrlicht/aesGladman/fileenc.h"
//#include "../../source/Irrlicht/aesGladman/aesopt.h"
#include "../../source/Irrlicht/aesGladman/prng.h"
#include "../../source/Irrlicht/aesGladman/sha2.h"
//#include "../../source/Irrlicht/aesGladman/aes_modes.h"
IrrlichtDevice* device;
irr::core::stringc sha2_str(irr::core::stringc &content);
int sha2_file(path fn, stringc &content);
stringc hex_to_string(const std::string& in);
stringc string_to_hex(const std::string& in);
std::string u2hex(unsigned char c);
stringc exe_cmd(stringc s, int &iret);
s32 str_encrypt(stringc &msg, stringc pass)
{
/*
The return value is 0 if the initialization was successful; non-zero values indicate errors. Note that
passwords are null-terminated ANSI strings; embedded nulls must not be used. (To avoid incompatibilities
between the various character sets in use, especially in different versions of Windows, users should be
encouraged to use passwords containing only the "standard" characters in the range 32-127.)
The function returns the password verification value in achPswdVerifier, which must be a 2-byte buffer.
If you are encrypting, store this value in the Zip file as indicated by the encryption specification. If
you are decrypting, compare this returned value to the value stored in the Zip file. If they are different,
then either the password provided by your user was incorrect or the encrypted file has been altered in
some way since it was encrypted. (Note that if they match, there is still a 1 in 65,536 chance that an
incorrect password was provided.)
https://github.com/nih-at/libzip/blob/master/docs/aes_coding_tips.txt
You may need to call the encrypt or decrypt function multiple times,
passing in successive chunks of data in the buffer. For AE-1 and AE-2
compatibility, the buffer size must be a multiple of 16 bytes except for
the last buffer, which may be smaller. For efficiency, a larger buffer size
such as 32,768 would generally be used.
*/
// ENC TEST: encode
u8 salt[16]={0};
//u8 *salt=prng();
unsigned char pwVerificationFile[2];
std::cout << "<<< str_encrypt() 0" << std::endl;
fcrypt_ctx zctx; // the encryption context
int rc = fcrypt_init(
0x03, // extra data value indicating key size (e.header.Sig & 0x00ff0000) >>16, ?? 1,2,3 ???
(const unsigned char*)pass.c_str(), // the password
pass.size(), // number of bytes in password
salt, // the salt
(unsigned char*)pwVerificationFile, // on return contains password verifier
&zctx); // encryption context
if(rc != 0)
{
// ERROR
std::cout << "<<< str_encrypt() rc init error!!!" << std::endl;
return 1;
}
/*
int fcrypt_init(
int mode, // the mode to be used (input) ? keysize
const unsigned char pwd[], // the user specified password (input)
unsigned int pwd_len, // the length of the password (input)
const unsigned char salt[], // the salt (input)
#ifdef PASSWORD_VERIFIER
unsigned char pwd_ver[PWD_VER_LENGTH], // 2 byte password verifier (output)
#endif
fcrypt_ctx cx[1]); // the file encryption context (output)
*/
//fcrypt_encrypt((unsigned char*)msg_enc, strlen(msg_enc), &zctx);
stringc msg_in = msg; // copy msg buffer
msg = ""; // clear msg buffer for return fill
stringc buf;
s32 len = 512;
u32 i = 0;
while(i < msg_in.size())
{
buf = msg_in.subString(i, len);
std::cout << " >--" << buf.c_str() << "--<" << std::endl;
i += len;
//fcrypt_encrypt((unsigned char*)msg_enc, strlen(msg_enc), &zctx);
fcrypt_encrypt((unsigned char*)buf.c_str(), strlen(buf.c_str()), &zctx);
msg += buf;
}
char resMAC[10];
rc = fcrypt_end(
(unsigned char*)resMAC, // on return contains the authentication code
&zctx); // encryption context
if(rc != 10)
{
// ERROR
std::cout << "<<< <<< <<< ENCRYPTED: Error on encryption closing: " << rc << std::endl;
return 1;
}
return 0;
}
stringc str_decrypt(stringc msg, stringc pass)
{
// ENC TEST: decode
u8 salt[16]={0};
unsigned char pwVerificationFile[2];
fcrypt_ctx zctx2; // the encryption context
int rc = fcrypt_init(
0x03, // extra data value indicating key size (e.header.Sig & 0x00ff0000) >>16,
(const unsigned char*)pass.c_str(), // the password
pass.size(), // number of bytes in password
salt, // the salt
(unsigned char*)pwVerificationFile, // on return contains password verifier
&zctx2); // encryption context
//std::cout << "<<< <<< <<< DECRYPT rc: " << rc << std::endl; // 0
if(rc != 0)
{
// ERROR
}
/*
int fcrypt_init(
int mode, // the mode to be used (input) ? keysize
const unsigned char pwd[], // the user specified password (input)
unsigned int pwd_len, // the length of the password (input)
const unsigned char salt[], // the salt (input)
#ifdef PASSWORD_VERIFIER
unsigned char pwd_ver[PWD_VER_LENGTH], // 2 byte password verifier (output)
#endif
fcrypt_ctx cx[1]); // the file encryption context (output)
*/
//fcrypt_decrypt((unsigned char*)msg_enc, strlen(msg_enc), &zctx2);
stringc msg_enc = "";
//stringc msg = "Now is the time for all good men to come to the aide of their country.";
stringc msg_in = msg.c_str();
stringc buf;
s32 len = 512;
u32 i = 0;
while(i < msg_in.size())
{
buf = msg_in.subString(i, len);
//std::cout << " >--" << buf.c_str() << "--<" << std::endl;
i += len;
//fcrypt_encrypt((unsigned char*)msg_enc, strlen(msg_enc), &zctx);
fcrypt_decrypt((unsigned char*)buf.c_str(), strlen(buf.c_str()), &zctx2);
msg_enc += buf;
}
char resMAC[10];
rc = fcrypt_end(
(unsigned char*)resMAC, // on return contains the authentication code
&zctx2); // encryption context
//std::cout << "<<< <<< <<< DECRYPT rc: " << rc << std::endl; // 10
if (rc != 10)
{
std::cout << "<<< <<< <<< DECRYPTED: Error on decryption closing: " << rc << std::endl;
//os::Printer::log("Error on encryption closing");
//delete [] decryptedBuf;
//return 0;
}
return msg_enc.c_str();
}
void test_encrypt()
{
// ENCRYPT TESTS
// =========================================================================
stringc msg = "My message to say... blah blah blah blah blah boing! blah blah blah blah blah boing! blah blah blah blah blah boing! blah blah blah blah blah boing! blah blah blah blah blah boing! blah blah blah blah blah boing! blah blah blah blah blah boing! blah blah blah blah blah boing! blah blah blah blah blah boing! blah blah blah blah blah boing! blah blah blah blah blah boing! blah blah blah blah blah boing! blah blah blah blah blah boing! blah blah blah blah blah boing! blah blah blah blah blah boing! blah blah blah blah blah boing! blah blah blah blah blah boing! blah blah blah blah blah boing! blah blah blah blah blah boing! blah blah blah blah blah boing! blah blah blah blah blah boing! BOING BOING!!!";
//stringc msg = "My message to say...wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwjjjttttttttttttttttttttttttttttttttttttttttttttssyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyeey_148";
std::cout << "<<< <<< <<< LEN: " << msg.size()<< std::endl;
stringc pass = "password";
// ENCRYPT
//stringc s_enc =
if(str_encrypt(msg, pass))
{
// ERROR
}
stringc s_enc = msg;
std::cout << "<<< <<< <<< ENCRYPTED: " << std::endl;
//std::cout << "<<< <<< <<< ENCRYPTED: " << s_enc.c_str() << std::endl;
// CONVERT TO HEX
stringc s_enc_h = string_to_hex(s_enc.c_str()); // const std::string& in);
std::cout << "<<< <<< <<< ENCRYPTED HEX: " << s_enc_h.c_str() << std::endl;
// CONVERT FROM HEX
stringc s_enc_hh = hex_to_string(s_enc_h.c_str()); // const std::string& in);
//std::cout << "<<< <<< <<< ENCRYPTED DE-HEX: " << s_enc_hh.c_str() << std::endl;
// DECRYPT
stringc s_out = str_decrypt(s_enc_hh, pass);
std::cout << "<<< <<< <<< DECRYPTED: " << s_out.c_str() << std::endl;
}
void tester()
{
std::cout << "<<< <<< <<< TESTER: chunkin'" << std::endl;
stringc msg = "Now is the time for all good men to come to the aide of their country.";
stringc buf;
s32 len = 4;
u32 i = 0;
while(i < msg.size())
{
buf = msg.subString(i, len);
std::cout << " >--" << buf.c_str() << "--<" << std::endl;
i += len;
}
}
void test_salt()
{
/*
std::string salt = prng();
//u8 *salt = prng();
std::cout << "<<< <<< <<< PRNG: " << salt << std::endl;
*/
}
void test_hash()
{
//stringc msg = "";
//stringc msg = "hello";
stringc msg = "Now is the time for all good men to come to the aide of their country. Now is the time for all good men to come to the aide of their country. Now is the time for all good men to come to the aide of their country. Now is the time for all good men to come to the aide of their country. Now is the time for all good men to come to the aide of their country. Now is the time for all good men to come to the aide of their country. Now is the time for all good men to come to the aide of their country. Now is the time for all good men to come to the aide of their country. Now is the time for all good men to come to the aide of their country. Now is the time for all good men to come to the aide of their country. Now is the time for all good men to come to the aide of their country. ";
//stringc msg = "The quick brown fox jumped over the lazy dog.";
//stringc stroutput = sha2_str("Blah, blah, blah, blah! Blah, blah, blah, blah! Blah, blah, blah, blah! Blah, blah, blah, blah! Blah, blah, blah, blah! Blah, blah, blah, blah! Blah, blah, blah, blah! Blah, blah, blah, blah! Blah, blah, blah, blah! Blah, blah, blah, blah! Blah, blah, blah, blah! Blah, blah, blah, blah! Blah, blah, blah, blah! Blah, blah, blah, blah! Blah, blah, blah, blah! Blah, blah, blah, blah! Blah, blah, blah, blah! Blah, blah, blah, blah! ");
// HASH STRING
stringc stroutput = sha2_str(msg);
//std::cout << "SHA2 HELLO: " << stroutput.c_str() << std::endl;
// SYSTEM TEST FOR COMPARISON
stringc cmd_prefix = "php test_hash.php \"";
stringc cmd = cmd_prefix+msg+"\"";
int iret = 0;
stringc php_res = exe_cmd(cmd, iret);
// OUTPUT
std::cout << "SHA2 MSG: " << msg.c_str() << std::endl;
std::cout << "IRR SHA2: " << stroutput.c_str() << std::endl;
std::cout << "PHP SHA2: " << php_res.c_str() << std::endl;
}
void test_hash_file()
{
path fn = "main.cpp";
stringc shash = "where the hash will be";
// HASH FILE
if(sha2_file(fn, shash))
{
// FAILED
}
// SYSTEM TEST FOR COMPARISON
//stringc cmd_prefix = "php test_hash.php \"";
stringc cmd_prefix = "sha256sum \"";
stringc cmd = cmd_prefix+fn+"\"";
int iret = 0;
stringc sys_res = exe_cmd(cmd, iret);
// OUTPUT
std::cout << "fn: " << fn.c_str() << std::endl;
std::cout << "IRR SHA2: " << shash.c_str() << std::endl;
std::cout << "SYS SHA2: " << sys_res.c_str() << std::endl;
//std::cout << "PHP SHA2: " << php_res.c_str() << std::endl;
}
int main()
{
device = createDevice(EDT_NULL);
if (device == 0)
return 1; // could not create selected driver.
//test_hash();
//test_hash_file();
test_encrypt();
//tester();
device->drop();
}
// CRYPTO FUNCTIONS
// ==================================================
#define SHA2___BUF_SIZE 16384
int sha2_file(path fn, stringc &content)
{
/*
$ sha256sum main.cpp
792108593a153787d9d7a336694d58aa4bce333d9658b79822dc67f850359b67 main.cpp
*/
FILE *inf;
sha256_ctx ctx[1];
unsigned char buf[SHA2___BUF_SIZE], hval[SHA256_DIGEST_SIZE];
int i;
// FILE OPEN (non irr)
if(!(inf = fopen(fn.c_str(), "rb")))
{
printf("\n%s not found\n", fn.c_str());
return 1;
}
// HASH START
sha256_begin(ctx);
do
{
// READ FILE BUFFER
i = (int)fread(buf, 1, SHA2___BUF_SIZE, inf);
if(i)
{
// HASH BUFFER
sha256_hash(buf, i, ctx);
}
}
while(i);
// FILE CLOSE
fclose(inf);
// HASH FINISH
sha256_end(hval, ctx);
// CONVERT TO HEX
content = "";
for(i = 0; i < SHA256_DIGEST_SIZE; ++i)
{
//printf("%02x", hval[i]);
content += u2hex(hval[i]).c_str();
}
return 0;
}
irr::core::stringc sha2_str(irr::core::stringc &content)
{
sha256_ctx ctx[1];
//unsigned char buf[SHA2___BUF_SIZE];
unsigned char hval[SHA256_DIGEST_SIZE];
int i; //, len;
// HASH START
sha256_begin(ctx);
// HASH CONTENT
sha256_hash((unsigned char*)content.c_str(), content.size(), ctx);
// HASH FINISH
sha256_end(hval, ctx);
// CONVERT TO HEX
irr::core::stringc stroutput = "";
for(i = 0; i < SHA256_DIGEST_SIZE; ++i)
{
stroutput += u2hex(hval[i]).c_str();
}
// RETURN HEX
return stroutput;
}
// HELPER FUNCTIONS
// ==================================================
stringc hex_to_string(const std::string& in)
{
std::string output = "";
if ((in.length() % 2) != 0) {
//throw std::runtime_error("String is not valid length ...");
return output.c_str();
}
size_t cnt = in.length() / 2;
for (size_t i = 0; cnt > i; ++i) {
uint32_t s = 0;
std::stringstream ss;
ss << std::hex << in.substr(i * 2, 2);
ss >> s;
output.push_back(static_cast<unsigned char>(s));
}
return output.c_str();
}
stringc string_to_hex(const std::string& in)
{
std::stringstream ss;
ss << std::hex << std::setfill('0');
for (size_t i = 0; in.length() > i; ++i) {
ss << std::setw(2) << static_cast<unsigned int>(static_cast<unsigned char>(in[i]));
}
return ss.str().c_str();
}
std::string u2hex(unsigned char c)
{
std::ostringstream o;
o << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(c);
//std::cout << "value: " << o.str() << std::endl;
return o.str();
}
stringc exe_cmd(stringc s, int &iret)
{
stringc sret = "";
FILE *in;
char buff[512];
// ADD TO ALSO COLLECT ERRORS
s += " 2>&1";
//if(!(in = popen("ls -sail", "r"))){
if(!(in = popen(s.c_str(), "r")))
{
return sret; //1;
}
while(fgets(buff, sizeof(buff), in)!=NULL)
{
//cout << buff;
sret += buff;
}
iret = pclose(in);
return sret;
}
And for the sha test, the php file is:
Code: Select all
$msg = "hello";
if($argc > 1){
$msg = $argv[1];
}
echo hash('sha256', $msg);
EDIT:
Oh, I'd like to make this compatible with standard php counterparts, so if you know of a simpler way? I have an example php script I test with OpenSSL for testing if need be...
Cheers