mirror of
https://github.com/vgough/encfs.git
synced 2025-01-07 14:39:03 +01:00
fb9a8ff879
git-svn-id: http://encfs.googlecode.com/svn/trunk@92 db9cf616-1c43-0410-9cb8-a902689de0d6
228 lines
5.6 KiB
C++
228 lines
5.6 KiB
C++
/*****************************************************************************
|
|
* Author: Valient Gough <vgough@pobox.com>
|
|
*
|
|
*****************************************************************************
|
|
* Copyright (c) 2002-2004, Valient Gough
|
|
*
|
|
* 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 Lesser 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, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "base/config.h"
|
|
#include "cipher/Cipher.h"
|
|
|
|
#include "base/Interface.h"
|
|
#include "base/Range.h"
|
|
#include "base/base64.h"
|
|
|
|
#include <map>
|
|
#include <list>
|
|
#include <string>
|
|
#include <iostream>
|
|
|
|
// for static build. Need to reference the modules which are registered at
|
|
// run-time, to ensure that the linker doesn't optimize them away.
|
|
#include "NullCipher.h"
|
|
#include "SSL_Cipher.h"
|
|
|
|
using namespace std;
|
|
|
|
#define REF_MODULE(TYPE) \
|
|
if( !TYPE::Enabled() ) \
|
|
cerr << "referenceModule: should never happen\n";
|
|
|
|
static
|
|
void AddSymbolReferences()
|
|
{
|
|
REF_MODULE(SSL_Cipher)
|
|
REF_MODULE(NullCipher)
|
|
}
|
|
|
|
|
|
struct CipherAlg
|
|
{
|
|
bool hidden;
|
|
Cipher::CipherConstructor constructor;
|
|
string description;
|
|
Interface iface;
|
|
Range keyLength;
|
|
Range blockSize;
|
|
bool hasStreamMode;
|
|
};
|
|
|
|
typedef multimap< string, CipherAlg> CipherMap_t;
|
|
static CipherMap_t *gCipherMap = NULL;
|
|
|
|
std::list<Cipher::CipherAlgorithm>
|
|
Cipher::GetAlgorithmList( bool includeHidden )
|
|
{
|
|
AddSymbolReferences();
|
|
|
|
list<CipherAlgorithm> result;
|
|
|
|
if(!gCipherMap)
|
|
return result;
|
|
|
|
CipherMap_t::const_iterator it;
|
|
CipherMap_t::const_iterator mapEnd = gCipherMap->end();
|
|
for(it = gCipherMap->begin(); it != mapEnd; ++it)
|
|
{
|
|
if(includeHidden || !it->second.hidden)
|
|
{
|
|
CipherAlgorithm tmp;
|
|
tmp.name = it->first;
|
|
tmp.description = it->second.description;
|
|
tmp.iface = it->second.iface;
|
|
tmp.keyLength = it->second.keyLength;
|
|
tmp.blockSize = it->second.blockSize;
|
|
tmp.hasStreamMode = it->second.hasStreamMode;
|
|
|
|
result.push_back( tmp );
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
bool Cipher::Register(const char *name, const char *description,
|
|
const Interface &iface, CipherConstructor fn,
|
|
bool hasStreamMode, bool hidden)
|
|
{
|
|
Range keyLength(-1,-1,1);
|
|
Range blockSize(-1,-1,1);
|
|
return Cipher::Register( name, description, iface,
|
|
keyLength, blockSize, fn, hasStreamMode, hidden );
|
|
}
|
|
|
|
bool Cipher::Register(const char *name, const char *description,
|
|
const Interface &iface, const Range &keyLength,
|
|
const Range &blockSize,
|
|
CipherConstructor fn,
|
|
bool hasStreamMode,
|
|
bool hidden)
|
|
{
|
|
if(!gCipherMap)
|
|
gCipherMap = new CipherMap_t;
|
|
|
|
CipherAlg ca;
|
|
ca.hidden = hidden;
|
|
ca.constructor = fn;
|
|
ca.description = description;
|
|
ca.iface = iface;
|
|
ca.keyLength = keyLength;
|
|
ca.blockSize = blockSize;
|
|
ca.hasStreamMode = hasStreamMode;
|
|
|
|
gCipherMap->insert( make_pair(string(name), ca) );
|
|
return true;
|
|
}
|
|
|
|
shared_ptr<Cipher> Cipher::New(const string &name, int keyLen)
|
|
{
|
|
shared_ptr<Cipher> result;
|
|
|
|
if(gCipherMap)
|
|
{
|
|
CipherMap_t::const_iterator it = gCipherMap->find( name );
|
|
if(it != gCipherMap->end())
|
|
{
|
|
CipherConstructor fn = it->second.constructor;
|
|
// use current interface..
|
|
result = (*fn)( it->second.iface, keyLen );
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
shared_ptr<Cipher> Cipher::New( const Interface &iface, int keyLen )
|
|
{
|
|
shared_ptr<Cipher> result;
|
|
if(gCipherMap)
|
|
{
|
|
CipherMap_t::const_iterator it;
|
|
CipherMap_t::const_iterator mapEnd = gCipherMap->end();
|
|
|
|
for(it = gCipherMap->begin(); it != mapEnd; ++it)
|
|
{
|
|
// TODO: we should look for the newest implementation..
|
|
if( implements(it->second.iface, iface) )
|
|
{
|
|
CipherConstructor fn = it->second.constructor;
|
|
// pass in requested interface..
|
|
result = (*fn)( iface, keyLen );
|
|
|
|
// if we're not going to compare the options, then just stop
|
|
// now..
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
Cipher::Cipher()
|
|
{
|
|
}
|
|
|
|
Cipher::~Cipher()
|
|
{
|
|
}
|
|
|
|
unsigned int Cipher::MAC_32( const unsigned char *src, int len,
|
|
const CipherKey &key, uint64_t *chainedIV ) const
|
|
{
|
|
uint64_t mac64 = MAC_64( src, len, key, chainedIV );
|
|
|
|
unsigned int mac32 = ((mac64 >> 32) & 0xffffffff) ^ (mac64 & 0xffffffff);
|
|
|
|
return mac32;
|
|
}
|
|
|
|
unsigned int Cipher::MAC_16( const unsigned char *src, int len,
|
|
const CipherKey &key, uint64_t *chainedIV ) const
|
|
{
|
|
uint64_t mac64 = MAC_64( src, len, key, chainedIV );
|
|
|
|
unsigned int mac32 = ((mac64 >> 32) & 0xffffffff) ^ (mac64 & 0xffffffff);
|
|
unsigned int mac16 = ((mac32 >> 16) & 0xffff) ^ (mac32 & 0xffff);
|
|
|
|
return mac16;
|
|
}
|
|
|
|
string Cipher::encodeAsString(const CipherKey &key,
|
|
const CipherKey &encodingKey )
|
|
{
|
|
int encodedKeySize = this->encodedKeySize();
|
|
unsigned char *keyBuf = new unsigned char[ encodedKeySize ];
|
|
|
|
this->writeKey( key, keyBuf, encodingKey );
|
|
|
|
int b64Len = B256ToB64Bytes( encodedKeySize );
|
|
unsigned char *b64Key = new unsigned char[ b64Len + 1 ];
|
|
|
|
changeBase2( keyBuf, encodedKeySize, 8, b64Key,
|
|
b64Len, 6 );
|
|
B64ToAscii( b64Key, b64Len );
|
|
b64Key[ b64Len - 1 ] = '\0';
|
|
|
|
return string( (const char *)b64Key );
|
|
}
|
|
|
|
bool Cipher::hasStreamMode() const
|
|
{
|
|
return true;
|
|
}
|
|
|