1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/stdlibs/libcrypt/src/encrypt.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,454 @@
1.4 +/*
1.5 +* Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description: Contains implementation for encryption/decryption.
1.18 +*
1.19 +*/
1.20 +
1.21 +
1.22 +// INCLUDE FILES
1.23 +
1.24 +#define EMULATOR ((defined(__WINS__) || defined(__WINSCW__)))
1.25 +
1.26 +#include <e32def.h>
1.27 +//#include <des.h>
1.28 +#include <hash.h>
1.29 +#include <errno.h>
1.30 +#include <string.h>
1.31 +
1.32 +// EXTERNAL FUNCTION PROTOTYPES
1.33 +extern "C" char *crypt_des(const char *key, const char *setting);
1.34 +extern "C" char *crypt_md5(const char *pw, const char *salt);
1.35 +
1.36 +// LOCAL CONSTANTS AND MACROS
1.37 +#define BYTE_SIZE 8
1.38 +#define ENCRYPTION 0
1.39 +#define DECRYPTION 1
1.40 +
1.41 +// STATIC DATA
1.42 +#if !EMULATOR
1.43 +TBuf8<BYTE_SIZE> desKey; // For persistence between calls
1.44 + // to setkey() and encrypt()
1.45 +static TInt bSetkeyInvoked = 0;
1.46 +#else
1.47 +#include <sys/types.h>
1.48 +#include "wsd_solution.h"
1.49 +#define bSetkeyInvoked (GetGlobals()->bSetkeyInvoked)
1.50 +#endif
1.51 +
1.52 +// LOCAL FUNCTION PROTOTYPES
1.53 +static unsigned char GetByte(const char *bitVector);
1.54 +static void DesEncryptionL(const TDes8& aKey, TDes8& aInputBlock);
1.55 +static void DesDecryptionL(const TDes8& aKey, TDes8& aInputBlock);
1.56 +
1.57 +// LOCAL class declaration
1.58 +class CEncDecHack : public CBase
1.59 +{
1.60 +public:
1.61 + virtual void Transform(TDes8& aBlock){}
1.62 +};
1.63 +
1.64 +typedef CEncDecHack* (*LookupFuncEncDecObjCreator)(const TDesC8& aKey, TBool aCheckWeakKey);
1.65 +
1.66 +_LIT(KCryptoDll,"cryptography.dll");
1.67 +
1.68 +// -----------------------------------------------------------------------------
1.69 +// function_name: _setkey
1.70 +//
1.71 +// Prepares a byte array for the key from the contents of the incoming bit vector.
1.72 +// Key thus constructed is statically stored for use during encryption/decryption.
1.73 +//
1.74 +// Returns: void
1.75 +// -----------------------------------------------------------------------------
1.76 +//
1.77 +extern "C"
1.78 +void _setkey (const char *key)
1.79 +{
1.80 +#if !EMULATOR
1.81 + // Reset the contents of the 'key' descriptor
1.82 + desKey.Delete(0,desKey.Length());
1.83 +#endif
1.84 +
1.85 +#if !EMULATOR
1.86 + // Pack the contents of the bit vector into a TDes derived object
1.87 + for( int i = 0 ; i < BYTE_SIZE ; ++i)
1.88 + {
1.89 + desKey.Append( GetByte( &key[i * BYTE_SIZE] ) );
1.90 + }
1.91 +#else
1.92 + for(int i=0 ; i<64 ; ++i)
1.93 + {
1.94 + (GetGlobals()->desKey)[i] = key[i];
1.95 + }
1.96 +#endif
1.97 +
1.98 + bSetkeyInvoked = 1;
1.99 +}
1.100 +
1.101 +// -----------------------------------------------------------------------------
1.102 +// function_name: _encrypt
1.103 +//
1.104 +// Performs either encryption or decryption of the data block. Prior to invoking
1.105 +// Symbian OS cryptography APIs for encryptions/decryption, this function
1.106 +// packs the contents of the bit vector into a byte array of size eight. The byte
1.107 +// array obtained after encryption/decryption is unpacked to present the output
1.108 +// in the form of a bit vector. The incoming data block is modified in place
1.109 +// during the process.
1.110 +//
1.111 +// Assumption: User of the libcrypt library is expected the create a cleanupstack
1.112 +//
1.113 +// Returns: void
1.114 +// -----------------------------------------------------------------------------
1.115 +//
1.116 +extern "C"
1.117 +void _encrypt (char block[], int edflag)
1.118 +{
1.119 +#if EMULATOR
1.120 + TBuf8<BYTE_SIZE> desKey;
1.121 +#endif
1.122 +
1.123 + // Determine if setkey() is invoked by the user
1.124 + if(!bSetkeyInvoked)
1.125 + {
1.126 + // Initialize the key with default values
1.127 + for(int i = 0 ; i < BYTE_SIZE ; ++i)
1.128 + {
1.129 + desKey.Append((unsigned char)0);
1.130 + }
1.131 + bSetkeyInvoked = 1;
1.132 + }
1.133 +#if EMULATOR
1.134 + else
1.135 + {
1.136 + for(int i=0 ; i<BYTE_SIZE ; ++i)
1.137 + {
1.138 + desKey.Append( GetByte( (const char*)&(GetGlobals()->desKey)[i * BYTE_SIZE] ));
1.139 + }
1.140 + }
1.141 +#endif
1.142 +
1.143 + // Determine whether encryption or decryption is requested
1.144 + if(edflag != ENCRYPTION)
1.145 + {
1.146 + if(edflag != DECRYPTION)
1.147 + {
1.148 + // Unrecognized flag parameter
1.149 + errno = EPERM;
1.150 + return;
1.151 + }
1.152 + }
1.153 +
1.154 + // Pack the contents of the input bit vector into a "byte" array
1.155 + TBuf8<BYTE_SIZE> inputBlock;
1.156 + TInt nIterator;
1.157 + for(nIterator = 0 ; nIterator < BYTE_SIZE ; ++nIterator)
1.158 + {
1.159 + inputBlock.Append( GetByte( &block[nIterator * BYTE_SIZE] ) );
1.160 + }
1.161 +
1.162 + TInt error = KErrNone;
1.163 + typedef void (*DesOperation)(const TDes8&, TDes8&);
1.164 + DesOperation funcOperationL = NULL;
1.165 +
1.166 + switch(edflag)
1.167 + {
1.168 + case ENCRYPTION: // Encryption
1.169 + funcOperationL = DesEncryptionL;
1.170 + break;
1.171 +
1.172 + case DECRYPTION: // Decryption
1.173 + funcOperationL = DesDecryptionL;
1.174 + break;
1.175 + }
1.176 +
1.177 + TRAP(error, (*funcOperationL)(desKey, inputBlock));
1.178 +
1.179 + if(error == KErrNone)
1.180 + {
1.181 + unsigned char chTemp;
1.182 + int k = 0;
1.183 +
1.184 + // Create the bit vector from the "byte" array (unpack)
1.185 + for(int i = 0 ; i < BYTE_SIZE ; ++i)
1.186 + {
1.187 + chTemp = inputBlock[i];
1.188 + for(int j = 0 ; j < BYTE_SIZE ; ++j)
1.189 + {
1.190 + block[k++] = ((chTemp & 0x80) >> 7);
1.191 + chTemp <<= 1;
1.192 + }
1.193 + }
1.194 + }
1.195 + else
1.196 + {
1.197 + // Set the errno flag to indicate failure
1.198 + errno = EPERM;
1.199 + }
1.200 +}
1.201 +
1.202 +// -----------------------------------------------------------------------------
1.203 +// function_name: _crypt
1.204 +//
1.205 +// Uses MD5-based algorithm or DES encryption mechanism to encode a constant
1.206 +// string using "key" as the key. Salt determines the algorithm to be used.
1.207 +//
1.208 +// Returns: pointer to a static data buffer containing the encoded "string"
1.209 +// -----------------------------------------------------------------------------
1.210 +//
1.211 +extern "C"
1.212 +char* _crypt (const char *key, const char *salt)
1.213 +{
1.214 + // Identify the algorithm to be used as part of crypt
1.215 + if(strstr(salt, "$1$"))
1.216 + {
1.217 + // MD5-based algorithm
1.218 + return crypt_md5(key, salt);
1.219 + }
1.220 + else
1.221 + {
1.222 + return crypt_des(key, salt);
1.223 + }
1.224 +}
1.225 +
1.226 +// -----------------------------------------------------------------------------
1.227 +// function_name: GetByte
1.228 +//
1.229 +// Packs the "bits" in the bit vector into a byte
1.230 +//
1.231 +// Returns: Byte composed of the bits from the bit vector
1.232 +// -----------------------------------------------------------------------------
1.233 +//
1.234 +LOCAL_C unsigned char GetByte(const char *bitVector)
1.235 +{
1.236 + unsigned char chTemp = 0;
1.237 +
1.238 + for(int nIterator = 0 ; nIterator < BYTE_SIZE ; ++nIterator)
1.239 + {
1.240 + chTemp |= ( bitVector[nIterator] << (BYTE_SIZE - nIterator - 1) );
1.241 + }
1.242 + return chTemp;
1.243 +}
1.244 +
1.245 +// -----------------------------------------------------------------------------
1.246 +// function_name: DesEncryptionL
1.247 +//
1.248 +// Function to encrypt the input data bytes by invoking Symbian OS API for
1.249 +// DES algorithm for encryption
1.250 +//
1.251 +// Assumption: 1. BLOCKSIZE within the cryptography library is 8 for
1.252 +// DES encryption
1.253 +// 2. The input key is not checked against a set of known
1.254 +// weak key values
1.255 +//
1.256 +// Returns: void, however, this function leaves if there is insufficient
1.257 +// memory
1.258 +// -----------------------------------------------------------------------------
1.259 +//
1.260 +LOCAL_C void DesEncryptionL(const TDes8& aKey, TDes8& aInputBlock)
1.261 +{
1.262 + // Construct the encryptor object
1.263 +/* CDESEncryptor *pEncryptor = CDESEncryptor::NewL(aKey, EFalse);
1.264 +
1.265 + if(!pEncryptor)
1.266 + {
1.267 + User::Leave(KErrNoMemory);
1.268 + }
1.269 +
1.270 + // Invoke DES trasnformation to encrypt the input data
1.271 + pEncryptor->Transform(aInputBlock);
1.272 +
1.273 + delete pEncryptor;
1.274 +*/
1.275 + RLibrary library;
1.276 + User::LeaveIfError(library.Load(KCryptoDll));
1.277 +
1.278 + #ifdef __WINSCW__
1.279 + TLibraryFunction func = library.Lookup(102); // CDESEncryptor::NewL
1.280 + #else
1.281 + TLibraryFunction func = library.Lookup(59); //CDESEncryptor::NewL
1.282 + #endif // ifdef __WINSCW__
1.283 +
1.284 + if (func == NULL)
1.285 + {
1.286 + library.Close();
1.287 + User::Leave(KErrNotFound);
1.288 + }
1.289 + LookupFuncEncDecObjCreator objCreatorFuncion = reinterpret_cast<LookupFuncEncDecObjCreator> (func);
1.290 + CEncDecHack* pEncryptor = reinterpret_cast<CEncDecHack*>(objCreatorFuncion(aKey, EFalse));
1.291 + pEncryptor->Transform(aInputBlock);
1.292 + delete pEncryptor;
1.293 + library.Close();
1.294 +}
1.295 +
1.296 +// -----------------------------------------------------------------------------
1.297 +// function_name: DesDecryptionL
1.298 +//
1.299 +// Function to encrypt the input data bytes by invoking Symbian OS API for
1.300 +// DES algorithm for decryption
1.301 +//
1.302 +// Assumption: 1. BLOCKSIZE within the cryptography library is 8 for
1.303 +// DES decryption
1.304 +// 2. The input key is not checked against a set of known
1.305 +// weak key values
1.306 +//
1.307 +// Returns: void, however, this function leaves if there is insufficient
1.308 +// memory
1.309 +// -----------------------------------------------------------------------------
1.310 +//
1.311 +LOCAL_C void DesDecryptionL(const TDes8& aKey, TDes8& aInputBlock)
1.312 +{
1.313 + // Construct the decryptor object
1.314 +/* CDESDecryptor *pDecryptor = CDESDecryptor::NewL(aKey, EFalse);
1.315 +
1.316 + if(!pDecryptor)
1.317 + {
1.318 + User::Leave(KErrNoMemory);
1.319 + }
1.320 +
1.321 + // Invoke DES decryption on the cipher text
1.322 + pDecryptor->Transform(aInputBlock);
1.323 +
1.324 + delete pDecryptor;
1.325 +*/
1.326 + RLibrary library;
1.327 + User::LeaveIfError(library.Load(KCryptoDll));
1.328 +
1.329 + #ifdef __WINSCW__
1.330 + TLibraryFunction func = library.Lookup(101); // CDESDecryptor::NewL
1.331 + #else
1.332 + TLibraryFunction func = library.Lookup(57); //CDESDecryptor::NewL
1.333 + #endif // ifdef __WINSCW
1.334 +
1.335 + if (func == NULL)
1.336 + {
1.337 + library.Close();
1.338 + return;
1.339 + }
1.340 + LookupFuncEncDecObjCreator objCreatorFuncion = reinterpret_cast<LookupFuncEncDecObjCreator> (func);
1.341 + CEncDecHack* pDecryptor = reinterpret_cast<CEncDecHack*>(objCreatorFuncion(aKey, EFalse));
1.342 + pDecryptor->Transform(aInputBlock);
1.343 + delete pDecryptor;
1.344 + library.Close();
1.345 +}
1.346 +
1.347 +extern "C" {
1.348 +
1.349 +// -----------------------------------------------------------------------------
1.350 +// function_name: Deallocate2DimensionalUchar
1.351 +//
1.352 +// To deallocate storage alloted for the two dimensional array
1.353 +//
1.354 +// Returns: void
1.355 +// -----------------------------------------------------------------------------
1.356 +//
1.357 +void Deallocate2DimensionalUchar(unsigned char **buffer, int row)
1.358 +{
1.359 + int m;
1.360 + for(m=0 ; m<row ; ++m)
1.361 + {
1.362 + User::Free((TAny *)buffer[m]);
1.363 + }
1.364 + User::Free((TAny *)buffer);
1.365 +}
1.366 +
1.367 +// -----------------------------------------------------------------------------
1.368 +// function_name: Deallocate2DimensionalUint
1.369 +//
1.370 +// To deallocate storage alloted for the two dimensional array
1.371 +//
1.372 +// Returns: void
1.373 +// -----------------------------------------------------------------------------
1.374 +//
1.375 +void Deallocate2DimensionalUint(__uint32_t **buffer, int row)
1.376 +{
1.377 + int m;
1.378 + for(m=0 ; m<row ; ++m)
1.379 + {
1.380 + User::Free((TAny *)buffer[m]);
1.381 + }
1.382 + User::Free((TAny *)buffer);
1.383 +}
1.384 +
1.385 +// -----------------------------------------------------------------------------
1.386 +// function_name: Allocate2DimensionalUchar
1.387 +//
1.388 +// Function to allocate storage for a two dimensional array from the heap.
1.389 +// If heap exhaustion occurs during the course of allocating memory to the array,
1.390 +// the previously allocated storage will be deleted prior to returning to the
1.391 +// caller.
1.392 +//
1.393 +// Returns: non-zero if allocation is successful, 0 if it fails
1.394 +// -----------------------------------------------------------------------------
1.395 +//
1.396 +int Allocate2DimensionalUchar(unsigned char ***buffer, int row, int column)
1.397 +{
1.398 + *buffer = (unsigned char **)User::Alloc(row * sizeof(unsigned char *));
1.399 + if(NULL == *buffer)
1.400 + {
1.401 + return 0;
1.402 + }
1.403 + for(int m=0 ; m<row ; ++m)
1.404 + {
1.405 + (*buffer)[m] = (unsigned char *)User::Alloc(column * sizeof(unsigned char));
1.406 + if(NULL == (*buffer)[m])
1.407 + {
1.408 + // Insufficient heap memory
1.409 + if(m)
1.410 + {
1.411 + // Deallocate the previously allocated storage
1.412 + Deallocate2DimensionalUchar(*buffer, m);
1.413 + }
1.414 + return 0;
1.415 + }
1.416 + }
1.417 +
1.418 + return 1;
1.419 +}
1.420 +
1.421 +// -----------------------------------------------------------------------------
1.422 +// function_name: Allocate2DimensionalUint
1.423 +//
1.424 +// Function to allocate storage for a two dimensional array of type unsigned int
1.425 +// from the heap. If heap exhaustion occurs while allocating memory to the array,
1.426 +// the previously allocated storage will be deleted prior to returning to the
1.427 +// caller.
1.428 +//
1.429 +// Returns: non-zero if allocation is successful, 0 if it fails
1.430 +// -----------------------------------------------------------------------------
1.431 +//
1.432 +int Allocate2DimensionalUint(__uint32_t ***buffer, int row, int column)
1.433 +{
1.434 + *buffer = (__uint32_t **)User::Alloc(row * sizeof(__uint32_t *));
1.435 + if(NULL == *buffer)
1.436 + {
1.437 + return 0;
1.438 + }
1.439 + for(int m=0 ; m<row ; ++m)
1.440 + {
1.441 + (*buffer)[m] = (__uint32_t *)User::Alloc(column * sizeof(__uint32_t));
1.442 + if(NULL == (*buffer)[m])
1.443 + {
1.444 + // Insufficient heap memory
1.445 + if(m)
1.446 + {
1.447 + // Deallocate the previously allocated storage
1.448 + Deallocate2DimensionalUint(*buffer, m);
1.449 + }
1.450 + return 0;
1.451 + }
1.452 + }
1.453 +
1.454 + return 1;
1.455 +}
1.456 +
1.457 +} // <<end extern "C">>