Blob Blame History Raw
diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c
--- a/lib/softoken/pkcs11c.c
+++ b/lib/softoken/pkcs11c.c
@@ -232,57 +232,26 @@ NSC_DestroyObject(CK_SESSION_HANDLE hSes
      * be in the data base.
      */
     status = sftk_FreeObject(object);
 
     return (status != SFTK_DestroyFailure) ? CKR_OK : CKR_DEVICE_ERROR;
 }
 
 /*
- ************** Crypto Functions:     Utilities ************************
- */
-/*
- * Utility function for converting PSS/OAEP parameter types into
- * HASH_HashTypes. Note: Only SHA family functions are defined in RFC 3447.
- */
-static HASH_HashType
-GetHashTypeFromMechanism(CK_MECHANISM_TYPE mech)
-{
-    switch (mech) {
-        case CKM_SHA_1:
-        case CKG_MGF1_SHA1:
-            return HASH_AlgSHA1;
-        case CKM_SHA224:
-        case CKG_MGF1_SHA224:
-            return HASH_AlgSHA224;
-        case CKM_SHA256:
-        case CKG_MGF1_SHA256:
-            return HASH_AlgSHA256;
-        case CKM_SHA384:
-        case CKG_MGF1_SHA384:
-            return HASH_AlgSHA384;
-        case CKM_SHA512:
-        case CKG_MGF1_SHA512:
-            return HASH_AlgSHA512;
-        default:
-            return HASH_AlgNULL;
-    }
-}
-
-/*
  * Returns true if "params" contains a valid set of PSS parameters
  */
 static PRBool
 sftk_ValidatePssParams(const CK_RSA_PKCS_PSS_PARAMS *params)
 {
     if (!params) {
         return PR_FALSE;
     }
-    if (GetHashTypeFromMechanism(params->hashAlg) == HASH_AlgNULL ||
-        GetHashTypeFromMechanism(params->mgf) == HASH_AlgNULL) {
+    if (sftk_GetHashTypeFromMechanism(params->hashAlg) == HASH_AlgNULL ||
+        sftk_GetHashTypeFromMechanism(params->mgf) == HASH_AlgNULL) {
         return PR_FALSE;
     }
     return PR_TRUE;
 }
 
 /*
  * Returns true if "params" contains a valid set of OAEP parameters
  */
@@ -293,18 +262,18 @@ sftk_ValidateOaepParams(const CK_RSA_PKC
         return PR_FALSE;
     }
     /* The requirements of ulSourceLen/pSourceData come from PKCS #11, which
      * state:
      *   If the parameter is empty, pSourceData must be NULL and
      *   ulSourceDataLen must be zero.
      */
     if (params->source != CKZ_DATA_SPECIFIED ||
-        (GetHashTypeFromMechanism(params->hashAlg) == HASH_AlgNULL) ||
-        (GetHashTypeFromMechanism(params->mgf) == HASH_AlgNULL) ||
+        (sftk_GetHashTypeFromMechanism(params->hashAlg) == HASH_AlgNULL) ||
+        (sftk_GetHashTypeFromMechanism(params->mgf) == HASH_AlgNULL) ||
         (params->ulSourceDataLen == 0 && params->pSourceData != NULL) ||
         (params->ulSourceDataLen != 0 && params->pSourceData == NULL)) {
         return PR_FALSE;
     }
     return PR_TRUE;
 }
 
 /*
@@ -606,18 +575,18 @@ sftk_RSAEncryptOAEP(SFTKOAEPInfo *info, 
     HASH_HashType maskHashAlg;
 
     PORT_Assert(info->key.pub->keyType == NSSLOWKEYRSAKey);
     if (info->key.pub->keyType != NSSLOWKEYRSAKey) {
         PORT_SetError(SEC_ERROR_INVALID_KEY);
         return SECFailure;
     }
 
-    hashAlg = GetHashTypeFromMechanism(info->params.hashAlg);
-    maskHashAlg = GetHashTypeFromMechanism(info->params.mgf);
+    hashAlg = sftk_GetHashTypeFromMechanism(info->params.hashAlg);
+    maskHashAlg = sftk_GetHashTypeFromMechanism(info->params.mgf);
 
     return RSA_EncryptOAEP(&info->key.pub->u.rsa, hashAlg, maskHashAlg,
                            (const unsigned char *)info->params.pSourceData,
                            info->params.ulSourceDataLen, NULL, 0,
                            output, outputLen, maxLen, input, inputLen);
 }
 
 static SECStatus
@@ -630,18 +599,18 @@ sftk_RSADecryptOAEP(SFTKOAEPInfo *info, 
     HASH_HashType maskHashAlg;
 
     PORT_Assert(info->key.priv->keyType == NSSLOWKEYRSAKey);
     if (info->key.priv->keyType != NSSLOWKEYRSAKey) {
         PORT_SetError(SEC_ERROR_INVALID_KEY);
         return SECFailure;
     }
 
-    hashAlg = GetHashTypeFromMechanism(info->params.hashAlg);
-    maskHashAlg = GetHashTypeFromMechanism(info->params.mgf);
+    hashAlg = sftk_GetHashTypeFromMechanism(info->params.hashAlg);
+    maskHashAlg = sftk_GetHashTypeFromMechanism(info->params.mgf);
 
     rv = RSA_DecryptOAEP(&info->key.priv->u.rsa, hashAlg, maskHashAlg,
                          (const unsigned char *)info->params.pSourceData,
                          info->params.ulSourceDataLen,
                          output, outputLen, maxLen, input, inputLen);
     if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
         sftk_fatalError = PR_TRUE;
     }
@@ -2646,18 +2615,18 @@ sftk_RSASignPSS(SFTKPSSSignInfo *info, u
     CK_RSA_PKCS_PSS_PARAMS *params = &info->params;
 
     PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey);
     if (info->key->keyType != NSSLOWKEYRSAKey) {
         PORT_SetError(SEC_ERROR_INVALID_KEY);
         return SECFailure;
     }
 
-    hashAlg = GetHashTypeFromMechanism(params->hashAlg);
-    maskHashAlg = GetHashTypeFromMechanism(params->mgf);
+    hashAlg = sftk_GetHashTypeFromMechanism(params->hashAlg);
+    maskHashAlg = sftk_GetHashTypeFromMechanism(params->mgf);
 
     rv = RSA_SignPSS(&info->key->u.rsa, hashAlg, maskHashAlg, NULL,
                      params->sLen, sig, sigLen, maxLen, hash, hashLen);
     if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
         sftk_fatalError = PR_TRUE;
     }
     return rv;
 }
@@ -3021,17 +2990,17 @@ NSC_SignInit(CK_SESSION_HANDLE hSession,
                 tlsPrfHash = HASH_AlgNULL;
                 if (tls12_mac_params->ulMacLength != 12) {
                     crv = CKR_MECHANISM_PARAM_INVALID;
                     break;
                 }
             } else {
                 /* The hash function for the TLS 1.2 PRF */
                 tlsPrfHash =
