You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@santuario.apache.org by sc...@apache.org on 2012/06/14 00:33:11 UTC

svn commit: r1350045 [1/2] - in /santuario/xml-security-cpp/trunk/xsec: dsig/ enc/ enc/NSS/ enc/OpenSSL/ enc/WinCAPI/ xenc/ xenc/impl/

Author: scantor
Date: Wed Jun 13 22:33:10 2012
New Revision: 1350045

URL: http://svn.apache.org/viewvc?rev=1350045&view=rev
Log:
AES-GCM decryption and OAEP with pluggable MGF support.

Modified:
    santuario/xml-security-cpp/trunk/xsec/dsig/DSIGConstants.cpp
    santuario/xml-security-cpp/trunk/xsec/dsig/DSIGConstants.hpp
    santuario/xml-security-cpp/trunk/xsec/enc/NSS/NSSCryptoKeyRSA.cpp
    santuario/xml-security-cpp/trunk/xsec/enc/NSS/NSSCryptoKeyRSA.hpp
    santuario/xml-security-cpp/trunk/xsec/enc/NSS/NSSCryptoSymmetricKey.cpp
    santuario/xml-security-cpp/trunk/xsec/enc/NSS/NSSCryptoSymmetricKey.hpp
    santuario/xml-security-cpp/trunk/xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.cpp
    santuario/xml-security-cpp/trunk/xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp
    santuario/xml-security-cpp/trunk/xsec/enc/OpenSSL/OpenSSLCryptoSymmetricKey.cpp
    santuario/xml-security-cpp/trunk/xsec/enc/OpenSSL/OpenSSLCryptoSymmetricKey.hpp
    santuario/xml-security-cpp/trunk/xsec/enc/WinCAPI/WinCAPICryptoKeyRSA.cpp
    santuario/xml-security-cpp/trunk/xsec/enc/WinCAPI/WinCAPICryptoKeyRSA.hpp
    santuario/xml-security-cpp/trunk/xsec/enc/WinCAPI/WinCAPICryptoSymmetricKey.cpp
    santuario/xml-security-cpp/trunk/xsec/enc/WinCAPI/WinCAPICryptoSymmetricKey.hpp
    santuario/xml-security-cpp/trunk/xsec/enc/XSECCryptoKeyRSA.hpp
    santuario/xml-security-cpp/trunk/xsec/enc/XSECCryptoSymmetricKey.hpp
    santuario/xml-security-cpp/trunk/xsec/xenc/XENCEncryptionMethod.hpp
    santuario/xml-security-cpp/trunk/xsec/xenc/impl/XENCAlgorithmHandlerDefault.cpp
    santuario/xml-security-cpp/trunk/xsec/xenc/impl/XENCAlgorithmHandlerDefault.hpp
    santuario/xml-security-cpp/trunk/xsec/xenc/impl/XENCCipherImpl.cpp
    santuario/xml-security-cpp/trunk/xsec/xenc/impl/XENCEncryptionMethodImpl.cpp
    santuario/xml-security-cpp/trunk/xsec/xenc/impl/XENCEncryptionMethodImpl.hpp

Modified: santuario/xml-security-cpp/trunk/xsec/dsig/DSIGConstants.cpp
URL: http://svn.apache.org/viewvc/santuario/xml-security-cpp/trunk/xsec/dsig/DSIGConstants.cpp?rev=1350045&r1=1350044&r2=1350045&view=diff
==============================================================================
--- santuario/xml-security-cpp/trunk/xsec/dsig/DSIGConstants.cpp (original)
+++ santuario/xml-security-cpp/trunk/xsec/dsig/DSIGConstants.cpp Wed Jun 13 22:33:10 2012
@@ -161,6 +161,7 @@ const XMLCh * DSIGConstants::s_unicodeSt
 const XMLCh * DSIGConstants::s_unicodeStrURIEC;
 const XMLCh * DSIGConstants::s_unicodeStrURIXPF;
 const XMLCh * DSIGConstants::s_unicodeStrURIXENC;
+const XMLCh * DSIGConstants::s_unicodeStrURIXENC11;
 
 const XMLCh * DSIGConstants::s_unicodeStrURISIGBASE;
 const XMLCh * DSIGConstants::s_unicodeStrURISIGBASEMORE;
@@ -212,12 +213,23 @@ const XMLCh * DSIGConstants::s_unicodeSt
 const XMLCh * DSIGConstants::s_unicodeStrURIAES128_CBC;
 const XMLCh * DSIGConstants::s_unicodeStrURIAES192_CBC;
 const XMLCh * DSIGConstants::s_unicodeStrURIAES256_CBC;
+const XMLCh * DSIGConstants::s_unicodeStrURIAES128_GCM;
+const XMLCh * DSIGConstants::s_unicodeStrURIAES192_GCM;
+const XMLCh * DSIGConstants::s_unicodeStrURIAES256_GCM;
 const XMLCh * DSIGConstants::s_unicodeStrURIKW_AES128;
 const XMLCh * DSIGConstants::s_unicodeStrURIKW_AES192;
 const XMLCh * DSIGConstants::s_unicodeStrURIKW_AES256;
 const XMLCh * DSIGConstants::s_unicodeStrURIKW_3DES;
 const XMLCh * DSIGConstants::s_unicodeStrURIRSA_1_5;
 const XMLCh * DSIGConstants::s_unicodeStrURIRSA_OAEP_MGFP1;
+const XMLCh * DSIGConstants::s_unicodeStrURIRSA_OAEP;
+
+const XMLCh * DSIGConstants::s_unicodeStrURIMGF1_BASE;
+const XMLCh * DSIGConstants::s_unicodeStrURIMGF1_SHA1;
+const XMLCh * DSIGConstants::s_unicodeStrURIMGF1_SHA224;
+const XMLCh * DSIGConstants::s_unicodeStrURIMGF1_SHA256;
+const XMLCh * DSIGConstants::s_unicodeStrURIMGF1_SHA384;
+const XMLCh * DSIGConstants::s_unicodeStrURIMGF1_SHA512;
 
 const XMLCh * DSIGConstants::s_unicodeStrURIXENC_ELEMENT;
 const XMLCh * DSIGConstants::s_unicodeStrURIXENC_CONTENT;
