/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/*
 * XSEC
 *
 * XSECCryptoSymmetricKey := Bulk encryption algorithms should all be
 *							implemented via this interface
 *
 * Author(s): Berin Lautenbach
 *
 * $Id$
 *
 */

#include <xsec/framework/XSECDefs.hpp>
#include <iostream>
#include <xsec/enc/OpenSSL/OpenSSLCryptoSymmetricKey.hpp>
#include <xsec/framework/XSECError.hpp>
#include <xsec/enc/XSECCryptoException.hpp>

#include <xercesc/util/Janitor.hpp>
XERCES_CPP_NAMESPACE_USE;

#if defined (XSEC_HAVE_OPENSSL)

#include <string.h>

#include <openssl/rand.h>

// --------------------------------------------------------------------------------
//           Constructors and Destructors
// --------------------------------------------------------------------------------

OpenSSLCryptoSymmetricKey::OpenSSLCryptoSymmetricKey(XSECCryptoSymmetricKey::SymmetricKeyType type) :
m_keyType(type),
m_keyMode(MODE_NONE),
m_keyBuf(""),
m_tagBuf(""),
m_keyLen(0),
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
mp_ctx(&m_ctx_space),
#else
mp_ctx(EVP_CIPHER_CTX_new()),
#endif
m_initialised(false),
m_blockSize(0),
m_ivSize(0),
m_bytesInLastBlock(0),
m_ivSent(false),
m_doPad(false) {
    if (!mp_ctx)
        throw XSECCryptoException(XSECCryptoException::ECError, "OpenSSL::CryptoSymmetricKey - cannot allocate contexts");

	EVP_CIPHER_CTX_init(mp_ctx);
	m_keyBuf.isSensitive();

}

OpenSSLCryptoSymmetricKey::~OpenSSLCryptoSymmetricKey() {

	// Clean up the context

	EVP_CIPHER_CTX_cleanup(mp_ctx);
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
    EVP_CIPHER_CTX_free(mp_ctx);
#endif
}

// --------------------------------------------------------------------------------
//           Basic Key interface methods
// --------------------------------------------------------------------------------

XSECCryptoSymmetricKey::SymmetricKeyType OpenSSLCryptoSymmetricKey::getSymmetricKeyType() const {

	return m_keyType;

}

const XMLCh * OpenSSLCryptoSymmetricKey::getProviderName() const {

	return DSIGConstants::s_unicodeStrPROVOpenSSL;

}

XSECCryptoKey * OpenSSLCryptoSymmetricKey::clone() const {

	OpenSSLCryptoSymmetricKey * ret;

	XSECnew(ret, OpenSSLCryptoSymmetricKey(m_keyType));
	ret->m_keyMode = m_keyMode;
	ret->m_keyLen = m_keyLen;
	ret->m_keyBuf = m_keyBuf;

	return ret;

}

// --------------------------------------------------------------------------------
//           Store the key value
// --------------------------------------------------------------------------------

void OpenSSLCryptoSymmetricKey::setKey(const unsigned char * key, unsigned int keyLen) {

	m_keyBuf.sbMemcpyIn(key, keyLen);
	m_keyLen = keyLen;

}

// --------------------------------------------------------------------------------
//           Decrypt
// --------------------------------------------------------------------------------