-                    GetHashTypeFromMechanism(tls12_mac_params->prfHashMechanism);
+                    sftk_GetHashTypeFromMechanism(tls12_mac_params->prfHashMechanism);
                 if (tlsPrfHash == HASH_AlgNULL ||
                     tls12_mac_params->ulMacLength < 12) {
                     crv = CKR_MECHANISM_PARAM_INVALID;
                     break;
                 }
             }
             if (tls12_mac_params->ulServerOrClient == 1) {
                 label = "server finished";
@@ -3539,18 +3508,18 @@ sftk_RSACheckSignPSS(SFTKPSSVerifyInfo *
     CK_RSA_PKCS_PSS_PARAMS *params = &info->params;
 
     PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey);
     if (info->key->keyType != NSSLOWKEYRSAKey) {
         PORT_SetError(SEC_ERROR_INVALID_KEY);
         return SECFailure;
     }
 
-    hashAlg = GetHashTypeFromMechanism(params->hashAlg);
-    maskHashAlg = GetHashTypeFromMechanism(params->mgf);
+    hashAlg = sftk_GetHashTypeFromMechanism(params->hashAlg);
+    maskHashAlg = sftk_GetHashTypeFromMechanism(params->mgf);
 
     return RSA_CheckSignPSS(&info->key->u.rsa, hashAlg, maskHashAlg,
                             params->sLen, sig, sigLen, digest, digestLen);
 }
 
 /* NSC_VerifyInit initializes a verification operation,
  * where the signature is an appendix to the data,
  * and plaintext cannot be recovered from the signature (e.g. DSA) */
