Index: src/lib/main.cpp
===================================================================
--- src/lib/main.cpp	(revision 6526)
+++ src/lib/main.cpp	(working copy)
@@ -51,6 +51,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <memory>
+#include <sstream>
 
 // C POSIX library header
 #include <sys/time.h>
@@ -65,6 +66,7 @@
 #include <botan/filters.h>
 #include <botan/pipe.h>
 #include <botan/emsa3.h>
+#include <botan/emsa4.h>
 #include <botan/emsa_raw.h>
 #include <botan/eme_pkcs.h>
 #include <botan/pk_keys.h>
@@ -1611,10 +1613,70 @@
       case CKM_SHA512_RSA_PKCS:
         hashFunc = new Botan::EMSA3(new Botan::SHA_512);
         break;
+      case CKM_SHA1_RSA_PKCS_PSS: 
+	if(pMechanism->pParameter == NULL_PTR || pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) {
+	  DEBUG_MSG("C_SignInit", "pParameter must be of type CK_RSA_PKCS_PSS_PARAMS");
+	  return CKR_ARGUMENTS_BAD;
+	}
+	if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA_1) {
+	  DEBUG_MSG("C_SignInit", "hashAlg must be CKM_SHA_1");
+	  return CKR_ARGUMENTS_BAD;
+	}
+	if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA1) {
+	  DEBUG_MSG("C_SignInit", "mgf must be CKG_MGF1_SHA1");
+	  return CKR_ARGUMENTS_BAD;
+	}
+	hashFunc = new Botan::EMSA4(new Botan::SHA_160, CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen);
+        break;
+      case CKM_SHA256_RSA_PKCS_PSS:
+	if(pMechanism->pParameter == NULL_PTR || pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) {
+	  DEBUG_MSG("C_SignInit", "pParameter must be of type CK_RSA_PKCS_PSS_PARAMS");
+	  return CKR_ARGUMENTS_BAD;
+	}
+	if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA256) {
+	  DEBUG_MSG("C_SignInit", "hashAlg must be CKM_SHA256");
+	  return CKR_ARGUMENTS_BAD;
+	}
+	if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA256) {
+	  DEBUG_MSG("C_SignInit", "mgf must be CKG_MGF1_SHA256");
+	  return CKR_ARGUMENTS_BAD;
+	}
+	hashFunc = new Botan::EMSA4(new Botan::SHA_256, CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen);
+        break;
+      case CKM_SHA384_RSA_PKCS_PSS:
+	if(pMechanism->pParameter == NULL_PTR || pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) {
+	  DEBUG_MSG("C_SignInit", "pParameter must be of type CK_RSA_PKCS_PSS_PARAMS");
+	  return CKR_ARGUMENTS_BAD;
+	}
+	if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA384) {
+	  DEBUG_MSG("C_SignInit", "hashAlg must be CKM_SHA384");
+	  return CKR_ARGUMENTS_BAD;
+	}
+	if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA384) {
+	  DEBUG_MSG("C_SignInit", "mgf must be CKG_MGF1_SHA384");
+	  return CKR_ARGUMENTS_BAD;
+	}
+	hashFunc = new Botan::EMSA4(new Botan::SHA_384, CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen);
+	break;
+      case CKM_SHA512_RSA_PKCS_PSS:
+	if(pMechanism->pParameter == NULL_PTR || pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) {
+	  DEBUG_MSG("C_SignInit", "pParameter must be of type CK_RSA_PKCS_PSS_PARAMS");
+	  return CKR_ARGUMENTS_BAD;
+	}
+	if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA512) {
+	  DEBUG_MSG("C_SignInit", "hashAlg must be CKM_SHA512");
+	  return CKR_ARGUMENTS_BAD;
+	}
+	if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA512) {
+	  DEBUG_MSG("C_SignInit", "mgf must be CKG_MGF1_SHA512");
+	  return CKR_ARGUMENTS_BAD;
+	}
+	hashFunc = new Botan::EMSA4(new Botan::SHA_512, CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen);
+	break;
       default:
