--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xmlsecurityengine/xmlseccrypto/src/xmlsecc_cryptowrapper.cpp Thu Dec 17 09:29:21 2009 +0200
@@ -0,0 +1,831 @@
+/*
+* 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: Methods that allows to encrypt and decrypt data.
+*
+*/
+
+#include <e32def.h>
+#include <string.h>
+#include <random.h>
+#include <stdlib.h>
+
+// reading different cipher algorithm
+#include <3des.h>
+#include <des.h>
+#include <rijndael.h>
+#include <nullcipher.h>
+#include <blocktransformation.h>
+#include <padding.h>
+#include <cbcmode.h>
+#include <bufferedtransformation.h>
+#include <msymmetriccipher.h>
+
+/** A port of gnu useful functions to Symbian **/
+#include "xmlsecc_config.h"
+#include "xmlsecc_globals.h"
+
+#include "xmlsec_error_flag.h"
+#include "xmlsecc_padding.h"
+
+#include "xmlsecc_cryptowrapper.h"
+
+// set block size according to "Symmetric ciphers - How To"
+//#define MAX_BLOCKSIZE 16
+const TInt KBlockSize( 8 );
+const TInt KAESBlockSize( 16 );
+
+#define CTX_MAGIC_NORMAL 0x24091964
+#define CTX_MAGIC_SECURE 0x46919042
+
+const TInt KDESKeySize( 8 );
+const TInt K3DESKeySize( 24 );
+const TInt KAESKeySize128( 16 );
+const TInt KAESKeySize192( 24 );
+const TInt KAESKeySize256( 32 );
+
+
+/* The handle structure. */
+struct sc_cipher_handle
+{
+ int magic;
+ size_t actual_handle_size; /* Allocated size of this handle. */
+ CSymmetricCipher* iEncryptor; // CBlockTransformation
+ CSymmetricCipher* iDecryptor;
+ HBufC8* iKey;
+ TInt algo;
+ size_t blocksize;
+ int mode;
+ unsigned int flags;
+ HBufC8* iv;
+ int unused; /* in IV */
+
+};
+
+
+// Call Symbian random generator
+void doRandomizeL(unsigned char* buffer, size_t length)
+ {
+ HBufC8* hbuf = HBufC8::NewLC(length);
+ TPtr8 ptr = hbuf->Des();
+ ptr.FillZ(ptr.MaxLength());
+
+ CSystemRandom* rand=CSystemRandom::NewLC();
+ rand->GenerateBytesL(ptr);
+ memcpy(buffer, hbuf->Ptr(), length);
+ CleanupStack::PopAndDestroy(rand);
+ CleanupStack::PopAndDestroy(hbuf);
+ }
+
+
+/**
+ - Function: void sc_randomize (unsigned char *BUFFER, size_t LENGTH,
+ enum sc_random_level LEVEL)
+ **/
+TInt sc_randomize(unsigned char* buffer, size_t length, enum sc_random_level level)
+ {
+ TInt leaveValue( KErrNone );
+ TRAP(leaveValue, doRandomizeL (buffer, length));
+
+ if ( leaveValue != KErrNone )
+ {
+ xmlSecSetErrorFlag( leaveValue );
+ }
+ return leaveValue;
+ }
+
+/* Retrieve the block length used with algorithm A. */
+size_t sc_cipher_get_algo_blklen (int algo)
+{
+ switch (algo) {
+ // set block size according to "Symmetric ciphers - How To"
+ case SC_CIPHER_AES128:
+ case SC_CIPHER_AES192:
+ case SC_CIPHER_AES256:
+ return KAESBlockSize;
+ case SC_CIPHER_NONE:
+ case SC_CIPHER_3DES:
+ case SC_CIPHER_DES:
+ default:
+ return KBlockSize; // 8 bytes
+
+ }
+
+}
+
+/* Set the IV to be used for the encryption context C to IV with
+ length IVLEN. The length should match the required length. */
+TInt
+sc_cipher_setiv( sc_cipher_hd_t c, const byte *iv, unsigned int ivlen )
+ {
+ TInt error( KErrNone );
+
+ if( iv ) {
+
+ if (c->iv)
+ {
+ delete c->iv;
+ c->iv = NULL;
+ }
+
+
+ if( ivlen != c->blocksize )
+ {
+ /*
+ log_info("WARNING: cipher_setiv: ivlen=%u blklen=%u\n",
+ ivlen, (unsigned) c->blocksize );
+ */
+ }
+ if (ivlen > c->blocksize)
+ ivlen = c->blocksize;
+
+ TInt len = ivlen;
+ TRAP( error, c->iv = HBufC8::NewL(ivlen) );
+ if ( error ) //!= KErrNone
+ {
+ xmlSecSetErrorFlag( error );
+ }
+ else
+ {
+ TPtrC8 ptr(iv, ivlen);
+ *(c->iv) = ptr;
+ }
+
+ }
+ c->unused = 0;
+
+ return error;
+ }
+
+/* Set the proper Symbian data structures */
+void
+cipher_encrypt_prerequisiteL (sc_cipher_hd_t c)
+{
+
+ if (c->iEncryptor)
+ return;
+
+ // Generate key and encryptor/decryptor
+ CBlockTransformation* bT_encrypt = NULL;
+ CBlockTransformation* encryptor = NULL;
+
+ switch(c->algo)
+ {
+
+ case SC_CIPHER_AES128:
+ case SC_CIPHER_AES192:
+ case SC_CIPHER_AES256:
+ bT_encrypt = CAESEncryptor::NewLC(c->iKey->Des());
+ CleanupStack::Pop(bT_encrypt);
+ break;
+ case SC_CIPHER_3DES:
+ bT_encrypt = C3DESEncryptor::NewLC(c->iKey->Des());
+ CleanupStack::Pop(bT_encrypt);
+ break;
+ case SC_CIPHER_DES:
+ bT_encrypt = CDESEncryptor::NewLC(c->iKey->Des());
+ CleanupStack::Pop(bT_encrypt);
+ break;
+ case SC_CIPHER_NONE:
+ c->iEncryptor = CNullCipher::NewL();
+ break;
+ default:
+ User::Leave(KErrNotSupported);
+ break;
+ }
+
+ switch (c->mode)
+ {
+ case SC_CIPHER_MODE_ECB:
+ break;
+ case SC_CIPHER_MODE_CBC:
+
+ CleanupStack::PushL(bT_encrypt);
+ encryptor = CModeCBCEncryptor::NewLC(bT_encrypt, c->iv->Des());
+ CleanupStack::Pop(encryptor);
+ CleanupStack::Pop(bT_encrypt);
+
+ break;
+ default:
+ break;
+ }
+
+ CleanupStack::PushL(encryptor);
+
+ if (!c->iEncryptor)
+ {
+ if (!encryptor)
+ {
+ User::Leave(KErrGeneral);
+ }
+ CPadding* ePadding = CXmlSecPadding::NewLC(encryptor->BlockSize());
+ c->iEncryptor = CBufferedEncryptor::NewL(encryptor, ePadding);
+ CleanupStack::Pop(ePadding);
+
+ }
+
+ CleanupStack::Pop(encryptor);
+}
+
+
+static TInt
+cipher_encrypt_doProcessL (sc_cipher_hd_t c, byte *outbuf, const byte *inbuf,
+ unsigned int nbytes, int last)
+ {
+ TInt rc(KErrNone);
+
+ switch( c->mode ) {
+
+ case SC_CIPHER_MODE_ECB:
+ case SC_CIPHER_MODE_CBC:
+ {
+ TUint blockSize = c->iEncryptor->BlockSize();
+
+ if ((c->mode == SC_CIPHER_MODE_CBC)
+ && (nbytes%blockSize && !last)
+ && !(nbytes > blockSize
+ && (c->flags & SC_CIPHER_CBC_CTS)))
+ {
+ rc = KErrArgument;
+ }
+ else if ((c->mode == SC_CIPHER_MODE_ECB)
+ && (nbytes%blockSize && !last))
+ {
+ rc = KErrArgument;
+ }
+ else
+ {
+ TInt outlen;
+ if (last)
+ outlen = c->iEncryptor->MaxFinalOutputLength(nbytes);
+ else
+ outlen = c->iEncryptor->MaxOutputLength(nbytes);
+ HBufC8 *result = HBufC8::NewLC(outlen);
+ TPtr8 resultActual= result->Des();
+ resultActual.FillZ(resultActual.MaxLength());
+ resultActual.SetLength(0);
+
+ // could improve memory usage later by allocating a smaller buffer
+ HBufC8 *input = HBufC8::NewLC(nbytes);
+ TPtrC8 inbufPtr(inbuf, nbytes);
+ *input = inbufPtr;
+
+ TInt j(0);
+ for(; j+blockSize<nbytes; j+=blockSize)
+ {// encryption in blocks of size blocksize
+ c->iEncryptor->Process(input->Mid(j,blockSize), resultActual);
+ }
+
+ if (last)
+ {
+ c->iEncryptor->ProcessFinalL(input->Mid(j), resultActual);
+ // we delete iEncryptor once the decryption finishes
+ // so that the next decryption can use a different key or iv
+ delete c->iEncryptor;
+ c->iEncryptor = NULL;
+ }
+ else
+ c->iEncryptor->Process(input->Mid(j,blockSize), resultActual);
+
+ memcpy(outbuf, result->Ptr(), result->Size());
+ CleanupStack::PopAndDestroy(input);
+ CleanupStack::PopAndDestroy(result);
+ }
+ }
+ break;
+ /*
+ case SC_CIPHER_MODE_CFB:
+ do_cfb_encrypt(c, outbuf, inbuf, nbytes );
+ break;
+ case SC_CIPHER_MODE_CTR:
+ do_ctr_encrypt(c, outbuf, inbuf, nbytes );
+ break;
+ case SC_CIPHER_MODE_STREAM:
+ c->cipher->stencrypt ( &c->context.c,
+ outbuf, (byte*)inbuf, nbytes );
+ break;
+ case SC_CIPHER_MODE_NONE:
+ if( inbuf != outbuf )
+ memmove( outbuf, inbuf, nbytes );
+ break;
+ */
+ default:
+ rc = KErrNotSupported;
+ break;
+
+ }
+
+ return rc;
+ }
+
+/****************
+ * Encrypt INBUF to OUTBUF with the mode selected at open.
+ * inbuf and outbuf may overlap or be the same.
+ * Depending on the mode some contraints apply to NBYTES.
+ */
+static TInt
+cipher_encrypt (sc_cipher_hd_t c, byte *outbuf,
+ const byte *inbuf, unsigned int nbytes, int last)
+{
+ TInt leaveValue;
+ TInt ret(KErrNone);
+
+ // Perform Symbian prerequisite data structure initialization
+ TRAP(leaveValue, cipher_encrypt_prerequisiteL (c));
+ if (leaveValue) //!= KErrNone;
+ {
+ xmlSecSetErrorFlag( leaveValue );
+ return leaveValue;
+ }
+
+ // Symbian encryption
+ TRAP(leaveValue, ret=cipher_encrypt_doProcessL (c, outbuf, inbuf, nbytes, last));
+ if (leaveValue) //!= KErrNone
+ {
+ xmlSecSetErrorFlag( leaveValue );
+ return leaveValue;
+ }
+ return ret;
+}
+
+/****************
+ * Encrypt IN and write it to OUT. If IN is NULL, in-place encryption has
+ * been requested.
+ */
+int
+sc_cipher_encrypt (sc_cipher_hd_t h, void *out, size_t outsize,
+ const void *in, size_t inlen, int last)
+{
+ int err;
+
+ if (!in)
+ /* Caller requested in-place encryption. */
+ /* Actullay cipher_encrypt() does not need to know about it, but
+ * we may change this to get better performance. */
+
+ err = cipher_encrypt (h, (byte *)out, (byte *)out, outsize, last);
+ else if (outsize < ((h->flags & SC_CIPHER_CBC_MAC) ?
+ h->blocksize : inlen))
+ err = KErrArgument;
+ else if ((h->mode == SC_CIPHER_MODE_ECB
+ || (h->mode == SC_CIPHER_MODE_CBC
+ && (! ((h->flags & SC_CIPHER_CBC_CTS)
+ && (inlen > h->blocksize)))))
+ && ((inlen % h->blocksize) && !last)) // let Symbian do the padding
+ err = KErrArgument;
+ else
+ err = cipher_encrypt (h, (byte *)out, (byte *)in, inlen, last);
+
+ if (err && out)
+ memset (out, 0x42, outsize); /* Failsafe: Make sure that the
+ plaintext will never make it into
+ OUT. */
+
+ return err;
+}
+
+/* Set the proper Symbian data structures */
+void
+cipher_decrypt_prerequisiteL (sc_cipher_hd_t c)
+{
+
+ if (c->iDecryptor)
+ return;
+
+ // Generate key and encryptor/decryptor
+ CBlockTransformation* bT_decrypt = NULL;
+ CBlockTransformation* decryptor = NULL;
+
+ switch(c->algo)
+ {
+
+ case SC_CIPHER_AES128:
+ case SC_CIPHER_AES192:
+ case SC_CIPHER_AES256:
+ bT_decrypt = CAESDecryptor::NewLC(c->iKey->Des());
+ CleanupStack::Pop(bT_decrypt);
+ break;
+ case SC_CIPHER_3DES:
+ bT_decrypt = C3DESDecryptor::NewLC(c->iKey->Des());
+ CleanupStack::Pop(bT_decrypt);
+ break;
+ case SC_CIPHER_DES:
+ bT_decrypt = CDESDecryptor::NewLC(c->iKey->Des());
+ CleanupStack::Pop(bT_decrypt);
+ break;
+ case SC_CIPHER_NONE:
+ c->iDecryptor = CNullCipher::NewL();
+ break;
+ default:
+ User::Leave(KErrNotSupported);
+ break;
+ }
+
+ switch (c->mode)
+ {
+ case SC_CIPHER_MODE_ECB:
+ break;
+ case SC_CIPHER_MODE_CBC:
+ CleanupStack::PushL(bT_decrypt);
+ decryptor = CModeCBCDecryptor::NewLC(bT_decrypt, c->iv->Des());
+ CleanupStack::Pop(decryptor);
+ CleanupStack::Pop(bT_decrypt);
+
+ break;
+ default:
+ break;
+ }
+
+ CleanupStack::PushL(decryptor);
+
+ if (!c->iDecryptor)
+ {
+ if (!decryptor)
+ {
+ User::Leave(KErrGeneral);
+ }
+ CPadding* dPadding = CXmlSecPadding::NewLC(decryptor->BlockSize());
+ c->iDecryptor = CBufferedDecryptor::NewL(decryptor, dPadding);
+ CleanupStack::Pop(dPadding);
+
+ }
+
+ CleanupStack::Pop(decryptor);
+}
+
+static TInt
+cipher_decrypt_doProcessL (sc_cipher_hd_t c, byte *outbuf, const byte *inbuf,
+ unsigned int nbytes, int* outputLen, int last)
+ {
+ TInt rc(KErrNone);
+
+ switch( c->mode ) {
+ case SC_CIPHER_MODE_ECB:
+ case SC_CIPHER_MODE_CBC:
+ {
+ TUint blockSize = c->iDecryptor->BlockSize();
+
+ if ((c->mode == SC_CIPHER_MODE_CBC)
+ && nbytes%blockSize
+ && !(nbytes > blockSize
+ && (c->flags & SC_CIPHER_CBC_CTS)))
+ {
+ rc = KErrArgument;
+ }
+ else if ((c->mode == SC_CIPHER_MODE_ECB)
+ && nbytes%blockSize)
+ {
+ rc = KErrArgument;
+ }
+ else
+ {
+ TInt outlen;
+ if (last)
+ outlen = c->iDecryptor->MaxFinalOutputLength(nbytes);
+ else
+ outlen = c->iDecryptor->MaxOutputLength(nbytes);
+ HBufC8 *result = HBufC8::NewLC(outlen);
+ TPtr8 resultActual= result->Des();
+ resultActual.FillZ(resultActual.MaxLength());
+ resultActual.SetLength(0);
+
+ // could improve memory usage later by allocating a smaller buffer
+ HBufC8* input = HBufC8::NewLC(nbytes);
+ TPtrC8 inbufPtr(inbuf, nbytes);
+ *input = inbufPtr;
+
+ TInt j=0;
+
+ for(; j+blockSize<nbytes; j+=blockSize)
+ { // decryption in blocks of size blocksize
+ c->iDecryptor->Process(input->Mid(j,blockSize), resultActual);
+ }
+
+ if (last)
+ {
+ c->iDecryptor->ProcessFinalL(input->Mid(j), resultActual);
+ *outputLen = result->Size();
+
+ // we delete iDecryptor once the decryption finishes
+ // so that the next decryption can use a different key or iv
+ delete c->iDecryptor;
+ c->iDecryptor = NULL;
+ }
+ else
+ c->iDecryptor->Process(input->Mid(j,blockSize), resultActual);
+
+ memcpy(outbuf, result->Ptr(), result->Size());
+
+ CleanupStack::PopAndDestroy(input);
+ CleanupStack::PopAndDestroy(result);
+
+ }
+ }
+ break;
+ /*
+ case SC_CIPHER_MODE_CFB:
+ do_cfb_decrypt(c, outbuf, inbuf, nbytes );
+ break;
+ case SC_CIPHER_MODE_CTR:
+ do_ctr_decrypt(c, outbuf, inbuf, nbytes );
+ break;
+ case SC_CIPHER_MODE_STREAM:
+ c->cipher->stdecrypt ( &c->context.c,
+ outbuf, (byte*) inbuf, nbytes );
+ break;
+ case SC_CIPHER_MODE_NONE:
+ if( inbuf != outbuf )
+ memmove( outbuf, inbuf, nbytes );
+ break;
+ */
+ default:
+ rc = KErrNotSupported;
+ break;
+
+ }
+
+ return rc;
+ }
+
+/****************
+ * Decrypt INBUF to OUTBUF with the mode selected at open.
+ * inbuf and outbuf may overlap or be the same.
+ * Depending on the mode some some contraints apply to NBYTES.
+ */
+static TInt
+cipher_decrypt (sc_cipher_hd_t c, byte *outbuf, const byte *inbuf,
+ unsigned int nbytes, int *outlen, int last)
+{
+ TInt rc( KErrNone );
+ TInt leaveValue;
+
+ // Perform Symbian prerequisite data structure initialization
+ TRAP(leaveValue, cipher_decrypt_prerequisiteL (c));
+ if (leaveValue != KErrNone)
+ {
+ xmlSecSetErrorFlag( leaveValue );
+ return leaveValue;
+ }
+
+ // Symbian decryption
+ TRAP(leaveValue, rc=cipher_decrypt_doProcessL (c, outbuf, inbuf, nbytes, outlen, last));
+ if (leaveValue != KErrNone)
+ {
+ xmlSecSetErrorFlag( leaveValue );
+ return leaveValue;
+ }
+ return rc;
+}
+
+
+
+int
+sc_cipher_decrypt (sc_cipher_hd_t h, void *out, size_t outsize,
+ const void *in, size_t inlen, int* outlen, int last)
+{
+ TInt err( KErrNone );
+
+ if (last && !outlen)
+ err = KErrArgument;
+ else if (! in)
+ /* Caller requested in-place encryption. */
+ /* Actullay cipher_encrypt() does not need to know about it, but
+ * we may chnage this to get better performance. */
+ err = cipher_decrypt (h, (byte*)out, (byte*)out, outsize, outlen, last);
+ else if (inlen == 0)
+ return err;
+ else if (outsize < inlen)
+ err = KErrArgument;
+ else if (((h->mode == SC_CIPHER_MODE_ECB)
+ || ((h->mode == SC_CIPHER_MODE_CBC)
+ && (! ((h->flags & SC_CIPHER_CBC_CTS)
+ && (inlen > h->blocksize)))))
+ && (inlen % h->blocksize))
+ err = KErrArgument;
+ else
+ err = cipher_decrypt (h, (byte*)out, (byte*)in, inlen, outlen, last);
+
+ return err;
+}
+
+/*
+ Open a cipher handle for use with cipher algorithm ALGORITHM, using
+ the cipher mode MODE (one of the SC_CIPHER_MODE_*) and return a
+ handle in HANDLE. Put NULL into HANDLE and return an error code if
+ something goes wrong. FLAGS may be used to modify the
+ operation. The defined flags are:
+
+ SC_CIPHER_SECURE: allocate all internal buffers in secure memory.
+ SC_CIPHER_ENABLE_SYNC: Enable the sync operation as used in OpenPGP.
+ SC_CIPHER_CBC_CTS: Enable CTS mode.
+ SC_CIPHER_CBC_MAC: Enable MAC mode.
+
+ Values for these flags may be combined using OR.
+ */
+TInt
+sc_cipher_open (sc_cipher_hd_t *handle,
+ int algo, int mode, unsigned int flags)
+{
+ int secure = (flags & SC_CIPHER_SECURE);
+ CSymmetricCipher* encryptor = NULL; //CBlockTransformation
+ CSymmetricCipher* decryptor = NULL;
+ sc_cipher_hd_t h = NULL;
+ TInt err( KErrNone );
+
+ /* If the application missed to call the random poll function, we do
+ it here to ensure that it is used once in a while. */
+
+ /* check flags */
+ if ((! err)
+ && ((flags & ~(0
+ | SC_CIPHER_SECURE
+ | SC_CIPHER_ENABLE_SYNC
+ | SC_CIPHER_CBC_CTS
+ | SC_CIPHER_CBC_MAC))
+ || (flags & SC_CIPHER_CBC_CTS & SC_CIPHER_CBC_MAC)))
+ err = KErrArgument;
+
+ /* check that a valid mode has been requested */
+ if (! err)
+ switch (mode)
+ {//
+ case SC_CIPHER_MODE_ECB:
+ case SC_CIPHER_MODE_CBC:
+ case SC_CIPHER_MODE_CFB:
+ case SC_CIPHER_MODE_CTR:
+ case SC_CIPHER_MODE_STREAM:
+ break;
+ case SC_CIPHER_MODE_NONE:
+ break;
+
+ default:
+ err = KErrNotSupported;
+ }
+
+
+ if (! err)
+ {
+ size_t size = sizeof(*h);
+ h = (sc_cipher_hd_t)malloc(size);
+
+ if ( !h )
+ {
+ err = KErrNoMemory;
+ xmlSecSetErrorFlag( KErrNoMemory );
+ }
+ else
+ {
+ h->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
+ h->actual_handle_size = size;
+ h->iEncryptor = encryptor;
+ h->iDecryptor = decryptor;
+ h->iKey = NULL;
+ h->algo = algo;
+ h->iv = NULL;
+
+ h->mode = mode;
+ h->flags = flags;
+
+ if (algo == SC_CIPHER_NONE)
+ {
+ TRAPD(leaveValue,h->iEncryptor = CNullCipher::NewL());
+ if (leaveValue) //!= KErrNone
+ {
+ xmlSecSetErrorFlag( leaveValue );
+ return leaveValue;
+ }
+ TRAP(leaveValue,h->iDecryptor = CNullCipher::NewL());
+ if (leaveValue) //!= KErrNone
+ {
+ xmlSecSetErrorFlag( leaveValue );
+ return leaveValue;
+ }
+
+ }
+ }
+ }
+
+ *handle = err ? NULL : h;
+
+ return err;
+}
+
+
+/* Release all resources associated with the cipher handle H. H may be
+ NULL in which case this is a no-operation. */
+void
+sc_cipher_close (sc_cipher_hd_t h)
+{
+ if (! h)
+ return;
+
+ if ((h->magic != CTX_MAGIC_SECURE)
+ && (h->magic != CTX_MAGIC_NORMAL))
+ {
+ /*
+ _sc_fatal_error(GPG_ERR_INTERNAL,
+ "sc_cipher_close: already closed/invalid handle");
+ */
+ return;
+ }
+
+ else
+ h->magic = 0;
+
+ if (h->iEncryptor)
+ {
+ delete h->iEncryptor;
+ h->iEncryptor = NULL;
+ }
+
+ if (h->iDecryptor)
+ {
+ delete h->iDecryptor;
+ h->iDecryptor = NULL;
+ }
+
+ if (h->iv)
+ {
+ delete h->iv;
+ h->iv = NULL;
+ }
+
+ if (h->iKey)
+ {
+ delete h->iKey;
+ h->iKey = NULL;
+ }
+
+
+ /* We always want to wipe out the memory even when the context has
+ been allocated in secure memory. The user might have disabled
+ do the wiping. To accomplish this we need to keep track of the
+ actual size of this structure because we have no way to known
+ how large the allocated area was when using a standard malloc. */
+ /*
+ TInt len = h->actual_handle_size;
+ memset(h, 'a', len); // fill with something
+ */
+
+ free (h);
+}
+
+size_t
+sc_cipher_get_algo_keylen (int algo)
+{
+ switch (algo) {
+
+ case SC_CIPHER_AES128:
+ return KAESKeySize128;
+ case SC_CIPHER_AES192:
+ return KAESKeySize192;
+ case SC_CIPHER_AES256:
+ return KAESKeySize256;
+ case SC_CIPHER_3DES:
+ return K3DESKeySize;
+ case SC_CIPHER_DES:
+ return KDESKeySize;
+ case SC_CIPHER_NONE:
+ default:
+ return 0;
+
+ }
+
+}
+
+
+/* Set the key to be used for the encryption context C to KEY with
+ length KEYLEN. The length should match the required length. */
+//sc_error_t
+TInt sc_cipher_setkey (sc_cipher_hd_t c, byte *key, unsigned int keylen)
+ {
+
+ // Change key into the right format
+ TRAPD(error, c->iKey = HBufC8::NewL(keylen));
+ if(error == KErrNone)
+ {
+ TPtrC8 keyPtr(key, keylen);
+ *(c->iKey) = keyPtr;
+ }
+ else
+ {
+ xmlSecSetErrorFlag( error );
+ }
+ return error;
+ }
+
+/* Set specification blocksize in context */
+void set_ctx_blocksize(sc_cipher_hd_t c, size_t bklen)
+{
+ c->blocksize = bklen;
+}