@@ -247,6 +259,7 @@ void DSIGConstants::create() {
 	s_unicodeStrURIEC = XMLString::transcode(URI_ID_EC);
 	s_unicodeStrURIXPF = XMLString::transcode(URI_ID_XPF);
 	s_unicodeStrURIXENC = XMLString::transcode(URI_ID_XENC);
+    s_unicodeStrURIXENC11 = XMLString::transcode(URI_ID_XENC11);
 
 	s_unicodeStrURISIGBASE = XMLString::transcode(URI_ID_SIG_BASE);
 	s_unicodeStrURISIGBASEMORE = XMLString::transcode(URI_ID_SIG_BASEMORE);
@@ -297,12 +310,23 @@ void DSIGConstants::create() {
 	s_unicodeStrURIAES128_CBC	= XMLString::transcode(URI_ID_AES128_CBC);
 	s_unicodeStrURIAES192_CBC	= XMLString::transcode(URI_ID_AES192_CBC);
 	s_unicodeStrURIAES256_CBC	= XMLString::transcode(URI_ID_AES256_CBC);
-	s_unicodeStrURIKW_AES128 = XMLString::transcode(URI_ID_KW_AES128);
+	s_unicodeStrURIAES128_GCM	= XMLString::transcode(URI_ID_AES128_GCM);
+    s_unicodeStrURIAES192_GCM	= XMLString::transcode(URI_ID_AES192_GCM);
+    s_unicodeStrURIAES256_GCM	= XMLString::transcode(URI_ID_AES256_GCM);
+    s_unicodeStrURIKW_AES128 = XMLString::transcode(URI_ID_KW_AES128);
 	s_unicodeStrURIKW_AES192 = XMLString::transcode(URI_ID_KW_AES192);
 	s_unicodeStrURIKW_AES256 = XMLString::transcode(URI_ID_KW_AES256);
 	s_unicodeStrURIKW_3DES = XMLString::transcode(URI_ID_KW_3DES);
 	s_unicodeStrURIRSA_1_5 = XMLString::transcode(URI_ID_RSA_1_5);
 	s_unicodeStrURIRSA_OAEP_MGFP1 = XMLString::transcode(URI_ID_RSA_OAEP_MGFP1);
+    s_unicodeStrURIRSA_OAEP = XMLString::transcode(URI_ID_RSA_OAEP);
+
+    s_unicodeStrURIMGF1_BASE = XMLString::transcode(URI_ID_MGF1_BASE);
+	s_unicodeStrURIMGF1_SHA1 = XMLString::transcode(URI_ID_MGF1_SHA1);
+	s_unicodeStrURIMGF1_SHA224 = XMLString::transcode(URI_ID_MGF1_SHA224);
+	s_unicodeStrURIMGF1_SHA256 = XMLString::transcode(URI_ID_MGF1_SHA256);
+	s_unicodeStrURIMGF1_SHA384 = XMLString::transcode(URI_ID_MGF1_SHA384);
+	s_unicodeStrURIMGF1_SHA512 = XMLString::transcode(URI_ID_MGF1_SHA512);
 
 	s_unicodeStrURIXENC_ELEMENT = XMLString::transcode(URI_ID_XENC_ELEMENT);
 	s_unicodeStrURIXENC_CONTENT = XMLString::transcode(URI_ID_XENC_CONTENT);
@@ -329,6 +353,7 @@ void DSIGConstants::destroy() {
 	XSEC_RELEASE_XMLCH(s_unicodeStrURIEC);
 	XSEC_RELEASE_XMLCH(s_unicodeStrURIXPF);
 	XSEC_RELEASE_XMLCH(s_unicodeStrURIXENC);
+    XSEC_RELEASE_XMLCH(s_unicodeStrURIXENC11);
 
 	XSEC_RELEASE_XMLCH(s_unicodeStrURISIGBASE);
 	XSEC_RELEASE_XMLCH(s_unicodeStrURISIGBASEMORE);
@@ -374,12 +399,24 @@ void DSIGConstants::destroy() {
 	XSEC_RELEASE_XMLCH(s_unicodeStrURIAES128_CBC);
 	XSEC_RELEASE_XMLCH(s_unicodeStrURIAES192_CBC);
 	XSEC_RELEASE_XMLCH(s_unicodeStrURIAES256_CBC);
+	XSEC_RELEASE_XMLCH(s_unicodeStrURIAES128_GCM);
+	XSEC_RELEASE_XMLCH(s_unicodeStrURIAES192_GCM);
+	XSEC_RELEASE_XMLCH(s_unicodeStrURIAES256_GCM);
 	XSEC_RELEASE_XMLCH(s_unicodeStrURIKW_AES128);
 	XSEC_RELEASE_XMLCH(s_unicodeStrURIKW_AES192);
 	XSEC_RELEASE_XMLCH(s_unicodeStrURIKW_AES256);
 	XSEC_RELEASE_XMLCH(s_unicodeStrURIKW_3DES);
 	XSEC_RELEASE_XMLCH(s_unicodeStrURIRSA_1_5);
 	XSEC_RELEASE_XMLCH(s_unicodeStrURIRSA_OAEP_MGFP1);
+    XSEC_RELEASE_XMLCH(s_unicodeStrURIRSA_OAEP);
+
+    XSEC_RELEASE_XMLCH(s_unicodeStrURIMGF1_BASE);
+	XSEC_RELEASE_XMLCH(s_unicodeStrURIMGF1_SHA1);
+	XSEC_RELEASE_XMLCH(s_unicodeStrURIMGF1_SHA224);
+	XSEC_RELEASE_XMLCH(s_unicodeStrURIMGF1_SHA256);
+	XSEC_RELEASE_XMLCH(s_unicodeStrURIMGF1_SHA384);
+	XSEC_RELEASE_XMLCH(s_unicodeStrURIMGF1_SHA512);
+
 	XSEC_RELEASE_XMLCH(s_unicodeStrURIXENC_ELEMENT);
 	XSEC_RELEASE_XMLCH(s_unicodeStrURIXENC_CONTENT);
 
@@ -555,7 +592,6 @@ bool XSECmapURIToHashMethod(const XMLCh 
 
 	hm = HASH_NONE;
 	return false;
-
 }
 
 bool XSECmapURIToCanonicalizationMethod(const XMLCh * URI,
@@ -592,3 +628,38 @@ bool XSECmapURIToCanonicalizationMethod(
 
 	return true;
 }
+
+bool XSECmapURIToMaskGenerationFunc(const XMLCh * URI, maskGenerationFunc & mgf) {
+
+
+	// Check this is a known prefix on the URI.
+	xsecsize_t len = XMLString::stringLen(DSIGConstants::s_unicodeStrURIMGF1_BASE);
+	if (XMLString::compareNString(URI, DSIGConstants::s_unicodeStrURIMGF1_BASE, len) == 0) {
+
+        hashMethod hm;
+		if (getHashMethod(&URI[len], hm)) {
+            switch (hm) {
+                case HASH_SHA1:
+                    mgf = MGF1_SHA1;
+                    return true;
+                case HASH_SHA224:
+                    mgf = MGF1_SHA224;
+                    return true;
+                case HASH_SHA256:
+                    mgf = MGF1_SHA256;
+                    return true;
+                case HASH_SHA384:
+                    mgf = MGF1_SHA384;
+                    return true;
+                case HASH_SHA512:
+                    mgf = MGF1_SHA512;
+                    return true;
+                default:
+                    ;
+            }
+        }
+	}
+
+	mgf = MGF_NONE;
+	return false;
+}
\ No newline at end of file

Modified: santuario/xml-security-cpp/trunk/xsec/dsig/DSIGConstants.hpp
URL: http://svn.apache.org/viewvc/santuario/xml-security-cpp/trunk/xsec/dsig/DSIGConstants.hpp?rev=1350045&r1=1350044&r2=1350045&view=diff
==============================================================================
--- santuario/xml-security-cpp/trunk/xsec/dsig/DSIGConstants.hpp (original)
+++ santuario/xml-security-cpp/trunk/xsec/dsig/DSIGConstants.hpp Wed Jun 13 22:33:10 2012
@@ -46,6 +46,7 @@ XSEC_USING_XERCES(XMLString);
 // Also used as algorithm ID for XPATH_FILTER
 #define URI_ID_XPF		"http://www.w3.org/2002/06/xmldsig-filter2"
 #define URI_ID_XENC		"http://www.w3.org/2001/04/xmlenc#"
+#define URI_ID_XENC11	"http://www.w3.org/2009/xmlenc11#"
 
 // Hashing Algorithms
 
@@ -61,6 +62,10 @@ XSEC_USING_XERCES(XMLString);
 #define URI_ID_AES128_CBC	"http://www.w3.org/2001/04/xmlenc#aes128-cbc"
 #define URI_ID_AES192_CBC	"http://www.w3.org/2001/04/xmlenc#aes192-cbc"
 #define URI_ID_AES256_CBC	"http://www.w3.org/2001/04/xmlenc#aes256-cbc"
+#define URI_ID_AES128_GCM	"http://www.w3.org/2009/xmlenc11#aes128-gcm"
+#define URI_ID_AES192_GCM	"http://www.w3.org/2009/xmlenc11#aes192-gcm"
+#define URI_ID_AES256_GCM	"http://www.w3.org/2009/xmlenc11#aes256-gcm"
+
 
 // Key Wrap Algorithm
 #define URI_ID_KW_AES128	"http://www.w3.org/2001/04/xmlenc#kw-aes128"
@@ -71,6 +76,15 @@ XSEC_USING_XERCES(XMLString);
 // Key Transport algorithms
 #define URI_ID_RSA_1_5			"http://www.w3.org/2001/04/xmlenc#rsa-1_5"
 #define URI_ID_RSA_OAEP_MGFP1	"http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"
+#define URI_ID_RSA_OAEP	        "http://www.w3.org/2009/xmlenc11#rsa-oaep"
+
+// OAEP MGFs
+#define URI_ID_MGF1_BASE	    "http://www.w3.org/2009/xmlenc11#mgf1"
+#define URI_ID_MGF1_SHA1        "http://www.w3.org/2009/xmlenc11#mgf1sha1"
+#define URI_ID_MGF1_SHA224      "http://www.w3.org/2009/xmlenc11#mgf1sha224"
+#define URI_ID_MGF1_SHA256      "http://www.w3.org/2009/xmlenc11#mgf1sha256"
+#define URI_ID_MGF1_SHA384      "http://www.w3.org/2009/xmlenc11#mgf1sha384"
+#define URI_ID_MGF1_SHA512      "http://www.w3.org/2009/xmlenc11#mgf1sha512"
 
 // Transforms
 
@@ -204,10 +218,21 @@ enum encryptionMethod {
 	ENCRYPT_KW_AES256		= 7,				// KeyWrap - AES256
 	ENCRYPT_KW_3DES			= 8,
 	ENCRYPT_RSA_15			= 9,				// RSA with PKCS 1.5 padding
-	ENCRYPT_RSA_OAEP_MGFP1	= 10				// RSA with OAEP
-
+	ENCRYPT_RSA_OAEP_MGFP1	= 10,				// RSA with OAEP and MGFP1
+    ENCRYPT_RSA_OAEP	    = 11,				// RSA with OAEP
+	ENCRYPT_AES128_GCM		= 12,				// 128 bit AES in GCM
+    ENCRYPT_AES192_GCM		= 13,				// 192 bit AES in GCM
+	ENCRYPT_AES256_GCM		= 14				// 256 bit AES in GCM
 };
 
+enum maskGenerationFunc {
+    MGF_NONE                = 0,                // No MGF defined
+    MGF1_SHA1               = 1,                // MGF1-SHA1
+    MGF1_SHA224             = 2,                // MGF1-SHA224
+    MGF1_SHA256             = 3,                // MGF1-SHA256
+    MGF1_SHA384             = 4,                // MGF1-SHA384
+    MGF1_SHA512             = 5                 // MGF1-SHA512
+};
 
 // --------------------------------------------------------------------------------
 //           Some utility functions
@@ -438,8 +463,67 @@ bool encryptionMethod2URI(safeBuffer &ur
 		uri = URI_ID_RSA_OAEP_MGFP1;
 		break;
 
-	default:
+	case (ENCRYPT_RSA_OAEP) :
+
+		uri = URI_ID_RSA_OAEP;
+		break;
+
+	case (ENCRYPT_AES128_GCM) :
+
+		uri = URI_ID_AES128_GCM;
+		break;
+
+	case (ENCRYPT_AES192_GCM) :
+
+		uri = URI_ID_AES192_GCM;
+		break;
+
+    case (ENCRYPT_AES256_GCM) :
+
+		uri = URI_ID_AES256_GCM;
+		break;
+
+    default:
+
+		return false;
+
+	}
+
+	return true;
 
+}
+
+inline
+bool maskGenerationFunc2URI(safeBuffer &uri, maskGenerationFunc mgf) {
+
+	switch (mgf) {
+
+	case (MGF1_SHA1) :
+
+		uri = URI_ID_MGF1_SHA1;
+		break;
+
+	case (MGF1_SHA224) :
+
+		uri = URI_ID_MGF1_SHA224;
+		break;
+
+	case (MGF1_SHA256) :
+
+		uri = URI_ID_MGF1_SHA256;
+		break;
+
+	case (MGF1_SHA384) :
+
+		uri = URI_ID_MGF1_SHA384;
+		break;
+
+	case (MGF1_SHA512) :
+
+		uri = URI_ID_MGF1_SHA512;
+		break;
+
+	default:
 		return false;
 
 	}
@@ -448,6 +532,7 @@ bool encryptionMethod2URI(safeBuffer &ur
 
 }
 
+
 // --------------------------------------------------------------------------------
 //           Constant Strings Class
 // --------------------------------------------------------------------------------
@@ -472,6 +557,7 @@ public:
 	static const XMLCh * s_unicodeStrURIEC;
 	static const XMLCh * s_unicodeStrURIXPF;
 	static const XMLCh * s_unicodeStrURIXENC;
+    static const XMLCh * s_unicodeStrURIXENC11;
 
 	static const XMLCh * s_unicodeStrURISIGBASE;
 	static const XMLCh * s_unicodeStrURISIGBASEMORE;
@@ -524,13 +610,24 @@ public:
 	static const XMLCh * s_unicodeStrURIAES128_CBC;
 	static const XMLCh * s_unicodeStrURIAES192_CBC;
 	static const XMLCh * s_unicodeStrURIAES256_CBC;
+	static const XMLCh * s_unicodeStrURIAES128_GCM;
+    static const XMLCh * s_unicodeStrURIAES192_GCM;
+	static const XMLCh * s_unicodeStrURIAES256_GCM;
 	static const XMLCh * s_unicodeStrURIKW_AES128;
 	static const XMLCh * s_unicodeStrURIKW_AES192;
 	static const XMLCh * s_unicodeStrURIKW_AES256;
 	static const XMLCh * s_unicodeStrURIKW_3DES;
 	static const XMLCh * s_unicodeStrURIRSA_1_5;
 	static const XMLCh * s_unicodeStrURIRSA_OAEP_MGFP1;
+    static const XMLCh * s_unicodeStrURIRSA_OAEP;
 
+    static const XMLCh * s_unicodeStrURIMGF1_BASE;
+	static const XMLCh * s_unicodeStrURIMGF1_SHA1;
+	static const XMLCh * s_unicodeStrURIMGF1_SHA224;
+	static const XMLCh * s_unicodeStrURIMGF1_SHA256;
+	static const XMLCh * s_unicodeStrURIMGF1_SHA384;
+	static const XMLCh * s_unicodeStrURIMGF1_SHA512;
+   
 	static const XMLCh * s_unicodeStrURIXENC_ELEMENT;
 	static const XMLCh * s_unicodeStrURIXENC_CONTENT;
 
@@ -599,5 +696,8 @@ bool DSIG_EXPORT XSECmapURIToHashMethod(
 bool DSIG_EXPORT XSECmapURIToCanonicalizationMethod(const XMLCh * URI,
 							canonicalizationMethod & cm);
 
+bool DSIG_EXPORT XSECmapURIToMaskGenerationFunc(const XMLCh * URI,
+												  maskGenerationFunc & mgf);
+
 #endif /* DSIGCONSTANTS_HEADER */
 

Modified: santuario/xml-security-cpp/trunk/xsec/enc/NSS/NSSCryptoKeyRSA.cpp
URL: http://svn.apache.org/viewvc/santuario/xml-security-cpp/trunk/xsec/enc/NSS/NSSCryptoKeyRSA.cpp?rev=1350045&r1=1350044&r2=1350045&view=diff
==============================================================================
--- santuario/xml-security-cpp/trunk/xsec/enc/NSS/NSSCryptoKeyRSA.cpp (original)
+++ santuario/xml-security-cpp/trunk/xsec/enc/NSS/NSSCryptoKeyRSA.cpp Wed Jun 13 22:33:10 2012
@@ -118,6 +118,14 @@ void NSSCryptoKeyRSA::setOAEPparams(unsi
 
 }
 
+void NSSCryptoKeyRSA::setMGF(maskGenerationFunc mgf) {
+
+	if (mgf != MGF1_SHA1)
+		throw XSECCryptoException(XSECCryptoException::UnsupportedError,
+			"NSS::setMGF - NSS does not support pluggable MGF for OAEP");
+
+}
+
 // --------------------------------------------------------------------------------
 //           Get OAEP parameters length
 // --------------------------------------------------------------------------------
@@ -138,6 +146,12 @@ const unsigned char * NSSCryptoKeyRSA::g
 
 }
 
+maskGenerationFunc NSSCryptoKeyRSA::getMGF() const {
+
+    return MGF1_SHA1;
+
+}
+
 
 // --------------------------------------------------------------------------------
 //           Load modulus

Modified: santuario/xml-security-cpp/trunk/xsec/enc/NSS/NSSCryptoKeyRSA.hpp
URL: http://svn.apache.org/viewvc/santuario/xml-security-cpp/trunk/xsec/enc/NSS/NSSCryptoKeyRSA.hpp?rev=1350045&r1=1350044&r2=1350045&view=diff
==============================================================================
--- santuario/xml-security-cpp/trunk/xsec/enc/NSS/NSSCryptoKeyRSA.hpp (original)
+++ santuario/xml-security-cpp/trunk/xsec/enc/NSS/NSSCryptoKeyRSA.hpp Wed Jun 13 22:33:10 2012
@@ -142,6 +142,26 @@ public :
 	virtual const unsigned char * getOAEPparams(void) const;
 
 	/**
+	 * \brief Set the MGF
+	 *
+	 * By default, the library expects crypto implementations to perform
+	 * OAEP padding with MGF_SHA1.  This call allows the library (or user)
+	 * to set a different choice.
+	 *
+	 * @param mgf the MGF constant identifying the function to use
+	 */
+
+	virtual void setMGF(maskGenerationFunc mgf);
+
+	/**
+	 * \brief Get the MGF
+	 *
+	 * @returns the MGF constant in use
+	 */
+
+	virtual enum maskGenerationFunc getMGF(void) const;
+
+	/**
 	 * \brief Verify a SHA1 PKCS1 encoded signature
 	 *
 	 * The library will call this function to validate an RSA signature

Modified: santuario/xml-security-cpp/trunk/xsec/enc/NSS/NSSCryptoSymmetricKey.cpp
URL: http://svn.apache.org/viewvc/santuario/xml-security-cpp/trunk/xsec/enc/NSS/NSSCryptoSymmetricKey.cpp?rev=1350045&r1=1350044&r2=1350045&view=diff
==============================================================================
--- santuario/xml-security-cpp/trunk/xsec/enc/NSS/NSSCryptoSymmetricKey.cpp (original)
+++ santuario/xml-security-cpp/trunk/xsec/enc/NSS/NSSCryptoSymmetricKey.cpp Wed Jun 13 22:33:10 2012
@@ -48,7 +48,7 @@ XERCES_CPP_NAMESPACE_USE
 
 NSSCryptoSymmetricKey::NSSCryptoSymmetricKey(XSECCryptoSymmetricKey::SymmetricKeyType type) :
 m_keyType(type),
-m_keyMode(MODE_CBC),
+m_keyMode(MODE_NONE),
 m_initialised(false),
 mp_k(NULL)
 {
@@ -177,11 +177,13 @@ int NSSCryptoSymmetricKey::decryptCtxIni
 		return 0;
 
 	if (mp_k == 0) {
-
 		throw XSECCryptoException(XSECCryptoException::SymmetricError,
 			"NSS:SymmetricKey - Cannot initialise without key"); 
-
 	}
+    else if (m_keyMode == MODE_NONE) {
+		throw XSECCryptoException(XSECCryptoException::SymmetricError,
+			"NSS:SymmetricKey - Cannot initialise without mode"); 
+    }
 
 	// Set up the context according to the required cipher type
 
@@ -199,32 +201,36 @@ int NSSCryptoSymmetricKey::decryptCtxIni
 
 			}
 
-      SECItem ivItem;
-      ivItem.data = (unsigned char*)iv;
-      ivItem.len = 8;
-	  int encryptAlg = (m_doPad == true ? CKM_DES3_CBC_PAD : CKM_DES3_CBC);
+            SECItem ivItem;
+            ivItem.data = (unsigned char*)iv;
+            ivItem.len = 8;
+            int encryptAlg = (m_doPad == true ? CKM_DES3_CBC_PAD : CKM_DES3_CBC);
 
-      SECItem * secParam = PK11_ParamFromIV(encryptAlg, &ivItem);
-      mp_ctx = PK11_CreateContextBySymKey(encryptAlg, CKA_DECRYPT, mp_k, secParam);
+            SECItem * secParam = PK11_ParamFromIV(encryptAlg, &ivItem);
+            mp_ctx = PK11_CreateContextBySymKey(encryptAlg, CKA_DECRYPT, mp_k, secParam);
 
-      if (secParam)
-        SECITEM_FreeItem(secParam, PR_TRUE);
+            if (secParam)
+                SECITEM_FreeItem(secParam, PR_TRUE);
 			
-      m_ivSize = 8;
-		}
-		else {
-			SECItem * secParam = PK11_ParamFromIV(CKM_DES3_ECB, NULL);
-      mp_ctx = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_DECRYPT, mp_k, secParam);
-      if (secParam)
-        SECITEM_FreeItem(secParam, PR_TRUE);	
-      m_ivSize = 0;
+            m_ivSize = 8;
+        }
+        else if (m_keyMode == MODE_ECB) {
+	        SECItem * secParam = PK11_ParamFromIV(CKM_DES3_ECB, NULL);
+            mp_ctx = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_DECRYPT, mp_k, secParam);
+            if (secParam)
+                SECITEM_FreeItem(secParam, PR_TRUE);	
+            m_ivSize = 0;
 		}
+        else {
+		    throw XSECCryptoException(XSECCryptoException::SymmetricError,
+			    "NSS:SymmetricKey - Unrecognized cipher mode");
+        }
 
 		break;
 
 	case (XSECCryptoSymmetricKey::KEY_AES_128) :
-  case (XSECCryptoSymmetricKey::KEY_AES_192) :
-  case (XSECCryptoSymmetricKey::KEY_AES_256) :
+    case (XSECCryptoSymmetricKey::KEY_AES_192) :
+    case (XSECCryptoSymmetricKey::KEY_AES_256) :
 
 		// An AES key
 
@@ -236,28 +242,33 @@ int NSSCryptoSymmetricKey::decryptCtxIni
 
 			}
 
-      SECItem ivItem;
-      ivItem.data = (unsigned char*)iv;
-      ivItem.len = 16;
+            SECItem ivItem;
+            ivItem.data = (unsigned char*)iv;
+            ivItem.len = 16;
 
-      SECItem * secParam = PK11_ParamFromIV(CKM_AES_CBC_PAD, &ivItem);
-      mp_ctx = PK11_CreateContextBySymKey(CKM_AES_CBC_PAD, CKA_DECRYPT, mp_k, secParam);
+            SECItem * secParam = PK11_ParamFromIV(CKM_AES_CBC_PAD, &ivItem);
+            mp_ctx = PK11_CreateContextBySymKey(CKM_AES_CBC_PAD, CKA_DECRYPT, mp_k, secParam);
 
-      if (secParam)
-        SECITEM_FreeItem(secParam, PR_TRUE);
+            if (secParam)
+                SECITEM_FreeItem(secParam, PR_TRUE);
 
-      m_ivSize = 16;
+            m_ivSize = 16;
 
 		}
-		else {
+		else if (m_keyMode == MODE_ECB {
+
 			SECItem * secParam = PK11_ParamFromIV(CKM_AES_ECB, NULL);
 			mp_ctx = PK11_CreateContextBySymKey(CKM_AES_ECB, CKA_DECRYPT, mp_k, secParam);
-      if (secParam)
-        SECITEM_FreeItem(secParam, PR_TRUE);
+            if (secParam)
+                SECITEM_FreeItem(secParam, PR_TRUE);
 
-      m_ivSize = 0;
+            m_ivSize = 0;
 
 		}
+        else {
+		    throw XSECCryptoException(XSECCryptoException::SymmetricError,
+			    "NSS:SymmetricKey - Unrecognized cipher mode");
+        }
 
 		break;
 	
@@ -282,7 +293,9 @@ int NSSCryptoSymmetricKey::decryptCtxIni
 
 bool NSSCryptoSymmetricKey::decryptInit(bool doPad, 
 											SymmetricKeyMode mode, 
-											const unsigned char * iv) {
+											const unsigned char * iv,
+                                            const unsigned char* tag,
+                                            unsigned int taglen) {
 
 	m_initialised = false;
     m_ivSent = iv == NULL;
@@ -316,21 +329,21 @@ unsigned int NSSCryptoSymmetricKey::decr
 
 	int outl = inLength - offset;
 
-  SECStatus s = PK11_CipherOp(mp_ctx, plainBuf, &outl, maxOutLength, (unsigned char*)inBuf, inLength);
+    SECStatus s = PK11_CipherOp(mp_ctx, plainBuf, &outl, maxOutLength, (unsigned char*)inBuf, inLength);
 
-  if (s != SECSuccess) {
+    if (s != SECSuccess) {
 
-    throw XSECCryptoException(XSECCryptoException::SymmetricError,
-			"NSS:SymmetricKey - Error during NSS decrypt");
+        throw XSECCryptoException(XSECCryptoException::SymmetricError,
+	    		"NSS:SymmetricKey - Error during NSS decrypt");
 
-  }
+    }
 
-  // remove IV
-  if (m_ivSent) {
-    memmove(plainBuf, &plainBuf[m_ivSize], outl);
-    outl -= m_ivSize;
-    m_ivSent = false;
-  }
+    // remove IV
+    if (m_ivSent) {
+        memmove(plainBuf, &plainBuf[m_ivSize], outl);
+        outl -= m_ivSize;
+        m_ivSent = false;
+    }
 
 	return outl;
 
@@ -345,20 +358,20 @@ unsigned int NSSCryptoSymmetricKey::decr
 
 	unsigned int outl = 0;
 
-  SECStatus s = PK11_DigestFinal(mp_ctx, plainBuf, &outl, maxOutLength);
+    SECStatus s = PK11_DigestFinal(mp_ctx, plainBuf, &outl, maxOutLength);
 
-  if (s != SECSuccess) {
+    if (s != SECSuccess) {
 
 		throw XSECCryptoException(XSECCryptoException::SymmetricError,
 			"NSS:SymmetricKey - Error during NSS decrypt finalisation");
 
-  }
+    }
 
-  PK11_DestroyContext(mp_ctx, PR_TRUE);
-  mp_ctx = NULL;
-  m_initialised = false;
+    PK11_DestroyContext(mp_ctx, PR_TRUE);
+    mp_ctx = NULL;
+    m_initialised = false;
 
-  return outl;
+    return outl;
 }
 
 // --------------------------------------------------------------------------------
@@ -376,11 +389,13 @@ bool NSSCryptoSymmetricKey::encryptInit(
 	m_keyMode = mode;
 	
 	if (mp_k == 0) {
-
 		throw XSECCryptoException(XSECCryptoException::SymmetricError,
 			"NSS:SymmetricKey - Cannot initialise without key"); 
-
 	}
+    else if (m_keyMode == MODE_NONE) {
+		throw XSECCryptoException(XSECCryptoException::SymmetricError,
+			"NSS:SymmetricKey - Cannot initialise without mode"); 
+    }
 
 	// Do some parameter initialisation
 	m_initialised = true;
@@ -402,47 +417,51 @@ bool NSSCryptoSymmetricKey::encryptInit(
 
 		if (m_keyMode == MODE_CBC) {
 
-			if (iv == NULL) {
+		    if (iv == NULL) {
 				
-        SECStatus s = PK11_GenerateRandom(genIV, 8);
+                SECStatus s = PK11_GenerateRandom(genIV, 8);
 
-        if (s != SECSuccess) {
+                if (s != SECSuccess) {
 
 					throw XSECCryptoException(XSECCryptoException::SymmetricError,
 						"NSS:SymmetricKey - Error generating random IV");
 
-        }
+                }
 
 				usedIV = genIV;
 
-			}
-			else
+		    }
+		    else
 				usedIV = iv;
 
-      SECItem ivItem;
-      ivItem.data = (unsigned char*)usedIV;
-      ivItem.len = 8;
-	  int encryptAlg = (m_doPad == true ? CKM_DES3_CBC_PAD : CKM_DES3_CBC);
-
-      SECItem * secParam = PK11_ParamFromIV(encryptAlg, &ivItem);
-      mp_ctx = PK11_CreateContextBySymKey(encryptAlg, CKA_ENCRYPT, mp_k, secParam);
-
-      if (secParam)
-        SECITEM_FreeItem(secParam, PR_TRUE);
+            SECItem ivItem;
+            ivItem.data = (unsigned char*)usedIV;
+            ivItem.len = 8;
+	        int encryptAlg = (m_doPad == true ? CKM_DES3_CBC_PAD : CKM_DES3_CBC);
+
+            SECItem * secParam = PK11_ParamFromIV(encryptAlg, &ivItem);
+            mp_ctx = PK11_CreateContextBySymKey(encryptAlg, CKA_ENCRYPT, mp_k, secParam);
+
+            if (secParam)
+                SECITEM_FreeItem(secParam, PR_TRUE);
+
+            m_ivSize = 8;
+	    }
+		else if (m_keyMode == MODE_ECB) {
+            mp_ctx = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, mp_k, NULL);
 
-      m_ivSize = 8;
-		}
-		else {
-      mp_ctx = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, mp_k, NULL);
-
-      m_ivSize = 0;
+            m_ivSize = 0;
 		}
+        else {
+		    throw XSECCryptoException(XSECCryptoException::SymmetricError,
+			        "NSS:SymmetricKey - Unsupported DES3 cipher mode");
+        }
 
 		break;
 
 	case (XSECCryptoSymmetricKey::KEY_AES_128) :
-  case (XSECCryptoSymmetricKey::KEY_AES_192) :
-  case (XSECCryptoSymmetricKey::KEY_AES_256) :
+    case (XSECCryptoSymmetricKey::KEY_AES_192) :
+    case (XSECCryptoSymmetricKey::KEY_AES_256) :
 
 		// An AES key
 
@@ -452,12 +471,12 @@ bool NSSCryptoSymmetricKey::encryptInit(
 				
 				SECStatus s = PK11_GenerateRandom(genIV, 16);
 				
-        if (s != SECSuccess) {
+                if (s != SECSuccess) {
 
 					throw XSECCryptoException(XSECCryptoException::SymmetricError,
 						"NSS:SymmetricKey - Error generating random IV");
 
-        }
+                }
 
 				usedIV = genIV;
 
@@ -466,25 +485,29 @@ bool NSSCryptoSymmetricKey::encryptInit(
 				usedIV = iv;
 
 			SECItem ivItem;
-      ivItem.data = (unsigned char*)usedIV;
-      ivItem.len = 16;
+            ivItem.data = (unsigned char*)usedIV;
+            ivItem.len = 16;
 
-      SECItem * secParam = PK11_ParamFromIV(CKM_AES_CBC_PAD, &ivItem);
-      mp_ctx = PK11_CreateContextBySymKey(CKM_AES_CBC_PAD, CKA_ENCRYPT, mp_k, secParam);
+            SECItem * secParam = PK11_ParamFromIV(CKM_AES_CBC_PAD, &ivItem);
+            mp_ctx = PK11_CreateContextBySymKey(CKM_AES_CBC_PAD, CKA_ENCRYPT, mp_k, secParam);
 
-      if (secParam)
-        SECITEM_FreeItem(secParam, PR_TRUE);
+            if (secParam)
+                SECITEM_FreeItem(secParam, PR_TRUE);
 
-      m_ivSize = 16;
+            m_ivSize = 16;
 		}
-		else {
+		else if (m_keyMode == MODE_ECB) {
 			SECItem * secParam = PK11_ParamFromIV(CKM_AES_ECB, NULL);
 			mp_ctx = PK11_CreateContextBySymKey(CKM_AES_ECB, CKA_ENCRYPT, mp_k, secParam);
 			if (secParam)
 				SECITEM_FreeItem(secParam, PR_TRUE);
 
-      m_ivSize = 0;
+            m_ivSize = 0;
 		}
+        else {
+		    throw XSECCryptoException(XSECCryptoException::SymmetricError,
+			        "NSS:SymmetricKey - Unsupported AES cipher mode");
+        }
 
 		break;
 
@@ -496,7 +519,7 @@ bool NSSCryptoSymmetricKey::encryptInit(
 	}
 
 	// Add IV
-	if (m_keyMode == MODE_CBC) {
+	if (m_keyMode == MODE_CBC || m_keyMode == MODE_GCM) {
 
 		memcpy(m_lastBlock, usedIV, m_ivSize);
 
@@ -515,7 +538,7 @@ unsigned int NSSCryptoSymmetricKey::encr
 								 unsigned int inLength,
 								 unsigned int maxOutLength) {
 
-  if (m_initialised == false) {
+    if (m_initialised == false) {
 
 		encryptInit();
 
@@ -543,7 +566,7 @@ unsigned int NSSCryptoSymmetricKey::encr
 
 	}
 
-  SECStatus s = PK11_CipherOp(mp_ctx,
+    SECStatus s = PK11_CipherOp(mp_ctx,
                               &cipherBuf[offset],
                               &outl,
                               maxOutLength - offset,

Modified: santuario/xml-security-cpp/trunk/xsec/enc/NSS/NSSCryptoSymmetricKey.hpp
URL: http://svn.apache.org/viewvc/santuario/xml-security-cpp/trunk/xsec/enc/NSS/NSSCryptoSymmetricKey.hpp?rev=1350045&r1=1350044&r2=1350045&view=diff
==============================================================================
--- santuario/xml-security-cpp/trunk/xsec/enc/NSS/NSSCryptoSymmetricKey.hpp (original)
+++ santuario/xml-security-cpp/trunk/xsec/enc/NSS/NSSCryptoSymmetricKey.hpp Wed Jun 13 22:33:10 2012
@@ -140,12 +140,16 @@ public :
 	 * @param mode mode selection (Currently ECB or CBC mode only)
 	 * @param iv Initialisation Vector to be used.  NULL if one is
 	 * not required, or if IV will be set from data stream
+     * @param tag Authentication tag to be used for AEAD ciphers
+     * @param taglen length of Authentication Tag
 	 * @returns true if the initialisation succeeded.
 	 */
 
 	virtual bool decryptInit(bool doPad = true,
 							 SymmetricKeyMode mode = MODE_CBC,
-							 const unsigned char * iv = NULL);
+							 const unsigned char * iv = NULL,
+                             const unsigned char* tag = NULL,
+                             unsigned int taglen = NULL);
 
 	/**
 	 * \brief Continue an decrypt operation using this key.

Modified: santuario/xml-security-cpp/trunk/xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.cpp
URL: http://svn.apache.org/viewvc/santuario/xml-security-cpp/trunk/xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.cpp?rev=1350045&r1=1350044&r2=1350045&view=diff
==============================================================================
--- santuario/xml-security-cpp/trunk/xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.cpp (original)
+++ santuario/xml-security-cpp/trunk/xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.cpp Wed Jun 13 22:33:10 2012
@@ -100,15 +100,16 @@ namespace {
     }
 #endif
 
-    static int MGF1(unsigned char *mask, long len, const unsigned char *seed, long seedlen)
+    static int MGF1(unsigned char *mask, long len, const unsigned char *seed, long seedlen, const EVP_MD* digest)
 	{
-	    return PKCS1_MGF1(mask, len, seed, seedlen, EVP_sha1());
+	    return PKCS1_MGF1(mask, len, seed, seedlen, digest);
 	}
 
     int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
 	    const unsigned char *from, int flen,
 	    const unsigned char *param, int plen,
-        const EVP_MD* digest)
+        const EVP_MD* digest,
+        const EVP_MD* mgf_digest)
 	{
 	    int i, digestlen = EVP_MD_size(digest), emlen = tlen - 1;
 	    unsigned char *db, *seed;
@@ -147,12 +148,12 @@ namespace {
 		    return 0;
 		    }
 
-	    if (MGF1(dbmask, emlen - digestlen, seed, digestlen) < 0)
+	    if (MGF1(dbmask, emlen - digestlen, seed, digestlen, mgf_digest) < 0)
 		    return 0;
 	    for (i = 0; i < emlen - digestlen; i++)
 		    db[i] ^= dbmask[i];
 
-	    if (MGF1(seedmask, digestlen, db, emlen - digestlen) < 0)
+	    if (MGF1(seedmask, digestlen, db, emlen - digestlen, mgf_digest) < 0)
 		    return 0;
 	    for (i = 0; i < digestlen; i++)
 		    seed[i] ^= seedmask[i];
@@ -164,7 +165,8 @@ namespace {
     int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
 	    const unsigned char *from, int flen, int num,
 	    const unsigned char *param, int plen,
-        const EVP_MD* digest)
+        const EVP_MD* digest,
+        const EVP_MD* mgf_digest)
 	{
 	    int i, digestlen = EVP_MD_size(digest), dblen, mlen = -1;
 	    const unsigned char *maskeddb;
@@ -207,12 +209,12 @@ namespace {
 
 	    maskeddb = padded_from + digestlen;
 
-	    if (MGF1(seed, digestlen, maskeddb, dblen))
+	    if (MGF1(seed, digestlen, maskeddb, dblen, mgf_digest))
 		    return -1;
 	    for (i = 0; i < digestlen; i++)
 		    seed[i] ^= padded_from[i];
   
-	    if (MGF1(db, dblen, seed, digestlen))
+	    if (MGF1(db, dblen, seed, digestlen, mgf_digest))
 		    return -1;
 	    for (i = 0; i < dblen; i++)
 		    db[i] ^= maskeddb[i];
@@ -259,7 +261,8 @@ namespace {
 OpenSSLCryptoKeyRSA::OpenSSLCryptoKeyRSA() :
 mp_rsaKey(NULL),
 mp_oaepParams(NULL),
-m_oaepParamsLen(0) {
+m_oaepParamsLen(0),
+m_mgf(MGF1_SHA1) {
 };
 
 OpenSSLCryptoKeyRSA::~OpenSSLCryptoKeyRSA() {
@@ -291,6 +294,12 @@ void OpenSSLCryptoKeyRSA::setOAEPparams(
 
 }
 
+void OpenSSLCryptoKeyRSA::setMGF(maskGenerationFunc mgf) {
+
+    m_mgf = mgf;
+
+}
+
 unsigned int OpenSSLCryptoKeyRSA::getOAEPparamsLen(void) const {
 
 	return m_oaepParamsLen;
@@ -303,6 +312,12 @@ const unsigned char * OpenSSLCryptoKeyRS
 
 }
 
+maskGenerationFunc OpenSSLCryptoKeyRSA::getMGF() const {
+
+    return m_mgf;
+
+}
+
 // Generic key functions
 
 XSECCryptoKey::KeyType OpenSSLCryptoKeyRSA::getKeyType() const {
@@ -350,6 +365,7 @@ OpenSSLCryptoKeyRSA::OpenSSLCryptoKeyRSA
 
 	mp_oaepParams = NULL;
 	m_oaepParamsLen = 0;
+    m_mgf = MGF1_SHA1;
 
 	mp_rsaKey = RSA_new();
 
@@ -654,9 +670,11 @@ unsigned int OpenSSLCryptoKeyRSA::privat
 
 			unsigned char * tBuf;
 			int num = RSA_size(mp_rsaKey);
-			XSECnew(tBuf, unsigned char[inLength]);
+			XSECnew(tBuf, unsigned char[num]);
 			ArrayJanitor<unsigned char> j_tBuf(tBuf);
             const EVP_MD* evp_md = NULL;
+            const EVP_MD* mgf_md = NULL;
+
             switch (hm) {
                 case HASH_SHA1:
                     evp_md = EVP_get_digestbyname("SHA1");
@@ -680,6 +698,29 @@ unsigned int OpenSSLCryptoKeyRSA::privat
 	        		"OpenSSL:RSA - OAEP digest algorithm not supported by this version of OpenSSL"); 
             }
 
+            switch (m_mgf) {
+                case MGF1_SHA1:
+                    mgf_md = EVP_get_digestbyname("SHA1");
+                    break;
+                case MGF1_SHA224:
+                    mgf_md = EVP_get_digestbyname("SHA224");
+                    break;
+                case MGF1_SHA256:
+                    mgf_md = EVP_get_digestbyname("SHA256");
+                    break;
+                case MGF1_SHA384:
+                    mgf_md = EVP_get_digestbyname("SHA384");
+                    break;
+                case MGF1_SHA512:
+                    mgf_md = EVP_get_digestbyname("SHA512");
+                    break;
+            }
+
+            if (mgf_md == NULL) {
+    			throw XSECCryptoException(XSECCryptoException::MDError,
+	        		"OpenSSL:RSA - MGF not supported by this version of OpenSSL");
+            }
+
 			decryptSize = RSA_private_decrypt(inLength,
 #if defined(XSEC_OPENSSL_CONST_BUFFERS)
 							    inBuf,
@@ -708,7 +749,8 @@ unsigned int OpenSSLCryptoKeyRSA::privat
 													   num,
 													   mp_oaepParams,
 													   m_oaepParamsLen,
-                                                       evp_md);
+                                                       evp_md,
+                                                       mgf_md);
 
 			if (decryptSize < 0) {
 
@@ -799,6 +841,8 @@ unsigned int OpenSSLCryptoKeyRSA::public
 			}
 
             const EVP_MD* evp_md = NULL;
+            const EVP_MD* mgf_md = NULL;
+
             switch (hm) {
                 case HASH_SHA1:
                     evp_md = EVP_get_digestbyname("SHA1");
@@ -822,6 +866,29 @@ unsigned int OpenSSLCryptoKeyRSA::public
 	        		"OpenSSL:RSA - OAEP digest algorithm not supported by this version of OpenSSL"); 
             }
 
+            switch (m_mgf) {
+                case MGF1_SHA1:
+                    mgf_md = EVP_get_digestbyname("SHA1");
+                    break;
+                case MGF1_SHA224:
+                    mgf_md = EVP_get_digestbyname("SHA224");
+                    break;
+                case MGF1_SHA256:
+                    mgf_md = EVP_get_digestbyname("SHA256");
+                    break;
+                case MGF1_SHA384:
+                    mgf_md = EVP_get_digestbyname("SHA384");
+                    break;
+                case MGF1_SHA512:
+                    mgf_md = EVP_get_digestbyname("SHA512");
+                    break;
+            }
+
+            if (mgf_md == NULL) {
+    			throw XSECCryptoException(XSECCryptoException::MDError,
+	        		"OpenSSL:RSA - MGF not supported by this version of OpenSSL");
+            }
+
 			XSECnew(tBuf, unsigned char[num]);
 			ArrayJanitor<unsigned char> j_tBuf(tBuf);
 
@@ -837,7 +904,8 @@ unsigned int OpenSSLCryptoKeyRSA::public
 													 inLength,
 													 mp_oaepParams,
 													 m_oaepParamsLen,
-                                                     evp_md);
+                                                     evp_md,
+                                                     mgf_md);
 
 			if (encryptSize <= 0) {
 

Modified: santuario/xml-security-cpp/trunk/xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp
URL: http://svn.apache.org/viewvc/santuario/xml-security-cpp/trunk/xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp?rev=1350045&r1=1350044&r2=1350045&view=diff
==============================================================================
--- santuario/xml-security-cpp/trunk/xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp (original)
+++ santuario/xml-security-cpp/trunk/xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp Wed Jun 13 22:33:10 2012
@@ -123,6 +123,26 @@ public :
 	virtual const unsigned char * getOAEPparams(void) const;
 
 	/**
+	 * \brief Set the MGF
+	 *
+	 * By default, the library expects crypto implementations to perform
+	 * OAEP padding with MGF_SHA1.  This call allows the library (or user)
+	 * to set a different choice.
+	 *
+	 * @param mgf the MGF constant identifying the function to use
+	 */
+
+	virtual void setMGF(maskGenerationFunc mgf);
+
+	/**
+	 * \brief Get the MGF
+	 *
+	 * @returns the MGF constant in use
+	 */
+
+	virtual enum maskGenerationFunc getMGF(void) const;
+
+	/**
 	 * \brief Verify a SHA1 PKCS1 encoded signature
 	 *
 	 * The library will call this function to validate an RSA signature
@@ -285,6 +305,7 @@ private:
 	RSA								* mp_rsaKey;
 	unsigned char					* mp_oaepParams;
 	unsigned int					m_oaepParamsLen;
+    maskGenerationFunc              m_mgf;
 
 };
 

Modified: santuario/xml-security-cpp/trunk/xsec/enc/OpenSSL/OpenSSLCryptoSymmetricKey.cpp
URL: http://svn.apache.org/viewvc/santuario/xml-security-cpp/trunk/xsec/enc/OpenSSL/OpenSSLCryptoSymmetricKey.cpp?rev=1350045&r1=1350044&r2=1350045&view=diff
==============================================================================
--- santuario/xml-security-cpp/trunk/xsec/enc/OpenSSL/OpenSSLCryptoSymmetricKey.cpp (original)
+++ santuario/xml-security-cpp/trunk/xsec/enc/OpenSSL/OpenSSLCryptoSymmetricKey.cpp Wed Jun 13 22:33:10 2012
@@ -50,8 +50,9 @@ XERCES_CPP_NAMESPACE_USE;
 
 OpenSSLCryptoSymmetricKey::OpenSSLCryptoSymmetricKey(XSECCryptoSymmetricKey::SymmetricKeyType type) :
 m_keyType(type),
-m_keyMode(MODE_CBC),
+m_keyMode(MODE_NONE),
 m_keyBuf(""),
+m_tagBuf(""),
 m_keyLen(0),
 m_initialised(false) {
 
@@ -111,35 +112,37 @@ void OpenSSLCryptoSymmetricKey::setKey(c
 //           Decrypt
 // --------------------------------------------------------------------------------
 
-int OpenSSLCryptoSymmetricKey::decryptCtxInit(const unsigned char * iv) {
+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 (XSECCryptoSymmetricKey::KEY_3DES_192) :
+	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
@@ -152,14 +155,18 @@ int OpenSSLCryptoSymmetricKey::decryptCt
 #endif
 			m_ivSize = 8;
 		}
-		else {
+		else if (m_keyMode == MODE_ECB) {
 #if defined(XSEC_OPENSSL_CONST_BUFFERS)
-			EVP_DecryptInit(&m_ctx, EVP_des_ede3(), m_keyBuf.rawBuffer(), NULL);
+			EVP_DecryptInit(&m_ctx, EVP_des_ecb(), m_keyBuf.rawBuffer(), NULL);
 #else
-			EVP_DecryptInit(&m_ctx, EVP_des_ede3(), (unsigned char *) m_keyBuf.rawBuffer(), NULL);
+			EVP_DecryptInit(&m_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;
@@ -167,84 +174,168 @@ int OpenSSLCryptoSymmetricKey::decryptCt
 
 #if defined (XSEC_OPENSSL_HAVE_AES)
 
-	case (XSECCryptoSymmetricKey::KEY_AES_128) :
+	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(&m_ctx, EVP_aes_128_cbc(), NULL, m_keyBuf.rawBuffer(), iv);
 
 		}
-		else {
+#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(&m_ctx, EVP_aes_128_gcm(), NULL, NULL, 0);
+            EVP_CIPHER_CTX_ctrl(&m_ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL);
+            EVP_CIPHER_CTX_ctrl(&m_ctx, EVP_CTRL_GCM_SET_TAG, 16, (void*)m_tagBuf.rawBuffer());
+            EVP_CipherInit(&m_ctx, NULL, m_keyBuf.rawBuffer(), iv, 0);
+		}
+#endif
+		else if (m_keyMode == MODE_ECB) {
 
 			EVP_DecryptInit_ex(&m_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 (XSECCryptoSymmetricKey::KEY_AES_192) :
+	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(&m_ctx, EVP_aes_192_cbc(), NULL, m_keyBuf.rawBuffer(), iv);
 
 		}
-		else {
+#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(&m_ctx, EVP_aes_192_gcm(), NULL, NULL, 0);
+            EVP_CIPHER_CTX_ctrl(&m_ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL);
+            EVP_CIPHER_CTX_ctrl(&m_ctx, EVP_CTRL_GCM_SET_TAG, 16, (void*)m_tagBuf.rawBuffer());
+            EVP_CipherInit(&m_ctx, NULL, m_keyBuf.rawBuffer(), iv, 0);
+
+		}
+#endif
+		else if (m_keyMode == MODE_ECB) {
 
 			EVP_DecryptInit_ex(&m_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) :
+	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(&m_ctx, EVP_aes_256_cbc(), NULL, m_keyBuf.rawBuffer(), iv);
 
 		}
-		else {
+#if defined (XSEC_OPENSSL_HAVE_GCM)
+        else if (m_keyMode == MODE_GCM) {
 
-			EVP_DecryptInit_ex(&m_ctx, EVP_aes_256_ecb(), NULL, m_keyBuf.rawBuffer(), NULL);
+            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(&m_ctx, EVP_aes_256_gcm(), NULL, NULL, 0);
+            EVP_CIPHER_CTX_ctrl(&m_ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL);
+            EVP_CIPHER_CTX_ctrl(&m_ctx, EVP_CTRL_GCM_SET_TAG, 16, (void*)m_tagBuf.rawBuffer());
+            EVP_CipherInit(&m_ctx, NULL, m_keyBuf.rawBuffer(), iv, 0);
 
 		}
+#endif
+		else if (m_keyMode == MODE_ECB) {
 
+			EVP_DecryptInit_ex(&m_ctx, EVP_aes_256_ecb(), NULL, m_keyBuf.rawBuffer(), NULL);
 
-		m_blockSize = 16;
+		}
+        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) :
+	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");
@@ -253,14 +344,25 @@ int OpenSSLCryptoSymmetricKey::decryptCt
 	
 	default :
 
-		// Cannot do this without an IV
 		throw XSECCryptoException(XSECCryptoException::SymmetricError,
 			"OpenSSL:SymmetricKey - Unknown key type"); 
 
 	}
 
+
 	// Setup ivSize
-	m_ivSize = (m_keyMode == MODE_CBC ? m_blockSize : 0);
+    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;
@@ -279,12 +381,14 @@ int OpenSSLCryptoSymmetricKey::decryptCt
 
 bool OpenSSLCryptoSymmetricKey::decryptInit(bool doPad, 
 											SymmetricKeyMode mode,
-											const unsigned char * iv) {
+											const unsigned char* iv,
+                                            const unsigned char* tag,
+                                            unsigned int taglen) {
 
 	m_doPad = doPad;
 	m_keyMode = mode;
 	m_initialised = false;
-	decryptCtxInit(iv);
+	decryptCtxInit(iv, tag, taglen);
 	return true;
 
 }
@@ -314,12 +418,16 @@ unsigned int OpenSSLCryptoSymmetricKey::
 
 #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);
-		if (offset > inLength) {
+        offset = decryptCtxInit(inBuf, NULL, 0);
+		
+        if (offset > inLength) {
 			throw XSECCryptoException(XSECCryptoException::SymmetricError,
-			"OpenSSL:SymmetricKey - Not enough data passed in to get IV");
+    			"OpenSSL:SymmetricKey - Not enough data passed in to get IV");
 		}
 	}
 
@@ -488,11 +596,13 @@ bool OpenSSLCryptoSymmetricKey::encryptI
 	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;
@@ -526,8 +636,9 @@ bool OpenSSLCryptoSymmetricKey::encryptI
 				usedIV = genIV;
 
 			}
-			else
+			else {
 				usedIV = iv;
+            }
 
 #if defined (XSEC_OPENSSL_CONST_BUFFERS)
 			EVP_EncryptInit(&m_ctx, EVP_des_ede3_cbc(), m_keyBuf.rawBuffer(), usedIV);
@@ -535,13 +646,17 @@ bool OpenSSLCryptoSymmetricKey::encryptI
 			EVP_EncryptInit(&m_ctx, EVP_des_ede3_cbc(), (unsigned char *) m_keyBuf.rawBuffer(), (unsigned char *) usedIV);
 #endif
 		}
-		else {
+		else if (m_keyMode == MODE_ECB) {
 #if defined (XSEC_OPENSSL_CONST_BUFFERS)
 			EVP_EncryptInit(&m_ctx, EVP_des_ede3_ecb(), m_keyBuf.rawBuffer(), NULL);
 #else
 			EVP_EncryptInit(&m_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;
@@ -571,11 +686,35 @@ bool OpenSSLCryptoSymmetricKey::encryptI
 
 			EVP_EncryptInit_ex(&m_ctx, EVP_aes_128_cbc(), NULL, m_keyBuf.rawBuffer(), usedIV);
 		}
-		else {
+		else if (m_keyMode == MODE_ECB) {
 
 			EVP_EncryptInit_ex(&m_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(&m_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;
@@ -603,11 +742,34 @@ bool OpenSSLCryptoSymmetricKey::encryptI
 			EVP_EncryptInit_ex(&m_ctx, EVP_aes_192_cbc(), NULL, m_keyBuf.rawBuffer(), usedIV);
 
 		}
+#ifdef XSEC_OPENSSL_HAVE_GCM
+		else if (m_keyMode == MODE_GCM) {
 
-		else {
+			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(&m_ctx, EVP_aes_192_gcm(), NULL, m_keyBuf.rawBuffer(), usedIV);
+		}
+#endif
+		else if (m_keyMode == MODE_ECB) {
 
 			EVP_EncryptInit_ex(&m_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;
@@ -634,11 +796,35 @@ bool OpenSSLCryptoSymmetricKey::encryptI
 			EVP_EncryptInit_ex(&m_ctx, EVP_aes_256_cbc(), NULL, m_keyBuf.rawBuffer(), usedIV);
 
 		}
-		else {
+#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(&m_ctx, EVP_aes_256_gcm(), NULL, m_keyBuf.rawBuffer(), usedIV);
+		}
+#endif
+		else if (m_keyMode == MODE_ECB) {
 
 			EVP_EncryptInit_ex(&m_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;
@@ -667,8 +853,13 @@ bool OpenSSLCryptoSymmetricKey::encryptI
 		m_ivSize = m_blockSize;
 		memcpy(m_lastBlock, usedIV, m_ivSize);
 	}
-	else
+    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

Modified: santuario/xml-security-cpp/trunk/xsec/enc/OpenSSL/OpenSSLCryptoSymmetricKey.hpp
URL: http://svn.apache.org/viewvc/santuario/xml-security-cpp/trunk/xsec/enc/OpenSSL/OpenSSLCryptoSymmetricKey.hpp?rev=1350045&r1=1350044&r2=1350045&view=diff
==============================================================================
--- santuario/xml-security-cpp/trunk/xsec/enc/OpenSSL/OpenSSLCryptoSymmetricKey.hpp (original)
+++ santuario/xml-security-cpp/trunk/xsec/enc/OpenSSL/OpenSSLCryptoSymmetricKey.hpp Wed Jun 13 22:33:10 2012
@@ -142,12 +142,16 @@ public :
 	 * @param mode mode selection (Currently ECB or CBC mode only)
 	 * @param iv Initialisation Vector to be used.  NULL if one is
 	 * not required, or if IV will be set from data stream
+     * @param tag Authentication tag to be used for AEAD ciphers
+     * @param taglen length of Authentication Tag
 	 * @returns true if the initialisation succeeded.
 	 */
 
 	virtual bool decryptInit(bool doPad = true,
 							 SymmetricKeyMode mode = MODE_CBC,
-							 const unsigned char * iv = NULL);
+							 const unsigned char * iv = NULL,
+                             const unsigned char* tag = NULL,
+                             unsigned int taglen = NULL);
 
 	/**
 	 * \brief Continue an decrypt operation using this key.
@@ -296,13 +300,14 @@ private:
 	OpenSSLCryptoSymmetricKey & operator= (const OpenSSLCryptoSymmetricKey &);
 
 	// Private functions
-	int decryptCtxInit(const unsigned char * iv);
+	int decryptCtxInit(const unsigned char* iv, const unsigned char* tag, unsigned int taglen);
 
 	// Private variables
 	SymmetricKeyType				m_keyType;
 	SymmetricKeyMode				m_keyMode;
 	EVP_CIPHER_CTX					m_ctx;			// OpenSSL Cipher Context structure
 	safeBuffer						m_keyBuf;		// Holder of the key
+    safeBuffer                      m_tagBuf;       // Holder of authentication tag
 	unsigned int					m_keyLen;
 	bool							m_initialised;	// Is the context ready to work?
 	unsigned char					m_lastBlock[MAX_BLOCK_SIZE];

Modified: santuario/xml-security-cpp/trunk/xsec/enc/WinCAPI/WinCAPICryptoKeyRSA.cpp
URL: http://svn.apache.org/viewvc/santuario/xml-security-cpp/trunk/xsec/enc/WinCAPI/WinCAPICryptoKeyRSA.cpp?rev=1350045&r1=1350044&r2=1350045&view=diff
==============================================================================
--- santuario/xml-security-cpp/trunk/xsec/enc/WinCAPI/WinCAPICryptoKeyRSA.cpp (original)
+++ santuario/xml-security-cpp/trunk/xsec/enc/WinCAPI/WinCAPICryptoKeyRSA.cpp Wed Jun 13 22:33:10 2012
@@ -155,6 +155,14 @@ void WinCAPICryptoKeyRSA::setOAEPparams(
 
 }
 
+void WinCAPICryptoKeyRSA::setMGF(maskGenerationFunc mgf) {
+
+	if (mgf != MGF1_SHA1)
+		throw XSECCryptoException(XSECCryptoException::UnsupportedError,
+			"WinCAPI::setMGF - Windows Crypto API does not support pluggable MGF for OAEP");
+
+}
+
 unsigned int WinCAPICryptoKeyRSA::getOAEPparamsLen(void) const {
 
 	return 0;
@@ -167,6 +175,11 @@ const unsigned char * WinCAPICryptoKeyRS
 
 }
 
+maskGenerationFunc WinCAPICryptoKeyRSA::getMGF() const {
+
+    return MGF1_SHA1;
+
+}
 
 // --------------------------------------------------------------------------------
 //           Load key from parameters

Modified: santuario/xml-security-cpp/trunk/xsec/enc/WinCAPI/WinCAPICryptoKeyRSA.hpp
URL: http://svn.apache.org/viewvc/santuario/xml-security-cpp/trunk/xsec/enc/WinCAPI/WinCAPICryptoKeyRSA.hpp?rev=1350045&r1=1350044&r2=1350045&view=diff
==============================================================================
--- santuario/xml-security-cpp/trunk/xsec/enc/WinCAPI/WinCAPICryptoKeyRSA.hpp (original)
+++ santuario/xml-security-cpp/trunk/xsec/enc/WinCAPI/WinCAPICryptoKeyRSA.hpp Wed Jun 13 22:33:10 2012
@@ -176,6 +176,26 @@ public :
 	virtual const unsigned char * getOAEPparams(void) const;
 
 	/**
+	 * \brief Set the MGF
+	 *
+	 * By default, the library expects crypto implementations to perform
+	 * OAEP padding with MGF_SHA1.  This call allows the library (or user)
+	 * to set a different choice.
+	 *
+	 * @param mgf the MGF constant identifying the function to use
+	 */
+
+	virtual void setMGF(maskGenerationFunc mgf);
+
+	/**
+	 * \brief Get the MGF
+	 *
+	 * @returns the MGF constant in use
+	 */
+
+	virtual enum maskGenerationFunc getMGF(void) const;
+
+	/**
 	 * \brief Verify a SHA1 PKCS1 encoded signature
 	 *
 	 * The library will call this function to validate an RSA signature

Modified: santuario/xml-security-cpp/trunk/xsec/enc/WinCAPI/WinCAPICryptoSymmetricKey.cpp
URL: http://svn.apache.org/viewvc/santuario/xml-security-cpp/trunk/xsec/enc/WinCAPI/WinCAPICryptoSymmetricKey.cpp?rev=1350045&r1=1350044&r2=1350045&view=diff
==============================================================================
--- santuario/xml-security-cpp/trunk/xsec/enc/WinCAPI/WinCAPICryptoSymmetricKey.cpp (original)
+++ santuario/xml-security-cpp/trunk/xsec/enc/WinCAPI/WinCAPICryptoSymmetricKey.cpp Wed Jun 13 22:33:10 2012
@@ -49,7 +49,7 @@ WinCAPICryptoSymmetricKey::WinCAPICrypto
 						HCRYPTPROV prov,
 						XSECCryptoSymmetricKey::SymmetricKeyType type) :
 m_keyType(type),
-m_keyMode(MODE_ECB),
+m_keyMode(MODE_NONE),
 m_initialised(false),
 m_doPad(true),
 m_p(prov),
@@ -134,11 +134,13 @@ int WinCAPICryptoSymmetricKey::decryptCt
 		return 0;
 
 	if (m_k == 0) {
-
 		throw XSECCryptoException(XSECCryptoException::SymmetricError,
 			"WinCAPI:SymmetricKey - Cannot initialise without key"); 
-
 	}
+    else if (m_keyMode == MODE_NONE) {
+		throw XSECCryptoException(XSECCryptoException::SymmetricError,
+			"WinCAPI:SymmetricKey - Cannot initialise without mode"); 
+    }
 
 	DWORD cryptMode;
 	if (m_keyMode == MODE_CBC) {
@@ -166,7 +168,7 @@ int WinCAPICryptoSymmetricKey::decryptCt
 		}
 
 	}
-	else {
+	else if (m_keyMode == MODE_ECB) {
 		cryptMode = CRYPT_MODE_ECB;
 
 		if (!CryptSetKeyParam(m_k, KP_MODE, (BYTE *) (&cryptMode), 0)) {
@@ -176,6 +178,10 @@ int WinCAPICryptoSymmetricKey::decryptCt
 
 		}
 	}
+    else {
+		throw XSECCryptoException(XSECCryptoException::SymmetricError,
+			"WinCAPI:SymmetricKey - Unknown cipher mode"); 
+    }
 
 	// Set up the context according to the required cipher type
 	switch (m_keyType) {
@@ -210,13 +216,29 @@ int WinCAPICryptoSymmetricKey::decryptCt
 
 	}
 
-	return (m_keyMode == MODE_CBC ? m_blockSize : 0);
+	// Setup ivSize
+    switch (m_keyMode) {
+        case MODE_CBC:
+            m_ivSize = m_blockSize;
+            break;
+
+        case MODE_GCM:
+            m_ivSize = 12;
+            break;
+
+        default:
+            m_ivSize = 0;
+    }
+
+    return m_ivSize;
 }
 
 
 bool WinCAPICryptoSymmetricKey::decryptInit(bool doPad, 
 											SymmetricKeyMode mode, 
-											const unsigned char * iv) {
+											const unsigned char* iv,
+                                            const unsigned char* tag,
+                                            unsigned int taglen) {
 
 	m_initialised = false;
 	m_doPad = doPad;
@@ -337,11 +359,13 @@ void WinCAPICryptoSymmetricKey::encryptC
 		return;
 	
 	if (m_keyLen == 0) {
-
 		throw XSECCryptoException(XSECCryptoException::SymmetricError,
 			"WinCAPI:SymmetricKey - Cannot initialise without key"); 
-
 	}
+    else if (m_keyMode == MODE_NONE) {
+		throw XSECCryptoException(XSECCryptoException::SymmetricError,
+			"WinCAPI:SymmetricKey - Cannot initialise without mode"); 
+    }
 
 	m_initialised = true;
 
@@ -388,7 +412,7 @@ void WinCAPICryptoSymmetricKey::encryptC
 		}
 
 	}
-	else {
+	else if (m_keyMode == MODE_ECB) {
 
 		cryptMode = CRYPT_MODE_ECB;
 
@@ -399,6 +423,10 @@ void WinCAPICryptoSymmetricKey::encryptC
 
 		}
 	}
+    else {
+		throw XSECCryptoException(XSECCryptoException::SymmetricError,
+			"OpenSSL:SymmetricKey - Unsupported cipher mode");
+    }
 
 	switch (m_keyType) {
 
@@ -424,6 +452,8 @@ void WinCAPICryptoSymmetricKey::encryptC
 		m_blockSize = 16;
 		if (m_keyMode == MODE_CBC)
 			m_ivSize = 16;
+        else if (m_keyMode == MODE_GCM)
+            m_ivSize = 12;
 		else 
 			m_ivSize = 0;
 		m_bytesInLastBlock = 0;
@@ -477,7 +507,7 @@ unsigned int WinCAPICryptoSymmetricKey::
 	
 	if (m_ivSize > 0) {
 
-		DWORD len = 16;
+		DWORD len = m_ivSize;
 		if (!CryptGetKeyParam(m_k, KP_IV, (unsigned char *) m_lastBlock, &len, 0)) {
 
 			throw XSECCryptoException(XSECCryptoException::SymmetricError,

Modified: santuario/xml-security-cpp/trunk/xsec/enc/WinCAPI/WinCAPICryptoSymmetricKey.hpp
URL: http://svn.apache.org/viewvc/santuario/xml-security-cpp/trunk/xsec/enc/WinCAPI/WinCAPICryptoSymmetricKey.hpp?rev=1350045&r1=1350044&r2=1350045&view=diff
==============================================================================
--- santuario/xml-security-cpp/trunk/xsec/enc/WinCAPI/WinCAPICryptoSymmetricKey.hpp (original)
+++ santuario/xml-security-cpp/trunk/xsec/enc/WinCAPI/WinCAPICryptoSymmetricKey.hpp Wed Jun 13 22:33:10 2012
@@ -149,12 +149,16 @@ public :
 	 * @param mode mode selection (Currently ECB or CBC mode only)
 	 * @param iv Initialisation Vector to be used.  NULL if one is
 	 * not required, or if IV will be set from data stream
+     * @param tag Authentication tag to be used for AEAD ciphers
+     * @param taglen length of Authentication Tag
 	 * @returns true if the initialisation succeeded.
 	 */
 
 	virtual bool decryptInit(bool doPad = true,
 							 SymmetricKeyMode mode = MODE_CBC,
-							 const unsigned char * iv = NULL);
+							 const unsigned char * iv = NULL,
+                             const unsigned char* tag = NULL,
+                             unsigned int taglen = NULL);
 
 	/**
 	 * \brief Continue an decrypt operation using this key.

Modified: santuario/xml-security-cpp/trunk/xsec/enc/XSECCryptoKeyRSA.hpp
URL: http://svn.apache.org/viewvc/santuario/xml-security-cpp/trunk/xsec/enc/XSECCryptoKeyRSA.hpp?rev=1350045&r1=1350044&r2=1350045&view=diff
==============================================================================
--- santuario/xml-security-cpp/trunk/xsec/enc/XSECCryptoKeyRSA.hpp (original)
+++ santuario/xml-security-cpp/trunk/xsec/enc/XSECCryptoKeyRSA.hpp Wed Jun 13 22:33:10 2012
@@ -129,6 +129,26 @@ public :
 	virtual const unsigned char * getOAEPparams(void) const = 0;
 
 	/**
+	 * \brief Set the MGF
+	 *
+	 * By default, the library expects crypto implementations to perform
+	 * OAEP padding with MGF_SHA1.  This call allows the library (or user)
+	 * to set a different choice.
+	 *
+	 * @param mgf the MGF constant identifying the function to use
+	 */
+
+	virtual void setMGF(maskGenerationFunc mgf) = 0;
+
+	/**
+	 * \brief Get the MGF
+	 *
+	 * @returns the MGF constant in use
+	 */
+
+	virtual enum maskGenerationFunc getMGF(void) const = 0;
+
+	/**
 	 * \brief Verify a SHA1 PKCS1 encoded signature
 	 *
 	 * The library will call this function to validate an RSA signature

Modified: santuario/xml-security-cpp/trunk/xsec/enc/XSECCryptoSymmetricKey.hpp
URL: http://svn.apache.org/viewvc/santuario/xml-security-cpp/trunk/xsec/enc/XSECCryptoSymmetricKey.hpp?rev=1350045&r1=1350044&r2=1350045&view=diff
==============================================================================
--- santuario/xml-security-cpp/trunk/xsec/enc/XSECCryptoSymmetricKey.hpp (original)
+++ santuario/xml-security-cpp/trunk/xsec/enc/XSECCryptoSymmetricKey.hpp Wed Jun 13 22:33:10 2012
@@ -77,7 +77,8 @@ public :
 
 		MODE_NONE,					/** An error condition */
 		MODE_ECB,					/** Electronic Code Book */
-		MODE_CBC					/** Cipher Block Chaining */
+		MODE_CBC,					/** Cipher Block Chaining */
+        MODE_GCM                    /** Galois-Counter Mode */
 
 	};
 
@@ -155,31 +156,41 @@ public :
 
 	virtual void setKey(const unsigned char * key, unsigned int keyLen) = 0;
 
-	/**
+   	/**
 	 * \brief Initialise an decryption process
 	 *
 	 * Setup the key to get ready for a decryption session.
+     *
 	 * Callers can pass in an IV.  If one is not provided, 
 	 * but the algorithm requires one (e.g. 3DES_CBC), then 
 	 * implementations should assume that the start of the
 	 * cipher text stream will in fact be the IV.
+     *
+     * Callers may need to pass a tag to fully initialise an
+     * authenticated encryption algorithm. If a tag is not
+     * supplied, the caller can obtain the length of the required
+     * tag instead, and call this method again once the tag is
+     * obtained.
 	 *
 	 * @param doPad By default, we perform padding for last block
-	 * @param mode mode selection (Currently ECB or CBC mode only).
-	 * Default is CBC
+	 * @param mode mode selection, default is CBC
 	 * @param iv Initialisation Vector to be used.  NULL if one is
 	 * not required, or if IV will be set from data stream
+     * @param tag Authentication tag to be used for AEAD ciphers
+     * @param taglen length of Authentication Tag
 	 * @returns true if the initialisation succeeded.
 	 */
 
 	virtual bool decryptInit(bool doPad = true,
 							 SymmetricKeyMode mode = MODE_CBC,
-							 const unsigned char * iv = NULL) = 0;
+							 const unsigned char* iv = NULL,
+                             const unsigned char* tag = NULL,
+                             unsigned int taglen = NULL) = 0;
 
 	/**
-	 * \brief Continue an decrypt operation using this key.
+	 * \brief Continue a decrypt operation using this key.
 	 *
-	 * Decryption must have been set up using an encryptInit
+	 * Decryption must have been set up using a decryptInit
 	 * call.  Takes the inBuf and continues a decryption operation,
 	 * writing the output to outBuf.
 	 *
@@ -228,8 +239,7 @@ public :
 	 * implementations are required to generate one.
 	 *
 	 * @param doPad By default, we perform padding for last block
-	 * @param mode What mode to handle blocks (Currently CBC or ECB)
-	 * Default is CBC.
+	 * @param mode What mode to handle blocks. default is CBC
 	 * @param iv Initialisation Vector to be used.  NULL if one is
 	 * not required, or if IV is to be generated
 	 * @returns true if the initialisation succeeded.
@@ -265,9 +275,9 @@ public :
 								 unsigned int maxOutLength) = 0;
 
 	/**
-	 * \brief Finish a encryption operation
+	 * \brief Finish an encryption operation
 	 *
-	 * Complete a encryption process.  No plain text is passed in,
+	 * Complete an encryption process.  No plain text is passed in,
 	 * as this should simply be removing any remaining text from
 	 * the plain storage buffer and creating a final padded block.
 	 *

Modified: santuario/xml-security-cpp/trunk/xsec/xenc/XENCEncryptionMethod.hpp
URL: http://svn.apache.org/viewvc/santuario/xml-security-cpp/trunk/xsec/xenc/XENCEncryptionMethod.hpp?rev=1350045&r1=1350044&r2=1350045&view=diff
==============================================================================
--- santuario/xml-security-cpp/trunk/xsec/xenc/XENCEncryptionMethod.hpp (original)
+++ santuario/xml-security-cpp/trunk/xsec/xenc/XENCEncryptionMethod.hpp Wed Jun 13 22:33:10 2012
@@ -107,6 +107,17 @@ public:
 	virtual const XMLCh * getOAEPparams(void) const = 0;
 
 	/**
+	 * \brief Get the MGF URI
+	 *
+	 * Return the Algorithm URI represtenting the Mask Generation Function for those
+	 * encryption algorithms that require it (such as RSA with OAEP padding)
+	 *
+	 * @returns the URI representing the mask generation function
+	 */
+
+	virtual const XMLCh * getMGF(void) const = 0;
+
+	/**
 	 * \brief Get the KeySize that was set in this EncryptionMethod.
 	 *
 	 * This field would not normally be used for the encryption algorithms
@@ -155,6 +166,18 @@ public:
 	virtual void setOAEPparams(const XMLCh * params) = 0;
 
 	/**
+	 * \brief Set the value of the MGF
+	 *
+	 * Sets the MGF element's Algorithm attribute to the passed in
+	 * value - should be a URI string
+	 *
+	 * @param method String to set in the Algorithm attribute.  Will create a
+	 * \<xenc11:MGF\> element if one does not already exist
+	 */
+
+	virtual void setMGF(const XMLCh * mgf) = 0;
+
+	/**
 	 * \brief Set the KeySize that in this EncryptionMethod.
 	 *
 	 * This field would not normally be used for the encryption algorithms

Modified: santuario/xml-security-cpp/trunk/xsec/xenc/impl/XENCAlgorithmHandlerDefault.cpp
URL: http://svn.apache.org/viewvc/santuario/xml-security-cpp/trunk/xsec/xenc/impl/XENCAlgorithmHandlerDefault.cpp?rev=1350045&r1=1350044&r2=1350045&view=diff
==============================================================================
--- santuario/xml-security-cpp/trunk/xsec/xenc/impl/XENCAlgorithmHandlerDefault.cpp (original)
+++ santuario/xml-security-cpp/trunk/xsec/xenc/impl/XENCAlgorithmHandlerDefault.cpp Wed Jun 13 22:33:10 2012
@@ -33,6 +33,7 @@
 #include <xsec/transformers/TXFMChain.hpp>
 #include <xsec/transformers/TXFMCipher.hpp>
 #include <xsec/transformers/TXFMBase64.hpp>
+#include <xsec/transformers/TXFMSB.hpp>
 #include <xsec/xenc/XENCEncryptionMethod.hpp>
 #include <xsec/enc/XSECCryptoKey.hpp>
 #include <xsec/enc/XSECCryptoSymmetricKey.hpp>
@@ -82,7 +83,9 @@ void XENCAlgorithmHandlerDefault::mapURI
 											  XSECCryptoKey * key,
 											  XSECCryptoKey::KeyType &kt,
 											  XSECCryptoSymmetricKey::SymmetricKeyType &skt,
-											  bool &isSymmetricKeyWrap) {
+											  bool &isSymmetricKeyWrap,
+                                              XSECCryptoSymmetricKey::SymmetricKeyMode &skm,
+                                              unsigned int& taglen) {
 
 	if (key == NULL) {
 		throw XSECException(XSECException::CipherError, 
@@ -95,15 +98,16 @@ void XENCAlgorithmHandlerDefault::mapURI
 	kt = key->getKeyType();
 	skt = XSECCryptoSymmetricKey::KEY_NONE;
 	isSymmetricKeyWrap = false;
+    skm = XSECCryptoSymmetricKey::MODE_NONE;
 	
 	switch (kt) {
 
 	case XSECCryptoKey::KEY_RSA_PUBLIC :
 	case XSECCryptoKey::KEY_RSA_PAIR :
 	case XSECCryptoKey::KEY_RSA_PRIVATE :
-
 		keyOK = strEquals(uri, DSIGConstants::s_unicodeStrURIRSA_1_5) ||
-			strEquals(uri, DSIGConstants::s_unicodeStrURIRSA_OAEP_MGFP1);
+			strEquals(uri, DSIGConstants::s_unicodeStrURIRSA_OAEP_MGFP1) ||
+            strEquals(uri, DSIGConstants::s_unicodeStrURIRSA_OAEP);
 		break;
 
 	case XSECCryptoKey::KEY_SYMMETRIC :
@@ -115,21 +119,68 @@ void XENCAlgorithmHandlerDefault::mapURI
 			switch (skt) {
 
 			case XSECCryptoSymmetricKey::KEY_3DES_192 :
-				isSymmetricKeyWrap = strEquals(uri, DSIGConstants::s_unicodeStrURIKW_3DES);
-				keyOK = isSymmetricKeyWrap || strEquals(uri, DSIGConstants::s_unicodeStrURI3DES_CBC);
+                if (strEquals(uri, DSIGConstants::s_unicodeStrURIKW_3DES)) {
+                    keyOK = true;
+                    isSymmetricKeyWrap = true;
+                    skm = XSECCryptoSymmetricKey::MODE_CBC;
+                }
+                else if (strEquals(uri, DSIGConstants::s_unicodeStrURI3DES_CBC)) {
+                    keyOK = true;
+                    skm = XSECCryptoSymmetricKey::MODE_CBC;
+                }
 				break;
+
 			case XSECCryptoSymmetricKey::KEY_AES_128 :
-				isSymmetricKeyWrap = strEquals(uri, DSIGConstants::s_unicodeStrURIKW_AES128);
-				keyOK =  isSymmetricKeyWrap || strEquals(uri, DSIGConstants::s_unicodeStrURIAES128_CBC);
+                if (strEquals(uri, DSIGConstants::s_unicodeStrURIKW_AES128)) {
+                    keyOK = true;
+                    isSymmetricKeyWrap = true;
+                    skm = XSECCryptoSymmetricKey::MODE_CBC;
+                }
+                else if (strEquals(uri, DSIGConstants::s_unicodeStrURIAES128_CBC)) {
+                    keyOK = true;
+                    skm = XSECCryptoSymmetricKey::MODE_CBC;
+                }
+                else if (strEquals(uri, DSIGConstants::s_unicodeStrURIAES128_GCM)) {
+                    keyOK = true;
+                    skm = XSECCryptoSymmetricKey::MODE_GCM;
+                    taglen = 16;
+                }
 				break;
+
 			case XSECCryptoSymmetricKey::KEY_AES_192 :
-				isSymmetricKeyWrap = strEquals(uri, DSIGConstants::s_unicodeStrURIKW_AES192);
-				keyOK =  isSymmetricKeyWrap || strEquals(uri, DSIGConstants::s_unicodeStrURIAES192_CBC);
+                if (strEquals(uri, DSIGConstants::s_unicodeStrURIKW_AES192)) {
+                    keyOK = true;
+                    isSymmetricKeyWrap = true;
+                    skm = XSECCryptoSymmetricKey::MODE_CBC;
+                }
+                else if (strEquals(uri, DSIGConstants::s_unicodeStrURIAES192_CBC)) {
+                    keyOK = true;
+                    skm = XSECCryptoSymmetricKey::MODE_CBC;
+                }
+                else if (strEquals(uri, DSIGConstants::s_unicodeStrURIAES192_GCM)) {
+                    keyOK = true;
+                    skm = XSECCryptoSymmetricKey::MODE_GCM;
+                    taglen = 16;
+                }
 				break;
+
 			case XSECCryptoSymmetricKey::KEY_AES_256 :
-				isSymmetricKeyWrap = strEquals(uri, DSIGConstants::s_unicodeStrURIKW_AES256);
-				keyOK =  isSymmetricKeyWrap || strEquals(uri, DSIGConstants::s_unicodeStrURIAES256_CBC);
+                if (strEquals(uri, DSIGConstants::s_unicodeStrURIKW_AES256)) {
+                    keyOK = true;
+                    isSymmetricKeyWrap = true;
+                    skm = XSECCryptoSymmetricKey::MODE_CBC;
+                }
+                else if (strEquals(uri, DSIGConstants::s_unicodeStrURIAES256_CBC)) {
+                    keyOK = true;
+                    skm = XSECCryptoSymmetricKey::MODE_CBC;
+                }
+                else if (strEquals(uri, DSIGConstants::s_unicodeStrURIAES256_GCM)) {
+                    keyOK = true;
+                    skm = XSECCryptoSymmetricKey::MODE_GCM;
+                    taglen = 16;
+                }
 				break;
+
 			default:
 				break;
 			}
@@ -516,18 +567,35 @@ bool XENCAlgorithmHandlerDefault::append
 	XSECCryptoKey::KeyType kt;
 	XSECCryptoSymmetricKey::SymmetricKeyType skt;
 	bool isKeyWrap = false;
+    XSECCryptoSymmetricKey::SymmetricKeyMode skm;
+    unsigned int taglen;
 
-	mapURIToKey(encryptionMethod->getAlgorithm(), key, kt, skt, isKeyWrap);
-	if (kt != XSECCryptoKey::KEY_SYMMETRIC || isKeyWrap == true) {
+	mapURIToKey(encryptionMethod->getAlgorithm(), key, kt, skt, isKeyWrap, skm, taglen);
+    if (kt != XSECCryptoKey::KEY_SYMMETRIC || isKeyWrap == true) {
 		throw XSECException(XSECException::CipherError, 
 			"XENCAlgorithmHandlerDefault::appendDecryptCipherTXFM - only supports bulk symmetric algorithms");
 	}
 
-	// Add the decryption TXFM
+    if (skm == XSECCryptoSymmetricKey::MODE_GCM) {
+
+        // GCM doesn't fit the pipelined model of the existing code, so we have a custom
+        // routine that decrypts to a safeBuffer directly.
+        safeBuffer result;
+        unsigned int sz = doGCMDecryptToSafeBuffer(cipherText, key, taglen, result);
+
+        // Now we hijack the original tansform chain with a safeBuffer-sourced link.
+        TXFMSB* tsb;
+        XSECnew(tsb, TXFMSB(doc));
+        tsb->setInput(result, sz);
+        cipherText->appendTxfm(tsb);
+        result.cleanseBuffer();
+        return true;
+    }
 
-	TXFMCipher * tcipher;
-	XSECnew(tcipher, TXFMCipher(doc, key, false));
 
+	// Add the decryption TXFM
+	TXFMCipher* tcipher;
+	XSECnew(tcipher, TXFMCipher(doc, key, false));
 	cipherText->appendTxfm(tcipher);
 
 	return true;
@@ -535,6 +603,67 @@ bool XENCAlgorithmHandlerDefault::append
 
 
 // --------------------------------------------------------------------------------
+//			GCM SafeBuffer decryption
+// --------------------------------------------------------------------------------
+
+unsigned int XENCAlgorithmHandlerDefault::doGCMDecryptToSafeBuffer(
+		TXFMChain * cipherText,
+		XSECCryptoKey * key,
+        unsigned int taglen,
+		safeBuffer & result) {
+
+	// Only works with symmetric key
+    if (key->getKeyType() != XSECCryptoKey::KEY_SYMMETRIC) {
+		throw XSECException(XSECException::CipherError, 
+			"XENCAlgorithmHandlerDefault - GCM Decrypt must use symmetric key");
+	}
+
+    // First read in all the data so we can get to the tag.
+    safeBuffer cipherBuf("");
+    XMLByte inbuf[3072];
+    unsigned int szTotal = 0, sz = cipherText->getLastTxfm()->readBytes(inbuf, 3072);
+    while (sz > 0) {
+        cipherBuf.sbMemcpyIn(szTotal, inbuf, sz);
+        szTotal += sz;
+        sz = cipherText->getLastTxfm()->readBytes(inbuf, 3072);
+    }
+
+    if (szTotal <= taglen) {
+		throw XSECException(XSECException::CipherError, 
+			"XENCAlgorithmHandlerDefault - GCM ciphertext size not large enough to include authentication tag");
+    }
+
+    const unsigned char* cipherPtr = cipherBuf.rawBuffer();
+
+    // Init the cipher with the tag at the end of the cipher text and omit it from later decryption.
+    szTotal -= taglen;
+    ((XSECCryptoSymmetricKey*) key)->decryptInit(false, XSECCryptoSymmetricKey::MODE_GCM, NULL, cipherPtr + szTotal, taglen);
+
+    unsigned int plainOffset = 0;
+    do {
+        // Feed the data in at most 2048-byte chunks.
+        sz = ((XSECCryptoSymmetricKey*) key)->decrypt(cipherPtr, inbuf, (szTotal > 2048 ? 2048 : szTotal), 3072);
+        cipherPtr += (szTotal > 2048 ? 2048 : szTotal);
+        szTotal -= (szTotal > 2048 ? 2048 : szTotal);
+        if (sz > 0) {
+            result.sbMemcpyIn(plainOffset, inbuf, sz);
+            plainOffset += sz;
+        }
+    } while (szTotal > 0);
+
+    // Wrap it up.
+    sz = ((XSECCryptoSymmetricKey*) key)->decryptFinish(inbuf, 3072);
+    if (sz > 0) {
+        result.sbMemcpyIn(plainOffset, inbuf, sz);
+        plainOffset += sz;
+    }
+
+    // In case any plaintext is left lying around.
+    memset(inbuf, 0, 3072);
+    return plainOffset;
+}
+
+// --------------------------------------------------------------------------------
 //			RSA SafeBuffer decryption
 // --------------------------------------------------------------------------------
 
@@ -586,13 +715,14 @@ unsigned int XENCAlgorithmHandlerDefault
 												  XSECCryptoKeyRSA::PAD_PKCS_1_5, 
 												  HASH_NONE);
 	}
-	else if (strEquals(encryptionMethod->getAlgorithm(), DSIGConstants::s_unicodeStrURIRSA_OAEP_MGFP1)) {
+	else if (strEquals(encryptionMethod->getAlgorithm(), DSIGConstants::s_unicodeStrURIRSA_OAEP_MGFP1) ||
+             strEquals(encryptionMethod->getAlgorithm(), DSIGConstants::s_unicodeStrURIRSA_OAEP)) {
 
         hashMethod hm;
 	    const XMLCh* digmeth = encryptionMethod->getDigestMethod();
 
 	    // Is this a URI we recognize?
-	    if (!digmeth || !*digmeth) {
+	    if (!digmeth|| !*digmeth) {
 	        hm = HASH_SHA1;
 	    }
 	    else if (!XSECmapURIToHashMethod(digmeth, hm)) {
@@ -604,6 +734,20 @@ unsigned int XENCAlgorithmHandlerDefault
 	            sb.rawXMLChBuffer());
 	    }
 
+        const XMLCh* mgfalg = encryptionMethod->getMGF();
+        if (mgfalg && *mgfalg) {
+            maskGenerationFunc mgf;
+            if (!XSECmapURIToMaskGenerationFunc(mgfalg, mgf)) {
+	            safeBuffer sb;
+	            sb.sbTranscodeIn("XENCAlgorithmHandlerDefault - Unknown MGF URI : ");
+	            sb.sbXMLChCat(mgfalg);
+
+	            throw XSECException(XSECException::AlgorithmMapperError,
+	                sb.rawXMLChBuffer());
+            }
+            rsa->setMGF(mgf);
+        }
+
 		// Read out any OAEP params
 		unsigned char * oaepParamsBuf = NULL;
 		const XMLCh * oaepParams = encryptionMethod->getOAEPparams();
@@ -667,6 +811,8 @@ unsigned int XENCAlgorithmHandlerDefault
 	XSECCryptoKey::KeyType kt;
 	XSECCryptoSymmetricKey::SymmetricKeyType skt;
 	bool isKeyWrap = false;
+    XSECCryptoSymmetricKey::SymmetricKeyMode skm;
+    unsigned int taglen;
 
 	if (encryptionMethod == NULL) {
 		throw XSECException(XSECException::CipherError,
@@ -675,7 +821,7 @@ unsigned int XENCAlgorithmHandlerDefault
 
 
 	// Check the uri against the key type
-	mapURIToKey(encryptionMethod->getAlgorithm(), key, kt, skt, isKeyWrap);
+	mapURIToKey(encryptionMethod->getAlgorithm(), key, kt, skt, isKeyWrap, skm, taglen);
 
 	// RSA?
 	if (kt == XSECCryptoKey::KEY_RSA_PAIR || 
@@ -715,14 +861,20 @@ unsigned int XENCAlgorithmHandlerDefault
 
 	}
 
-	// It's symmetric and it's not a key wrap, so just treat as a block algorithm
+    if (skm == XSECCryptoSymmetricKey::MODE_GCM) {
+        // GCM doesn't fit the pipelined model of the existing code, so we have a custom
+        // routine that decrypts to a safeBuffer directly.
+        return doGCMDecryptToSafeBuffer(cipherText, key, taglen, result);
+    }
+
+	// It's symmetric and it's not a key wrap or GCM, so just treat as a block algorithm.
 
 	TXFMCipher * tcipher;
 	XSECnew(tcipher, TXFMCipher(doc, key, false));
 
 	cipherText->appendTxfm(tcipher);
 
-	// Do the decrypt to the safeBuffer
+	// Do the decrypt to the safeBuffer.
 
 	result.sbStrcpyIn("");
 	unsigned int offset = 0;
@@ -794,9 +946,41 @@ bool XENCAlgorithmHandlerDefault::doRSAE
 												  HASH_NONE);
 	}
 
-	else if (strEquals(encryptionMethod->getAlgorithm(), DSIGConstants::s_unicodeStrURIRSA_OAEP_MGFP1)) {
+	else if (strEquals(encryptionMethod->getAlgorithm(), DSIGConstants::s_unicodeStrURIRSA_OAEP_MGFP1) ||
+            strEquals(encryptionMethod->getAlgorithm(), DSIGConstants::s_unicodeStrURIRSA_OAEP)) {
+        
+        hashMethod hm;
+        if (encryptionMethod->getDigestMethod() == NULL) {
+            hm = HASH_SHA1;
+		    encryptionMethod->setDigestMethod(DSIGConstants::s_unicodeStrURISHA1);
+        }
+        else if (!XSECmapURIToHashMethod(encryptionMethod->getDigestMethod(), hm)) {
+	        safeBuffer sb;
+	        sb.sbTranscodeIn("XENCAlgorithmHandlerDefault - Unknown Digest URI : ");
+	        sb.sbXMLChCat(encryptionMethod->getDigestMethod());
 
-		encryptionMethod->setDigestMethod(DSIGConstants::s_unicodeStrURISHA1);
+	        throw XSECException(XSECException::AlgorithmMapperError,
+	            sb.rawXMLChBuffer());
+	    }
+
+        const XMLCh* mgfalg = encryptionMethod->getMGF();
+        if (mgfalg && *mgfalg) {
+            maskGenerationFunc mgf;
+            if (!XSECmapURIToMaskGenerationFunc(mgfalg, mgf)) {
+	            safeBuffer sb;
+	            sb.sbTranscodeIn("XENCAlgorithmHandlerDefault - Unknown MGF URI : ");
+	            sb.sbXMLChCat(mgfalg);
+
+	            throw XSECException(XSECException::AlgorithmMapperError,
+	                sb.rawXMLChBuffer());
+            }
+            rsa->setMGF(mgf);
+        }
+        else if (rsa->getMGF() != MGF1_SHA1) {
+            safeBuffer sb;
+            if (maskGenerationFunc2URI(sb, rsa->getMGF()))
+                encryptionMethod->setMGF(sb.rawXMLChBuffer());
+        }
 
 		// Check for OAEP params
 		int oaepParamsLen = rsa->getOAEPparamsLen();
@@ -825,7 +1009,7 @@ bool XENCAlgorithmHandlerDefault::doRSAE
 										  offset, 
 										  rsa->getLength(), 
 										  XSECCryptoKeyRSA::PAD_OAEP_MGFP1, 
-										  HASH_SHA1);
+										  hm);
 
 	}
 	else {
@@ -868,6 +1052,8 @@ bool XENCAlgorithmHandlerDefault::encryp
 	XSECCryptoKey::KeyType kt;
 	XSECCryptoSymmetricKey::SymmetricKeyType skt;
 	bool isKeyWrap = false;
+    XSECCryptoSymmetricKey::SymmetricKeyMode skm;
+    unsigned int taglen;
 
 	if (encryptionMethod == NULL) {
 		throw XSECException(XSECException::CipherError,
@@ -876,7 +1062,7 @@ bool XENCAlgorithmHandlerDefault::encryp
 
 
 	// Check the uri against the key type
-	mapURIToKey(encryptionMethod->getAlgorithm(), key, kt, skt, isKeyWrap);
+	mapURIToKey(encryptionMethod->getAlgorithm(), key, kt, skt, isKeyWrap, skm, taglen);
 
 	// RSA?
 	if (kt == XSECCryptoKey::KEY_RSA_PRIVATE || 
@@ -957,6 +1143,15 @@ XSECCryptoKey * XENCAlgorithmHandlerDefa
 	else if (strEquals(uri, DSIGConstants::s_unicodeStrURIAES256_CBC)) {
 		sk = XSECPlatformUtils::g_cryptoProvider->keySymmetric(XSECCryptoSymmetricKey::KEY_AES_256);
 	}
+	else if (strEquals(uri, DSIGConstants::s_unicodeStrURIAES128_GCM)) {
+		sk = XSECPlatformUtils::g_cryptoProvider->keySymmetric(XSECCryptoSymmetricKey::KEY_AES_128);
+	}
+	else if (strEquals(uri, DSIGConstants::s_unicodeStrURIAES192_GCM)) {
+		sk = XSECPlatformUtils::g_cryptoProvider->keySymmetric(XSECCryptoSymmetricKey::KEY_AES_192);
+	}
+	else if (strEquals(uri, DSIGConstants::s_unicodeStrURIAES256_GCM)) {
+		sk = XSECPlatformUtils::g_cryptoProvider->keySymmetric(XSECCryptoSymmetricKey::KEY_AES_256);
+	}
 
 	if (sk != NULL) {
 		sk->setKey(keyBuffer, keyLen);

Modified: santuario/xml-security-cpp/trunk/xsec/xenc/impl/XENCAlgorithmHandlerDefault.hpp
URL: http://svn.apache.org/viewvc/santuario/xml-security-cpp/trunk/xsec/xenc/impl/XENCAlgorithmHandlerDefault.hpp?rev=1350045&r1=1350044&r2=1350045&view=diff
==============================================================================
--- santuario/xml-security-cpp/trunk/xsec/xenc/impl/XENCAlgorithmHandlerDefault.hpp (original)
+++ santuario/xml-security-cpp/trunk/xsec/xenc/impl/XENCAlgorithmHandlerDefault.hpp Wed Jun 13 22:33:10 2012
@@ -116,7 +116,9 @@ private:
 		XSECCryptoKey * key,
 		XSECCryptoKey::KeyType &kt,
 		XSECCryptoSymmetricKey::SymmetricKeyType &skt,
-		bool &isSymmetricKeyWrap);
+		bool &isSymmetricKeyWrap,
+        XSECCryptoSymmetricKey::SymmetricKeyMode &skm,
+        unsigned int& taglen);
 	unsigned int doRSADecryptToSafeBuffer(
 		TXFMChain * cipherText,
 		XENCEncryptionMethod * encryptionMethod,
@@ -129,6 +131,11 @@ private:
 		XSECCryptoKey * key,
 		XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * doc,
 		safeBuffer & result);
+	unsigned int doGCMDecryptToSafeBuffer(
+		TXFMChain * cipherText,
+		XSECCryptoKey * key,
+        unsigned int taglen,
+		safeBuffer & result);
 	unsigned int unwrapKeyAES(
    		TXFMChain * cipherText,
 		XSECCryptoKey * key,
@@ -145,7 +152,6 @@ private:
    		TXFMChain * cipherText,
 		XSECCryptoKey * key,
 		safeBuffer & result);
-
 };
 
 /*\@}*/