-        DEBUG_MSG("C_SignInit", "The selected mechanism is not supported");
-        return CKR_MECHANISM_INVALID;
-        break;
+	DEBUG_MSG("C_SignInit", "The selected mechanism is not supported");
+	return CKR_MECHANISM_INVALID;
+	break;
     }
 
     if(hashFunc == NULL_PTR) {
@@ -1652,6 +1714,82 @@
       case CKM_SHA512_RSA_PKCS:
         emsa = "EMSA3(SHA-512)";
         break;
+      case CKM_SHA1_RSA_PKCS_PSS:
+	std::ostringstream request;
+	if(pMechanism->pParameter == NULL_PTR || pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) {
+	  DEBUG_MSG("C_SignInit", "pParameter must be of type CK_RSA_PKCS_PSS_PARAMS");
+	  return CKR_ARGUMENTS_BAD;
+	}
+	if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA_1) {
+	  DEBUG_MSG("C_SignInit", "hashAlg must be CKM_SHA_1");
+	  return CKR_ARGUMENTS_BAD;
+	}
+	if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA1) {
+	  DEBUG_MSG("C_SignInit", "mgf must be CKG_MGF1_SHA1");
+	  return CKR_ARGUMENTS_BAD;
+	}
+	request << "EMSA4(SHA-160,MGF1," 
+		<< CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen
+		<< ")";
+        emsa = request.str();
+        break;
+      case CKM_SHA256_RSA_PKCS_PSS:
+	std::ostringstream request;
+	if(pMechanism->pParameter == NULL_PTR || pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) {
+	  DEBUG_MSG("C_SignInit", "pParameter must be of type CK_RSA_PKCS_PSS_PARAMS");
+	  return CKR_ARGUMENTS_BAD;
+	}
+	if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA256) {
+	  DEBUG_MSG("C_SignInit", "hashAlg must be CKM_SHA256");
+	  return CKR_ARGUMENTS_BAD;
+	}
+	if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA256) {
+	  DEBUG_MSG("C_SignInit", "mgf must be CKG_MGF1_SHA256");
+	  return CKR_ARGUMENTS_BAD;
+	}
+	request << "EMSA4(SHA-256,MGF1," 
+		<< CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen
+		<< ")";
+        emsa = request.str();
+        break;
+      case CKM_SHA384_RSA_PKCS_PSS:
+	std::ostringstream request;
+	if(pMechanism->pParameter == NULL_PTR || pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) {
+	  DEBUG_MSG("C_SignInit", "pParameter must be of type CK_RSA_PKCS_PSS_PARAMS");
+	  return CKR_ARGUMENTS_BAD;
+	}
+	if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA384) {
+	  DEBUG_MSG("C_SignInit", "hashAlg must be CKM_SHA384");
+	  return CKR_ARGUMENTS_BAD;
+	}
+	if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA384) {
+	  DEBUG_MSG("C_SignInit", "mgf must be CKG_MGF1_SHA384");
+	  return CKR_ARGUMENTS_BAD;
+	}
+	request << "EMSA4(SHA-384,MGF1," 
+		<< CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen
+		<< ")";
+        emsa = request.str();
+        break;
+      case CKM_SHA512_RSA_PKCS_PSS:
+	std::ostringstream request;
+	if(pMechanism->pParameter == NULL_PTR || pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) {
+	  DEBUG_MSG("C_SignInit", "pParameter must be of type CK_RSA_PKCS_PSS_PARAMS");
+	  return CKR_ARGUMENTS_BAD;
+	}
+	if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA512) {
+	  DEBUG_MSG("C_SignInit", "hashAlg must be CKM_SHA512");
+	  return CKR_ARGUMENTS_BAD;
+	}
+	if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA512) {
+	  DEBUG_MSG("C_SignInit", "mgf must be CKG_MGF1_SHA512");
+	  return CKR_ARGUMENTS_BAD;
+	}
+	request << "EMSA4(SHA-512,MGF1," 
+		<< CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen
+		<< ")";
+        emsa = request.str();
+        break;
       default:
         DEBUG_MSG("C_SignInit", "The selected mechanism is not supported");
         return CKR_MECHANISM_INVALID;