int OpenSSLCryptoSymmetricKey::decryptCtxInit(const unsigned char* iv, const unsigned char* tag, unsigned taglen) {

	// Returns amount of IV data used (in bytes)
	// Sets m_initialised iff the key is OK and the IV is OK.

    // GCM modes will leave this unset until the second call with the iv

	if (m_initialised)
		return 0;

	if (m_keyLen == 0) {
		throw XSECCryptoException(XSECCryptoException::SymmetricError,
			"OpenSSL:SymmetricKey - Cannot initialise without key"); 
	}
    else if (m_keyMode == MODE_NONE) {
		throw XSECCryptoException(XSECCryptoException::SymmetricError,
			"OpenSSL:SymmetricKey - Cannot initialise without mode"); 
    }

	// Set up the context according to the required cipher type

	switch (m_keyType) {

	case (KEY_3DES_192) :

		// A 3DES key

		if (m_keyMode == MODE_CBC) {

			if (iv == NULL) {
				return 0;	// Cannot initialise without an IV
			}

			/* Do not use "_ex" calls yet - as want backwards compatibility
			   with 0.9.6 */

#if defined(XSEC_OPENSSL_CONST_BUFFERS)
			EVP_DecryptInit(mp_ctx, EVP_des_ede3_cbc(),m_keyBuf.rawBuffer(), iv);
#else
			EVP_DecryptInit(mp_ctx, EVP_des_ede3_cbc(),(unsigned char *) m_keyBuf.rawBuffer(), (unsigned char *) iv);
#endif
			m_ivSize = 8;
		}
		else if (m_keyMode == MODE_ECB) {
#if defined(XSEC_OPENSSL_CONST_BUFFERS)
			EVP_DecryptInit(mp_ctx, EVP_des_ecb(), m_keyBuf.rawBuffer(), NULL);
#else
			EVP_DecryptInit(mp_ctx, EVP_des_ecb(), (unsigned char *) m_keyBuf.rawBuffer(), NULL);
#endif
			m_ivSize = 0;
		}
        else {
		    throw XSECCryptoException(XSECCryptoException::SymmetricError,
			    "OpenSSL:SymmetricKey - Unsupported DES3 cipher mode"); 
        }


		m_blockSize = 8;
		break;

#if defined (XSEC_OPENSSL_HAVE_AES)

	case (KEY_AES_128) :

		// An AES key

		if (m_keyMode == MODE_CBC) {

			if (iv == NULL) {
				return 0;	// Cannot initialise without an IV
			}

			EVP_DecryptInit_ex(mp_ctx, EVP_aes_128_cbc(), NULL, m_keyBuf.rawBuffer(), iv);

		}
#if defined (XSEC_OPENSSL_HAVE_GCM)
        else if (m_keyMode == MODE_GCM) {

            if (tag != NULL && taglen != 16) {
		        throw XSECCryptoException(XSECCryptoException::SymmetricError,
			        "OpenSSL:SymmetricKey - Invalid authentication tag"); 
            }

            if (iv == NULL) {
                // Just save off tag for later.
                m_tagBuf.sbMemcpyIn(tag, taglen);
                return 0;
            }

            if (m_tagBuf.sbRawBufferSize() == 0) {
		        throw XSECCryptoException(XSECCryptoException::SymmetricError,
			        "OpenSSL:SymmetricKey - Authentication tag not set"); 
            }

            // We have everything, so we can fully init.
            EVP_CipherInit_ex(mp_ctx, EVP_aes_128_gcm(), NULL, NULL, NULL, 0);
            EVP_CIPHER_CTX_ctrl(mp_ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL);
            EVP_CIPHER_CTX_ctrl(mp_ctx, EVP_CTRL_GCM_SET_TAG, 16, (void*)m_tagBuf.rawBuffer());
            EVP_CipherInit_ex(mp_ctx, NULL, NULL, m_keyBuf.rawBuffer(), iv, 0);
		}
#endif
		else if (m_keyMode == MODE_ECB) {

			EVP_DecryptInit_ex(mp_ctx, EVP_aes_128_ecb(), NULL, m_keyBuf.rawBuffer(), NULL);

		}
        else {
		    throw XSECCryptoException(XSECCryptoException::SymmetricError,
			    "OpenSSL:SymmetricKey - Unsupported AES cipher mode"); 
        }

		m_blockSize = 16;
		break;
	
	case (KEY_AES_192) :

		// An AES key

		if (m_keyMode == MODE_CBC) {

			if (iv == NULL) {
				return 0;	// Cannot initialise without an IV
			}

			EVP_DecryptInit_ex(mp_ctx, EVP_aes_192_cbc(), NULL, m_keyBuf.rawBuffer(), iv);

		}
#if defined (XSEC_OPENSSL_HAVE_GCM)
        else if (m_keyMode == MODE_GCM) {

            if (tag != NULL && taglen != 16) {
		        throw XSECCryptoException(XSECCryptoException::SymmetricError,
			        "OpenSSL:SymmetricKey - Invalid authentication tag"); 
            }

            if (iv == NULL) {
                // Just save off tag for later.
                m_tagBuf.sbMemcpyIn(tag, taglen);
                return 0;
            }

            if (m_tagBuf.sbRawBufferSize() == 0) {
		        throw XSECCryptoException(XSECCryptoException::SymmetricError,
			        "OpenSSL:SymmetricKey - Authentication tag not set"); 
            }

            // We have everything, so we can fully init.
            EVP_CipherInit_ex(mp_ctx, EVP_aes_192_gcm(), NULL, NULL, NULL, 0);
            EVP_CIPHER_CTX_ctrl(mp_ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL);
            EVP_CIPHER_CTX_ctrl(mp_ctx, EVP_CTRL_GCM_SET_TAG, 16, (void*)m_tagBuf.rawBuffer());
            EVP_CipherInit_ex(mp_ctx, NULL, NULL, m_keyBuf.rawBuffer(), iv, 0);

		}
#endif
		else if (m_keyMode == MODE_ECB) {

			EVP_DecryptInit_ex(mp_ctx, EVP_aes_192_ecb(), NULL, m_keyBuf.rawBuffer(), NULL);

		}
        else {
		    throw XSECCryptoException(XSECCryptoException::SymmetricError,
			    "OpenSSL:SymmetricKey - Unsupported AES cipher mode"); 
        }

		m_blockSize = 16;
		break;

	case (KEY_AES_256) :

		// An AES key

		if (m_keyMode == MODE_CBC) {

			if (iv == NULL) {
				return 0;	// Cannot initialise without an IV
			}

			EVP_DecryptInit_ex(mp_ctx, EVP_aes_256_cbc(), NULL, m_keyBuf.rawBuffer(), iv);

		}
#if defined (XSEC_OPENSSL_HAVE_GCM)
        else if (m_keyMode == MODE_GCM) {

            if (tag != NULL && taglen != 16) {
		        throw XSECCryptoException(XSECCryptoException::SymmetricError,
			        "OpenSSL:SymmetricKey - Invalid authentication tag"); 
            }

            if (iv == NULL) {
                // Just save off tag for later.
                m_tagBuf.sbMemcpyIn(tag, taglen);
                return 0;
            }

            if (m_tagBuf.sbRawBufferSize() == 0) {
		        throw XSECCryptoException(XSECCryptoException::SymmetricError,
			        "OpenSSL:SymmetricKey - Authentication tag not set"); 
            }

            // We have everything, so we can fully init.
            EVP_CipherInit_ex(mp_ctx, EVP_aes_256_gcm(), NULL, NULL, NULL, 0);
            EVP_CIPHER_CTX_ctrl(mp_ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL);
            EVP_CIPHER_CTX_ctrl(mp_ctx, EVP_CTRL_GCM_SET_TAG, 16, (void*)m_tagBuf.rawBuffer());
            EVP_CipherInit_ex(mp_ctx, NULL, NULL, m_keyBuf.rawBuffer(), iv, 0);

		}
#endif
		else if (m_keyMode == MODE_ECB) {

			EVP_DecryptInit_ex(mp_ctx, EVP_aes_256_ecb(), NULL, m_keyBuf.rawBuffer(), NULL);

		}
        else {
		    throw XSECCryptoException(XSECCryptoException::SymmetricError,
			    "OpenSSL:SymmetricKey - Unsupported AES cipher mode"); 
        }

		m_blockSize = 16;
		break;
#else 

	case (KEY_AES_128) :
	case (KEY_AES_192) :
	case (KEY_AES_256) :

		throw XSECCryptoException(XSECCryptoException::UnsupportedAlgorithm,
			 "OpenSSL:SymmetricKey - AES not supported in this version of OpenSSL");

#endif /* XSEC_OPENSSL_HAVE_AES */
	
	default :

		throw XSECCryptoException(XSECCryptoException::SymmetricError,
			"OpenSSL:SymmetricKey - Unknown key type"); 

	}


	// Setup ivSize
    switch (m_keyMode) {
        case MODE_CBC:
            m_ivSize = m_blockSize;
            break;

        case MODE_GCM:
            m_ivSize = 12;
            break;

        default:
            m_ivSize = 0;
    }

	// Reset some parameters
	m_initialised = true;
	m_bytesInLastBlock = 0;

	// Disable OpenSSL padding - The interop samples have broken PKCS padding - AARGHH

#if defined (XSEC_OPENSSL_CANSET_PADDING)
	EVP_CIPHER_CTX_set_padding(mp_ctx, 0);
#endif

	// Return number of bytes chewed up by IV
	return m_ivSize;
}


