--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/stdlibs/libcrypt/src/encrypt.cpp Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,454 @@
+/*
+* Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Contains implementation for encryption/decryption.
+*
+*/
+
+
+// INCLUDE FILES
+
+#define EMULATOR ((defined(__WINS__) || defined(__WINSCW__)))
+
+#include <e32def.h>
+//#include <des.h>
+#include <hash.h>
+#include <errno.h>
+#include <string.h>
+
+// EXTERNAL FUNCTION PROTOTYPES
+extern "C" char *crypt_des(const char *key, const char *setting);
+extern "C" char *crypt_md5(const char *pw, const char *salt);
+
+// LOCAL CONSTANTS AND MACROS
+#define BYTE_SIZE 8
+#define ENCRYPTION 0
+#define DECRYPTION 1
+
+// STATIC DATA
+#if !EMULATOR
+TBuf8<BYTE_SIZE> desKey; // For persistence between calls
+ // to setkey() and encrypt()
+static TInt bSetkeyInvoked = 0;
+#else
+#include <sys/types.h>
+#include "wsd_solution.h"
+#define bSetkeyInvoked (GetGlobals()->bSetkeyInvoked)
+#endif
+
+// LOCAL FUNCTION PROTOTYPES
+static unsigned char GetByte(const char *bitVector);
+static void DesEncryptionL(const TDes8& aKey, TDes8& aInputBlock);
+static void DesDecryptionL(const TDes8& aKey, TDes8& aInputBlock);
+
+// LOCAL class declaration
+class CEncDecHack : public CBase
+{
+public:
+ virtual void Transform(TDes8& aBlock){}
+};
+
+typedef CEncDecHack* (*LookupFuncEncDecObjCreator)(const TDesC8& aKey, TBool aCheckWeakKey);
+
+_LIT(KCryptoDll,"cryptography.dll");
+
+// -----------------------------------------------------------------------------
+// function_name: _setkey
+//
+// Prepares a byte array for the key from the contents of the incoming bit vector.
+// Key thus constructed is statically stored for use during encryption/decryption.
+//
+// Returns: void
+// -----------------------------------------------------------------------------
+//
+extern "C"
+void _setkey (const char *key)
+{
+#if !EMULATOR
+ // Reset the contents of the 'key' descriptor
+ desKey.Delete(0,desKey.Length());
+#endif
+
+#if !EMULATOR
+ // Pack the contents of the bit vector into a TDes derived object
+ for( int i = 0 ; i < BYTE_SIZE ; ++i)
+ {
+ desKey.Append( GetByte( &key[i * BYTE_SIZE] ) );
+ }
+#else
+ for(int i=0 ; i<64 ; ++i)
+ {
+ (GetGlobals()->desKey)[i] = key[i];
+ }
+#endif
+
+ bSetkeyInvoked = 1;
+}
+
+// -----------------------------------------------------------------------------
+// function_name: _encrypt
+//
+// Performs either encryption or decryption of the data block. Prior to invoking
+// Symbian OS cryptography APIs for encryptions/decryption, this function
+// packs the contents of the bit vector into a byte array of size eight. The byte
+// array obtained after encryption/decryption is unpacked to present the output
+// in the form of a bit vector. The incoming data block is modified in place
+// during the process.
+//
+// Assumption: User of the libcrypt library is expected the create a cleanupstack
+//
+// Returns: void
+// -----------------------------------------------------------------------------
+//
+extern "C"
+void _encrypt (char block[], int edflag)
+{
+#if EMULATOR
+ TBuf8<BYTE_SIZE> desKey;
+#endif
+
+ // Determine if setkey() is invoked by the user
+ if(!bSetkeyInvoked)
+ {
+ // Initialize the key with default values
+ for(int i = 0 ; i < BYTE_SIZE ; ++i)
+ {
+ desKey.Append((unsigned char)0);
+ }
+ bSetkeyInvoked = 1;
+ }
+#if EMULATOR
+ else
+ {
+ for(int i=0 ; i<BYTE_SIZE ; ++i)
+ {
+ desKey.Append( GetByte( (const char*)&(GetGlobals()->desKey)[i * BYTE_SIZE] ));
+ }
+ }
+#endif
+
+ // Determine whether encryption or decryption is requested
+ if(edflag != ENCRYPTION)
+ {
+ if(edflag != DECRYPTION)
+ {
+ // Unrecognized flag parameter
+ errno = EPERM;
+ return;
+ }
+ }
+
+ // Pack the contents of the input bit vector into a "byte" array
+ TBuf8<BYTE_SIZE> inputBlock;
+ TInt nIterator;
+ for(nIterator = 0 ; nIterator < BYTE_SIZE ; ++nIterator)
+ {
+ inputBlock.Append( GetByte( &block[nIterator * BYTE_SIZE] ) );
+ }
+
+ TInt error = KErrNone;
+ typedef void (*DesOperation)(const TDes8&, TDes8&);
+ DesOperation funcOperationL = NULL;
+
+ switch(edflag)
+ {
+ case ENCRYPTION: // Encryption
+ funcOperationL = DesEncryptionL;
+ break;
+
+ case DECRYPTION: // Decryption
+ funcOperationL = DesDecryptionL;
+ break;
+ }
+
+ TRAP(error, (*funcOperationL)(desKey, inputBlock));
+
+ if(error == KErrNone)
+ {
+ unsigned char chTemp;
+ int k = 0;
+
+ // Create the bit vector from the "byte" array (unpack)
+ for(int i = 0 ; i < BYTE_SIZE ; ++i)
+ {
+ chTemp = inputBlock[i];
+ for(int j = 0 ; j < BYTE_SIZE ; ++j)
+ {
+ block[k++] = ((chTemp & 0x80) >> 7);
+ chTemp <<= 1;
+ }
+ }
+ }
+ else
+ {
+ // Set the errno flag to indicate failure
+ errno = EPERM;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// function_name: _crypt
+//
+// Uses MD5-based algorithm or DES encryption mechanism to encode a constant
+// string using "key" as the key. Salt determines the algorithm to be used.
+//
+// Returns: pointer to a static data buffer containing the encoded "string"
+// -----------------------------------------------------------------------------
+//
+extern "C"
+char* _crypt (const char *key, const char *salt)
+{
+ // Identify the algorithm to be used as part of crypt
+ if(strstr(salt, "$1$"))
+ {
+ // MD5-based algorithm
+ return crypt_md5(key, salt);
+ }
+ else
+ {
+ return crypt_des(key, salt);
+ }
+}
+
+// -----------------------------------------------------------------------------
+// function_name: GetByte
+//
+// Packs the "bits" in the bit vector into a byte
+//
+// Returns: Byte composed of the bits from the bit vector
+// -----------------------------------------------------------------------------
+//
+LOCAL_C unsigned char GetByte(const char *bitVector)
+{
+ unsigned char chTemp = 0;
+
+ for(int nIterator = 0 ; nIterator < BYTE_SIZE ; ++nIterator)
+ {
+ chTemp |= ( bitVector[nIterator] << (BYTE_SIZE - nIterator - 1) );
+ }
+ return chTemp;
+}
+
+// -----------------------------------------------------------------------------
+// function_name: DesEncryptionL
+//
+// Function to encrypt the input data bytes by invoking Symbian OS API for
+// DES algorithm for encryption
+//
+// Assumption: 1. BLOCKSIZE within the cryptography library is 8 for
+// DES encryption
+// 2. The input key is not checked against a set of known
+// weak key values
+//
+// Returns: void, however, this function leaves if there is insufficient
+// memory
+// -----------------------------------------------------------------------------
+//
+LOCAL_C void DesEncryptionL(const TDes8& aKey, TDes8& aInputBlock)
+{
+ // Construct the encryptor object
+/* CDESEncryptor *pEncryptor = CDESEncryptor::NewL(aKey, EFalse);
+
+ if(!pEncryptor)
+ {
+ User::Leave(KErrNoMemory);
+ }
+
+ // Invoke DES trasnformation to encrypt the input data
+ pEncryptor->Transform(aInputBlock);
+
+ delete pEncryptor;
+*/
+ RLibrary library;
+ User::LeaveIfError(library.Load(KCryptoDll));
+
+ #ifdef __WINSCW__
+ TLibraryFunction func = library.Lookup(102); // CDESEncryptor::NewL
+ #else
+ TLibraryFunction func = library.Lookup(59); //CDESEncryptor::NewL
+ #endif // ifdef __WINSCW__
+
+ if (func == NULL)
+ {
+ library.Close();
+ User::Leave(KErrNotFound);
+ }
+ LookupFuncEncDecObjCreator objCreatorFuncion = reinterpret_cast<LookupFuncEncDecObjCreator> (func);
+ CEncDecHack* pEncryptor = reinterpret_cast<CEncDecHack*>(objCreatorFuncion(aKey, EFalse));
+ pEncryptor->Transform(aInputBlock);
+ delete pEncryptor;
+ library.Close();
+}
+
+// -----------------------------------------------------------------------------
+// function_name: DesDecryptionL
+//
+// Function to encrypt the input data bytes by invoking Symbian OS API for
+// DES algorithm for decryption
+//
+// Assumption: 1. BLOCKSIZE within the cryptography library is 8 for
+// DES decryption
+// 2. The input key is not checked against a set of known
+// weak key values
+//
+// Returns: void, however, this function leaves if there is insufficient
+// memory
+// -----------------------------------------------------------------------------
+//
+LOCAL_C void DesDecryptionL(const TDes8& aKey, TDes8& aInputBlock)
+{
+ // Construct the decryptor object
+/* CDESDecryptor *pDecryptor = CDESDecryptor::NewL(aKey, EFalse);
+
+ if(!pDecryptor)
+ {
+ User::Leave(KErrNoMemory);
+ }
+
+ // Invoke DES decryption on the cipher text
+ pDecryptor->Transform(aInputBlock);
+
+ delete pDecryptor;
+*/
+ RLibrary library;
+ User::LeaveIfError(library.Load(KCryptoDll));
+
+ #ifdef __WINSCW__
+ TLibraryFunction func = library.Lookup(101); // CDESDecryptor::NewL
+ #else
+ TLibraryFunction func = library.Lookup(57); //CDESDecryptor::NewL
+ #endif // ifdef __WINSCW
+
+ if (func == NULL)
+ {
+ library.Close();
+ return;
+ }
+ LookupFuncEncDecObjCreator objCreatorFuncion = reinterpret_cast<LookupFuncEncDecObjCreator> (func);
+ CEncDecHack* pDecryptor = reinterpret_cast<CEncDecHack*>(objCreatorFuncion(aKey, EFalse));
+ pDecryptor->Transform(aInputBlock);
+ delete pDecryptor;
+ library.Close();
+}
+
+extern "C" {
+
+// -----------------------------------------------------------------------------
+// function_name: Deallocate2DimensionalUchar
+//
+// To deallocate storage alloted for the two dimensional array
+//
+// Returns: void
+// -----------------------------------------------------------------------------
+//
+void Deallocate2DimensionalUchar(unsigned char **buffer, int row)
+{
+ int m;
+ for(m=0 ; m<row ; ++m)
+ {
+ User::Free((TAny *)buffer[m]);
+ }
+ User::Free((TAny *)buffer);
+}
+
+// -----------------------------------------------------------------------------
+// function_name: Deallocate2DimensionalUint
+//
+// To deallocate storage alloted for the two dimensional array
+//
+// Returns: void
+// -----------------------------------------------------------------------------
+//
+void Deallocate2DimensionalUint(__uint32_t **buffer, int row)
+{
+ int m;
+ for(m=0 ; m<row ; ++m)
+ {
+ User::Free((TAny *)buffer[m]);
+ }
+ User::Free((TAny *)buffer);
+}
+
+// -----------------------------------------------------------------------------
+// function_name: Allocate2DimensionalUchar
+//
+// Function to allocate storage for a two dimensional array from the heap.
+// If heap exhaustion occurs during the course of allocating memory to the array,
+// the previously allocated storage will be deleted prior to returning to the
+// caller.
+//
+// Returns: non-zero if allocation is successful, 0 if it fails
+// -----------------------------------------------------------------------------
+//
+int Allocate2DimensionalUchar(unsigned char ***buffer, int row, int column)
+{
+ *buffer = (unsigned char **)User::Alloc(row * sizeof(unsigned char *));
+ if(NULL == *buffer)
+ {
+ return 0;
+ }
+ for(int m=0 ; m<row ; ++m)
+ {
+ (*buffer)[m] = (unsigned char *)User::Alloc(column * sizeof(unsigned char));
+ if(NULL == (*buffer)[m])
+ {
+ // Insufficient heap memory
+ if(m)
+ {
+ // Deallocate the previously allocated storage
+ Deallocate2DimensionalUchar(*buffer, m);
+ }
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+// function_name: Allocate2DimensionalUint
+//
+// Function to allocate storage for a two dimensional array of type unsigned int
+// from the heap. If heap exhaustion occurs while allocating memory to the array,
+// the previously allocated storage will be deleted prior to returning to the
+// caller.
+//
+// Returns: non-zero if allocation is successful, 0 if it fails
+// -----------------------------------------------------------------------------
+//
+int Allocate2DimensionalUint(__uint32_t ***buffer, int row, int column)
+{
+ *buffer = (__uint32_t **)User::Alloc(row * sizeof(__uint32_t *));
+ if(NULL == *buffer)
+ {
+ return 0;
+ }
+ for(int m=0 ; m<row ; ++m)
+ {
+ (*buffer)[m] = (__uint32_t *)User::Alloc(column * sizeof(__uint32_t));
+ if(NULL == (*buffer)[m])
+ {
+ // Insufficient heap memory
+ if(m)
+ {
+ // Deallocate the previously allocated storage
+ Deallocate2DimensionalUint(*buffer, m);
+ }
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+} // <<end extern "C">>