@@ -1991,6 +2129,66 @@
     case CKM_SHA512_RSA_PKCS:
       hashFunc = new Botan::EMSA3(new Botan::SHA_512);
       break;
+    case CKM_SHA1_RSA_PKCS_PSS: 
+      if(pMechanism->pParameter == NULL_PTR || pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) {
+	DEBUG_MSG("C_VerifyInit", "pParameter must be of type CK_RSA_PKCS_PSS_PARAMS");
+	return CKR_ARGUMENTS_BAD;
+      }
+      if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA_1) {
+	DEBUG_MSG("C_VerifyInit", "hashAlg must be CKM_SHA_1");
+	return CKR_ARGUMENTS_BAD;
+      }
+      if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA1) {
+	DEBUG_MSG("C_VerifyInit", "mgf must be CKG_MGF1_SHA1");
+	return CKR_ARGUMENTS_BAD;
+      }
+      hashFunc = new Botan::EMSA4(new Botan::SHA_160, CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen);
+      break;
+    case CKM_SHA256_RSA_PKCS_PSS:
+      if(pMechanism->pParameter == NULL_PTR || pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) {
+	DEBUG_MSG("C_VerifyInit", "pParameter must be of type CK_RSA_PKCS_PSS_PARAMS");
+	return CKR_ARGUMENTS_BAD;
+      }
+      if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA256) {
+	DEBUG_MSG("C_VerifyInit", "hashAlg must be CKM_SHA256");
+	return CKR_ARGUMENTS_BAD;
+      }
+      if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA256) {
+	DEBUG_MSG("C_VerifyInit", "mgf must be CKG_MGF1_SHA256");
+	return CKR_ARGUMENTS_BAD;
+      }
+      hashFunc = new Botan::EMSA4(new Botan::SHA_256, CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen);
+      break;
+    case CKM_SHA384_RSA_PKCS_PSS:
+      if(pMechanism->pParameter == NULL_PTR || pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) {
+	DEBUG_MSG("C_VerifyInit", "pParameter must be of type CK_RSA_PKCS_PSS_PARAMS");
+	return CKR_ARGUMENTS_BAD;
+      }
+      if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA384) {
+	DEBUG_MSG("C_VerifyInit", "hashAlg must be CKM_SHA384");
+	return CKR_ARGUMENTS_BAD;
+      }
+      if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA384) {
+	DEBUG_MSG("C_VerifyInit", "mgf must be CKG_MGF1_SHA384");
+	return CKR_ARGUMENTS_BAD;
+      }
+      hashFunc = new Botan::EMSA4(new Botan::SHA_384, CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen);
+      break;
+    case CKM_SHA512_RSA_PKCS_PSS:
+      if(pMechanism->pParameter == NULL_PTR || pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) {
+	DEBUG_MSG("C_VerifyInit", "pParameter must be of type CK_RSA_PKCS_PSS_PARAMS");
+	return CKR_ARGUMENTS_BAD;
+      }
+      if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA512) {
+	DEBUG_MSG("C_VerifyInit", "hashAlg must be CKM_SHA512");
+	return CKR_ARGUMENTS_BAD;
+      }
+      if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA512) {
+	DEBUG_MSG("C_VerifyInit", "mgf must be CKG_MGF1_SHA512");
+	return CKR_ARGUMENTS_BAD;
+      }
+      hashFunc = new Botan::EMSA4(new Botan::SHA_512, CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen);
+      break;      
     default:
       DEBUG_MSG("C_VerifyInit", "The selected mechanism is not supported");
       return CKR_MECHANISM_INVALID;
@@ -2032,6 +2230,82 @@
     case CKM_SHA512_RSA_PKCS:
       emsa = "EMSA3(SHA-512)";
       break;
