Bug 1297552 - Perform U2F hash operations more efficiently r=keeler draft
authorJ.C. Jones <jjones@mozilla.com>
Thu, 06 Oct 2016 13:07:17 -0700
changeset 424592 81a4388dff82894da7c41107b6944dc2551f59e8
parent 424520 22be4ae74653b25186665f22e52a50e7027fd36b
child 424593 761f6cc02a4a266b34892f957689128794593c73
push id32199
push userjjones@mozilla.com
push dateThu, 13 Oct 2016 03:07:09 +0000
reviewerskeeler
bugs1297552
milestone52.0a1
Bug 1297552 - Perform U2F hash operations more efficiently r=keeler Moves hash calculations to happen only once per JS-invoked Register/Sign operation. MozReview-Commit-ID: FuA95qCl1rG
dom/u2f/U2F.cpp
--- a/dom/u2f/U2F.cpp
+++ b/dom/u2f/U2F.cpp
@@ -171,16 +171,33 @@ U2FRegisterTask::Run()
 
       if (isCompatible && isRegistered) {
         ReturnError(ErrorCode::DEVICE_INELIGIBLE);
         return NS_OK;
       }
     }
   }
 
+  // Hash the AppID into the AppParam
+  SECStatus srv;
+  nsCString cAppId = NS_ConvertUTF16toUTF8(mAppId);
+  CryptoBuffer appParam;
+  if (!appParam.SetLength(SHA256_LENGTH, fallible)) {
+    ReturnError(ErrorCode::OTHER_ERROR);
+    return NS_ERROR_FAILURE;
+  }
+
+  srv = PK11_HashBuf(SEC_OID_SHA256, appParam.Elements(),
+                     reinterpret_cast<const uint8_t*>(cAppId.BeginReading()),
+                     cAppId.Length());
+  if (srv != SECSuccess) {
+    ReturnError(ErrorCode::OTHER_ERROR);
+    return NS_ERROR_FAILURE;
+  }
+
   // Search the requests in order for the first some token can fulfill
   for (size_t i = 0; i < mRegisterRequests.Length(); ++i) {
     RegisterRequest request(mRegisterRequests[i]);
 
     // Check for equired attributes
     if (!(request.mVersion.WasPassed() &&
         request.mChallenge.WasPassed())) {
       continue;
@@ -190,31 +207,19 @@ U2FRegisterTask::Run()
     nsresult rv = AssembleClientData(mOrigin, kFinishEnrollment,
                                      request.mChallenge.Value(),
                                      clientData);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       ReturnError(ErrorCode::OTHER_ERROR);
       return NS_ERROR_FAILURE;
     }
 
-    // Hash the AppID and the ClientData into the AppParam and ChallengeParam
-    SECStatus srv;
-    nsCString cAppId = NS_ConvertUTF16toUTF8(mAppId);
-    CryptoBuffer appParam;
+    // Hash the ClientData into the ChallengeParam
     CryptoBuffer challengeParam;
-    if (!appParam.SetLength(SHA256_LENGTH, fallible) ||
-        !challengeParam.SetLength(SHA256_LENGTH, fallible)) {
-      ReturnError(ErrorCode::OTHER_ERROR);
-      return NS_ERROR_FAILURE;
-    }
-
-    srv = PK11_HashBuf(SEC_OID_SHA256, appParam.Elements(),
-                       reinterpret_cast<const uint8_t*>(cAppId.BeginReading()),
-                       cAppId.Length());
-    if (srv != SECSuccess) {
+    if (!challengeParam.SetLength(SHA256_LENGTH, fallible)) {
       ReturnError(ErrorCode::OTHER_ERROR);
       return NS_ERROR_FAILURE;
     }
 
     srv = PK11_HashBuf(SEC_OID_SHA256, challengeParam.Elements(),
                        clientData.Elements(), clientData.Length());
     if (srv != SECSuccess) {
       ReturnError(ErrorCode::OTHER_ERROR);
@@ -325,16 +330,33 @@ NS_IMETHODIMP
 U2FSignTask::Run()
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     ReturnError(ErrorCode::OTHER_ERROR);
     return NS_ERROR_FAILURE;
   }
 
+  // Hash the AppID into the AppParam
+  SECStatus srv;
+  nsCString cAppId = NS_ConvertUTF16toUTF8(mAppId);
+  CryptoBuffer appParam;
+  if (!appParam.SetLength(SHA256_LENGTH, fallible)) {
+    ReturnError(ErrorCode::OTHER_ERROR);
+    return NS_ERROR_FAILURE;
+  }
+
+  srv = PK11_HashBuf(SEC_OID_SHA256, appParam.Elements(),
+                     reinterpret_cast<const uint8_t*>(cAppId.BeginReading()),
+                     cAppId.Length());
+  if (srv != SECSuccess) {
+    ReturnError(ErrorCode::OTHER_ERROR);
+    return NS_ERROR_FAILURE;
+  }
+
   // Search the requests for one a token can fulfill
   for (size_t i = 0; i < mRegisteredKeys.Length(); i += 1) {
     RegisteredKey request(mRegisteredKeys[i]);
 
     // Check for required attributes
     if (!(request.mVersion.WasPassed() &&
           request.mKeyHandle.WasPassed())) {
       continue;
@@ -349,31 +371,19 @@ U2FSignTask::Run()
     CryptoBuffer clientData;
     nsresult rv = AssembleClientData(mOrigin, kGetAssertion, mChallenge,
                                      clientData);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       ReturnError(ErrorCode::OTHER_ERROR);
       return NS_ERROR_FAILURE;
     }
 
-    // Hash the AppID and the ClientData into the AppParam and ChallengeParam
-    SECStatus srv;
-    nsCString cAppId = NS_ConvertUTF16toUTF8(mAppId);
-    CryptoBuffer appParam;
+    // Hash the ClientData into the ChallengeParam
     CryptoBuffer challengeParam;
-    if (!appParam.SetLength(SHA256_LENGTH, fallible) ||
-        !challengeParam.SetLength(SHA256_LENGTH, fallible)) {
-      ReturnError(ErrorCode::OTHER_ERROR);
-      return NS_ERROR_FAILURE;
-    }
-
-    srv = PK11_HashBuf(SEC_OID_SHA256, appParam.Elements(),
-                       reinterpret_cast<const uint8_t*>(cAppId.BeginReading()),
-                       cAppId.Length());
-    if (srv != SECSuccess) {
+    if (!challengeParam.SetLength(SHA256_LENGTH, fallible)) {
       ReturnError(ErrorCode::OTHER_ERROR);
       return NS_ERROR_FAILURE;
     }
 
     srv = PK11_HashBuf(SEC_OID_SHA256, challengeParam.Elements(),
                        clientData.Elements(), clientData.Length());
     if (srv != SECSuccess) {
       ReturnError(ErrorCode::OTHER_ERROR);