1. Andreas Tscharner
  2. lrc

Source

lrc / src / strategies / SerpentEncryption.cxx

//      SerpentEncryption.cxx
//
//      Copyright 2011 Andreas Tscharner <andy@vis.ethz.ch>
//
//      This program is free software; you can redistribute it and/or modify
//      it under the terms of the GNU Lesser 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 Lesser General Public
//      License along with this program; if not, write to the Free Software
//      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
//      MA 02110-1301, USA.


#include "cryptopp/serpent.h"
#include "cryptopp/modes.h"
#include "cryptopp/filters.h"
#include "../Utils.hxx"
#include "../StatusCodes.hxx"
#include "SerpentEncryption.hxx"


int SerpentEncryption::create_initialization_vector(unsigned char *p_ivArray, size_t p_ivSize)
{
	if (p_ivArray == nullptr) {
		return ERROR_INVALID_PARAMETER;
	};

	for (int i=0; i<p_ivSize; i++) {
		p_ivArray[i] = random() % 256;
	};

	return NO_ERROR;
}


int SerpentEncryption::encrypt(const unsigned char *p_key,
                               const unsigned char *p_clearData,
                               size_t p_clearSize,
                               unsigned char **p_encData,
                               size_t &p_encSize)
{
	int keyLen;
	unsigned char initVec[CryptoPP::Serpent::BLOCKSIZE];
	CryptoPP::StreamTransformationFilter *stf;


	if (p_encData == nullptr) {
		return ERROR_INVALID_PARAMETER;
	};

	*p_encData = new unsigned char[p_clearSize];
	this->create_initialization_vector(initVec, sizeof(initVec));

	keyLen = password_len(p_key);

	CryptoPP::OFB_Mode<CryptoPP::Serpent>::Encryption encryptor(p_key, keyLen, initVec);
	stf = new CryptoPP::StreamTransformationFilter(encryptor, new CryptoPP::ArraySink(*p_encData, p_clearSize));
	CryptoPP::StringSource(p_clearData, p_clearSize, true, stf);

	p_encSize = p_clearSize;

	return NO_ERROR;
}

int SerpentEncryption::decrypt(const unsigned char *p_key,
                               const unsigned char *p_encData,
                               size_t p_encSize,
                               unsigned char **p_clearData,
                               size_t &p_clearSize)
{
	int keyLen;
	unsigned char initVec[CryptoPP::Serpent::BLOCKSIZE];
	CryptoPP::StreamTransformationFilter *stf;


	if (p_clearData == nullptr) {
		return ERROR_INVALID_PARAMETER;
	};

	*p_clearData = new unsigned char[p_encSize];
	this->create_initialization_vector(initVec, sizeof(initVec));

	keyLen = password_len(p_key);

	CryptoPP::OFB_Mode<CryptoPP::Serpent>::Decryption decryptor(p_key, keyLen, initVec);
	stf = new CryptoPP::StreamTransformationFilter (decryptor, new CryptoPP::ArraySink(*p_clearData, p_encSize));
	CryptoPP::StringSource(p_encData, p_encSize, true, stf);

	p_clearSize = p_encSize;

	return NO_ERROR;
}