+    case CKM_SHA1_RSA_PKCS_PSS:
+      std::ostringstream request;
+      if(pMechanism->pParameter == NULL_PTR || pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) {
+	DEBUG_MSG("C_VerifyInit", "pParameter must be of type CK_RSA_PKCS_PSS_PARAMS");
+	return CKR_ARGUMENTS_BAD;
+      }
+      if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA_1) {
+	DEBUG_MSG("C_VerifyInit", "hashAlg must be CKM_SHA_1");
+	return CKR_ARGUMENTS_BAD;
+      }
+      if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA1) {
+	DEBUG_MSG("C_VerifyInit", "mgf must be CKG_MGF1_SHA1");
+	return CKR_ARGUMENTS_BAD;
+      }
+      request << "EMSA4(SHA-160,MGF1," 
+	      << CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen
+	      << ")";
+      emsa = request.str();
+      break;
+    case CKM_SHA256_RSA_PKCS_PSS:
+      std::ostringstream request;
+      if(pMechanism->pParameter == NULL_PTR || pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) {
+	DEBUG_MSG("C_VerifyInit", "pParameter must be of type CK_RSA_PKCS_PSS_PARAMS");
+	return CKR_ARGUMENTS_BAD;
+      }
+      if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA256) {
+	DEBUG_MSG("C_VerifyInit", "hashAlg must be CKM_SHA256");
+	return CKR_ARGUMENTS_BAD;
+      }
+      if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA256) {
+	DEBUG_MSG("C_VerifyInit", "mgf must be CKG_MGF1_SHA256");
+	return CKR_ARGUMENTS_BAD;
+      }
+      request << "EMSA4(SHA-256,MGF1," 
+	      << CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen
+	      << ")";
+      emsa = request.str();
+      break;
+    case CKM_SHA384_RSA_PKCS_PSS:
+      std::ostringstream request;
+      if(pMechanism->pParameter == NULL_PTR || pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) {
+	DEBUG_MSG("C_VerifyInit", "pParameter must be of type CK_RSA_PKCS_PSS_PARAMS");
+	return CKR_ARGUMENTS_BAD;
+      }
+      if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA384) {
+	DEBUG_MSG("C_VerifyInit", "hashAlg must be CKM_SHA384");
+	return CKR_ARGUMENTS_BAD;
+      }
+      if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA384) {
+	DEBUG_MSG("C_VerifyInit", "mgf must be CKG_MGF1_SHA384");
+	return CKR_ARGUMENTS_BAD;
+      }
+      request << "EMSA4(SHA-384,MGF1," 
+	      << CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen
+	      << ")";
+      emsa = request.str();
+      break;
+    case CKM_SHA512_RSA_PKCS_PSS:
+      std::ostringstream request;
+      if(pMechanism->pParameter == NULL_PTR || pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) {
+	DEBUG_MSG("C_VerifyInit", "pParameter must be of type CK_RSA_PKCS_PSS_PARAMS");
+	return CKR_ARGUMENTS_BAD;
+      }
+      if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA512) {
+	DEBUG_MSG("C_VerifyInit", "hashAlg must be CKM_SHA512");
+	return CKR_ARGUMENTS_BAD;
+      }
+      if(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA512) {
+	DEBUG_MSG("C_VerifyInit", "mgf must be CKG_MGF1_SHA512");
+	return CKR_ARGUMENTS_BAD;
+      }
+      request << "EMSA4(SHA-512,MGF1," 
+	      << CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen
+	      << ")";
+      emsa = request.str();
+      break;
     default:
       DEBUG_MSG("C_VerifyInit", "The selected mechanism is not supported");
       return CKR_MECHANISM_INVALID;
Index: src/lib/cryptoki_compat/pkcs11.h
===================================================================
--- src/lib/cryptoki_compat/pkcs11.h	(revision 6526)
+++ src/lib/cryptoki_compat/pkcs11.h	(working copy)
@@ -161,6 +161,9 @@
 #define min_key_size ulMinKeySize
 #define max_key_size ulMaxKeySize
 