Modified: santuario/xml-security-cpp/trunk/xsec/xenc/impl/XENCCipherImpl.cpp
URL: http://svn.apache.org/viewvc/santuario/xml-security-cpp/trunk/xsec/xenc/impl/XENCCipherImpl.cpp?rev=1350045&r1=1350044&r2=1350045&view=diff
==============================================================================
--- santuario/xml-security-cpp/trunk/xsec/xenc/impl/XENCCipherImpl.cpp (original)
+++ santuario/xml-security-cpp/trunk/xsec/xenc/impl/XENCCipherImpl.cpp Wed Jun 13 22:33:10 2012
@@ -128,12 +128,16 @@ void XENCCipherImpl::Initialise(void) {
     XSECPlatformUtils::registerAlgorithmHandler(DSIGConstants::s_unicodeStrURIAES128_CBC, def);
     XSECPlatformUtils::registerAlgorithmHandler(DSIGConstants::s_unicodeStrURIAES192_CBC, def);
     XSECPlatformUtils::registerAlgorithmHandler(DSIGConstants::s_unicodeStrURIAES256_CBC, def);
+    XSECPlatformUtils::registerAlgorithmHandler(DSIGConstants::s_unicodeStrURIAES128_GCM, def);
+    XSECPlatformUtils::registerAlgorithmHandler(DSIGConstants::s_unicodeStrURIAES192_GCM, def);
+    XSECPlatformUtils::registerAlgorithmHandler(DSIGConstants::s_unicodeStrURIAES256_GCM, def);
     XSECPlatformUtils::registerAlgorithmHandler(DSIGConstants::s_unicodeStrURIKW_AES128, def);
     XSECPlatformUtils::registerAlgorithmHandler(DSIGConstants::s_unicodeStrURIKW_AES192, def);
     XSECPlatformUtils::registerAlgorithmHandler(DSIGConstants::s_unicodeStrURIKW_AES256, def);
     XSECPlatformUtils::registerAlgorithmHandler(DSIGConstants::s_unicodeStrURIKW_3DES, def);
     XSECPlatformUtils::registerAlgorithmHandler(DSIGConstants::s_unicodeStrURIRSA_1_5, def);
     XSECPlatformUtils::registerAlgorithmHandler(DSIGConstants::s_unicodeStrURIRSA_OAEP_MGFP1, def);
+    XSECPlatformUtils::registerAlgorithmHandler(DSIGConstants::s_unicodeStrURIRSA_OAEP, def);
 
 }
 
@@ -636,8 +640,6 @@ XSECBinTXFMInputStream * XENCCipherImpl:
 
     }
 
-    safeBuffer sb("");
-
     if (handler != NULL) {
 
         if (handler->appendDecryptCipherTXFM(c,