Parameterize MGF algorithm for key encryption.

git-svn-id: https://svn.apache.org/repos/asf/santuario/xml-security-cpp/trunk@1817964 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/xsec/tools/xtest/xtest.cpp b/xsec/tools/xtest/xtest.cpp
index c61029c..4db48bc 100644
--- a/xsec/tools/xtest/xtest.cpp
+++ b/xsec/tools/xtest/xtest.cpp
@@ -1871,7 +1871,7 @@
 }
 
 
-void unitTestKeyEncrypt(DOMImplementation *impl, XSECCryptoKey * k, const XMLCh* algorithm) {
+void unitTestKeyEncrypt(DOMImplementation* impl, XSECCryptoKey* k, const XMLCh* algorithm, const XMLCh* mgf=NULL) {
 
 	// Create a document that we will embed the encrypted key in
 	DOMDocument *doc = impl->createDocument(
@@ -1902,7 +1902,7 @@
 		cipher->setKEK(k);
 
 		XENCEncryptedKey * encryptedKey;
-		encryptedKey = cipher->encryptKey(toEncryptStr, (unsigned int) strlen((char *) toEncryptStr), algorithm);
+		encryptedKey = cipher->encryptKey(toEncryptStr, (unsigned int) strlen((char *) toEncryptStr), algorithm, mgf);
 		Janitor<XENCEncryptedKey> j_encryptedKey(encryptedKey);
 
 		rootElem->appendChild(encryptedKey->getElement());
@@ -1988,18 +1988,42 @@
 
 			cerr << "RSA OAEP key wrap... ";
 			k = new OpenSSLCryptoKeyRSA(pk);
-			unitTestKeyEncrypt(impl, k, DSIGConstants::s_unicodeStrURIRSA_OAEP_MGFP1);
+			unitTestKeyEncrypt(impl, k, DSIGConstants::s_unicodeStrURIRSA_OAEP_MGFP1, DSIGConstants::s_unicodeStrURIMGF1_SHA1);
 
 			cerr << "RSA OAEP key wrap + params... ";
 			k = new OpenSSLCryptoKeyRSA(pk);
 			k->setOAEPparams(s_tstOAEPparams, (unsigned int) strlen((char *) s_tstOAEPparams));
-			unitTestKeyEncrypt(impl, k, DSIGConstants::s_unicodeStrURIRSA_OAEP_MGFP1);
+			unitTestKeyEncrypt(impl, k, DSIGConstants::s_unicodeStrURIRSA_OAEP_MGFP1, DSIGConstants::s_unicodeStrURIMGF1_SHA1);
 
             cerr << "RSA OAEP 1.1 key wrap... ";
             k = new OpenSSLCryptoKeyRSA(pk);
-            unitTestKeyEncrypt(impl, k, DSIGConstants::s_unicodeStrURIRSA_OAEP);
+            unitTestKeyEncrypt(impl, k, DSIGConstants::s_unicodeStrURIRSA_OAEP, DSIGConstants::s_unicodeStrURIMGF1_SHA1);
 
-			BIO_free(bioMem);
+            if (XSECPlatformUtils::g_cryptoProvider->algorithmSupported(XSECCryptoHash::HASH_SHA224)) {
+                cerr << "RSA OAEP 1.1 key wrap with MGF1+SHA224... ";
+                k = new OpenSSLCryptoKeyRSA(pk);
+                unitTestKeyEncrypt(impl, k, DSIGConstants::s_unicodeStrURIRSA_OAEP, DSIGConstants::s_unicodeStrURIMGF1_SHA224);
+            }
+
+            if (XSECPlatformUtils::g_cryptoProvider->algorithmSupported(XSECCryptoHash::HASH_SHA256)) {
+                cerr << "RSA OAEP 1.1 key wrap with MGF1+SHA256... ";
+                k = new OpenSSLCryptoKeyRSA(pk);
+                unitTestKeyEncrypt(impl, k, DSIGConstants::s_unicodeStrURIRSA_OAEP, DSIGConstants::s_unicodeStrURIMGF1_SHA256);
+            }
+
+            if (XSECPlatformUtils::g_cryptoProvider->algorithmSupported(XSECCryptoHash::HASH_SHA384)) {
+                cerr << "RSA OAEP 1.1 key wrap with MGF1+SHA384... ";
+                k = new OpenSSLCryptoKeyRSA(pk);
+                unitTestKeyEncrypt(impl, k, DSIGConstants::s_unicodeStrURIRSA_OAEP, DSIGConstants::s_unicodeStrURIMGF1_SHA384);
+            }
+
+            if (XSECPlatformUtils::g_cryptoProvider->algorithmSupported(XSECCryptoHash::HASH_SHA512)) {
+                cerr << "RSA OAEP 1.1 key wrap with MGF1+SHA512... ";
+                k = new OpenSSLCryptoKeyRSA(pk);
+                unitTestKeyEncrypt(impl, k, DSIGConstants::s_unicodeStrURIRSA_OAEP, DSIGConstants::s_unicodeStrURIMGF1_SHA512);
+            }
+
+            BIO_free(bioMem);
 			EVP_PKEY_free(pk);
 		}
 #endif
diff --git a/xsec/xenc/XENCCipher.hpp b/xsec/xenc/XENCCipher.hpp
index e1b6c66..dddc6fa 100644
--- a/xsec/xenc/XENCCipher.hpp
+++ b/xsec/xenc/XENCCipher.hpp
@@ -78,504 +78,506 @@
 class XENCCipher {
 
 public:
-	
-	/** @name Constructors and Destructors */
-	//@{
-	
-	virtual ~XENCCipher() {};
 
-	//@}
+    /** @name Constructors and Destructors */
+    //@{
 
-	/** @name Decryption Functions */
-	//@{
+    virtual ~XENCCipher() {};
 
-	/**
-	 * \brief Decrypt the nominated element.
-	 *
-	 * Decrypts the passed in element, which must be the root
-	 * node of a \<EncryptedData\> method with a type of "#Element".
-	 * If not, the library will throw an XSECException exception.
-	 *
-	 * This is an "all in one method".  The library will replace
-	 * the passed in Element (i.e. the encrypted XML data) with
-	 * the resultant plain text, after it has been parsed back into
-	 * DOM nodes
-	 *
-	 * @param element Root of EncryptedData DOM structyre to decrypt
-	 * @returns The owning document with the element replaced, or NULL
-	 * if the decryption fails for some reason (normally an exception).
-	 * @throws XSECException if the decryption fails, or if this is
-	 * not a valid EncryptedData DOM structure.
-	 */
+    //@}
 
-	virtual XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * decryptElement(
-		XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * element
-	) = 0;
+    /** @name Decryption Functions */
+    //@{
 
-	/**
-	 * \brief Decrypt the nominated element without replacing it.
-	 *
-	 * Decrypts the passed in element, which must be the root
-	 * node of a \<EncryptedData\> method with a type of "#Element".
-	 * If not, the library will throw an XSECException exception.  Rather
-	 * than replacing the element with the decrypted content, the
-	 * result is passed to the caller as an orphaned document fragment.
-	 *
-	 * @param element Root of EncryptedData DOM structyre to decrypt
-	 * @returns The document fragment containing the decrypted node-set.
-	 * @throws XSECException if the decryption fails, or if this is
-	 * not a valid EncryptedData DOM structure.
-	 */
+    /**
+     * \brief Decrypt the nominated element.
+     *
+     * Decrypts the passed in element, which must be the root
+     * node of a \<EncryptedData\> method with a type of "#Element".
+     * If not, the library will throw an XSECException exception.
+     *
+     * This is an "all in one method".  The library will replace
+     * the passed in Element (i.e. the encrypted XML data) with
+     * the resultant plain text, after it has been parsed back into
+     * DOM nodes
+     *
+     * @param element Root of EncryptedData DOM structyre to decrypt
+     * @returns The owning document with the element replaced, or NULL
+     * if the decryption fails for some reason (normally an exception).
+     * @throws XSECException if the decryption fails, or if this is
+     * not a valid EncryptedData DOM structure.
+     */
 
-	virtual XERCES_CPP_NAMESPACE_QUALIFIER DOMNode * decryptElementDetached(
-		XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * element
-	) = 0;
+    virtual XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * decryptElement(
+        XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * element
+    ) = 0;
 
-	/**
-	 * \brief Decrypt currently loaded element.
-	 *
-	 * Decrypts the an element that was previously passed in via 
-	 * loadEncryptedData with a type of "#Element".
-	 * If not, the library will throw an XSECException exception.
-	 *
-	 * This is an "all in one method".  The library will replace
-	 * the passed in Element (i.e. the encrypted XML data) with
-	 * the resultant plain text, after it has been parsed back into
-	 * DOM nodes
-	 *
-	 * @param element Root of EncryptedData DOM structyre to decrypt
-	 * @returns The owning document with the element replaced, or NULL
-	 * if the decryption fails for some reason (normally an exception).
-	 * @throws XSECException if the decryption fails, or if this is
-	 * not a valid EncryptedData DOM structure.
-	 */
+    /**
+     * \brief Decrypt the nominated element without replacing it.
+     *
+     * Decrypts the passed in element, which must be the root
+     * node of a \<EncryptedData\> method with a type of "#Element".
+     * If not, the library will throw an XSECException exception.  Rather
+     * than replacing the element with the decrypted content, the
+     * result is passed to the caller as an orphaned document fragment.
+     *
+     * @param element Root of EncryptedData DOM structyre to decrypt
+     * @returns The document fragment containing the decrypted node-set.
+     * @throws XSECException if the decryption fails, or if this is
+     * not a valid EncryptedData DOM structure.
+     */
 
-	virtual XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * decryptElement() = 0;
+    virtual XERCES_CPP_NAMESPACE_QUALIFIER DOMNode * decryptElementDetached(
+        XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * element
+    ) = 0;
 
-	/**
-	 * \brief Decrypt currently loaded element without replacing it.
-	 *
-	 * Decrypts the an element that was previously passed in via 
-	 * loadEncryptedData with a type of "#Element".
-	 * If not, the library will throw an XSECException exception.
-	 *
-	 * This does not replace the currently existing DOM document.  It returns
-	 * an "orphaned" document fragment containing the serialised version of the
-	 * decrypted data.
-	 *
-	 * @param element Root of EncryptedData DOM structyre to decrypt
-	 * @returns The owning document with the element replaced, or NULL
-	 * if the decryption fails for some reason (normally an exception).
-	 * @throws XSECException if the decryption fails, or if this is
-	 * not a valid EncryptedData DOM structure.
-	 */
+    /**
+     * \brief Decrypt currently loaded element.
+     *
+     * Decrypts the an element that was previously passed in via
+     * loadEncryptedData with a type of "#Element".
+     * If not, the library will throw an XSECException exception.
+     *
+     * This is an "all in one method".  The library will replace
+     * the passed in Element (i.e. the encrypted XML data) with
+     * the resultant plain text, after it has been parsed back into
+     * DOM nodes
+     *
+     * @param element Root of EncryptedData DOM structyre to decrypt
+     * @returns The owning document with the element replaced, or NULL
+     * if the decryption fails for some reason (normally an exception).
+     * @throws XSECException if the decryption fails, or if this is
+     * not a valid EncryptedData DOM structure.
+     */
 
-	virtual XERCES_CPP_NAMESPACE_QUALIFIER DOMNode * decryptElementDetached() = 0;
-	
-	/**
-	 * \brief Decrypt the nominated element and put the output to an InputStream.
-	 *
-	 * Decrypts the passed in element, which must be the root
-	 * node of a \<EncryptedData\> method.
-	 *
-	 * This call does not change the source DOM in any way.  It simply
-	 * processes the encrypted data and provides an InputStream that the
-	 * caller can read from to read the plain text data.
-	 *
-	 * @param element Root of EncryptedData DOM structyre to decrypt
-	 * @returns A BinInputStream object that the application can use to
-	 * read the decrypted data.
-	 * @throws XSECException if the decryption fails, or if this is
-	 * not a valid EncryptedData DOM structure.
-	 */
+    virtual XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * decryptElement() = 0;
 
-	virtual XSECBinTXFMInputStream * decryptToBinInputStream(
-		XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * element
-	) = 0;
+    /**
+     * \brief Decrypt currently loaded element without replacing it.
+     *
+     * Decrypts the an element that was previously passed in via
+     * loadEncryptedData with a type of "#Element".
+     * If not, the library will throw an XSECException exception.
+     *
+     * This does not replace the currently existing DOM document.  It returns
+     * an "orphaned" document fragment containing the serialised version of the
+     * decrypted data.
+     *
+     * @param element Root of EncryptedData DOM structyre to decrypt
+     * @returns The owning document with the element replaced, or NULL
+     * if the decryption fails for some reason (normally an exception).
+     * @throws XSECException if the decryption fails, or if this is
+     * not a valid EncryptedData DOM structure.
+     */
 
-	/**
-	 * \brief Decrypt a key
-	 *
-	 * Reads in the passed in KeyInfo structure for an EncryptedKey and 
-	 * decrypts the key to a buffer.
-	 *
-	 * @param encryptedKey the already loaded encryptedKey structure
-	 * @param rawKey Buffer to place the decrypted key into
-	 * @param maxKeySize Maximum number of bytes to place in the buffer
-	 */
+    virtual XERCES_CPP_NAMESPACE_QUALIFIER DOMNode * decryptElementDetached() = 0;
 
-	virtual int decryptKey(
-		XENCEncryptedKey * encryptedKey,
-		XMLByte * rawKey,
-		int maxKeySize
-	) = 0;
+    /**
+     * \brief Decrypt the nominated element and put the output to an InputStream.
+     *
+     * Decrypts the passed in element, which must be the root
+     * node of a \<EncryptedData\> method.
+     *
+     * This call does not change the source DOM in any way.  It simply
+     * processes the encrypted data and provides an InputStream that the
+     * caller can read from to read the plain text data.
+     *
+     * @param element Root of EncryptedData DOM structyre to decrypt
+     * @returns A BinInputStream object that the application can use to
+     * read the decrypted data.
+     * @throws XSECException if the decryption fails, or if this is
+     * not a valid EncryptedData DOM structure.
+     */
 
-	/**
-	 * \brief Decrypt a key directly from DOM
-	 *
-	 * Loads an EncryptedKey from DOM and then decrypts the key.
-	 * If a NULL buffer is passed in, will simply load the key and return
-	 *
-	 * @param keyNode Node to load from
-	 * @param rawKey Buffer to decrypt to
-	 * @param maxKeySize Length of rawKey buffer
-	 * @returns The number of bytes decrypted
-	 */
+    virtual XSECBinTXFMInputStream * decryptToBinInputStream(
+        XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * element
+    ) = 0;
 
-	virtual int decryptKey(
-		XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * keyNode,
-		XMLByte * rawKey,
-		int maxKeySize
-	) = 0;
+    /**
+     * \brief Decrypt a key
+     *
+     * Reads in the passed in KeyInfo structure for an EncryptedKey and
+     * decrypts the key to a buffer.
+     *
+     * @param encryptedKey the already loaded encryptedKey structure
+     * @param rawKey Buffer to place the decrypted key into
+     * @param maxKeySize Maximum number of bytes to place in the buffer
+     */
 
-	//@}
+    virtual int decryptKey(
+        XENCEncryptedKey * encryptedKey,
+        XMLByte * rawKey,
+        int maxKeySize
+    ) = 0;
 
-	/** @name Encryption Functions */
-	//@{
+    /**
+     * \brief Decrypt a key directly from DOM
+     *
+     * Loads an EncryptedKey from DOM and then decrypts the key.
+     * If a NULL buffer is passed in, will simply load the key and return
+     *
+     * @param keyNode Node to load from
+     * @param rawKey Buffer to decrypt to
+     * @param maxKeySize Length of rawKey buffer
+     * @returns The number of bytes decrypted
+     */
 
-	/**
-	 * \brief Encrypt the nominated element.
-	 * 
-	 * Encrypts the passed in element and all children.  The element
-	 * is replaced with an EncryptedData element
-	 *
-	 * @param element Element (and children) to encrypt
-	 * @param algorithmURI algorithm URI to set
-	 *
-	 * @returns The owning document with the element replaced, or NULL
-	 * if the decryption fails for some reason (normally an exception).
-	 * @throws XSECException if the encryption fails.
-	 */
+    virtual int decryptKey(
+        XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * keyNode,
+        XMLByte * rawKey,
+        int maxKeySize
+    ) = 0;
 
-	virtual XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * encryptElement(
-		XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * element,
-		const XMLCh * algorithmURI
-	) = 0;
+    //@}
 
-	/**
-	 * \brief Encrypt the nominated element without affecting the current document.
-	 * 
-	 * Encrypts the passed in element and all children.  The element
-	 * is not replaced - the return node is an "orphaned" subtree from
-	 * the passed in document and the original document is untouched.
-	 *
-	 * @param element Element (and children) to encrypt
+    /** @name Encryption Functions */
+    //@{
+
+    /**
+     * \brief Encrypt the nominated element.
+     *
+     * Encrypts the passed in element and all children.  The element
+     * is replaced with an EncryptedData element
+     *
+     * @param element Element (and children) to encrypt
      * @param algorithmURI algorithm URI to set
      *
-	 * @returns The resulting document fragment containing the encrypted data.
-	 * @throws XSECException if the encryption fails.
-	 */
+     * @returns The owning document with the element replaced, or NULL
+     * if the decryption fails for some reason (normally an exception).
+     * @throws XSECException if the encryption fails.
+     */
 
-	virtual XERCES_CPP_NAMESPACE_QUALIFIER DOMNode * encryptElementDetached(
-		XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * element,
-		const XMLCh * algorithmURI
-	) = 0;
-	
-	/**
-	 * \brief Encrypt the children of the nominated element
-	 * 
-	 * Encrypts the all children of the passed in element, but
-	 * leaves the element itself in place, with one new child - an
-	 * EncryptedData node of type #content
-	 *
-	 * @param element Element whose children are to be encrypted
+    virtual XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * encryptElement(
+        XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * element,
+        const XMLCh * algorithmURI
+    ) = 0;
+
+    /**
+     * \brief Encrypt the nominated element without affecting the current document.
+     *
+     * Encrypts the passed in element and all children.  The element
+     * is not replaced - the return node is an "orphaned" subtree from
+     * the passed in document and the original document is untouched.
+     *
+     * @param element Element (and children) to encrypt
      * @param algorithmURI algorithm URI to set
      *
-	 * @returns The owning document with the element's children replaced, or NULL
-	 * if the decryption fails for some reason (normally an exception).
-	 * @throws XSECException if the encryption fails.
-	 */
+     * @returns The resulting document fragment containing the encrypted data.
+     * @throws XSECException if the encryption fails.
+     */
 
-	virtual XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * encryptElementContent(
-		XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * element,
-		const XMLCh * algorithmURI
-	) = 0;
+    virtual XERCES_CPP_NAMESPACE_QUALIFIER DOMNode * encryptElementDetached(
+        XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * element,
+        const XMLCh * algorithmURI
+    ) = 0;
 
-	/**
-	 * \brief Encrypt the children of the nominated element
-	 * 
-	 * Encrypts the all children of the passed in element.  The input
-	 * DOM node set is untouched, but the function returns an orphaned
-	 * sub-tree owned by the passed in document containing the encrypted
-	 * data.
-	 *
-	 * @param element Element whose children are to be encrypted
+    /**
+     * \brief Encrypt the children of the nominated element
+     *
+     * Encrypts the all children of the passed in element, but
+     * leaves the element itself in place, with one new child - an
+     * EncryptedData node of type #content
+     *
+     * @param element Element whose children are to be encrypted
      * @param algorithmURI algorithm URI to set
      *
-	 * @returns The resulting (orphaned) sub-tree from the passed in document
-	 * containing the encrypted data.
-	 * @throws XSECException if the encryption fails.
-	 */
+     * @returns The owning document with the element's children replaced, or NULL
+     * if the decryption fails for some reason (normally an exception).
+     * @throws XSECException if the encryption fails.
+     */
 
-	virtual XERCES_CPP_NAMESPACE_QUALIFIER DOMNode * encryptElementContentDetached(
-		XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * element,
-		const XMLCh * algorithmURI
-	) = 0;
-	
-	/**
-	 * \brief Encrypt a buffer of data as a key
-	 *
-	 * Encrypts the passed in data and creates an EncryptedKey element
-	 *
-	 * @param keyBuffer The key data to encrypt
-	 * @param keyLen Bytes to encrypt
+    virtual XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * encryptElementContent(
+        XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * element,
+        const XMLCh * algorithmURI
+    ) = 0;
+
+    /**
+     * \brief Encrypt the children of the nominated element
+     *
+     * Encrypts the all children of the passed in element.  The input
+     * DOM node set is untouched, but the function returns an orphaned
+     * sub-tree owned by the passed in document containing the encrypted
+     * data.
+     *
+     * @param element Element whose children are to be encrypted
      * @param algorithmURI algorithm URI to set
      *
-	 * @returns The EncryptedKey element
-	 */
+     * @returns The resulting (orphaned) sub-tree from the passed in document
+     * containing the encrypted data.
+     * @throws XSECException if the encryption fails.
+     */
 
-	virtual XENCEncryptedKey * encryptKey(
-		const unsigned char * keyBuffer,
-		unsigned int keyLen,
-		const XMLCh * algorithmURI
-	) = 0;
+    virtual XERCES_CPP_NAMESPACE_QUALIFIER DOMNode * encryptElementContentDetached(
+        XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * element,
+        const XMLCh * algorithmURI
+    ) = 0;
 
-	/**
-	 * \brief Encrypt an input stream to a CipherValue
-	 *
-	 * Encrypts the data passed in via a Xerces BinInputStream and places it
-	 * directly into a new EncryptedData element that contains a CipherValue
-	 *
-	 * @param plainText The InputStream to read the plain text from
+    /**
+     * \brief Encrypt a buffer of data as a key
+     *
+     * Encrypts the passed in data and creates an EncryptedKey element
+     *
+     * @param keyBuffer The key data to encrypt
+     * @param keyLen Bytes to encrypt
+     * @param algorithmURI algorithm URI to set
+     * @param mgfURI RSA-OAEP mask generation algorithm
+     *
+     * @returns The EncryptedKey element
+     */
+
+    virtual XENCEncryptedKey* encryptKey(
+        const unsigned char* keyBuffer,
+        unsigned int keyLen,
+        const XMLCh* algorithmURI,
+        const XMLCh* mgfURI=NULL
+    ) = 0;
+
+    /**
+     * \brief Encrypt an input stream to a CipherValue
+     *
+     * Encrypts the data passed in via a Xerces BinInputStream and places it
+     * directly into a new EncryptedData element that contains a CipherValue
+     *
+     * @param plainText The InputStream to read the plain text from
      * @param algorithmURI algorithm URI to set
      *
-	 * @returns the EncryptedData element containing the CipherValue of the data
-	 */
+     * @returns the EncryptedData element containing the CipherValue of the data
+     */
 
-	virtual XENCEncryptedData * encryptBinInputStream(
-		XERCES_CPP_NAMESPACE_QUALIFIER BinInputStream * plainText,
-		const XMLCh * algorithmURI
-	) = 0;
+    virtual XENCEncryptedData * encryptBinInputStream(
+        XERCES_CPP_NAMESPACE_QUALIFIER BinInputStream * plainText,
+        const XMLCh * algorithmURI
+    ) = 0;
 
-	/**
-	 * \brief Encrypt a TXFMChain to a CipherValue
-	 *
-	 * Encrypts the data passed in via a TXFMChain and places it
-	 * directly into a new EncryptedData element that contains a CipherValue.
-	 *
-	 * @note This is not really intended for client apps, but is used internally
-	 * and is provided for flexibility.  The "formal" method is encryptBinInputStream
-	 *
-	 * @param plainText The TXFMChain to read the plain text from
+    /**
+     * \brief Encrypt a TXFMChain to a CipherValue
+     *
+     * Encrypts the data passed in via a TXFMChain and places it
+     * directly into a new EncryptedData element that contains a CipherValue.
+     *
+     * @note This is not really intended for client apps, but is used internally
+     * and is provided for flexibility.  The "formal" method is encryptBinInputStream
+     *
+     * @param plainText The TXFMChain to read the plain text from
      * @param algorithmURI algorithm URI to set
      *
-	 * @returns the EncryptedData element containing the CipherValue of the data
-	 */
+     * @returns the EncryptedData element containing the CipherValue of the data
+     */
 
-	virtual XENCEncryptedData * encryptTXFMChain(
-		TXFMChain * plainText,
-		const XMLCh * algorithmURI
-	) = 0;
+    virtual XENCEncryptedData * encryptTXFMChain(
+        TXFMChain * plainText,
+        const XMLCh * algorithmURI
+    ) = 0;
 
-	//@}
-	/** @name Getter Functions */
-	//@{
+    //@}
+    /** @name Getter Functions */
+    //@{
 
-	/**
-	 * \brief Get owning document
-	 *
-	 * Every Cipher object is associated with an owning document (for generation of
-	 * nodes etc.)  This allows callers to retrieve this value.
-	 *
-	 * @returns The DOMDocument that is used by this object
-	 */
+    /**
+     * \brief Get owning document
+     *
+     * Every Cipher object is associated with an owning document (for generation of
+     * nodes etc.)  This allows callers to retrieve this value.
+     *
+     * @returns The DOMDocument that is used by this object
+     */
 
-	virtual XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * getDocument() const = 0;
+    virtual XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * getDocument() const = 0;
 
-	/**
-	 * \brief Get namespace prefix for XENC nodes
-	 *
-	 * Find the string being used by the library to prefix nodes in the 
-	 * xenc: namespace.
-	 *
-	 * @returns XENC namespace prefix
-	 */
+    /**
+     * \brief Get namespace prefix for XENC nodes
+     *
+     * Find the string being used by the library to prefix nodes in the
+     * xenc: namespace.
+     *
+     * @returns XENC namespace prefix
+     */
 
-	virtual const XMLCh * getXENCNSPrefix() const = 0;
+    virtual const XMLCh * getXENCNSPrefix() const = 0;
 
-	/**
-	 * \brief Get the EncryptedData element
-	 *
-	 * Allows the user to get the EncryptedData element that was last processed/
-	 * created by this XENCCipher object.
-	 *
-	 * @returns The last used EncryptedData
-	 */
+    /**
+     * \brief Get the EncryptedData element
+     *
+     * Allows the user to get the EncryptedData element that was last processed/
+     * created by this XENCCipher object.
+     *
+     * @returns The last used EncryptedData
+     */
 
-	virtual XENCEncryptedData * getEncryptedData() const = 0;
+    virtual XENCEncryptedData * getEncryptedData() const = 0;
 
-	/**
-	 * \brief Tell caller whether PrettyPrinting is active
-	 *
-	 * @returns True if Pretty Printing is active, false if not
-	 */
+    /**
+     * \brief Tell caller whether PrettyPrinting is active
+     *
+     * @returns True if Pretty Printing is active, false if not
+     */
 
-	virtual bool getPrettyPrint() const = 0;
+    virtual bool getPrettyPrint() const = 0;
 
-	/**
-	 * \brief Tell caller whether the serialisation routines will
-	 * use exclusive or normal canonicalisation.
-	 *
-	 * When serialising an element prior to encryption, the c14n
-	 * canonicalisation routines are used.  By default, exclusive
-	 * c14n is used, however this can be turned off using the
-	 * setExclusiveC14nSerialisation call.  This function returns 
-	 * the current state of the associated flag.
-	 *
-	 * @returns True if Exclusive c14n will be used, false if standard
-	 */
+    /**
+     * \brief Tell caller whether the serialisation routines will
+     * use exclusive or normal canonicalisation.
+     *
+     * When serialising an element prior to encryption, the c14n
+     * canonicalisation routines are used.  By default, exclusive
+     * c14n is used, however this can be turned off using the
+     * setExclusiveC14nSerialisation call.  This function returns
+     * the current state of the associated flag.
+     *
+     * @returns True if Exclusive c14n will be used, false if standard
+     */
 
-	virtual bool getExclusiveC14nSerialisation() const = 0;
+    virtual bool getExclusiveC14nSerialisation() const = 0;
 
-	//@}
+    //@}
 
-	/** @name Setter Functions */
-	//@{
+    /** @name Setter Functions */
+    //@{
 
-	/**
-	 * \brief Set decryption key for next operation
-	 *
-	 * Set the passed in key for the next decryption/encryption
-	 * operation.
-	 *
-	 * @param key Key to use
-	 * @note This function will take ownership of the key and delete it when done.
-	 */
+    /**
+     * \brief Set decryption key for next operation
+     *
+     * Set the passed in key for the next decryption/encryption
+     * operation.
+     *
+     * @param key Key to use
+     * @note This function will take ownership of the key and delete it when done.
+     */
 
-	virtual void setKey(XSECCryptoKey * key) = 0;
+    virtual void setKey(XSECCryptoKey * key) = 0;
 
-	/**
-	 * \brief Set Key Encryption Key for next operation
-	 *
-	 * Set the passed in key for the next key decryption/encryption
-	 * operation.
-	 *
-	 * @note This key will only be used to decrypt EncryptedKey elements.
-	 * To set a key for decrypting an EncryptedData use #setKey instead.
-	 *
-	 * @param key Key to use
-	 * @note This function will take ownership of the key and delete it when done.
-	 */
+    /**
+     * \brief Set Key Encryption Key for next operation
+     *
+     * Set the passed in key for the next key decryption/encryption
+     * operation.
+     *
+     * @note This key will only be used to decrypt EncryptedKey elements.
+     * To set a key for decrypting an EncryptedData use #setKey instead.
+     *
+     * @param key Key to use
+     * @note This function will take ownership of the key and delete it when done.
+     */
 
-	virtual void setKEK(XSECCryptoKey * key) = 0;
+    virtual void setKEK(XSECCryptoKey * key) = 0;
 
-	/**
-	 * \brief Register a KeyInfoResolver 
-	 *
-	 * Registers a KeyInfoResolver to be used by the cipher when 
-	 * it needs to find a key to be used to decrypt some ciper text
-	 *
-	 * @note The library will use the #clone() function from the resolver
-	 * to get a copy.  The passed in resolver remains the property of
-	 * the calling function
-	 *
-	 * @param resolver Resolver to clone and use for resolving keys
-	 *
-	 */
+    /**
+     * \brief Register a KeyInfoResolver
+     *
+     * Registers a KeyInfoResolver to be used by the cipher when
+     * it needs to find a key to be used to decrypt some ciper text
+     *
+     * @note The library will use the #clone() function from the resolver
+     * to get a copy.  The passed in resolver remains the property of
+     * the calling function
+     *
+     * @param resolver Resolver to clone and use for resolving keys
+     *
+     */
 
-	virtual void setKeyInfoResolver(const XSECKeyInfoResolver * resolver) = 0;
+    virtual void setKeyInfoResolver(const XSECKeyInfoResolver * resolver) = 0;
 
-	/**
-	 * \brief Set prefix for XENC nodes
-	 *
-	 * Set the namespace prefix the library will use when creating
-	 * nodes in the XENC namespace
-	 */
+    /**
+     * \brief Set prefix for XENC nodes
+     *
+     * Set the namespace prefix the library will use when creating
+     * nodes in the XENC namespace
+     */
 
-	virtual void setXENCNSPrefix(const XMLCh * prefix) = 0;
+    virtual void setXENCNSPrefix(const XMLCh * prefix) = 0;
 
-	/**
-	 * \brief Set Pretty Print
-	 *
-	 * The pretty print functions controls whether the library will output
-	 * CR/LF after the elements it adds to a document
-	 *
-	 * By default the library will do pretty printing (flag is true)
-	 *
-	 * @param flag Value to set for Pretty Printing (true = do pretty printing)
-	 */
+    /**
+     * \brief Set Pretty Print
+     *
+     * The pretty print functions controls whether the library will output
+     * CR/LF after the elements it adds to a document
+     *
+     * By default the library will do pretty printing (flag is true)
+     *
+     * @param flag Value to set for Pretty Printing (true = do pretty printing)
+     */
 
-	virtual void setPrettyPrint(bool flag) = 0;
+    virtual void setPrettyPrint(bool flag) = 0;
 
-	/**
-	 * \brief Set whether the serialisation routines will
-	 * use exclusive or normal canonicalisation.
-	 *
-	 * When serialising an element prior to encryption, the c14n
-	 * canonicalisation routines are used.  By default, exclusive
-	 * c14n is used, however this can be turned off using the
-	 * setExclusiveC14nSerialisation call.
-	 *
-	 * @param flag Set for true if Exclusive c14n will be used, 
-	 * false otherwise
-	 */
+    /**
+     * \brief Set whether the serialisation routines will
+     * use exclusive or normal canonicalisation.
+     *
+     * When serialising an element prior to encryption, the c14n
+     * canonicalisation routines are used.  By default, exclusive
+     * c14n is used, however this can be turned off using the
+     * setExclusiveC14nSerialisation call.
+     *
+     * @param flag Set for true if Exclusive c14n will be used,
+     * false otherwise
+     */
 
-	virtual void setExclusiveC14nSerialisation(bool flag) = 0;
+    virtual void setExclusiveC14nSerialisation(bool flag) = 0;
 
-	//@}
+    //@}
 
-	/** @name Creation and loading Functions */
-	//@{
+    /** @name Creation and loading Functions */
+    //@{
 
-	/**
-	 * \brief Create a new EncryptedData element
-	 *
-	 * Method for creating a basic Encrypted Data element.  Can be used
-	 * in cases where an application needs to build this from scratch.
-	 *
-	 * In general, applications should use the higher level methods such
-	 * as #encryptElement or #encryptElementContent.
-	 *
-	 * @note The Cipher object will take on this new object as the current
-	 * EncryptedData and delete any currently being held.
-	 *
-	 * @param type Should this set up a CipherReference or a CipherValue
-	 * @param algorithm URI string to use for the Algorithm attribute in EncryptionMethod.
-	 * Set to NULL for no defined algorithm.
-	 * @param value String to set the cipher data to if the type is VALUE_TYPE.
-	 * for REFERENCE_TYPE CipherData elements, this should be the URI value.
-	 * @returns An XENCEncryptedData object
-	 */
+    /**
+     * \brief Create a new EncryptedData element
+     *
+     * Method for creating a basic Encrypted Data element.  Can be used
+     * in cases where an application needs to build this from scratch.
+     *
+     * In general, applications should use the higher level methods such
+     * as #encryptElement or #encryptElementContent.
+     *
+     * @note The Cipher object will take on this new object as the current
+     * EncryptedData and delete any currently being held.
+     *
+     * @param type Should this set up a CipherReference or a CipherValue
+     * @param algorithm URI string to use for the Algorithm attribute in EncryptionMethod.
+     * Set to NULL for no defined algorithm.
+     * @param value String to set the cipher data to if the type is VALUE_TYPE.
+     * for REFERENCE_TYPE CipherData elements, this should be the URI value.
+     * @returns An XENCEncryptedData object
+     */
 
-	virtual XENCEncryptedData * createEncryptedData(XENCCipherData::XENCCipherDataType type,
-													const XMLCh * algorithm,
-													const XMLCh * value) = 0;
+    virtual XENCEncryptedData * createEncryptedData(XENCCipherData::XENCCipherDataType type,
+                                                    const XMLCh * algorithm,
+                                                    const XMLCh * value) = 0;
 
-	/**
-	 * \brief Load an EncryptedKey element
-	 *
-	 * Take a passed in EncryptedKey DOMNode and return a loaded XENCEncryptedKey
-	 * object based on the DOMNode from the passed in element.
-	 *
-	 * @param keyNode Element node to load EncryptedKey from
-	 * @returns An XENCEncryptedKey structure (owned by the caller) based on the 
-	 * node.
-	 */
+    /**
+     * \brief Load an EncryptedKey element
+     *
+     * Take a passed in EncryptedKey DOMNode and return a loaded XENCEncryptedKey
+     * object based on the DOMNode from the passed in element.
+     *
+     * @param keyNode Element node to load EncryptedKey from
+     * @returns An XENCEncryptedKey structure (owned by the caller) based on the
+     * node.
+     */
 
-	virtual XENCEncryptedKey * loadEncryptedKey(
-		XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * keyNode
-		) = 0;
+    virtual XENCEncryptedKey * loadEncryptedKey(
+        XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * keyNode
+        ) = 0;
 
-	/**
-	 * \brief Load an EncryptedData element
-	 *
-	 * Take a passed in EncryptedData DOMNode and return a loaded XENCEncryptedData
-	 * object based on the DOMNode from the passed in element.
-	 *
-	 * @note The Cipher object will take on this new object as the current
-	 * EncryptedData and delete any currently being held.
-	 *
-	 * @param dataNode Element node to load EncryptedData from
-	 * @returns An XENCEncryptedData structure (owned by the caller) based on the 
-	 * node.
-	 */
+    /**
+     * \brief Load an EncryptedData element
+     *
+     * Take a passed in EncryptedData DOMNode and return a loaded XENCEncryptedData
+     * object based on the DOMNode from the passed in element.
+     *
+     * @note The Cipher object will take on this new object as the current
+     * EncryptedData and delete any currently being held.
+     *
+     * @param dataNode Element node to load EncryptedData from
+     * @returns An XENCEncryptedData structure (owned by the caller) based on the
+     * node.
+     */
 
-	virtual XENCEncryptedData * loadEncryptedData(
-		XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * dataNode
-		) = 0;
+    virtual XENCEncryptedData * loadEncryptedData(
+        XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * dataNode
+        ) = 0;
 
 
-	//@}
+    //@}
 
 };
 
diff --git a/xsec/xenc/impl/XENCCipherImpl.cpp b/xsec/xenc/impl/XENCCipherImpl.cpp
index 305ecc1..b928f53 100644
--- a/xsec/xenc/impl/XENCCipherImpl.cpp
+++ b/xsec/xenc/impl/XENCCipherImpl.cpp
@@ -819,7 +819,11 @@
 //			Encrypt a key
 // --------------------------------------------------------------------------------
 
-XENCEncryptedKey * XENCCipherImpl::encryptKey(const unsigned char * keyBuffer, unsigned int keyLen, const XMLCh * algorithmURI) {
+XENCEncryptedKey * XENCCipherImpl::encryptKey(
+        const unsigned char* keyBuffer,
+        unsigned int keyLen,
+        const XMLCh* algorithmURI,
+        const XMLCh* mgfURI) {
 
     if (mp_kek == NULL) {
         throw XSECException(XSECException::CipherError, "XENCCipherImpl::encryptKey - No KEK set");
@@ -837,6 +841,9 @@
 
     encryptedKey->createBlankEncryptedKey(XENCCipherData::VALUE_TYPE, algorithmURI, s_noData);
 
+    if (mgfURI)
+        encryptedKey->getEncryptionMethod()->setMGF(mgfURI);
+
     // Create a transform chain to do pass the key to the encrypto
 
     safeBuffer rawKey;
diff --git a/xsec/xenc/impl/XENCCipherImpl.hpp b/xsec/xenc/impl/XENCCipherImpl.hpp
index 59889e1..efe1c35 100644
--- a/xsec/xenc/impl/XENCCipherImpl.hpp
+++ b/xsec/xenc/impl/XENCCipherImpl.hpp
@@ -92,10 +92,11 @@
 		const XMLCh * algorithmURI);
 
 	// Encrypt a key
-	virtual XENCEncryptedKey * encryptKey(
-		const unsigned char * keyBuffer,
+	virtual XENCEncryptedKey* encryptKey(
+		const unsigned char* keyBuffer,
 		unsigned int keyLen,
-		const XMLCh * algorithmURI
+		const XMLCh* algorithmURI,
+		const XMLCh* mgfURI=NULL
 	);
 	// Encrypt octet streams
 	virtual XENCEncryptedData * encryptBinInputStream(