+#define hash_alg hashAlg
+#define salt_len sLen
+
 #define ck_rv_t CK_RV
 #define ck_notify_t CK_NOTIFY
 
@@ -687,6 +690,21 @@
   ck_flags_t flags;
 };
 
+
+/* The following MGFs are defined */
+/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512
+ * are new for v2.20 */
+#define CKG_MGF1_SHA1         (0x00000001)
+#define CKG_MGF1_SHA256       (0x00000002)
+#define CKG_MGF1_SHA384       (0x00000003)
+#define CKG_MGF1_SHA512       (0x00000004)
+
+struct ck_rsa_pkcs_pss_params {
+  ck_mechanism_type_t hash_alg;
+  unsigned long mgf;
+  unsigned long salt_len;
+};
+
 #define CKF_HW			(1 << 0)
 #define CKF_ENCRYPT		(1 << 8)
 #define CKF_DECRYPT		(1 << 9)
@@ -1249,6 +1267,9 @@
 typedef struct ck_mechanism_info CK_MECHANISM_INFO;
 typedef struct ck_mechanism_info *CK_MECHANISM_INFO_PTR;
 
+typedef struct ck_rsa_pkcs_pss_params CK_RSA_PKCS_PSS_PARAMS;
+typedef struct ck_rsa_pkcs_pss_params *CK_RSA_PKCS_PSS_PARAMS_PTR;
+
 typedef struct ck_function_list CK_FUNCTION_LIST;
 typedef struct ck_function_list *CK_FUNCTION_LIST_PTR;
 typedef struct ck_function_list **CK_FUNCTION_LIST_PTR_PTR;
@@ -1321,6 +1342,10 @@
 #undef min_key_size
 #undef max_key_size
 
+#undef ck_rsa_pkcs_pss_params
+#undef hash_alg
+#undef salt_len
+
 #undef ck_rv_t
 #undef ck_notify_t
 
Index: src/lib/mechanisms.h
===================================================================
--- src/lib/mechanisms.h	(revision 6526)
+++ src/lib/mechanisms.h	(working copy)
@@ -32,7 +32,7 @@
 #include "cryptoki.h"
 
 // The number of supported mechanisms
-#define NR_SUPPORTED_MECHANISMS 15
+#define NR_SUPPORTED_MECHANISMS 19
 
 // A list with the supported mechanisms
 static CK_MECHANISM_TYPE supportedMechanisms[] = {
@@ -50,7 +50,11 @@
 	CKM_SHA1_RSA_PKCS,
 	CKM_SHA256_RSA_PKCS,
 	CKM_SHA384_RSA_PKCS,
-	CKM_SHA512_RSA_PKCS
+	CKM_SHA512_RSA_PKCS,
+	CKM_SHA1_RSA_PKCS_PSS,
+	CKM_SHA256_RSA_PKCS_PSS,
+	CKM_SHA384_RSA_PKCS_PSS,
+	CKM_SHA512_RSA_PKCS_PSS	
 };
 
 CK_RV getMechanismInfo(CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo);
Index: src/lib/mechanisms.cpp
===================================================================
--- src/lib/mechanisms.cpp	(revision 6526)
+++ src/lib/mechanisms.cpp	(working copy)
@@ -73,6 +73,10 @@
     case CKM_SHA256_RSA_PKCS:
     case CKM_SHA384_RSA_PKCS:
     case CKM_SHA512_RSA_PKCS:
+    case CKM_SHA1_RSA_PKCS_PSS:
+    case CKM_SHA256_RSA_PKCS_PSS:
+    case CKM_SHA384_RSA_PKCS_PSS:
+    case CKM_SHA512_RSA_PKCS_PSS:
       pInfo->ulMinKeySize = 512;
       pInfo->ulMaxKeySize = 4096;
       pInfo->flags = CKF_SIGN | CKF_VERIFY;