bool OpenSSLCryptoSymmetricKey::decryptInit(bool doPad, 
											SymmetricKeyMode mode,
											const unsigned char* iv,
                                            const unsigned char* tag,
                                            unsigned int taglen) {

	m_doPad = doPad;
	m_keyMode = mode;
	m_initialised = false;
	decryptCtxInit(iv, tag, taglen);
	return true;

}

unsigned int OpenSSLCryptoSymmetricKey::decrypt(const unsigned char * inBuf, 
								 unsigned char * plainBuf, 
								 unsigned int inLength,
								 unsigned int maxOutLength) {



	// NOTE: This won't actually stop OpenSSL blowing the buffer, so the onus is
	// on the caller.

#if 0

	/* normally commented out code to determine endian problems */
	unsigned int i;
	unsigned char e[2048];
	unsigned char * inBuf1 = (unsigned char *) inBuf;
	if (inLength < 2048) {
		memcpy(e, inBuf, inLength);
		for (i = 0; i < inLength;++i) {
			inBuf1[i] = e[inLength - 1 - i];
		}
	}

#endif

    // If cipher isn't initialized yet, we call back in with the ciphertext to supply the IV
    // For GCM, the tag has to have been supplied already or this will fail.

	unsigned int offset = 0;
	if (!m_initialised) {
        offset = decryptCtxInit(inBuf, NULL, 0);
		
        if (offset > inLength) {
			throw XSECCryptoException(XSECCryptoException::SymmetricError,
    			"OpenSSL:SymmetricKey - Not enough data passed in to get IV");
		}
	}

	int outl = maxOutLength;

	if (inLength - offset + m_bytesInLastBlock > maxOutLength) {
		throw XSECCryptoException(XSECCryptoException::SymmetricError,
			"OpenSSLSymmetricKey::decrypt - Not enough space in output buffer");
	}

#if defined (XSEC_OPENSSL_CONST_BUFFERS)
	if (EVP_DecryptUpdate(mp_ctx, &plainBuf[m_bytesInLastBlock], &outl, &inBuf[offset], inLength - offset) == 0) {
#else
	if (EVP_DecryptUpdate(mp_ctx, &plainBuf[m_bytesInLastBlock], &outl, (unsigned char *) &inBuf[offset], inLength - offset) == 0) {
#endif
		throw XSECCryptoException(XSECCryptoException::SymmetricError,
			"OpenSSL:SymmetricKey - Error during OpenSSL decrypt"); 

	}

	// Store the last block if we are padding
	if (m_doPad && m_blockSize > 0 && outl >= m_blockSize) {

		// Output will always be *at least* the blocksize

		// Copy the previous last block into the start of the output buffer
		memcpy(plainBuf, m_lastBlock, m_bytesInLastBlock);

		// Copy the tail into the buffer
		memcpy(m_lastBlock, &plainBuf[outl + m_bytesInLastBlock - m_blockSize], m_blockSize);

		outl = outl + m_bytesInLastBlock - m_blockSize;
		m_bytesInLastBlock = m_blockSize;

	}

	return outl;

}

unsigned int OpenSSLCryptoSymmetricKey::decryptFinish(unsigned char * plainBuf,
													  unsigned int maxOutLength) {

	int outl = maxOutLength;
	m_initialised = false;

#if defined (XSEC_OPENSSL_CANSET_PADDING)

	if (EVP_DecryptFinal(mp_ctx, plainBuf, &outl) == 0) {

		throw XSECCryptoException(XSECCryptoException::SymmetricError,
			"OpenSSL:SymmetricKey - Error during OpenSSL decrypt finalisation"); 

	}
	
	if (outl > 0) {
	
		// Should never see any bytes output, as we are not padding

		throw XSECCryptoException(XSECCryptoException::SymmetricError,
			"OpenSSL:SymmetricKey - Unexpectedly received bytes from EVP_DecryptFinal_ex");

	}

	// Calculate any padding issues
	if (m_doPad && m_bytesInLastBlock == m_blockSize) {

		outl = m_blockSize - m_lastBlock[m_blockSize - 1];

		if (outl > m_blockSize || outl < 0) {
			
			throw XSECCryptoException(XSECCryptoException::SymmetricError,
				"OpenSSL:SymmetricKey::decryptFinish - Out of range padding value in final block"); 
	
		}

		memcpy(plainBuf, m_lastBlock, outl);

	}

	if ((unsigned int) outl > maxOutLength) {
		throw XSECCryptoException(XSECCryptoException::SymmetricError,
			"OpenSSLSymmetricKey::decryptFinish - **WARNING** - Plaintext output > maxOutLength!"); 
	}

	return outl;

#else

	/* Working with a version of OpenSSL that *always* performs padding
	   so we need to work around it */
	unsigned char *scrPlainBuf;
	unsigned char *cipherBuf;
	scrPlainBuf = new unsigned char[3 * m_blockSize];
	ArrayJanitor<unsigned char> j_scrPlainBuf(scrPlainBuf);
	cipherBuf = new unsigned char[m_blockSize];
	ArrayJanitor<unsigned char> j_cipherBuf(cipherBuf);

	/* Zeroise the cipher buffer */
	memset(cipherBuf, 0, m_blockSize);

	unsigned int offset = 0;

	/* Get any previous bytes from the m_lastBlock */
	if (m_bytesInLastBlock > 0 && m_bytesInLastBlock <= m_blockSize) {
		memcpy(scrPlainBuf, m_lastBlock, m_bytesInLastBlock);
		offset = m_bytesInLastBlock;
	}

	outl = m_blockSize;

	/* This is really ugly - but we have to trick OpenSSL into thinking there
       is more, so that it sends us the lasts block with the padding in it.
       We can then clean that up ourselves
	*/

	if (EVP_DecryptUpdate(mp_ctx, &scrPlainBuf[offset], &outl, cipherBuf, m_blockSize) == 0) {
		throw XSECCryptoException(XSECCryptoException::SymmetricError,
			"OpenSSL:SymmetricKey - Error cecrypting final block during OpenSSL");
	} 

	outl += offset;

	if (m_doPad && outl > 0) {

		/* Strip any padding */
		outl -= scrPlainBuf[outl - 1];

		if (outl > (2 * m_blockSize) || outl < 0) {
			
			throw XSECCryptoException(XSECCryptoException::SymmetricError,
				"OpenSSL:SymmetricKey::decryptFinish - Out of range padding value in final block"); 
	
		}

	}

	if (outl > (int) maxOutLength) {
		throw XSECCryptoException(XSECCryptoException::SymmetricError,
			"OpenSSLSymmetricKey::decryptFinish - **WARNING** - Plaintext output > maxOutLength!"); 
	}

	if (outl > 0) {

		memcpy(plainBuf, scrPlainBuf, outl);

	}

	return outl;
#endif

}

// --------------------------------------------------------------------------------
//           Encrypt
// --------------------------------------------------------------------------------

bool OpenSSLCryptoSymmetricKey::encryptInit(bool doPad, 
											SymmetricKeyMode mode,
											const unsigned char * iv) {

	if (m_initialised == true)
		return true;

	m_doPad = doPad;
	m_keyMode = mode;
	
	if (m_keyLen == 0) {
		throw XSECCryptoException(XSECCryptoException::SymmetricError,
			"OpenSSL:SymmetricKey - Cannot initialise without key"); 
	}
    else if (m_keyMode == MODE_NONE) {
		throw XSECCryptoException(XSECCryptoException::SymmetricError,
			"OpenSSL:SymmetricKey - Cannot initialise without mode"); 
    }

	// Do some parameter initialisation
	m_initialised = true;
	m_bytesInLastBlock = 0;

	// Set up the context according to the required cipher type

	const unsigned char * usedIV = NULL;
	unsigned char genIV[256];

	// Tell the library that the IV still has to be sent

	m_ivSent = false;

	switch (m_keyType) {

	case (XSECCryptoSymmetricKey::KEY_3DES_192) :

		// A 3DES key

		if (m_keyMode == MODE_CBC) {

			if (iv == NULL) {
				
				bool res = ((RAND_status() == 1) && (RAND_bytes(genIV, 8) == 1));
				if (res == false) {
					throw XSECCryptoException(XSECCryptoException::SymmetricError,
						"OpenSSL:SymmetricKey - Error generating random IV");
				}

				usedIV = genIV;

			}
			else {
				usedIV = iv;
            }

#if defined (XSEC_OPENSSL_CONST_BUFFERS)
			EVP_EncryptInit(mp_ctx, EVP_des_ede3_cbc(), m_keyBuf.rawBuffer(), usedIV);
#else
			EVP_EncryptInit(mp_ctx, EVP_des_ede3_cbc(), (unsigned char *) m_keyBuf.rawBuffer(), (unsigned char *) usedIV);
#endif
		}
		else if (m_keyMode == MODE_ECB) {
#if defined (XSEC_OPENSSL_CONST_BUFFERS)
			EVP_EncryptInit(mp_ctx, EVP_des_ede3_ecb(), m_keyBuf.rawBuffer(), NULL);
#else
			EVP_EncryptInit(mp_ctx, EVP_des_ede3(), (unsigned char *) m_keyBuf.rawBuffer(), NULL);
#endif
		}
        else {
		    throw XSECCryptoException(XSECCryptoException::SymmetricError,
			    "OpenSSL:SymmetricKey - Unsupported DES3 cipher mode"); 
        }


		m_blockSize = 8;
		break;

#if defined (XSEC_OPENSSL_HAVE_AES)

	case (XSECCryptoSymmetricKey::KEY_AES_128) :

		// An AES key

		if (m_keyMode == MODE_CBC) {

			if (iv == NULL) {
				
				bool res = ((RAND_status() == 1) && (RAND_bytes(genIV, 16) == 1));
				if (res == false) {
					throw XSECCryptoException(XSECCryptoException::SymmetricError,
						"OpenSSL:SymmetricKey - Error generating random IV");
				}

				usedIV = genIV;

			}
			else
				usedIV = iv;

			EVP_EncryptInit_ex(mp_ctx, EVP_aes_128_cbc(), NULL, m_keyBuf.rawBuffer(), usedIV);
		}
		else if (m_keyMode == MODE_ECB) {

			EVP_EncryptInit_ex(mp_ctx, EVP_aes_128_ecb(), NULL, m_keyBuf.rawBuffer(), NULL);

		}
#ifdef XSEC_OPENSSL_HAVE_GCM
		else if (m_keyMode == MODE_GCM) {

			if (iv == NULL) {
				
				bool res = ((RAND_status() == 1) && (RAND_bytes(genIV, 12) == 1));
				if (res == false) {
					throw XSECCryptoException(XSECCryptoException::SymmetricError,
						"OpenSSL:SymmetricKey - Error generating random IV");
				}

				usedIV = genIV;

			}
			else
				usedIV = iv;

			EVP_EncryptInit_ex(mp_ctx, EVP_aes_128_gcm(), NULL, m_keyBuf.rawBuffer(), usedIV);
		}
#endif
        else {
		    throw XSECCryptoException(XSECCryptoException::SymmetricError,
			    "OpenSSL:SymmetricKey - Unsupported AES cipher mode");
        }

		m_blockSize = 16;
		break;

	case (XSECCryptoSymmetricKey::KEY_AES_192) :

		// An AES key

		if (m_keyMode == MODE_CBC) {

			if (iv == NULL) {
				
				bool res = ((RAND_status() == 1) && (RAND_bytes(genIV, 16) == 1));
				if (res == false) {
					throw XSECCryptoException(XSECCryptoException::SymmetricError,
						"OpenSSL:SymmetricKey - Error generating random IV");
				}

				usedIV = genIV;

			}
			else
				usedIV = iv;

			EVP_EncryptInit_ex(mp_ctx, EVP_aes_192_cbc(), NULL, m_keyBuf.rawBuffer(), usedIV);

		}
#ifdef XSEC_OPENSSL_HAVE_GCM
		else if (m_keyMode == MODE_GCM) {

			if (iv == NULL) {
				
				bool res = ((RAND_status() == 1) && (RAND_bytes(genIV, 12) == 1));
				if (res == false) {
					throw XSECCryptoException(XSECCryptoException::SymmetricError,
						"OpenSSL:SymmetricKey - Error generating random IV");
				}

				usedIV = genIV;

			}
			else
				usedIV = iv;

			EVP_EncryptInit_ex(mp_ctx, EVP_aes_192_gcm(), NULL, m_keyBuf.rawBuffer(), usedIV);
		}
#endif
		else if (m_keyMode == MODE_ECB) {

			EVP_EncryptInit_ex(mp_ctx, EVP_aes_192_ecb(), NULL, m_keyBuf.rawBuffer(), NULL);
		}
        else {
		    throw XSECCryptoException(XSECCryptoException::SymmetricError,
			    "OpenSSL:SymmetricKey - Unsupported AES cipher mode");
        }

		m_blockSize = 16;
		break;

	case (XSECCryptoSymmetricKey::KEY_AES_256) :

		// An AES key

		if (m_keyMode == MODE_CBC) {
			if (iv == NULL) {
				
				bool res = ((RAND_status() == 1) && (RAND_bytes(genIV, 16) == 1));
				if (res == false) {
					throw XSECCryptoException(XSECCryptoException::SymmetricError,
						"OpenSSL:SymmetricKey - Error generating random IV");
				}

				usedIV = genIV;

			}
			else
				usedIV = iv;

			EVP_EncryptInit_ex(mp_ctx, EVP_aes_256_cbc(), NULL, m_keyBuf.rawBuffer(), usedIV);

		}
#ifdef XSEC_OPENSSL_HAVE_GCM
		else if (m_keyMode == MODE_GCM) {

			if (iv == NULL) {
				
				bool res = ((RAND_status() == 1) && (RAND_bytes(genIV, 12) == 1));
				if (res == false) {
					throw XSECCryptoException(XSECCryptoException::SymmetricError,
						"OpenSSL:SymmetricKey - Error generating random IV");
				}

				usedIV = genIV;

			}
			else
				usedIV = iv;

			EVP_EncryptInit_ex(mp_ctx, EVP_aes_256_gcm(), NULL, m_keyBuf.rawBuffer(), usedIV);
		}
#endif
		else if (m_keyMode == MODE_ECB) {

			EVP_EncryptInit_ex(mp_ctx, EVP_aes_256_ecb(), NULL, m_keyBuf.rawBuffer(), NULL);

		}
        else {
		    throw XSECCryptoException(XSECCryptoException::SymmetricError,
			    "OpenSSL:SymmetricKey - Unsupported AES cipher mode");
        }

		m_blockSize = 16;
		break;

#else 

	case (XSECCryptoSymmetricKey::KEY_AES_128) :
	case (XSECCryptoSymmetricKey::KEY_AES_192) :
	case (XSECCryptoSymmetricKey::KEY_AES_256) :

		throw XSECCryptoException(XSECCryptoException::UnsupportedAlgorithm,
			 "OpenSSL:SymmetricKey - AES not supported in this version of OpenSSL");

#endif /* XSEC_OPENSSL_HAVE_AES */

	default :

		throw XSECCryptoException(XSECCryptoException::SymmetricError,
			"OpenSSL:SymmetricKey - Unknown key type"); 

	}

	// Clear up any read padding

	if (m_keyMode == MODE_CBC) {
		m_ivSize = m_blockSize;
		memcpy(m_lastBlock, usedIV, m_ivSize);
	}
    else if (m_keyMode == MODE_GCM) {
        m_ivSize = 12;
        memcpy(m_lastBlock, usedIV, m_ivSize);
    }
	else {
		m_ivSize = 0;
    }

#if defined (XSEC_OPENSSL_CANSET_PADDING)
	// Setup padding
	if (m_doPad) {
		EVP_CIPHER_CTX_set_padding(mp_ctx, 1);
	}
	else {
		EVP_CIPHER_CTX_set_padding(mp_ctx, 0);
	}
#endif

	return true;

}

unsigned int OpenSSLCryptoSymmetricKey::encrypt(const unsigned char * inBuf, 
								 unsigned char * cipherBuf, 
								 unsigned int inLength,
								 unsigned int maxOutLength) {

	if (m_initialised == false) {

		encryptInit();

	}

	// NOTE: This won't actually stop OpenSSL blowing the buffer, so the onus is
	// on the caller.

	unsigned int offset = 0;
	if (m_ivSent == false && m_ivSize > 0) {

		memcpy(cipherBuf, m_lastBlock, m_ivSize);
		m_ivSent = true;

		offset = m_ivSize;

	}

	int outl = maxOutLength - offset;

	if (inLength + offset > maxOutLength) {

		throw XSECCryptoException(XSECCryptoException::SymmetricError,
			"OpenSSL:SymmetricKey - Not enough space in output buffer for encrypt"); 

	}
#if defined (XSEC_OPENSSL_CONST_BUFFERS)
	if (EVP_EncryptUpdate(mp_ctx, &cipherBuf[offset], &outl, inBuf, inLength) == 0) {
#else
	if (EVP_EncryptUpdate(mp_ctx, &cipherBuf[offset], &outl, (unsigned char *) inBuf, inLength) == 0) {
#endif

		throw XSECCryptoException(XSECCryptoException::SymmetricError,
			"OpenSSL:SymmetricKey - Error during OpenSSL encrypt"); 

	}

	return outl + offset;

}

unsigned int OpenSSLCryptoSymmetricKey::encryptFinish(unsigned char * cipherBuf,
													  unsigned int maxOutLength,
                                                      unsigned int taglen) {

	int outl = maxOutLength;
	m_initialised = false;

	if (EVP_EncryptFinal(mp_ctx, cipherBuf, &outl) == 0) {

		throw XSECCryptoException(XSECCryptoException::SymmetricError,
		  "OpenSSLSymmetricKey::encryptFinish - Error during OpenSSL decrypt finalisation"); 

	}

	if ((unsigned int) outl > maxOutLength) {
		throw XSECCryptoException(XSECCryptoException::SymmetricError,
			"OpenSSLSymmetricKey::encryptFinish - **WARNING** - Cipheroutput > maxOutLength!"); 
	}
	
#if !defined (XSEC_OPENSSL_CANSET_PADDING)
	if (!m_doPad) {

		if (outl < m_blockSize) {
			throw XSECCryptoException(XSECCryptoException::SymmetricError,
			   "OpenSSLSymmetricKey::encryptFinish - cannot remove padding!"); 
		}

		outl -= m_blockSize;

	}
#endif

    if (taglen > 0) {
        // Extract authentication tag and add to ciphertext.
        if (maxOutLength - outl < taglen) {
		    throw XSECCryptoException(XSECCryptoException::SymmetricError,
			    "OpenSSLSymmetricKey::encryptFinish - **WARNING** - no room in ciphertext buffer for authentication tag"); 
        }
        if (m_keyMode == MODE_GCM) {
#ifdef XSEC_OPENSSL_HAVE_GCM
            EVP_CIPHER_CTX_ctrl(mp_ctx, EVP_CTRL_GCM_GET_TAG, taglen, cipherBuf + outl);
            outl += taglen;
#else
		    throw XSECCryptoException(XSECCryptoException::SymmetricError,
			    "OpenSSLSymmetricKey::encryptFinish - AES-GCM not supported in this version of OpenSSL"); 
#endif
        }
        else {
		    throw XSECCryptoException(XSECCryptoException::SymmetricError,
			    "OpenSSLSymmetricKey::encryptFinish - cipher mode does not support authentication tag"); 
        }
    }

	return outl;

}

#endif /* XSEC_HAVE_OPENSSL */