@@ -6951,17 +6920,17 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_
     unsigned genLen = 0;
     unsigned char hashbuf[HASH_LENGTH_MAX];
     unsigned char keyBlock[9 * SFTK_MAX_MAC_LENGTH];
     unsigned char *keyBlockAlloc = NULL;    /* allocated keyBlock */
     unsigned char *keyBlockData = keyBlock; /* pointer to current keyBlock */
     const unsigned char *prk;               /* psuedo-random key */
     CK_ULONG prkLen;
     const unsigned char *okm; /* output keying material */
-    HASH_HashType hashType = GetHashTypeFromMechanism(params->prfHashMechanism);
+    HASH_HashType hashType = sftk_GetHashTypeFromMechanism(params->prfHashMechanism);
     SFTKObject *saltKey = NULL;
     CK_RV crv = CKR_OK;
 
     /* Spec says it should be the base hash, but also accept the HMAC */
     if (hashType == HASH_AlgNULL) {
         hashType = sftk_HMACMechanismToHash(params->prfHashMechanism);
     }
     rawHash = HASH_GetRawHashObject(hashType);
@@ -7389,17 +7358,17 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
             if ((mechanism == CKM_TLS12_MASTER_KEY_DERIVE) ||
                 (mechanism == CKM_TLS12_MASTER_KEY_DERIVE_DH)) {
                 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS))) {
                     crv = CKR_MECHANISM_PARAM_INVALID;
                     break;
                 }
                 CK_TLS12_MASTER_KEY_DERIVE_PARAMS *tls12_master =
                     (CK_TLS12_MASTER_KEY_DERIVE_PARAMS *)pMechanism->pParameter;
-                tlsPrfHash = GetHashTypeFromMechanism(tls12_master->prfHashMechanism);
+                tlsPrfHash = sftk_GetHashTypeFromMechanism(tls12_master->prfHashMechanism);
                 if (tlsPrfHash == HASH_AlgNULL) {
                     crv = CKR_MECHANISM_PARAM_INVALID;
                     break;
                 }
             } else if ((mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256) ||
                        (mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256)) {
                 tlsPrfHash = HASH_AlgSHA256;
             }
@@ -7607,17 +7576,17 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
                     break;
                 }
 
                 status = TLS_PRF(&pms, "extended master secret",
                                  &seed, &master, isFIPS);
             } else {
                 const SECHashObject *hashObj;
 
-                tlsPrfHash = GetHashTypeFromMechanism(ems_params->prfHashMechanism);
+                tlsPrfHash = sftk_GetHashTypeFromMechanism(ems_params->prfHashMechanism);
                 if (tlsPrfHash == HASH_AlgNULL) {
                     crv = CKR_MECHANISM_PARAM_INVALID;
                     break;
                 }
 
                 hashObj = HASH_GetRawHashObject(tlsPrfHash);
                 if (seed.len != hashObj->length) {
                     crv = CKR_TEMPLATE_INCONSISTENT;
@@ -7665,17 +7634,17 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
 
             if (mechanism == CKM_TLS12_KEY_AND_MAC_DERIVE) {
                 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_TLS12_KEY_MAT_PARAMS))) {
                     crv = CKR_MECHANISM_PARAM_INVALID;
                     break;
                 }
                 CK_TLS12_KEY_MAT_PARAMS *tls12_keys =
                     (CK_TLS12_KEY_MAT_PARAMS *)pMechanism->pParameter;
-                tlsPrfHash = GetHashTypeFromMechanism(tls12_keys->prfHashMechanism);
+                tlsPrfHash = sftk_GetHashTypeFromMechanism(tls12_keys->prfHashMechanism);
                 if (tlsPrfHash == HASH_AlgNULL) {
                     crv = CKR_MECHANISM_PARAM_INVALID;
                     break;
                 }
             } else if (mechanism == CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256) {
                 tlsPrfHash = HASH_AlgSHA256;
             }
 
diff --git a/lib/softoken/pkcs11i.h b/lib/softoken/pkcs11i.h
--- a/lib/softoken/pkcs11i.h
+++ b/lib/softoken/pkcs11i.h
@@ -908,16 +908,19 @@ sftk_MACConstantTimeCtx *sftk_HMACConsta
 sftk_MACConstantTimeCtx *sftk_SSLv3MACConstantTime_New(
     CK_MECHANISM_PTR mech, SFTKObject *key);
 void sftk_HMACConstantTime_Update(void *pctx, const void *data, unsigned int len);
 void sftk_SSLv3MACConstantTime_Update(void *pctx, const void *data, unsigned int len);
 void sftk_MACConstantTime_EndHash(
     void *pctx, void *out, unsigned int *outLength, unsigned int maxLength);
 void sftk_MACConstantTime_DestroyContext(void *pctx, PRBool);
 
