* limitations under the License
*/
#include <openssl/md5.h>
+#include <openssl/rand.h>
+#include <openssl/crypto.h>
+#include <openssl/hmac.h>
+#include <openssl/aes.h>
+#include <openssl/err.h>
+#include <openssl/sha.h>
#include <klay/filesystem.h>
#include <klay/audit/logger.h>
#include "key-generator.h"
-#define PBKDF_DEFAULT_ITERATION 8
+#define PBKDF_DEFAULT_ITERATION 1000
+#define AES_256_CBC_IV "01234567890123456"
+#define AES_256_KEY_LEN 32
+#define AES_BLOCK_LEN 16
namespace ode {
KeyGenerator::KeyGenerator(int size) :
keySize(size)
{
+ ::OpenSSL_add_all_algorithms();
}
KeyGenerator::~KeyGenerator()
const KeyGenerator::data KeyGenerator::PBKDF(const KeyGenerator::data& pass, const KeyGenerator::data& salt)
{
- data ret;
+ data ret(keySize, 0);
+ std::string strPass(pass.begin(), pass.end());
+ std::string strSalt(salt.begin(), salt.end());
- //TODO
+ ::PKCS5_PBKDF2_HMAC((char*)strPass.c_str(), strPass.size(),
+ (unsigned char*)strSalt.c_str(), strSalt.size(), PBKDF_DEFAULT_ITERATION,
+ EVP_sha256(), keySize, reinterpret_cast<unsigned char*>(ret.data()));
return ret;
}
-const KeyGenerator::data KeyGenerator::AES(const KeyGenerator::data& in1, const KeyGenerator::data& in2)
+const KeyGenerator::data KeyGenerator::AESEncrypt(const KeyGenerator::data& key, const KeyGenerator::data& in)
{
- data ret;
+ data ret(keySize, 0);
+ std::string strKey(key.begin(), key.end());
+ std::string strIn(in.begin(), in.end());
+ EVP_CIPHER_CTX* ctx;
+ int outLen, len;
- //TODO
+ //if ((strKey.size() != AES_256_KEY_LEN) || (strIn.size() % AES_BLOCK_LEN != 0))
+
+ ctx = ::EVP_CIPHER_CTX_new();
+
+ ::EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, (unsigned char*)strKey.c_str(), (unsigned char*)AES_256_CBC_IV);
+
+ ::EVP_CIPHER_CTX_set_padding(ctx, 0);
+ ::EVP_EncryptUpdate(ctx, reinterpret_cast<unsigned char*>(ret.data()), &len, (unsigned char*)strIn.c_str(), strIn.size());
+ outLen = len;
+
+ ::EVP_EncryptFinal_ex(ctx, &ret[len], &len);
+ outLen += len;
+
+ ::EVP_CIPHER_CTX_free(ctx);
+
+ return ret;
+}
+
+const KeyGenerator::data KeyGenerator::AESDecrypt(const KeyGenerator::data& key, const KeyGenerator::data& in)
+{
+ data ret(keySize, 0);
+ std::string strKey(key.begin(), key.end());
+ std::string strIn(in.begin(), in.end());
+ EVP_CIPHER_CTX* ctx;
+
+ int len, len1;
+
+ //if ((strKey.size() != AES_256_KEY_LEN) || (strIn.size() % AES_BLOCK_LEN != 0))
+
+ ctx = ::EVP_CIPHER_CTX_new();
+
+ ::EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, (unsigned char*)strKey.c_str(), (unsigned char*)AES_256_CBC_IV);
+ ::EVP_CIPHER_CTX_set_padding(ctx, 0);
+ ::EVP_DecryptUpdate(ctx, reinterpret_cast<unsigned char*>(ret.data()), &len, (unsigned char*)strIn.c_str(), keySize);
+
+ len1 = len;
+
+ ::EVP_DecryptFinal_ex(ctx, &ret[len], &len);
+ len1 += len;
+
+ ::EVP_CIPHER_CTX_free(ctx);
return ret;
}
const KeyGenerator::data KeyGenerator::HMAC(const KeyGenerator::data& original, const KeyGenerator::data& key)
{
- data ret;
+ data ret(keySize, 0);
+
+ unsigned int md_len;
+ std::string strOrigin(key.begin(), key.end());
+ std::string strKey(original.begin(), original.end());
+ std::string result;
- //TODO
+ ::HMAC(EVP_sha256(), (unsigned char*)strKey.c_str(), strKey.size(),
+ (unsigned char*)strOrigin.c_str(), strOrigin.size(),
+ reinterpret_cast<unsigned char*>(ret.data()), &md_len);
return ret;
}
const KeyGenerator::data KeyGenerator::RNG()
{
- data ret;
+ data ret(keySize);
- //TODO
+ ::RAND_bytes(reinterpret_cast<unsigned char*>(ret.data()), keySize);
return ret;
}
mk = keyGen.PBKDF(password, salt);
dek = keyGen.RNG();
- edk = keyGen.AES(dek, mk);
+ edk = keyGen.AESEncrypt(mk, dek);
emk = keyGen.HMAC(mk, edk);
store.setSalt(salt);
edk = store.getEDK();
mk = keyGen.PBKDF(old_password, salt);
- dek = keyGen.AES(edk, mk);
+ dek = keyGen.AESDecrypt(mk, edk);
salt = keyGen.RNG();
mk = keyGen.PBKDF(new_password, salt);
- edk = keyGen.AES(dek, mk);
+ edk = keyGen.AESEncrypt(mk, dek);
emk = keyGen.HMAC(mk, edk);
store.setSalt(salt);
mk = keyGen.PBKDF(password, salt);
- return keyGen.AES(edk, mk);
+ return keyGen.AESDecrypt(mk, edk);
}
} // namespace ode