+/* Crypto Utilities */
+HASH_HashType sftk_GetHashTypeFromMechanism(CK_MECHANISM_TYPE mech);
+
 /****************************************
  * implement TLS Pseudo Random Function (PRF)
  */
 
 extern CK_RV
 sftk_TLSPRFInit(SFTKSessionContext *context,
                 SFTKObject *key,
                 CK_KEY_TYPE key_type,
diff --git a/lib/softoken/pkcs11u.c b/lib/softoken/pkcs11u.c
--- a/lib/softoken/pkcs11u.c
+++ b/lib/softoken/pkcs11u.c
@@ -95,16 +95,17 @@ CK_RV
 sftk_MapVerifyError(int error)
 {
     CK_RV crv = sftk_MapCryptError(error);
     if (crv == CKR_DEVICE_ERROR)
         crv = CKR_SIGNATURE_INVALID;
     return crv;
 }
 
+
 /*
  * ******************** Attribute Utilities *******************************
  */
 
 /*
  * create a new attribute with type, value, and length. Space is allocated
  * to hold value.
  */
@@ -2243,17 +2244,49 @@ sftk_AttributeToFlags(CK_ATTRIBUTE_TYPE 
             flags = CKF_MESSAGE_VERIFY;
             break;
         default:
             break;
     }
     return flags;
 }
 
+/*
+ * ******************** Hash Utilities **************************
+ */
+/*
+ * Utility function for converting PSS/OAEP parameter types into
+ * HASH_HashTypes. Note: Only SHA family functions are defined in RFC 3447.
+ */
+HASH_HashType
+sftk_GetHashTypeFromMechanism(CK_MECHANISM_TYPE mech)
+{
+    switch (mech) {
+        case CKM_SHA_1:
+        case CKG_MGF1_SHA1:
+            return HASH_AlgSHA1;
+        case CKM_SHA224:
+        case CKG_MGF1_SHA224:
+            return HASH_AlgSHA224;
+        case CKM_SHA256:
+        case CKG_MGF1_SHA256:
+            return HASH_AlgSHA256;
+        case CKM_SHA384:
+        case CKG_MGF1_SHA384:
+            return HASH_AlgSHA384;
+        case CKM_SHA512:
+        case CKG_MGF1_SHA512:
+            return HASH_AlgSHA512;
+        default:
+            return HASH_AlgNULL;
+    }
+}
+
 #ifdef NSS_HAS_FIPS_INDICATORS
+/**************** FIPS Indicator Utilities *************************/
 /* sigh, we probably need a version of this in secutil so that both
  * softoken and NSS can use it */
 static SECOidTag
 sftk_quickGetECCCurveOid(SFTKObject *source)
 {
     SFTKAttribute *attribute = sftk_FindAttribute(source, CKA_EC_PARAMS);
     unsigned char *encoded;
     int len;
@@ -2379,16 +2412,39 @@ sftk_handleSpecial(SFTKSlot *slot, CK_ME
             if (mech->ulParameterLen == 0) {
                 /* AEAD ciphers are only in FIPS mode if we are using the
                  * MESSAGE interface. This takes an empty parameter
                  * in the init function */
                 return PR_TRUE;
             }
             return PR_FALSE;
         }
+        case SFTKFIPSRSAPSS: {
+            /* PSS salt must not be greater than the length of the
+             * underlying hash. We verify that the underlying hash of the
+             * parameters matches Hash of the combined hash mechanisms, so
+             * we don't need to look at the specific PSS mechanism */
+            CK_RSA_PKCS_PSS_PARAMS *pss = (CK_RSA_PKCS_PSS_PARAMS *)
+                                           mech->pParameter;
+            const SECHashObject *hashObj = NULL;
+            if (mech->ulParameterLen != sizeof(*pss)) {
+                return PR_FALSE;
+            }
+            /* we use the existing hash utilities to find the length of
+             * the hash */
+            hashObj = HASH_GetRawHashObject(sftk_GetHashTypeFromMechanism(
+                      pss->hashAlg));
+            if (hashObj == NULL) {
+                return PR_FALSE;
+            }
+            if (pss->sLen > hashObj->length) {
+                return PR_FALSE;
+            }
+            return PR_TRUE;
+        }
         default:
             break;
     }
     /* if we didn't understand the special processing, mark it non-fips */
     return PR_FALSE;
 }
 #endif