Merge mozilla-inbound to mozilla-central a=merge
authorRazvan Maries <rmaries@mozilla.com>
Fri, 02 Aug 2019 06:50:08 +0300
changeset 485834 4748c006ae7b7711a5f0c62459b5ce906b1a47f4
parent 485825 22bda3da7ce3439a1ccafce4753ad59ad098bddc (current diff)
parent 485833 7acf0e8d6a667761882ea445e22cf6e3b4abbb72 (diff)
child 485835 b5f2fa86e69682a8cf1571f478c31c9afb26fba1
child 485862 13205fb92ec8c5e6d304409cf0ae80757615690b
push id36374
push userrmaries@mozilla.com
push dateFri, 02 Aug 2019 03:53:17 +0000
treeherdermozilla-central@4748c006ae7b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone70.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-inbound to mozilla-central a=merge
dom/media/encoder/EncodedFrame.h
js/xpconnect/tests/mochitest/mochitest.ini
--- a/devtools/server/tests/unit/head_dbg.js
+++ b/devtools/server/tests/unit/head_dbg.js
@@ -920,34 +920,38 @@ async function setupTestFromUrl(url) {
  *           principals by default.
  *        - ThreadFront threadFront
  *          A reference to a ThreadFront instance that is attached to the debuggee.
  *        - DebuggerClient client
  *          A reference to the DebuggerClient used to communicated with the RDP server.
  * @param Object options
  *        Optional arguments to tweak test environment
  *        - JSPrincipal principal
- *          Principal to use for the debuggee.
+ *          Principal to use for the debuggee. Defaults to systemPrincipal.
  *        - boolean doNotRunWorker
- *          If true, do not run this tests in worker debugger context.
+ *          If true, do not run this tests in worker debugger context. Defaults to false.
+ *        - bool wantXrays
+ *          Whether the debuggee wants Xray vision with respect to same-origin objects
+ *          outside the sandbox. Defaults to true.
  */
 function threadFrontTest(test, options = {}) {
-  let { principal, doNotRunWorker } = options;
-  if (!principal) {
-    principal = systemPrincipal;
-  }
+  const {
+    principal = systemPrincipal,
+    doNotRunWorker = false,
+    wantXrays = true,
+  } = options;
 
   async function runThreadFrontTestWithServer(server, test) {
     // Setup a server and connect a client to it.
     initTestDebuggerServer(server);
 
     // Create a custom debuggee and register it to the server.
     // We are using a custom Sandbox as debuggee. Create a new zone because
     // debugger and debuggee must be in different compartments.
-    const debuggee = Cu.Sandbox(principal, { freshZone: true });
+    const debuggee = Cu.Sandbox(principal, { freshZone: true, wantXrays });
     const scriptName = "debuggee.js";
     debuggee.__name = scriptName;
     server.addTestGlobal(debuggee);
 
     const client = new DebuggerClient(server.connectPipe());
     await client.connect();
 
     // Attach to the fake tab target and retrieve the ThreadFront instance.
--- a/devtools/server/tests/unit/test_objectgrips-17.js
+++ b/devtools/server/tests/unit/test_objectgrips-17.js
@@ -7,38 +7,38 @@
 Services.prefs.setBoolPref("security.allow_eval_with_system_principal", true);
 
 registerCleanupFunction(() => {
   Services.prefs.clearUserPref("security.allow_eval_with_system_principal");
 });
 
 async function testPrincipal(options, globalPrincipal, debuggeeHasXrays) {
   const { debuggee } = options;
-  let global, subsumes, isOpaque, globalIsInvisible;
   // Create a global object with the specified security principal.
   // If none is specified, use the debuggee.
   if (globalPrincipal === undefined) {
-    global = debuggee;
-    subsumes = true;
-    isOpaque = false;
-    globalIsInvisible = false;
-    await test(options, { global, subsumes, isOpaque, globalIsInvisible });
+    await test(options, {
+      global: debuggee,
+      subsumes: true,
+      isOpaque: false,
+      globalIsInvisible: false,
+    });
     return;
   }
 
   const debuggeePrincipal = Cu.getObjectPrincipal(debuggee);
-  const sameOrigin = debuggeePrincipal === globalPrincipal;
-  subsumes = sameOrigin || debuggeePrincipal === systemPrincipal;
+  const sameOrigin = debuggeePrincipal.origin === globalPrincipal.origin;
+  const subsumes = debuggeePrincipal.subsumes(globalPrincipal);
   for (const globalHasXrays of [true, false]) {
-    isOpaque =
+    const isOpaque =
       subsumes &&
       globalPrincipal !== systemPrincipal &&
       ((sameOrigin && debuggeeHasXrays) || globalHasXrays);
-    for (globalIsInvisible of [true, false]) {
-      global = Cu.Sandbox(globalPrincipal, {
+    for (const globalIsInvisible of [true, false]) {
+      let global = Cu.Sandbox(globalPrincipal, {
         wantXrays: globalHasXrays,
         invisibleToDebugger: globalIsInvisible,
       });
       // Previously, the Sandbox constructor would (bizarrely) waive xrays on
       // the return Sandbox if wantXrays was false. This has now been fixed,
       // but we need to mimic that behavior here to make the test continue
       // to pass.
       if (!globalHasXrays) {
@@ -273,16 +273,20 @@ function check_prototype(
       proto
     );
   } else {
     // The debuggee is not allowed to access the object. It sees a null prototype.
     strictEqual(proto.type, "null", "The prototype is null.");
   }
 }
 
+function createNullPrincipal() {
+  return Cc["@mozilla.org/nullprincipal;1"].createInstance(Ci.nsIPrincipal);
+}
+
 async function run_tests_in_principal(
   options,
   debuggeePrincipal,
   debuggeeHasXrays
 ) {
   const { debuggee } = options;
   debuggee.eval(
     function stopMe(arg1, arg2) {
@@ -292,57 +296,26 @@ async function run_tests_in_principal(
 
   // Test objects created in the debuggee.
   await testPrincipal(options, undefined, debuggeeHasXrays);
 
   // Test objects created in a system principal new global.
   await testPrincipal(options, systemPrincipal, debuggeeHasXrays);
 
   // Test objects created in a cross-origin null principal new global.
-  await testPrincipal(options, null, debuggeeHasXrays);
+  await testPrincipal(options, createNullPrincipal(), debuggeeHasXrays);
 
-  if (debuggeePrincipal === null) {
-    // Test objects created in a same-origin null principal new global.
-    await testPrincipal(
-      options,
-      Cu.getObjectPrincipal(debuggee),
-      debuggeeHasXrays
-    );
+  if (debuggeePrincipal != systemPrincipal) {
+    // Test objects created in a same-origin principal new global.
+    await testPrincipal(options, debuggeePrincipal, debuggeeHasXrays);
   }
 }
 
-// threadFrontTest uses systemPrincipal by default, but let's be explicit here.
-add_task(
-  threadFrontTest(
-    options => {
-      return run_tests_in_principal(options, systemPrincipal, true);
-    },
-    { principal: systemPrincipal, wantXrays: true }
-  )
-);
-add_task(
-  threadFrontTest(
-    options => {
-      return run_tests_in_principal(options, systemPrincipal, false);
-    },
-    { principal: systemPrincipal, wantXrays: false }
-  )
-);
-
-const nullPrincipal = Cc["@mozilla.org/nullprincipal;1"].createInstance(
-  Ci.nsIPrincipal
-);
-add_task(
-  threadFrontTest(
-    options => {
-      return run_tests_in_principal(options, nullPrincipal, true);
-    },
-    { principal: nullPrincipal, wantXrays: true }
-  )
-);
-add_task(
-  threadFrontTest(
-    options => {
-      return run_tests_in_principal(options, nullPrincipal, false);
-    },
-    { principal: nullPrincipal, wantXrays: false }
-  )
-);
+for (const principal of [systemPrincipal, createNullPrincipal()]) {
+  for (const wantXrays of [true, false]) {
+    add_task(
+      threadFrontTest(
+        options => run_tests_in_principal(options, principal, wantXrays),
+        { principal, wantXrays }
+      )
+    );
+  }
+}
--- a/docshell/base/BrowsingContext.cpp
+++ b/docshell/base/BrowsingContext.cpp
@@ -524,21 +524,57 @@ BrowsingContext* BrowsingContext::FindWi
             child->FindWithNameInSubtree(aName, aRequestingContext)) {
       return found;
     }
   }
 
   return nullptr;
 }
 
-bool BrowsingContext::CanAccess(BrowsingContext* aContext) {
-  // TODO(farre): Bouncing this to nsDocShell::CanAccessItem is
-  // temporary, we should implement a replacement for this in
-  // BrowsingContext. See Bug 151590.
-  return aContext && nsDocShell::CanAccessItem(aContext->mDocShell, mDocShell);
+// For historical context, see:
+//
+// Bug 13871:   Prevent frameset spoofing
+// Bug 103638:  Targets with same name in different windows open in wrong
+//              window with javascript
+// Bug 408052:  Adopt "ancestor" frame navigation policy
+// Bug 1570207: Refactor logic to rely on BrowsingContextGroups to enforce
+//              origin attribute isolation.
+bool BrowsingContext::CanAccess(BrowsingContext* aTarget,
+                                bool aConsiderOpener) {
+  MOZ_ASSERT(
+      mDocShell,
+      "CanAccess() may only be called in the process of the accessing window");
+  MOZ_ASSERT(aTarget, "Must have a target");
+
+  MOZ_DIAGNOSTIC_ASSERT(
+      Group() == aTarget->Group(),
+      "A BrowsingContext should never see a context from a different group");
+
+  // A frame can navigate itself and its own root.
+  if (aTarget == this || aTarget == Top()) {
+    return true;
+  }
+
+  // A frame can navigate any frame with a same-origin ancestor.
+  for (BrowsingContext* bc = aTarget; bc; bc = bc->GetParent()) {
+    if (bc->mDocShell &&
+        nsDocShell::ValidateOrigin(mDocShell, bc->mDocShell)) {
+      return true;
+    }
+  }
+
+  // If the target is a top-level document, a frame can navigate it if it can
+  // navigate its opener.
+  if (aConsiderOpener && !aTarget->GetParent()) {
+    if (RefPtr<BrowsingContext> opener = aTarget->GetOpener()) {
+      return CanAccess(opener, false);
+    }
+  }
+
+  return false;
 }
 
 BrowsingContext::~BrowsingContext() {
   MOZ_DIAGNOSTIC_ASSERT(!mParent || !mParent->mChildren.Contains(this));
   MOZ_DIAGNOSTIC_ASSERT(!mGroup || !mGroup->Toplevels().Contains(this));
   MOZ_DIAGNOSTIC_ASSERT(!mGroup || !mGroup->IsContextCached(this));
 
   if (sBrowsingContexts) {
--- a/docshell/base/BrowsingContext.h
+++ b/docshell/base/BrowsingContext.h
@@ -376,16 +376,19 @@ class BrowsingContext : public nsWrapper
   // Create an IPCInitializer object for this BrowsingContext.
   IPCInitializer GetIPCInitializer();
 
   // Create a BrowsingContext object from over IPC.
   static already_AddRefed<BrowsingContext> CreateFromIPC(
       IPCInitializer&& aInitializer, BrowsingContextGroup* aGroup,
       ContentParent* aOriginProcess);
 
+  // Performs access control to check that 'this' can access 'aTarget'.
+  bool CanAccess(BrowsingContext* aTarget, bool aConsiderOpener = true);
+
  protected:
   virtual ~BrowsingContext();
   BrowsingContext(BrowsingContext* aParent, BrowsingContextGroup* aGroup,
                   uint64_t aBrowsingContextId, Type aType);
 
  private:
   // Find the special browsing context if aName is '_self', '_parent',
   // '_top', but not '_blank'. The latter is handled in FindWithName
@@ -393,19 +396,16 @@ class BrowsingContext : public nsWrapper
 
   // Find a browsing context in the subtree rooted at 'this' Doesn't
   // consider the special names, '_self', '_parent', '_top', or
   // '_blank'. Performs access control with regard to
   // 'aRequestingContext'.
   BrowsingContext* FindWithNameInSubtree(const nsAString& aName,
                                          BrowsingContext* aRequestingContext);
 
-  // Performs access control to check that 'this' can access 'aContext'.
-  bool CanAccess(BrowsingContext* aContext);
-
   // Removes the context from its group and sets mIsDetached to true.
   void Unregister();
 
   friend class ::nsOuterWindowProxy;
   friend class ::nsGlobalWindowOuter;
   // Update the window proxy object that corresponds to this browsing context.
   // This should be called from the window proxy object's objectMoved hook, if
   // the object mWindowProxy points to was moved by the JS GC.
--- a/docshell/base/LoadContext.cpp
+++ b/docshell/base/LoadContext.cpp
@@ -143,27 +143,16 @@ NS_IMETHODIMP
 LoadContext::SetRemoteSubframes(bool aUseRemoteSubframes) {
   MOZ_ASSERT(mIsNotNull);
 
   // We shouldn't need this on parent...
   return NS_ERROR_UNEXPECTED;
 }
 
 NS_IMETHODIMP
-LoadContext::GetIsInIsolatedMozBrowserElement(
-    bool* aIsInIsolatedMozBrowserElement) {
-  MOZ_ASSERT(mIsNotNull);
-
-  NS_ENSURE_ARG_POINTER(aIsInIsolatedMozBrowserElement);
-
-  *aIsInIsolatedMozBrowserElement = mOriginAttributes.mInIsolatedMozBrowser;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 LoadContext::GetScriptableOriginAttributes(JSContext* aCx,
                                            JS::MutableHandleValue aAttrs) {
   bool ok = ToJSValue(aCx, mOriginAttributes, aAttrs);
   NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
   return NS_OK;
 }
 
 NS_IMETHODIMP_(void)
--- a/docshell/base/LoadContext.h
+++ b/docshell/base/LoadContext.h
@@ -28,34 +28,30 @@ namespace mozilla {
  */
 
 class LoadContext final : public nsILoadContext, public nsIInterfaceRequestor {
  public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSILOADCONTEXT
   NS_DECL_NSIINTERFACEREQUESTOR
 
-  // inIsolatedMozBrowser argumentsoverrides that in
-  // SerializedLoadContext provided by child process.
   LoadContext(const IPC::SerializedLoadContext& aToCopy,
               dom::Element* aTopFrameElement, OriginAttributes& aAttrs)
       : mTopFrameElement(do_GetWeakReference(aTopFrameElement)),
         mNestedFrameId(0),
         mIsContent(aToCopy.mIsContent),
         mUseRemoteTabs(aToCopy.mUseRemoteTabs),
         mUseRemoteSubframes(aToCopy.mUseRemoteSubframes),
         mUseTrackingProtection(aToCopy.mUseTrackingProtection),
 #ifdef DEBUG
         mIsNotNull(aToCopy.mIsNotNull),
 #endif
         mOriginAttributes(aAttrs) {
   }
 
-  // inIsolatedMozBrowser argument overrides that in
-  // SerializedLoadContext provided by child process.
   LoadContext(const IPC::SerializedLoadContext& aToCopy,
               uint64_t aNestedFrameId, OriginAttributes& aAttrs)
       : mTopFrameElement(nullptr),
         mNestedFrameId(aNestedFrameId),
         mIsContent(aToCopy.mIsContent),
         mUseRemoteTabs(aToCopy.mUseRemoteTabs),
         mUseRemoteSubframes(aToCopy.mUseRemoteSubframes),
         mUseTrackingProtection(aToCopy.mUseTrackingProtection),
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -251,21 +251,16 @@ static NS_DEFINE_CID(kAppShellCID, NS_AP
 static int32_t gNumberOfDocumentsLoading = 0;
 
 // Global count of existing docshells.
 static int32_t gDocShellCount = 0;
 
 // Global count of docshells with the private attribute set
 static uint32_t gNumberOfPrivateDocShells = 0;
 
-// True means we validate window targets to prevent frameset
-// spoofing. Initialize this to a non-bolean value so we know to check
-// the pref on the creation of the first docshell.
-static uint32_t gValidateOrigin = 0xffffffff;
-
 #ifdef DEBUG
 static mozilla::LazyLogModule gDocShellLog("nsDocShell");
 #endif
 static mozilla::LazyLogModule gDocShellLeakLog("nsDocShellLeak");
 extern mozilla::LazyLogModule gPageCacheLog;
 
 const char kBrandBundleURL[] = "chrome://branding/locale/brand.properties";
 const char kAppstringsBundleURL[] =
@@ -2842,159 +2837,31 @@ nsDocShell::GetSameTypeRootTreeItemIgnor
 }
 
 /* static */
 bool nsDocShell::CanAccessItem(nsIDocShellTreeItem* aTargetItem,
                                nsIDocShellTreeItem* aAccessingItem,
                                bool aConsiderOpener) {
   MOZ_ASSERT(aTargetItem, "Must have target item!");
 
-  if (!gValidateOrigin || !aAccessingItem) {
+  if (!aAccessingItem) {
     // Good to go
     return true;
   }
 
-  // XXXbz should we care if aAccessingItem or the document therein is
-  // chrome?  Should those get extra privileges?
-
-  // For historical context, see:
-  //
-  // Bug 13871:  Prevent frameset spoofing
-  // Bug 103638: Targets with same name in different windows open in wrong
-  //             window with javascript
-  // Bug 408052: Adopt "ancestor" frame navigation policy
-
-  // Now do a security check.
-  //
-  // Disallow navigation if the two frames are not part of the same app, or if
-  // they have different is-in-browser-element states.
-  //
-  // Allow navigation if
-  //  1) aAccessingItem can script aTargetItem or one of its ancestors in
-  //     the frame hierarchy or
-  //  2) aTargetItem is a top-level frame and aAccessingItem is its descendant
-  //  3) aTargetItem is a top-level frame and aAccessingItem can target
-  //     its opener per rule (1) or (2).
-
-  if (aTargetItem == aAccessingItem) {
-    // A frame is allowed to navigate itself.
-    return true;
-  }
-
   nsCOMPtr<nsIDocShell> targetDS = do_QueryInterface(aTargetItem);
   nsCOMPtr<nsIDocShell> accessingDS = do_QueryInterface(aAccessingItem);
   if (!targetDS || !accessingDS) {
     // We must be able to convert both to nsIDocShell.
     return false;
   }
 
-  if (targetDS->GetIsInIsolatedMozBrowserElement() !=
-      accessingDS->GetIsInIsolatedMozBrowserElement()) {
-    return false;
-  }
-
-  nsCOMPtr<nsIDocShellTreeItem> accessingRoot;
-  aAccessingItem->GetInProcessSameTypeRootTreeItem(
-      getter_AddRefs(accessingRoot));
-  nsCOMPtr<nsIDocShell> accessingRootDS = do_QueryInterface(accessingRoot);
-
-  nsCOMPtr<nsIDocShellTreeItem> targetRoot;
-  aTargetItem->GetInProcessSameTypeRootTreeItem(getter_AddRefs(targetRoot));
-  nsCOMPtr<nsIDocShell> targetRootDS = do_QueryInterface(targetRoot);
-
-  OriginAttributes targetOA =
-      static_cast<nsDocShell*>(targetDS.get())->GetOriginAttributes();
-  OriginAttributes accessingOA =
-      static_cast<nsDocShell*>(accessingDS.get())->GetOriginAttributes();
-
-  // When the first party isolation is on, the top-level docShell may not have
-  // the firstPartyDomain in its originAttributes, but its document will have
-  // it. So we get the firstPartyDomain from the nodePrincipal of the document
-  // before we compare the originAttributes.
-  if (OriginAttributes::IsFirstPartyEnabled()) {
-    if (aAccessingItem->ItemType() == nsIDocShellTreeItem::typeContent &&
-        (accessingDS == accessingRootDS || accessingDS->GetIsMozBrowser())) {
-      RefPtr<Document> accessingDoc = aAccessingItem->GetDocument();
-
-      if (accessingDoc) {
-        nsCOMPtr<nsIPrincipal> accessingPrincipal =
-            accessingDoc->NodePrincipal();
-
-        accessingOA.mFirstPartyDomain =
-            accessingPrincipal->OriginAttributesRef().mFirstPartyDomain;
-      }
-    }
-
-    if (aTargetItem->ItemType() == nsIDocShellTreeItem::typeContent &&
-        (targetDS == targetRootDS || targetDS->GetIsMozBrowser())) {
-      RefPtr<Document> targetDoc = aAccessingItem->GetDocument();
-
-      if (targetDoc) {
-        nsCOMPtr<nsIPrincipal> targetPrincipal = targetDoc->NodePrincipal();
-
-        targetOA.mFirstPartyDomain =
-            targetPrincipal->OriginAttributesRef().mFirstPartyDomain;
-      }
-    }
-  }
-
-  if (targetOA != accessingOA) {
-    return false;
-  }
-
-  // A private document can't access a non-private one, and vice versa.
-  if (static_cast<nsDocShell*>(targetDS.get())->UsePrivateBrowsing() !=
-      static_cast<nsDocShell*>(accessingDS.get())->UsePrivateBrowsing()) {
-    return false;
-  }
-
-  if (aTargetItem == accessingRoot) {
-    // A frame can navigate its root.
-    return true;
-  }
-
-  // Check if aAccessingItem can navigate one of aTargetItem's ancestors.
-  nsCOMPtr<nsIDocShellTreeItem> target = aTargetItem;
-  do {
-    if (ValidateOrigin(aAccessingItem, target)) {
-      return true;
-    }
-
-    nsCOMPtr<nsIDocShellTreeItem> parent;
-    target->GetInProcessSameTypeParent(getter_AddRefs(parent));
-    parent.swap(target);
-  } while (target);
-
-  if (aTargetItem != targetRoot) {
-    // target is a subframe, not in accessor's frame hierarchy, and all its
-    // ancestors have origins different from that of the accessor. Don't
-    // allow access.
-    return false;
-  }
-
-  if (!aConsiderOpener) {
-    // All done here
-    return false;
-  }
-
-  nsCOMPtr<nsPIDOMWindowOuter> targetWindow = aTargetItem->GetWindow();
-  if (!targetWindow) {
-    NS_ERROR("This should not happen, really");
-    return false;
-  }
-
-  nsCOMPtr<mozIDOMWindowProxy> targetOpener = targetWindow->GetOpener();
-  nsCOMPtr<nsIWebNavigation> openerWebNav(do_GetInterface(targetOpener));
-  nsCOMPtr<nsIDocShellTreeItem> openerItem(do_QueryInterface(openerWebNav));
-
-  if (!openerItem) {
-    return false;
-  }
-
-  return CanAccessItem(openerItem, aAccessingItem, false);
+  return Cast(accessingDS)
+      ->mBrowsingContext->CanAccess(Cast(targetDS)->mBrowsingContext,
+                                    aConsiderOpener);
 }
 
 static bool ItemIsActive(nsIDocShellTreeItem* aItem) {
   if (nsCOMPtr<nsPIDOMWindowOuter> window = aItem->GetWindow()) {
     auto* win = nsGlobalWindowOuter::Cast(window);
     if (!win->GetClosedOuter()) {
       return true;
     }
@@ -4945,22 +4812,16 @@ nsDocShell::Create() {
   }
 
   NS_ASSERTION(mItemType == typeContent || mItemType == typeChrome,
                "Unexpected item type in docshell");
 
   NS_ENSURE_TRUE(Preferences::GetRootBranch(), NS_ERROR_FAILURE);
   mCreated = true;
 
-  if (gValidateOrigin == 0xffffffff) {
-    // Check pref to see if we should prevent frameset spoofing
-    gValidateOrigin =
-        Preferences::GetBool("browser.frame.validate_origin", true);
-  }
-
   mUseStrictSecurityChecks = Preferences::GetBool(
       "security.strict_security_checks.enabled", mUseStrictSecurityChecks);
 
   // Should we use XUL error pages instead of alerts if possible?
   mUseErrorPages = StaticPrefs::browser_xul_error_pages_enabled();
 
   mDisableMetaRefreshWhenInactive =
       Preferences::GetBool("browser.meta_refresh_when_inactive.disabled",
@@ -8620,20 +8481,18 @@ nsresult nsDocShell::CheckLoadingPermiss
   // this docshell. Even though we've done our best to hide windows
   // from code that doesn't have the right to access them, it's
   // still possible for an evil site to open a window and access
   // frames in the new window through window.frames[] (which is
   // allAccess for historic reasons), so we still need to do this
   // check on load.
   nsresult rv = NS_OK;
 
-  if (!gValidateOrigin || !IsFrame()) {
-    // Origin validation was turned off, or we're not a frame.
-    // Permit all loads.
-
+  if (!IsFrame()) {
+    // We're not a frame. Permit all loads.
     return rv;
   }
 
   // Note - The check for a current JSContext here isn't necessarily sensical.
   // It's just designed to preserve the old semantics during a mass-conversion
   // patch.
   if (!nsContentUtils::GetCurrentJSContext()) {
     return NS_OK;
@@ -13192,37 +13051,16 @@ uint32_t nsDocShell::GetInheritedFrameTy
   if (!parent) {
     return FRAME_TYPE_REGULAR;
   }
 
   return static_cast<nsDocShell*>(parent.get())->GetInheritedFrameType();
 }
 
 /* [infallible] */
-NS_IMETHODIMP nsDocShell::GetIsIsolatedMozBrowserElement(
-    bool* aIsIsolatedMozBrowserElement) {
-  bool result = mFrameType == FRAME_TYPE_BROWSER &&
-                mOriginAttributes.mInIsolatedMozBrowser;
-  *aIsIsolatedMozBrowserElement = result;
-  return NS_OK;
-}
-
-/* [infallible] */
-NS_IMETHODIMP nsDocShell::GetIsInIsolatedMozBrowserElement(
-    bool* aIsInIsolatedMozBrowserElement) {
-  MOZ_ASSERT(!mOriginAttributes.mInIsolatedMozBrowser ||
-                 (GetInheritedFrameType() == FRAME_TYPE_BROWSER),
-             "Isolated mozbrowser should only be true inside browser frames");
-  bool result = (GetInheritedFrameType() == FRAME_TYPE_BROWSER) &&
-                mOriginAttributes.mInIsolatedMozBrowser;
-  *aIsInIsolatedMozBrowserElement = result;
-  return NS_OK;
-}
-
-/* [infallible] */
 NS_IMETHODIMP nsDocShell::GetIsInMozBrowser(bool* aIsInMozBrowser) {
   *aIsInMozBrowser = (GetInheritedFrameType() == FRAME_TYPE_BROWSER);
   return NS_OK;
 }
 
 /* [infallible] */
 NS_IMETHODIMP nsDocShell::GetIsTopLevelContentDocShell(
     bool* aIsTopLevelContentDocShell) {
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -728,44 +728,16 @@ interface nsIDocShell : nsIDocShellTreeI
 
   /**
    * Returns true if this docshell corresponds to an <iframe mozbrowser>.
    * <xul:browser> returns false here.
    */
   [infallible] readonly attribute boolean isMozBrowser;
 
   /**
-   * Returns true if this docshell corresponds to an isolated <iframe
-   * mozbrowser>.
-   *
-   * <xul:browser> is not considered to be a mozbrowser element.
-   * <iframe mozbrowser noisolation> does not count as isolated since
-   * isolation is disabled.  Isolation can only be disabled if the
-   * containing document is chrome.
-   */
-  [infallible] readonly attribute boolean isIsolatedMozBrowserElement;
-
-  /**
-   * Returns true if this docshell corresponds to an isolated <iframe
-   * mozbrowser> or if the docshell is contained in an isolated <iframe
-   * mozbrowser>.
-   *
-   * <xul:browser> is not considered to be a mozbrowser element. <iframe
-   * mozbrowser noisolation> does not count as isolated since isolation is
-   * disabled.  Isolation can only be disabled if the containing document is
-   * chrome.
-   *
-   * Our notion here of "contained in" means: Walk up the docshell hierarchy in
-   * this process until we hit an <iframe mozbrowser> (or until the hierarchy
-   * ends).  Return true iff the docshell we stopped on has
-   * isIsolatedMozBrowserElement == true.
-   */
-  [infallible] readonly attribute boolean isInIsolatedMozBrowserElement;
-
-  /**
    * Returns true if this docshell corresponds to an <iframe mozbrowser>, or
    * if this docshell is contained in an <iframe mozbrowser>. <xul:browser>
    * returns false here.
    *
    * To compute this value, we walk up the docshell hierarchy.  If we encounter
    * a docshell with isMozBrowser before we hit the end of the hierarchy,
    * we return true.  Otherwise, we return false.
    */
--- a/docshell/base/nsILoadContext.idl
+++ b/docshell/base/nsILoadContext.idl
@@ -136,25 +136,16 @@ interface nsILoadContext : nsISupports
   [noscript] void SetRemoteTabs(in boolean aUseRemoteTabs);
 
   /**
    * Set the remote subframes bit of this load context. Exclusively meant to be used internally.
    */
   [noscript] void SetRemoteSubframes(in boolean aUseRemoteSubframes);
 
   /**
-   * Returns true iff the load is occurring inside an isolated mozbrowser
-   * element. <xul:browser> is not considered to be a mozbrowser element.
-   * <iframe mozbrowser noisolation> does not count as isolated since
-   * isolation is disabled.  Isolation can only be disabled if the
-   * containing document is chrome.
-   */
-  readonly attribute boolean isInIsolatedMozBrowserElement;
-
-  /**
    * A dictionary of the non-default origin attributes associated with this
    * nsILoadContext.
    */
   [binaryname(ScriptableOriginAttributes), implicit_jscontext]
   readonly attribute jsval originAttributes;
 
   /**
    * The C++ getter for origin attributes.
--- a/dom/base/PostMessageEvent.cpp
+++ b/dom/base/PostMessageEvent.cpp
@@ -112,20 +112,16 @@ PostMessageEvent::Run() {
     //       be compliant while being safer.
     if (!targetPrin->Equals(mProvidedPrincipal)) {
       OriginAttributes sourceAttrs = mProvidedPrincipal->OriginAttributesRef();
       OriginAttributes targetAttrs = targetPrin->OriginAttributesRef();
 
       MOZ_DIAGNOSTIC_ASSERT(
           sourceAttrs.mUserContextId == targetAttrs.mUserContextId,
           "Target and source should have the same userContextId attribute.");
-      MOZ_DIAGNOSTIC_ASSERT(sourceAttrs.mInIsolatedMozBrowser ==
-                                targetAttrs.mInIsolatedMozBrowser,
-                            "Target and source should have the same "
-                            "inIsolatedMozBrowser attribute.");
 
       nsAutoString providedOrigin, targetOrigin;
       nsresult rv = nsContentUtils::GetUTFOrigin(targetPrin, targetOrigin);
       NS_ENSURE_SUCCESS(rv, rv);
       rv = nsContentUtils::GetUTFOrigin(mProvidedPrincipal, providedOrigin);
       NS_ENSURE_SUCCESS(rv, rv);
 
       nsAutoString errorText;
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -1139,21 +1139,16 @@ nsresult nsFrameLoader::SwapWithOtherRem
 
   auto* browserParent = GetBrowserParent();
   auto* otherBrowserParent = aOther->GetBrowserParent();
 
   if (!browserParent || !otherBrowserParent) {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 
-  if (browserParent->IsIsolatedMozBrowserElement() !=
-      otherBrowserParent->IsIsolatedMozBrowserElement()) {
-    return NS_ERROR_NOT_IMPLEMENTED;
-  }
-
   // When we swap docShells, maybe we have to deal with a new page created just
   // for this operation. In this case, the browser code should already have set
   // the correct userContextId attribute value in the owning element, but our
   // docShell, that has been created way before) doesn't know that that
   // happened.
   // This is the reason why now we must retrieve the correct value from the
   // usercontextid attribute before comparing our originAttributes with the
   // other one.
@@ -1545,21 +1540,16 @@ nsresult nsFrameLoader::SwapWithOtherLoa
   NS_ASSERTION(otherDoc == otherParentDocument, "Unexpected parent document");
 
   PresShell* ourPresShell = ourDoc->GetPresShell();
   PresShell* otherPresShell = otherDoc->GetPresShell();
   if (!ourPresShell || !otherPresShell) {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 
-  if (ourDocshell->GetIsIsolatedMozBrowserElement() !=
-      otherDocshell->GetIsIsolatedMozBrowserElement()) {
-    return NS_ERROR_NOT_IMPLEMENTED;
-  }
-
   // When we swap docShells, maybe we have to deal with a new page created just
   // for this operation. In this case, the browser code should already have set
   // the correct userContextId attribute value in the owning element, but our
   // docShell, that has been created way before) doesn't know that that
   // happened.
   // This is the reason why now we must retrieve the correct value from the
   // usercontextid attribute before comparing our originAttributes with the
   // other one.
@@ -1954,34 +1944,16 @@ void nsFrameLoader::SetOwnerContent(Elem
   }
 }
 
 bool nsFrameLoader::OwnerIsMozBrowserFrame() {
   nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
   return browserFrame ? browserFrame->GetReallyIsBrowser() : false;
 }
 
-bool nsFrameLoader::OwnerIsIsolatedMozBrowserFrame() {
-  nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
-  if (!browserFrame) {
-    return false;
-  }
-
-  if (!OwnerIsMozBrowserFrame()) {
-    return false;
-  }
-
-  bool isolated = browserFrame->GetIsolated();
-  if (isolated) {
-    return true;
-  }
-
-  return false;
-}
-
 bool nsFrameLoader::ShouldUseRemoteProcess() {
   if (PR_GetEnv("MOZ_DISABLE_OOP_TABS") ||
       Preferences::GetBool("dom.ipc.tabs.disabled", false)) {
     return false;
   }
 
   // Don't try to launch nested children if we don't have OMTC.
   // They won't render!
@@ -2166,28 +2138,24 @@ nsresult nsFrameLoader::MaybeCreateDocSh
     // Assert on the firstPartyDomain from top-level docshell should be empty
     MOZ_ASSERT_IF(mIsTopLevelContent, attrs.mFirstPartyDomain.IsEmpty());
 
     // So far we want to make sure Inherit doesn't override any other origin
     // attribute than firstPartyDomain.
     MOZ_ASSERT(
         attrs.mUserContextId == oa.mUserContextId,
         "docshell and document should have the same userContextId attribute.");
-    MOZ_ASSERT(attrs.mInIsolatedMozBrowser == oa.mInIsolatedMozBrowser,
-               "docshell and document should have the same "
-               "inIsolatedMozBrowser attribute.");
     MOZ_ASSERT(attrs.mPrivateBrowsingId == oa.mPrivateBrowsingId,
                "docshell and document should have the same privateBrowsingId "
                "attribute.");
 
     attrs = oa;
   }
 
   if (OwnerIsMozBrowserFrame()) {
-    attrs.mInIsolatedMozBrowser = OwnerIsIsolatedMozBrowserFrame();
     docShell->SetFrameType(nsIDocShell::FRAME_TYPE_BROWSER);
   } else {
     nsCOMPtr<nsIDocShellTreeItem> parentCheck;
     docShell->GetInProcessSameTypeParent(getter_AddRefs(parentCheck));
     if (!!parentCheck) {
       docShell->SetIsFrame();
     }
   }
@@ -3362,17 +3330,16 @@ void nsFrameLoader::MaybeUpdatePrimaryBr
         kNameSpaceID_None, nsGkAtoms::primary, nsGkAtoms::_true, eIgnoreCase);
     parentTreeOwner->RemoteTabAdded(browserHost, isPrimary);
   }
 }
 
 nsresult nsFrameLoader::GetNewTabContext(MutableTabContext* aTabContext,
                                          nsIURI* aURI) {
   OriginAttributes attrs;
-  attrs.mInIsolatedMozBrowser = OwnerIsIsolatedMozBrowserFrame();
   nsresult rv;
 
   // set the userContextId on the attrs before we pass them into
   // the tab context
   rv = PopulateUserContextIdFromAttribute(attrs);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoString presentationURLStr;
--- a/dom/base/nsFrameLoader.h
+++ b/dom/base/nsFrameLoader.h
@@ -401,25 +401,16 @@ class nsFrameLoader final : public nsStu
                 const mozilla::dom::RemotenessOptions& aOptions);
   ~nsFrameLoader();
 
   void SetOwnerContent(mozilla::dom::Element* aContent);
 
   bool ShouldUseRemoteProcess();
 
   /**
-   * Is this a frame loader for an isolated <iframe mozbrowser>?
-   *
-   * By default, mozbrowser frames are isolated.  Isolation can be disabled by
-   * setting the frame's noisolation attribute.  Disabling isolation is
-   * only allowed if the containing document is chrome.
-   */
-  bool OwnerIsIsolatedMozBrowserFrame();
-
-  /**
    * Get our owning element's app manifest URL, or return the empty string if
    * our owning element doesn't have an app manifest URL.
    */
   void GetOwnerAppManifestURL(nsAString& aOut);
 
   /**
    * If we are an IPC frame, set mRemoteFrame. Otherwise, create and
    * initialize mDocShell.
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -873,17 +873,16 @@ skip-if = fission && (debug || asan) # C
 [test_window_define_nonconfigurable.html]
 [test_window_define_symbol.html]
 [test_window_element_enumeration.html]
 [test_window_enumeration.html]
 [test_window_extensible.html]
 [test_window_indexing.html]
 [test_window_keys.html]
 [test_window_named_frame_enumeration.html]
-fail-if = fission
 skip-if = fission && (debug || asan) # Causes shutdown leaks under Fission.
 [test_window_own_props.html]
 [test_window_proto.html]
 [test_writable-replaceable.html]
 [test_x-frame-options.html]
 fail-if = fission
 skip-if = toolkit == 'android' && debug && !is_fennec
 [test_youtube_flash_embed.html]
--- a/dom/browser-element/mochitest/mochitest.ini
+++ b/dom/browser-element/mochitest/mochitest.ini
@@ -90,16 +90,17 @@ support-files =
 [test_browserElement_NoAttr.html]
 [test_browserElement_NoPref.html]
 [test_browserElement_NoPermission.html]
 [test_browserElement_inproc_Alert.html]
 [test_browserElement_inproc_Viewmode.html]
 [test_browserElement_inproc_ThemeColor.html]
 [test_browserElement_inproc_AlertInFrame.html]
 [test_browserElement_inproc_Auth.html]
+disabled = No longer supported
 [test_browserElement_inproc_BrowserWindowNamespace.html]
 [test_browserElement_inproc_BrowserWindowResize.html]
 [test_browserElement_inproc_Close.html]
 [test_browserElement_inproc_CloseFromOpener.html]
 [test_browserElement_inproc_ContextmenuEvents.html]
 [test_browserElement_inproc_CookiesNotThirdParty.html]
 [test_browserElement_inproc_CopyPaste.html]
 tags = clipboard
--- a/dom/html/nsGenericHTMLFrameElement.cpp
+++ b/dom/html/nsGenericHTMLFrameElement.cpp
@@ -417,29 +417,16 @@ bool nsGenericHTMLFrameElement::IsHTMLFo
  * permissions.)
  */
 /* [infallible] */
 nsresult nsGenericHTMLFrameElement::GetReallyIsBrowser(bool* aOut) {
   *aOut = mReallyIsBrowser;
   return NS_OK;
 }
 
-/* [infallible] */
-NS_IMETHODIMP nsGenericHTMLFrameElement::GetIsolated(bool* aOut) {
-  *aOut = true;
-
-  if (!nsContentUtils::IsSystemPrincipal(NodePrincipal())) {
-    return NS_OK;
-  }
-
-  // Isolation is only disabled if the attribute is present
-  *aOut = !HasAttr(kNameSpaceID_None, nsGkAtoms::noisolation);
-  return NS_OK;
-}
-
 NS_IMETHODIMP
 nsGenericHTMLFrameElement::InitializeBrowserAPI() {
   MOZ_ASSERT(mFrameLoader);
   InitBrowserElementAPI();
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/dom/interfaces/html/nsIMozBrowserFrame.idl
+++ b/dom/interfaces/html/nsIMozBrowserFrame.idl
@@ -17,30 +17,16 @@ interface nsIMozBrowserFrame : nsIDOMMoz
    *
    * In order to really be a browser frame, this frame's
    * nsIDOMMozBrowserFrame::mozbrowser attribute must be true, and the frame
    * may have to pass various security checks.
    */
   [infallible] readonly attribute boolean reallyIsBrowser;
 
   /**
-   * Gets whether this frame is an isolated frame.
-   *
-   * By default, browser frames are isolated, meaning they have a principal
-   * where OriginAttributes.mIsInIsolatedMozBrowser == true.  This isolates
-   * storage and other origin related items from non-browser apps, xul:browsers,
-   * etc.
-   *
-   * Isolation can be disabled by setting the frame's isolated attribute to
-   * false.  Disabling isolation is only allowed if the containing document has
-   * browser permission (or equivalent access).
-   */
-  [infallible] readonly attribute boolean isolated;
-
-  /**
    * Initialize the API, and add frame message listener that supports API
    * invocations.
    */
   [noscript] void initializeBrowserAPI();
 
   /**
    * Notify frame scripts that support the API to destroy.
    */
--- a/dom/ipc/BrowserBridgeParent.cpp
+++ b/dom/ipc/BrowserBridgeParent.cpp
@@ -35,19 +35,16 @@ BrowserBridgeParent::~BrowserBridgeParen
 nsresult BrowserBridgeParent::Init(const nsString& aPresentationURL,
                                    const nsString& aRemoteType,
                                    CanonicalBrowsingContext* aBrowsingContext,
                                    const uint32_t& aChromeFlags, TabId aTabId) {
   mIPCOpen = true;
 
   // We can inherit most TabContext fields for the new BrowserParent actor from
   // our Manager BrowserParent.
-  //
-  // We don't intend to support mozbrowsers with Fission currently, so we set
-  // |aMozBrowserElement| to be false.
   MutableTabContext tabContext;
   tabContext.SetTabContext(false, Manager()->ChromeOuterWindowID(),
                            Manager()->ShowFocusRings(),
                            Manager()->OriginAttributesRef(), aPresentationURL,
                            Manager()->GetMaxTouchPoints());
 
   ProcessPriority initialPriority = PROCESS_PRIORITY_FOREGROUND;
 
--- a/dom/ipc/BrowserParent.cpp
+++ b/dom/ipc/BrowserParent.cpp
@@ -3526,17 +3526,16 @@ class FakeChannel final : public nsIChan
     elem.forget(aElement);
     return NS_OK;
   }
   NS_IMETHOD GetNestedFrameId(uint64_t*) NO_IMPL;
   NS_IMETHOD GetIsContent(bool*) NO_IMPL;
   NS_IMETHOD GetUsePrivateBrowsing(bool*) NO_IMPL;
   NS_IMETHOD SetUsePrivateBrowsing(bool) NO_IMPL;
   NS_IMETHOD SetPrivateBrowsing(bool) NO_IMPL;
-  NS_IMETHOD GetIsInIsolatedMozBrowserElement(bool*) NO_IMPL;
   NS_IMETHOD GetScriptableOriginAttributes(JSContext*,
                                            JS::MutableHandleValue) NO_IMPL;
   NS_IMETHOD_(void)
   GetOriginAttributes(mozilla::OriginAttributes& aAttrs) override {}
   NS_IMETHOD GetUseRemoteTabs(bool*) NO_IMPL;
   NS_IMETHOD SetRemoteTabs(bool) NO_IMPL;
   NS_IMETHOD GetUseRemoteSubframes(bool*) NO_IMPL;
   NS_IMETHOD SetRemoteSubframes(bool) NO_IMPL;
--- a/dom/ipc/TabContext.cpp
+++ b/dom/ipc/TabContext.cpp
@@ -23,20 +23,16 @@ TabContext::TabContext()
       mIsMozBrowserElement(false),
       mChromeOuterWindowID(0),
       mJSPluginID(-1),
       mShowFocusRings(UIStateChangeType_NoChange),
       mMaxTouchPoints(0) {}
 
 bool TabContext::IsMozBrowserElement() const { return mIsMozBrowserElement; }
 
-bool TabContext::IsIsolatedMozBrowserElement() const {
-  return mOriginAttributes.mInIsolatedMozBrowser;
-}
-
 bool TabContext::IsMozBrowser() const { return IsMozBrowserElement(); }
 
 bool TabContext::IsJSPlugin() const { return mJSPluginID >= 0; }
 
 int32_t TabContext::JSPluginId() const { return mJSPluginID; }
 
 uint64_t TabContext::ChromeOuterWindowID() const {
   return mChromeOuterWindowID;
--- a/dom/ipc/TabContext.h
+++ b/dom/ipc/TabContext.h
@@ -42,25 +42,16 @@ class TabContext {
   /**
    * Does this TabContext correspond to a mozbrowser?
    *
    * <iframe mozbrowser> is a mozbrowser element, but <xul:browser> is not.
    */
   bool IsMozBrowserElement() const;
 
   /**
-   * Does this TabContext correspond to an isolated mozbrowser?
-   *
-   * <iframe mozbrowser> is a mozbrowser element, but <xul:browser> is not.
-   * <iframe mozbrowser noisolation> does not count as isolated since isolation
-   * is disabled.  Isolation can only be disabled by chrome pages.
-   */
-  bool IsIsolatedMozBrowserElement() const;
-
-  /**
    * Does this TabContext correspond to a mozbrowser?  This is equivalent to
    * IsMozBrowserElement().  Returns false for <xul:browser>, which isn't a
    * mozbrowser.
    */
   bool IsMozBrowser() const;
 
   bool IsJSPlugin() const;
   int32_t JSPluginId() const;
--- a/dom/tests/mochitest/dom-level0/mochitest.ini
+++ b/dom/tests/mochitest/dom-level0/mochitest.ini
@@ -8,25 +8,22 @@ support-files =
   idn_child.html
   innerWidthHeight_script.html
   iframe1_location_setters.html
   iframe2_location_setters.html
   iframe3_location_setters.html
   file_test_background_loading_iframes.html
 
 [test_crossdomainprops.html]
-skip-if = fission && debug # Crashes: @ nsDocShell::CanAccessItem(nsIDocShellTreeItem*, nsIDocShellTreeItem*, bool)
 [test_innerWidthHeight_script.html]
 [test_location.html]
 fail-if = fission
 [test_location_framed.html]
 [test_location_getters.html]
 [test_location_sandboxed.html]
 [test_location_setters.html]
 fail-if = fission
 [test_setting_document.domain_idn.html]
-skip-if = fission && debug # Crashes: @ nsDocShell::CanAccessItem(nsIDocShellTreeItem*, nsIDocShellTreeItem*, bool)
 fail-if = fission
+skip-if = fission && debug # Causes shutdown leaks under Fission.
 [test_setting_document.domain_to_shortened_ipaddr.html]
-skip-if = fission && debug # Crashes: @ nsDocShell::CanAccessItem(nsIDocShellTreeItem*, nsIDocShellTreeItem*, bool)
-fail-if = fission
 [test_separate_post_message_queue.html]
 [test_background_loading_iframes.html]
--- a/dom/tests/mochitest/localstorage/mochitest.ini
+++ b/dom/tests/mochitest/localstorage/mochitest.ini
@@ -22,17 +22,16 @@ support-files =
 [test_brokenUTF-16.html]
 [test_bug600307-DBOps.html]
 [test_bug746272-1.html]
 [test_bug746272-2.html]
 skip-if = os == "android" || verify # bug 962029
 [test_cookieBlock.html]
 [test_embededNulls.html]
 [test_keySync.html]
-skip-if = fission # Crashes: @ nsDocShell::CanAccessItem(nsIDocShellTreeItem*, nsIDocShellTreeItem*, bool)
 [test_localStorageBase.html]
 skip-if = e10s
 [test_localStorageBaseSessionOnly.html]
 [test_localStorageCookieSettings.html]
 skip-if = fission && debug # Crashes: @ std::_Function_handler<void (mozilla::Tuple<nsresult, mozilla::dom::PBrowserBridgeParent*>&&), mozilla::dom::WindowGlobalParent::ChangeFrameRemoteness(mozilla::dom::BrowsingContext*, nsTSubstring<char16_t> const&, unsigned long, mozilla::ErrorResult&)::$_2>::_M_invoke(std::_Any_data const&, mozilla::Tuple<nsresult, mozilla::dom::PBrowserBridgeParent*>&&)
 [test_localStorageEnablePref.html]
 [test_localStorageKeyOrder.html]
 [test_localStorageOriginsDiff.html]
@@ -42,19 +41,17 @@ skip-if = fission
 [test_localStorageOriginsEquals.html]
 skip-if = fission || toolkit == 'android'
 [test_localStorageOriginsPortDiffs.html]
 skip-if = fission
 [test_localStorageOriginsSchemaDiffs.html]
 skip-if = fission || toolkit == 'android' #TIMED_OUT
 [test_localStorageQuota.html]
 fail-if = fission
-skip-if =
-  toolkit == 'android' || #TIMED_OUT
-  fission && debug # Crashes: @ nsDocShell::CanAccessItem(nsIDocShellTreeItem*, nsIDocShellTreeItem*, bool)
+skip-if = toolkit == 'android' #TIMED_OUT
 [test_localStorageQuotaSessionOnly.html]
 skip-if = toolkit == 'android' || (verify && (os == 'linux' || os == 'mac' || os == 'win')) #TIMED_OUT
 [test_localStorageQuotaSessionOnly2.html]
 skip-if = true # bug 1347690
 [test_localStorageReplace.html]
 fail-if = fission
 skip-if = toolkit == 'android'
 [test_storageConstructor.html]
--- a/dom/tests/mochitest/sessionstorage/mochitest.ini
+++ b/dom/tests/mochitest/sessionstorage/mochitest.ini
@@ -9,15 +9,12 @@ support-files =
   interOriginTest.js
 
 [test_sessionStorageBase.html]
 [test_sessionStorageBaseSessionOnly.html]
 [test_sessionStorageClone.html]
 fail-if = fission
 skip-if = toolkit == 'android'
 [test_sessionStorageHttpHttps.html]
-fail-if = fission
-skip-if =
-  toolkit == 'android' || #TIMED_OUT
-  fission && debug # Crashes: @ nsDocShell::CanAccessItem(nsIDocShellTreeItem*, nsIDocShellTreeItem*, bool)
+skip-if = toolkit == 'android' #TIMED_OUT
 [test_sessionStorageReplace.html]
 fail-if = fission
 [test_sessionStorageUsage.html]
--- a/dom/tests/mochitest/whatwg/mochitest.ini
+++ b/dom/tests/mochitest/whatwg/mochitest.ini
@@ -22,34 +22,32 @@ skip-if = fission && debug # Causes shut
 [test_MessageEvent_dispatchToOther.html]
 skip-if = fission && (debug || asan) # Causes shutdown leaks under Fission.
 [test_MessageEvent.html]
 [test_postMessage_basehref.html]
 [test_postMessage_closed.html]
 skip-if = toolkit == 'android' #bug 894914 - wrong data - got FAIL, expected message
 [test_postMessage_hash.html]
 [test_postMessage.html]
-skip-if = fission && debug # Crashes: @ nsDocShell::CanAccessItem(nsIDocShellTreeItem*, nsIDocShellTreeItem*, bool)
 fail-if = fission
 [test_postMessage_idn.xhtml]
 fail-if = fission
 [test_postMessage_joined.html]
 fail-if = fission
 skip-if = fission && (debug || asan) # Causes shutdown leaks under Fission.
 [test_postMessage_onOther.html]
 fail-if = fission
 skip-if = fission && (debug || asan) # Causes shutdown leaks under Fission.
 [test_postMessage_origin.xhtml]
 fail-if = fission
 skip-if = fission && (debug || asan) # Causes shutdown leaks under Fission.
 [test_postMessage_override.html]
 skip-if = fission
 [test_postMessage_special.xhtml]
 [test_postMessage_structured_clone.html]
-skip-if = fission && debug # Crashes: @ nsDocShell::CanAccessItem(nsIDocShellTreeItem*, nsIDocShellTreeItem*, bool)
 fail-if = fission
 [test_postMessage_throw.html]
 fail-if = fission
 skip-if = fission && (debug || asan) # Causes shutdown leaks under Fission.
 [test_postMessage_transfer.html]
 fail-if = fission
 skip-if = fission && (debug || asan) # Causes shutdown leaks under Fission.
 [test_postMessage_userpass.html]
--- a/js/xpconnect/tests/mochitest/mochitest.ini
+++ b/js/xpconnect/tests/mochitest/mochitest.ini
@@ -94,17 +94,16 @@ fail-if = fission
 [test_bug862380.html]
 [test_bug865260.html]
 [test_bug870423.html]
 fail-if = fission
 skip-if = fission && (debug || asan) # Causes shutdown leaks under Fission.
 [test_bug871887.html]
 [test_bug912322.html]
 [test_bug916945.html]
-skip-if = fission && debug # Crashes: @ nsDocShell::CanAccessItem(nsIDocShellTreeItem*, nsIDocShellTreeItem*, bool)
 fail-if = fission
 [test_bug92773.html]
 [test_bug940783.html]
 fail-if = fission
 [test_bug965082.html]
 fail-if = fission
 skip-if = fission && webrender && debug # Crashes intermittently: @ nsDocShell::SetParentWidget(nsIWidget*)
 [test_bug960820.html]
--- a/netwerk/base/nsNetUtil.cpp
+++ b/netwerk/base/nsNetUtil.cpp
@@ -861,24 +861,17 @@ bool NS_LoadGroupMatchesPrincipal(nsILoa
     return false;
   }
 
   nsCOMPtr<nsILoadContext> loadContext;
   NS_QueryNotificationCallbacks(nullptr, aLoadGroup, NS_GET_IID(nsILoadContext),
                                 getter_AddRefs(loadContext));
   NS_ENSURE_TRUE(loadContext, false);
 
-  // Verify load context browser flag match the principal
-  bool contextInIsolatedBrowser;
-  nsresult rv =
-      loadContext->GetIsInIsolatedMozBrowserElement(&contextInIsolatedBrowser);
-  NS_ENSURE_SUCCESS(rv, false);
-
-  return contextInIsolatedBrowser ==
-         aPrincipal->GetIsInIsolatedMozBrowserElement();
+  return true;
 }
 
 nsresult NS_NewDownloader(nsIStreamListener** result,
                           nsIDownloadObserver* observer,
                           nsIFile* downloadLocation /* = nullptr */) {
   nsresult rv;
   nsCOMPtr<nsIDownloader> downloader =
       do_CreateInstance(NS_DOWNLOADER_CONTRACTID, &rv);
@@ -2996,40 +2989,28 @@ nsresult NS_CompareLoadInfoAndLoadContex
   // originAttributes between loadInfo and loadContext will be different.
   // That's why we have to skip the comparison for the favicon loading.
   if (nsContentUtils::IsSystemPrincipal(loadInfo->LoadingPrincipal()) &&
       loadInfo->InternalContentPolicyType() ==
           nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON) {
     return NS_OK;
   }
 
-  bool loadContextIsInBE = false;
-  nsresult rv =
-      loadContext->GetIsInIsolatedMozBrowserElement(&loadContextIsInBE);
-  if (NS_FAILED(rv)) {
-    return NS_ERROR_UNEXPECTED;
-  }
-
   OriginAttributes originAttrsLoadInfo = loadInfo->GetOriginAttributes();
   OriginAttributes originAttrsLoadContext;
   loadContext->GetOriginAttributes(originAttrsLoadContext);
 
   LOG(
-      ("NS_CompareLoadInfoAndLoadContext - loadInfo: %d, %d, %d; "
-       "loadContext: %d %d, %d. [channel=%p]",
-       originAttrsLoadInfo.mInIsolatedMozBrowser,
+      ("NS_CompareLoadInfoAndLoadContext - loadInfo: %d, %d; "
+       "loadContext: %d, %d. [channel=%p]",
        originAttrsLoadInfo.mUserContextId,
-       originAttrsLoadInfo.mPrivateBrowsingId, loadContextIsInBE,
+       originAttrsLoadInfo.mPrivateBrowsingId,
        originAttrsLoadContext.mUserContextId,
        originAttrsLoadContext.mPrivateBrowsingId, aChannel));
 
-  MOZ_ASSERT(originAttrsLoadInfo.mInIsolatedMozBrowser == loadContextIsInBE,
-             "The value of InIsolatedMozBrowser in the loadContext and in "
-             "the loadInfo are not the same!");
-
   MOZ_ASSERT(originAttrsLoadInfo.mUserContextId ==
                  originAttrsLoadContext.mUserContextId,
              "The value of mUserContextId in the loadContext and in the "
              "loadInfo are not the same!");
 
   MOZ_ASSERT(originAttrsLoadInfo.mPrivateBrowsingId ==
                  originAttrsLoadContext.mPrivateBrowsingId,
              "The value of mPrivateBrowsingId in the loadContext and in the "
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -2900,20 +2900,16 @@ already_AddRefed<nsILoadInfo> HttpBaseCh
     }
 
     OriginAttributes attrs = newLoadInfo->GetOriginAttributes();
 
     MOZ_ASSERT(
         docShellAttrs.mUserContextId == attrs.mUserContextId,
         "docshell and necko should have the same userContextId attribute.");
     MOZ_ASSERT(
-        docShellAttrs.mInIsolatedMozBrowser == attrs.mInIsolatedMozBrowser,
-        "docshell and necko should have the same inIsolatedMozBrowser "
-        "attribute.");
-    MOZ_ASSERT(
         docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId,
         "docshell and necko should have the same privateBrowsingId attribute.");
     MOZ_ASSERT(docShellAttrs.mGeckoViewSessionContextId ==
                  attrs.mGeckoViewSessionContextId,
                "docshell and necko should have the same "
                "geckoViewSessionContextId attribute");
 
     attrs = docShellAttrs;
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-a31fc0eefc4c
+009a7163c80a
--- a/security/nss/cmd/lib/secpwd.c
+++ b/security/nss/cmd/lib/secpwd.c
@@ -61,17 +61,17 @@ SEC_GetPassword(FILE *input, FILE *outpu
 #if defined(_WINDOWS)
     int isTTY = (input == stdin);
 #define echoOn(x)
 #define echoOff(x)
 #else
     int infd = fileno(input);
     int isTTY = isatty(infd);
 #endif
-    char phrase[200] = { '\0' }; /* ensure EOF doesn't return junk */
+    char phrase[500] = { '\0' }; /* ensure EOF doesn't return junk */
 
     for (;;) {
         /* Prompt for password */
         if (isTTY) {
             fprintf(output, "%s", prompt);
             fflush(output);
             echoOff(infd);
         }
--- a/security/nss/cmd/pk11mode/pk11mode.c
+++ b/security/nss/cmd/pk11mode/pk11mode.c
@@ -5224,17 +5224,17 @@ PKM_Digest(CK_FUNCTION_LIST_PTR pFunctio
     }
 
     return crv;
 }
 
 char *
 PKM_FilePasswd(char *pwFile)
 {
-    unsigned char phrase[200];
+    unsigned char phrase[500];
     PRFileDesc *fd;
     PRInt32 nb;
     int i;
 
     if (!pwFile)
         return 0;
 
     fd = PR_Open(pwFile, PR_RDONLY, 0);
--- a/security/nss/cmd/shlibsign/shlibsign.c
+++ b/security/nss/cmd/shlibsign/shlibsign.c
@@ -609,17 +609,17 @@ cleanup:
     }
 
     return crv;
 }
 
 static char *
 filePasswd(char *pwFile)
 {
-    unsigned char phrase[200];
+    unsigned char phrase[500];
     PRFileDesc *fd;
     PRInt32 nb;
     int i;
 
     if (!pwFile)
         return 0;
 
     fd = PR_Open(pwFile, PR_RDONLY, 0);
--- a/security/nss/coreconf/coreconf.dep
+++ b/security/nss/coreconf/coreconf.dep
@@ -5,9 +5,8 @@
 
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSS in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
-
--- a/security/nss/gtests/softoken_gtest/softoken_gtest.cc
+++ b/security/nss/gtests/softoken_gtest/softoken_gtest.cc
@@ -1,13 +1,14 @@
 #include "cert.h"
 #include "certdb.h"
 #include "nspr.h"
 #include "nss.h"
 #include "pk11pub.h"
+#include "secmod.h"
 #include "secerr.h"
 
 #include "nss_scoped_ptrs.h"
 #include "util.h"
 
 #define GTEST_HAS_RTTI 0
 #include "gtest/gtest.h"
 
@@ -114,16 +115,37 @@ TEST_F(SoftokenTest, CreateObjectChangeP
   EXPECT_EQ(SECSuccess, PK11_InitPin(slot.get(), nullptr, nullptr));
   EXPECT_EQ(SECSuccess, PK11_ChangePW(slot.get(), "", "password"));
   EXPECT_EQ(SECSuccess, PK11_Logout(slot.get()));
   ScopedPK11GenericObject obj(PK11_CreateGenericObject(
       slot.get(), attributes, PR_ARRAY_SIZE(attributes), true));
   EXPECT_EQ(nullptr, obj);
 }
 
+/* The size limit for a password is 500 characters as defined in pkcs11i.h */
+TEST_F(SoftokenTest, CreateObjectChangeToBigPassword) {
+  ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot());
+  ASSERT_TRUE(slot);
+  EXPECT_EQ(SECSuccess, PK11_InitPin(slot.get(), nullptr, nullptr));
+  EXPECT_EQ(
+      SECSuccess,
+      PK11_ChangePW(slot.get(), "",
+                    "rUIFIFr2bxKnbJbitsfkyqttpk6vCJzlYMNxcxXcaN37gSZKbLk763X7iR"
+                    "yeVNWZHQ02lSF69HYjzTyPW3318ZD0DBFMMbALZ8ZPZP73CIo5uIQlaowV"
+                    "IbP8eOhRYtGUqoLGlcIFNEYogV8Q3GN58VeBMs0KxrIOvPQ9s8SnYYkqvt"
+                    "zzgntmAvCgvk64x6eQf0okHwegd5wi6m0WVJytEepWXkP9J629FSa5kNT8"
+                    "FvL3jvslkiImzTNuTvl32fQDXXMSc8vVk5Q3mH7trMZM0VDdwHWYERjHbz"
+                    "kGxFgp0VhediHx7p9kkz6H6ac4et9sW4UkTnN7xhYc1Zr17wRSk2heQtcX"
+                    "oZJGwuzhiKm8A8wkuVxms6zO56P4JORIk8oaUW6lyNTLo2kWWnTA"));
+  EXPECT_EQ(SECSuccess, PK11_Logout(slot.get()));
+  ScopedPK11GenericObject obj(PK11_CreateGenericObject(
+      slot.get(), attributes, PR_ARRAY_SIZE(attributes), true));
+  EXPECT_EQ(nullptr, obj);
+}
+
 TEST_F(SoftokenTest, CreateObjectChangeToEmptyPassword) {
   ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot());
   ASSERT_TRUE(slot);
   EXPECT_EQ(SECSuccess, PK11_InitPin(slot.get(), nullptr, "password"));
   EXPECT_EQ(SECSuccess, PK11_ChangePW(slot.get(), "password", ""));
   // PK11_Logout returnes an error and SEC_ERROR_TOKEN_NOT_LOGGED_IN if the user
   // is not "logged in".
   EXPECT_EQ(SECFailure, PK11_Logout(slot.get()));
@@ -260,15 +282,109 @@ TEST_F(SoftokenNoDBTest, NeedUserInitNoD
   ASSERT_TRUE(slot);
   EXPECT_EQ(PR_FALSE, PK11_NeedUserInit(slot.get()));
 
   // When shutting down in here we have to release the slot first.
   slot = nullptr;
   ASSERT_EQ(SECSuccess, NSS_Shutdown());
 }
 
+#ifndef NSS_FIPS_DISABLED
+
+class SoftokenFipsTest : public SoftokenTest {
+ protected:
+  SoftokenFipsTest() : SoftokenTest("SoftokenFipsTest.d-") {}
+
+  virtual void SetUp() {
+    SoftokenTest::SetUp();
+
+    // Turn on FIPS mode (code borrowed from FipsMode in modutil/pk11.c)
+    char *internal_name;
+    ASSERT_FALSE(PK11_IsFIPS());
+    internal_name = PR_smprintf("%s", SECMOD_GetInternalModule()->commonName);
+    ASSERT_EQ(SECSuccess, SECMOD_DeleteInternalModule(internal_name));
+    PR_smprintf_free(internal_name);
+    ASSERT_TRUE(PK11_IsFIPS());
+  }
+};
+
+const std::vector<std::string> kFipsPasswordCases[] = {
+    // FIPS level1 -> level1 -> level1
+    {"", "", ""},
+    // FIPS level1 -> level1 -> level2
+    {"", "", "strong-_123"},
+    // FIXME: this should work: FIPS level1 -> level2 -> level2
+    // {"", "strong-_123", "strong-_456"},
+    // FIPS level2 -> level2 -> level2
+    {"strong-_123", "strong-_456", "strong-_123"}};
+
+const std::vector<std::string> kFipsPasswordBadCases[] = {
+    // FIPS level1 -> level2 -> level1
+    {"", "strong-_123", ""},
+    // FIPS level2 -> level1 -> level1
+    {"strong-_123", ""},
+    // FIPS level2 -> level2 -> level1
+    {"strong-_123", "strong-_456", ""},
+    // initialize with a weak password
+    {"weak"},
+    // FIPS level1 -> weak password
+    {"", "weak"},
+    // FIPS level2 -> weak password
+    {"strong-_123", "weak"}};
+
+class SoftokenFipsPasswordTest
+    : public SoftokenFipsTest,
+      public ::testing::WithParamInterface<std::vector<std::string>> {};
+
+class SoftokenFipsBadPasswordTest
+    : public SoftokenFipsTest,
+      public ::testing::WithParamInterface<std::vector<std::string>> {};
+
+TEST_P(SoftokenFipsPasswordTest, SetPassword) {
+  const std::vector<std::string> &passwords = GetParam();
+  ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot());
+  ASSERT_TRUE(slot);
+
+  auto it = passwords.begin();
+  auto prev_it = it;
+  EXPECT_EQ(SECSuccess, PK11_InitPin(slot.get(), nullptr, (*it).c_str()));
+  for (it++; it != passwords.end(); it++, prev_it++) {
+    EXPECT_EQ(SECSuccess,
+              PK11_ChangePW(slot.get(), (*prev_it).c_str(), (*it).c_str()));
+  }
+}
+
+TEST_P(SoftokenFipsBadPasswordTest, SetBadPassword) {
+  const std::vector<std::string> &passwords = GetParam();
+  ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot());
+  ASSERT_TRUE(slot);
+
+  auto it = passwords.begin();
+  auto prev_it = it;
+  SECStatus rv = PK11_InitPin(slot.get(), nullptr, (*it).c_str());
+  if (it + 1 == passwords.end())
+    EXPECT_EQ(SECFailure, rv);
+  else
+    EXPECT_EQ(SECSuccess, rv);
+  for (it++; it != passwords.end(); it++, prev_it++) {
+    rv = PK11_ChangePW(slot.get(), (*prev_it).c_str(), (*it).c_str());
+    if (it + 1 == passwords.end())
+      EXPECT_EQ(SECFailure, rv);
+    else
+      EXPECT_EQ(SECSuccess, rv);
+  }
+}
+
+INSTANTIATE_TEST_CASE_P(FipsPasswordCases, SoftokenFipsPasswordTest,
+                        ::testing::ValuesIn(kFipsPasswordCases));
+
+INSTANTIATE_TEST_CASE_P(BadFipsPasswordCases, SoftokenFipsBadPasswordTest,
+                        ::testing::ValuesIn(kFipsPasswordBadCases));
+
+#endif
+
 }  // namespace nss_test
 
 int main(int argc, char **argv) {
   ::testing::InitGoogleTest(&argc, argv);
 
   return RUN_ALL_TESTS();
 }
--- a/security/nss/lib/freebl/Makefile
+++ b/security/nss/lib/freebl/Makefile
@@ -236,19 +236,34 @@ ifeq ($(CPU_ARCH),x86)
     DEFINES += -DMP_ASSEMBLY_DIV_2DX1D -DMP_USE_UINT_DIGIT
     DEFINES += -DMP_IS_LITTLE_ENDIAN
 endif
 ifeq ($(CPU_ARCH),arm)
     DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE 
     DEFINES += -DMP_USE_UINT_DIGIT
     DEFINES += -DSHA_NO_LONG_LONG # avoid 64-bit arithmetic in SHA512
     MPI_SRCS += mpi_arm.c
+    ifdef CC_IS_CLANG
+        DEFINES += -DUSE_HW_AES
+        EXTRA_SRCS += aes-armv8.c
+    else ifeq (1,$(CC_IS_GCC))
+        # Old compiler doesn't support ARM AES.
+        ifneq (,$(filter 4.9,$(word 1,$(GCC_VERSION)).$(word 2,$(GCC_VERSION))))
+            DEFINES += -DUSE_HW_AES
+            EXTRA_SRCS += aes-armv8.c
+        endif
+        ifeq (,$(filter 0 1 2 3 4,$(word 1,$(GCC_VERSION))))
+            DEFINES += -DUSE_HW_AES
+            EXTRA_SRCS += aes-armv8.c
+        endif
+    endif
 endif
 ifeq ($(CPU_ARCH),aarch64)
-    EXTRA_SRCS += gcm-aarch64.c
+    DEFINES += -DUSE_HW_AES
+    EXTRA_SRCS += aes-armv8.c gcm-aarch64.c
 endif
 ifeq ($(CPU_ARCH),ppc)
 ifdef USE_64
     DEFINES += -DNSS_NO_INIT_SUPPORT
 endif # USE_64
 endif # ppc
 endif # Linux
 
@@ -756,11 +771,15 @@ endif
 
 ifdef INTEL_GCM_CLANG_CL
 #
 # clang-cl needs -mssse3
 #
 $(OBJDIR)/$(PROG_PREFIX)intel-gcm-wrap$(OBJ_SUFFIX): CFLAGS += -mssse3
 endif
 
+ifeq ($(CPU_ARCH),arm)
+$(OBJDIR)/$(PROG_PREFIX)aes-armv8$(OBJ_SUFFIX): CFLAGS += -march=armv8-a -mfpu=crypto-neon-fp-armv8
+endif
 ifeq ($(CPU_ARCH),aarch64)
+$(OBJDIR)/$(PROG_PREFIX)aes-armv8$(OBJ_SUFFIX): CFLAGS += -march=armv8-a+crypto
 $(OBJDIR)/$(PROG_PREFIX)gcm-aarch64$(OBJ_SUFFIX): CFLAGS += -march=armv8-a+crypto
 endif
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/freebl/aes-armv8.c
@@ -0,0 +1,1168 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "secerr.h"
+#include "rijndael.h"
+
+#if (defined(__clang__) ||                            \
+     (defined(__GNUC__) && defined(__GNUC_MINOR__) && \
+      (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 8))))
+
+#ifndef __ARM_FEATURE_CRYPTO
+#error "Compiler option is invalid"
+#endif
+
+#include <arm_neon.h>
+
+SECStatus
+arm_aes_encrypt_ecb_128(AESContext *cx, unsigned char *output,
+                        unsigned int *outputLen,
+                        unsigned int maxOutputLen,
+                        const unsigned char *input,
+                        unsigned int inputLen,
+                        unsigned int blocksize)
+{
+#if !defined(HAVE_UNALIGNED_ACCESS)
+    pre_align unsigned char buf[16] post_align;
+#endif
+    uint8x16_t key1, key2, key3, key4, key5, key6, key7, key8, key9, key10;
+    uint8x16_t key11;
+    const PRUint8 *key = (const PRUint8 *)cx->expandedKey;
+
+    if (!inputLen) {
+        return SECSuccess;
+    }
+
+    key1 = vld1q_u8(__builtin_assume_aligned(key, 16));
+    key2 = vld1q_u8(__builtin_assume_aligned(key + 16, 16));
+    key3 = vld1q_u8(__builtin_assume_aligned(key + 32, 16));
+    key4 = vld1q_u8(__builtin_assume_aligned(key + 48, 16));
+    key5 = vld1q_u8(__builtin_assume_aligned(key + 64, 16));
+    key6 = vld1q_u8(__builtin_assume_aligned(key + 80, 16));
+    key7 = vld1q_u8(__builtin_assume_aligned(key + 96, 16));
+    key8 = vld1q_u8(__builtin_assume_aligned(key + 112, 16));
+    key9 = vld1q_u8(__builtin_assume_aligned(key + 128, 16));
+    key10 = vld1q_u8(__builtin_assume_aligned(key + 144, 16));
+    key11 = vld1q_u8(__builtin_assume_aligned(key + 160, 16));
+
+    while (inputLen > 0) {
+        uint8x16_t state;
+#if defined(HAVE_UNALIGNED_ACCESS)
+        state = vld1q_u8(input);
+#else
+        if ((uintptr_t)input & 0x7) {
+            memcpy(buf, input, 16);
+            state = vld1q_u8(__builtin_assume_aligned(buf, 16));
+        } else {
+            state = vld1q_u8(__builtin_assume_aligned(input, 8));
+        }
+#endif
+        input += 16;
+        inputLen -= 16;
+
+        /* Rounds */
+        state = vaeseq_u8(state, key1);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key2);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key3);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key4);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key5);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key6);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key7);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key8);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key9);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key10);
+        /* AddRoundKey */
+        state = veorq_u8(state, key11);
+
+#if defined(HAVE_UNALIGNED_ACCESS)
+        vst1q_u8(output, state);
+#else
+        if ((uintptr_t)output & 0x7) {
+            vst1q_u8(__builtin_assume_aligned(buf, 16), state);
+            memcpy(output, buf, 16);
+        } else {
+            vst1q_u8(__builtin_assume_aligned(output, 8), state);
+        }
+#endif
+        output += 16;
+    }
+
+    return SECSuccess;
+}
+
+SECStatus
+arm_aes_decrypt_ecb_128(AESContext *cx, unsigned char *output,
+                        unsigned int *outputLen,
+                        unsigned int maxOutputLen,
+                        const unsigned char *input,
+                        unsigned int inputLen,
+                        unsigned int blocksize)
+{
+#if !defined(HAVE_UNALIGNED_ACCESS)
+    pre_align unsigned char buf[16] post_align;
+#endif
+    uint8x16_t key1, key2, key3, key4, key5, key6, key7, key8, key9, key10;
+    uint8x16_t key11;
+    const PRUint8 *key = (const PRUint8 *)cx->expandedKey;
+
+    if (inputLen == 0) {
+        return SECSuccess;
+    }
+
+    key1 = vld1q_u8(__builtin_assume_aligned(key, 16));
+    key2 = vld1q_u8(__builtin_assume_aligned(key + 16, 16));
+    key3 = vld1q_u8(__builtin_assume_aligned(key + 32, 16));
+    key4 = vld1q_u8(__builtin_assume_aligned(key + 48, 16));
+    key5 = vld1q_u8(__builtin_assume_aligned(key + 64, 16));
+    key6 = vld1q_u8(__builtin_assume_aligned(key + 80, 16));
+    key7 = vld1q_u8(__builtin_assume_aligned(key + 96, 16));
+    key8 = vld1q_u8(__builtin_assume_aligned(key + 112, 16));
+    key9 = vld1q_u8(__builtin_assume_aligned(key + 128, 16));
+    key10 = vld1q_u8(__builtin_assume_aligned(key + 144, 16));
+    key11 = vld1q_u8(__builtin_assume_aligned(key + 160, 16));
+
+    while (inputLen > 0) {
+        uint8x16_t state;
+#if defined(HAVE_UNALIGNED_ACCESS)
+        state = vld1q_u8(input);
+#else
+        if ((uintptr_t)input & 0x7) {
+            memcpy(buf, input, 16);
+            state = vld1q_u8(__builtin_assume_aligned(buf, 16));
+        } else {
+            state = vld1q_u8(__builtin_assume_aligned(input, 8));
+        }
+#endif
+        input += 16;
+        inputLen -= 16;
+
+        /* Rounds */
+        state = vaesdq_u8(state, key11);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key10);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key9);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key8);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key7);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key6);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key5);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key4);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key3);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key2);
+        /* AddRoundKey */
+        state = veorq_u8(state, key1);
+
+#if defined(HAVE_UNALIGNED_ACCESS)
+        vst1q_u8(output, state);
+#else
+        if ((uintptr_t)output & 0x7) {
+            vst1q_u8(__builtin_assume_aligned(buf, 16), state);
+            memcpy(output, buf, 16);
+        } else {
+            vst1q_u8(__builtin_assume_aligned(output, 8), state);
+        }
+#endif
+        output += 16;
+    }
+
+    return SECSuccess;
+}
+
+SECStatus
+arm_aes_encrypt_cbc_128(AESContext *cx, unsigned char *output,
+                        unsigned int *outputLen,
+                        unsigned int maxOutputLen,
+                        const unsigned char *input,
+                        unsigned int inputLen,
+                        unsigned int blocksize)
+{
+#if !defined(HAVE_UNALIGNED_ACCESS)
+    pre_align unsigned char buf[16] post_align;
+#endif
+    uint8x16_t key1, key2, key3, key4, key5, key6, key7, key8, key9, key10;
+    uint8x16_t key11;
+    uint8x16_t iv;
+    const PRUint8 *key = (const PRUint8 *)cx->expandedKey;
+
+    if (!inputLen) {
+        return SECSuccess;
+    }
+
+    /* iv */
+    iv = vld1q_u8(__builtin_assume_aligned(cx->iv, 16));
+
+    /* expanedKey */
+    key1 = vld1q_u8(__builtin_assume_aligned(key, 16));
+    key2 = vld1q_u8(__builtin_assume_aligned(key + 16, 16));
+    key3 = vld1q_u8(__builtin_assume_aligned(key + 32, 16));
+    key4 = vld1q_u8(__builtin_assume_aligned(key + 48, 16));
+    key5 = vld1q_u8(__builtin_assume_aligned(key + 64, 16));
+    key6 = vld1q_u8(__builtin_assume_aligned(key + 80, 16));
+    key7 = vld1q_u8(__builtin_assume_aligned(key + 96, 16));
+    key8 = vld1q_u8(__builtin_assume_aligned(key + 112, 16));
+    key9 = vld1q_u8(__builtin_assume_aligned(key + 128, 16));
+    key10 = vld1q_u8(__builtin_assume_aligned(key + 144, 16));
+    key11 = vld1q_u8(__builtin_assume_aligned(key + 160, 16));
+
+    while (inputLen > 0) {
+        uint8x16_t state;
+#if defined(HAVE_UNALIGNED_ACCESS)
+        state = vld1q_u8(input);
+#else
+        if ((uintptr_t)input & 0x7) {
+            memcpy(buf, input, 16);
+            state = vld1q_u8(__builtin_assume_aligned(buf, 16));
+        } else {
+            state = vld1q_u8(__builtin_assume_aligned(input, 8));
+        }
+#endif
+        input += 16;
+        inputLen -= 16;
+
+        state = veorq_u8(state, iv);
+
+        /* Rounds */
+        state = vaeseq_u8(state, key1);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key2);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key3);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key4);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key5);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key6);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key7);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key8);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key9);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key10);
+        /* AddRoundKey */
+        state = veorq_u8(state, key11);
+
+#if defined(HAVE_UNALIGNED_ACCESS)
+        vst1q_u8(output, state);
+#else
+        if ((uintptr_t)output & 0x7) {
+            vst1q_u8(__builtin_assume_aligned(buf, 16), state);
+            memcpy(output, buf, 16);
+        } else {
+            vst1q_u8(__builtin_assume_aligned(output, 8), state);
+        }
+#endif
+        output += 16;
+        iv = state;
+    }
+    vst1q_u8(__builtin_assume_aligned(cx->iv, 16), iv);
+
+    return SECSuccess;
+}
+
+SECStatus
+arm_aes_decrypt_cbc_128(AESContext *cx, unsigned char *output,
+                        unsigned int *outputLen,
+                        unsigned int maxOutputLen,
+                        const unsigned char *input,
+                        unsigned int inputLen,
+                        unsigned int blocksize)
+{
+#if !defined(HAVE_UNALIGNED_ACCESS)
+    pre_align unsigned char buf[16] post_align;
+#endif
+    uint8x16_t iv;
+    uint8x16_t key1, key2, key3, key4, key5, key6, key7, key8, key9, key10;
+    uint8x16_t key11;
+    const PRUint8 *key = (const PRUint8 *)cx->expandedKey;
+
+    if (!inputLen) {
+        return SECSuccess;
+    }
+
+    /* iv */
+    iv = vld1q_u8(__builtin_assume_aligned(cx->iv, 16));
+
+    /* expanedKey */
+    key1 = vld1q_u8(__builtin_assume_aligned(key, 16));
+    key2 = vld1q_u8(__builtin_assume_aligned(key + 16, 16));
+    key3 = vld1q_u8(__builtin_assume_aligned(key + 32, 16));
+    key4 = vld1q_u8(__builtin_assume_aligned(key + 48, 16));
+    key5 = vld1q_u8(__builtin_assume_aligned(key + 64, 16));
+    key6 = vld1q_u8(__builtin_assume_aligned(key + 80, 16));
+    key7 = vld1q_u8(__builtin_assume_aligned(key + 96, 16));
+    key8 = vld1q_u8(__builtin_assume_aligned(key + 112, 16));
+    key9 = vld1q_u8(__builtin_assume_aligned(key + 128, 16));
+    key10 = vld1q_u8(__builtin_assume_aligned(key + 144, 16));
+    key11 = vld1q_u8(__builtin_assume_aligned(key + 160, 16));
+
+    while (inputLen > 0) {
+        uint8x16_t state, old_state;
+#if defined(HAVE_UNALIGNED_ACCESS)
+        state = vld1q_u8(input);
+#else
+        if ((uintptr_t)input & 0x7) {
+            memcpy(buf, input, 16);
+            state = vld1q_u8(__builtin_assume_aligned(buf, 16));
+        } else {
+            state = vld1q_u8(__builtin_assume_aligned(input, 8));
+        }
+#endif
+        old_state = state;
+        input += 16;
+        inputLen -= 16;
+
+        /* Rounds */
+        state = vaesdq_u8(state, key11);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key10);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key9);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key8);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key7);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key6);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key5);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key4);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key3);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key2);
+        /* AddRoundKey */
+        state = veorq_u8(state, key1);
+
+        state = veorq_u8(state, iv);
+
+#if defined(HAVE_UNALIGNED_ACCESS)
+        vst1q_u8(output, state);
+#else
+        if ((uintptr_t)output & 0x7) {
+            vst1q_u8(__builtin_assume_aligned(buf, 16), state);
+            memcpy(output, buf, 16);
+        } else {
+            vst1q_u8(__builtin_assume_aligned(output, 8), state);
+        }
+#endif
+        output += 16;
+
+        iv = old_state;
+    }
+    vst1q_u8(__builtin_assume_aligned(cx->iv, 16), iv);
+
+    return SECSuccess;
+}
+
+SECStatus
+arm_aes_encrypt_ecb_192(AESContext *cx, unsigned char *output,
+                        unsigned int *outputLen,
+                        unsigned int maxOutputLen,
+                        const unsigned char *input,
+                        unsigned int inputLen,
+                        unsigned int blocksize)
+{
+#if !defined(HAVE_UNALIGNED_ACCESS)
+    pre_align unsigned char buf[16] post_align;
+#endif
+    uint8x16_t key1, key2, key3, key4, key5, key6, key7, key8, key9, key10;
+    uint8x16_t key11, key12, key13;
+    PRUint8 *key = (PRUint8 *)cx->expandedKey;
+
+    if (!inputLen) {
+        return SECSuccess;
+    }
+
+    key1 = vld1q_u8(__builtin_assume_aligned(key, 16));
+    key2 = vld1q_u8(__builtin_assume_aligned(key + 16, 16));
+    key3 = vld1q_u8(__builtin_assume_aligned(key + 32, 16));
+    key4 = vld1q_u8(__builtin_assume_aligned(key + 48, 16));
+    key5 = vld1q_u8(__builtin_assume_aligned(key + 64, 16));
+    key6 = vld1q_u8(__builtin_assume_aligned(key + 80, 16));
+    key7 = vld1q_u8(__builtin_assume_aligned(key + 96, 16));
+    key8 = vld1q_u8(__builtin_assume_aligned(key + 112, 16));
+    key9 = vld1q_u8(__builtin_assume_aligned(key + 128, 16));
+    key10 = vld1q_u8(__builtin_assume_aligned(key + 144, 16));
+    key11 = vld1q_u8(__builtin_assume_aligned(key + 160, 16));
+    key12 = vld1q_u8(__builtin_assume_aligned(key + 176, 16));
+    key13 = vld1q_u8(__builtin_assume_aligned(key + 192, 16));
+
+    while (inputLen > 0) {
+        uint8x16_t state;
+#if defined(HAVE_UNALIGNED_ACCESS)
+        state = vld1q_u8(input);
+#else
+        if ((uintptr_t)input & 0x7) {
+            memcpy(buf, input, 16);
+            state = vld1q_u8(__builtin_assume_aligned(buf, 16));
+        } else {
+            state = vld1q_u8(__builtin_assume_aligned(input, 8));
+        }
+#endif
+        input += 16;
+        inputLen -= 16;
+
+        /* Rounds */
+        state = vaeseq_u8(state, key1);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key2);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key3);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key4);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key5);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key6);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key7);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key8);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key9);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key10);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key11);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key12);
+        /* AddRoundKey */
+        state = veorq_u8(state, key13);
+
+#if defined(HAVE_UNALIGNED_ACCESS)
+        vst1q_u8(output, state);
+#else
+        if ((uintptr_t)output & 0x7) {
+            vst1q_u8(__builtin_assume_aligned(buf, 16), state);
+            memcpy(output, buf, 16);
+        } else {
+            vst1q_u8(__builtin_assume_aligned(output, 8), state);
+        }
+#endif
+        output += 16;
+    }
+
+    return SECSuccess;
+}
+
+SECStatus
+arm_aes_decrypt_ecb_192(AESContext *cx, unsigned char *output,
+                        unsigned int *outputLen,
+                        unsigned int maxOutputLen,
+                        const unsigned char *input,
+                        unsigned int inputLen,
+                        unsigned int blocksize)
+{
+#if !defined(HAVE_UNALIGNED_ACCESS)
+    pre_align unsigned char buf[16] post_align;
+#endif
+    uint8x16_t key1, key2, key3, key4, key5, key6, key7, key8, key9, key10;
+    uint8x16_t key11, key12, key13;
+    const PRUint8 *key = (const PRUint8 *)cx->expandedKey;
+
+    if (!inputLen) {
+        return SECSuccess;
+    }
+
+    key1 = vld1q_u8(__builtin_assume_aligned(key, 16));
+    key2 = vld1q_u8(__builtin_assume_aligned(key + 16, 16));
+    key3 = vld1q_u8(__builtin_assume_aligned(key + 32, 16));
+    key4 = vld1q_u8(__builtin_assume_aligned(key + 48, 16));
+    key5 = vld1q_u8(__builtin_assume_aligned(key + 64, 16));
+    key6 = vld1q_u8(__builtin_assume_aligned(key + 80, 16));
+    key7 = vld1q_u8(__builtin_assume_aligned(key + 96, 16));
+    key8 = vld1q_u8(__builtin_assume_aligned(key + 112, 16));
+    key9 = vld1q_u8(__builtin_assume_aligned(key + 128, 16));
+    key10 = vld1q_u8(__builtin_assume_aligned(key + 144, 16));
+    key11 = vld1q_u8(__builtin_assume_aligned(key + 160, 16));
+    key12 = vld1q_u8(__builtin_assume_aligned(key + 176, 16));
+    key13 = vld1q_u8(__builtin_assume_aligned(key + 192, 16));
+
+    while (inputLen > 0) {
+        uint8x16_t state;
+#if defined(HAVE_UNALIGNED_ACCESS)
+        state = vld1q_u8(input);
+#else
+        if ((uintptr_t)input & 0x7) {
+            memcpy(buf, input, 16);
+            state = vld1q_u8(__builtin_assume_aligned(buf, 16));
+        } else {
+            state = vld1q_u8(__builtin_assume_aligned(input, 8));
+        }
+#endif
+        input += 16;
+        inputLen -= 16;
+
+        /* Rounds */
+        state = vaesdq_u8(state, key13);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key12);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key11);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key10);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key9);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key8);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key7);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key6);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key5);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key4);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key3);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key2);
+        /* AddRoundKey */
+        state = veorq_u8(state, key1);
+
+#if defined(HAVE_UNALIGNED_ACCESS)
+        vst1q_u8(output, state);
+#else
+        if ((uintptr_t)output & 0x7) {
+            vst1q_u8(__builtin_assume_aligned(buf, 16), state);
+            memcpy(output, buf, 16);
+        } else {
+            vst1q_u8(__builtin_assume_aligned(output, 8), state);
+        }
+#endif
+        output += 16;
+    }
+
+    return SECSuccess;
+}
+
+SECStatus
+arm_aes_encrypt_cbc_192(AESContext *cx, unsigned char *output,
+                        unsigned int *outputLen,
+                        unsigned int maxOutputLen,
+                        const unsigned char *input,
+                        unsigned int inputLen,
+                        unsigned int blocksize)
+{
+#if !defined(HAVE_UNALIGNED_ACCESS)
+    pre_align unsigned char buf[16] post_align;
+#endif
+    uint8x16_t key1, key2, key3, key4, key5, key6, key7, key8, key9, key10;
+    uint8x16_t key11, key12, key13;
+    uint8x16_t iv;
+    PRUint8 *key = (PRUint8 *)cx->expandedKey;
+
+    if (!inputLen) {
+        return SECSuccess;
+    }
+
+    /* iv */
+    iv = vld1q_u8(cx->iv);
+
+    /* expanedKey */
+    key1 = vld1q_u8(__builtin_assume_aligned(key, 16));
+    key2 = vld1q_u8(__builtin_assume_aligned(key + 16, 16));
+    key3 = vld1q_u8(__builtin_assume_aligned(key + 32, 16));
+    key4 = vld1q_u8(__builtin_assume_aligned(key + 48, 16));
+    key5 = vld1q_u8(__builtin_assume_aligned(key + 64, 16));
+    key6 = vld1q_u8(__builtin_assume_aligned(key + 80, 16));
+    key7 = vld1q_u8(__builtin_assume_aligned(key + 96, 16));
+    key8 = vld1q_u8(__builtin_assume_aligned(key + 112, 16));
+    key9 = vld1q_u8(__builtin_assume_aligned(key + 128, 16));
+    key10 = vld1q_u8(__builtin_assume_aligned(key + 144, 16));
+    key11 = vld1q_u8(__builtin_assume_aligned(key + 160, 16));
+    key12 = vld1q_u8(__builtin_assume_aligned(key + 176, 16));
+    key13 = vld1q_u8(__builtin_assume_aligned(key + 192, 16));
+
+    while (inputLen > 0) {
+        uint8x16_t state;
+#if defined(HAVE_UNALIGNED_ACCESS)
+        state = vld1q_u8(input);
+#else
+        if ((uintptr_t)input & 0x7) {
+            memcpy(buf, input, 16);
+            state = vld1q_u8(__builtin_assume_aligned(buf, 16));
+        } else {
+            state = vld1q_u8(__builtin_assume_aligned(input, 8));
+        }
+#endif
+        input += 16;
+        inputLen -= 16;
+
+        state = veorq_u8(state, iv);
+
+        /* Rounds */
+        state = vaeseq_u8(state, key1);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key2);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key3);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key4);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key5);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key6);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key7);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key8);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key9);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key10);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key11);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key12);
+        state = veorq_u8(state, key13);
+
+#if defined(HAVE_UNALIGNED_ACCESS)
+        vst1q_u8(output, state);
+#else
+        if ((uintptr_t)output & 0x7) {
+            vst1q_u8(__builtin_assume_aligned(buf, 16), state);
+            memcpy(output, buf, 16);
+        } else {
+            vst1q_u8(__builtin_assume_aligned(output, 8), state);
+        }
+#endif
+        output += 16;
+        iv = state;
+    }
+    vst1q_u8(__builtin_assume_aligned(cx->iv, 16), iv);
+
+    return SECSuccess;
+}
+
+SECStatus
+arm_aes_decrypt_cbc_192(AESContext *cx, unsigned char *output,
+                        unsigned int *outputLen,
+                        unsigned int maxOutputLen,
+                        const unsigned char *input,
+                        unsigned int inputLen,
+                        unsigned int blocksize)
+{
+#if !defined(HAVE_UNALIGNED_ACCESS)
+    pre_align unsigned char buf[16] post_align;
+#endif
+    uint8x16_t iv;
+    uint8x16_t key1, key2, key3, key4, key5, key6, key7, key8, key9, key10;
+    uint8x16_t key11, key12, key13;
+    const PRUint8 *key = (const PRUint8 *)cx->expandedKey;
+
+    if (!inputLen) {
+        return SECSuccess;
+    }
+
+    /* iv */
+    iv = vld1q_u8(__builtin_assume_aligned(cx->iv, 16));
+
+    /* expanedKey */
+    key1 = vld1q_u8(__builtin_assume_aligned(key, 16));
+    key2 = vld1q_u8(__builtin_assume_aligned(key + 16, 16));
+    key3 = vld1q_u8(__builtin_assume_aligned(key + 32, 16));
+    key4 = vld1q_u8(__builtin_assume_aligned(key + 48, 16));
+    key5 = vld1q_u8(__builtin_assume_aligned(key + 64, 16));
+    key6 = vld1q_u8(__builtin_assume_aligned(key + 80, 16));
+    key7 = vld1q_u8(__builtin_assume_aligned(key + 96, 16));
+    key8 = vld1q_u8(__builtin_assume_aligned(key + 112, 16));
+    key9 = vld1q_u8(__builtin_assume_aligned(key + 128, 16));
+    key10 = vld1q_u8(__builtin_assume_aligned(key + 144, 16));
+    key11 = vld1q_u8(__builtin_assume_aligned(key + 160, 16));
+    key12 = vld1q_u8(__builtin_assume_aligned(key + 176, 16));
+    key13 = vld1q_u8(__builtin_assume_aligned(key + 192, 16));
+
+    while (inputLen > 0) {
+        uint8x16_t state, old_state;
+#if defined(HAVE_UNALIGNED_ACCESS)
+        state = vld1q_u8(input);
+#else
+        if ((uintptr_t)input & 0x7) {
+            memcpy(buf, input, 16);
+            state = vld1q_u8(__builtin_assume_aligned(buf, 16));
+        } else {
+            state = vld1q_u8(__builtin_assume_aligned(input, 8));
+        }
+#endif
+        old_state = state;
+        input += 16;
+        inputLen -= 16;
+
+        /* Rounds */
+        state = vaesdq_u8(state, key13);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key12);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key11);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key10);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key9);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key8);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key7);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key6);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key5);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key4);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key3);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key2);
+        /* AddRoundKey */
+        state = veorq_u8(state, key1);
+
+        state = veorq_u8(state, iv);
+
+#if defined(HAVE_UNALIGNED_ACCESS)
+        vst1q_u8(output, state);
+#else
+        if ((uintptr_t)output & 0x7) {
+            vst1q_u8(__builtin_assume_aligned(buf, 16), state);
+            memcpy(output, buf, 16);
+        } else {
+            vst1q_u8(__builtin_assume_aligned(output, 8), state);
+        }
+#endif
+        output += 16;
+
+        iv = old_state;
+    }
+    vst1q_u8(__builtin_assume_aligned(cx->iv, 16), iv);
+
+    return SECSuccess;
+}
+
+SECStatus
+arm_aes_encrypt_ecb_256(AESContext *cx, unsigned char *output,
+                        unsigned int *outputLen,
+                        unsigned int maxOutputLen,
+                        const unsigned char *input,
+                        unsigned int inputLen,
+                        unsigned int blocksize)
+{
+#if !defined(HAVE_UNALIGNED_ACCESS)
+    pre_align unsigned char buf[16] post_align;
+#endif
+    uint8x16_t key1, key2, key3, key4, key5, key6, key7, key8, key9, key10;
+    uint8x16_t key11, key12, key13, key14, key15;
+    PRUint8 *key = (PRUint8 *)cx->expandedKey;
+
+    if (inputLen == 0) {
+        return SECSuccess;
+    }
+
+    key1 = vld1q_u8(__builtin_assume_aligned(key, 16));
+    key2 = vld1q_u8(__builtin_assume_aligned(key + 16, 16));
+    key3 = vld1q_u8(__builtin_assume_aligned(key + 32, 16));
+    key4 = vld1q_u8(__builtin_assume_aligned(key + 48, 16));
+    key5 = vld1q_u8(__builtin_assume_aligned(key + 64, 16));
+    key6 = vld1q_u8(__builtin_assume_aligned(key + 80, 16));
+    key7 = vld1q_u8(__builtin_assume_aligned(key + 96, 16));
+    key8 = vld1q_u8(__builtin_assume_aligned(key + 112, 16));
+    key9 = vld1q_u8(__builtin_assume_aligned(key + 128, 16));
+    key10 = vld1q_u8(__builtin_assume_aligned(key + 144, 16));
+    key11 = vld1q_u8(__builtin_assume_aligned(key + 160, 16));
+    key12 = vld1q_u8(__builtin_assume_aligned(key + 176, 16));
+    key13 = vld1q_u8(__builtin_assume_aligned(key + 192, 16));
+    key14 = vld1q_u8(__builtin_assume_aligned(key + 208, 16));
+    key15 = vld1q_u8(__builtin_assume_aligned(key + 224, 16));
+
+    while (inputLen > 0) {
+        uint8x16_t state;
+#if defined(HAVE_UNALIGNED_ACCESS)
+        state = vld1q_u8(input);
+#else
+        if ((uintptr_t)input & 0x7) {
+            memcpy(buf, input, 16);
+            state = vld1q_u8(__builtin_assume_aligned(buf, 16));
+        } else {
+            state = vld1q_u8(__builtin_assume_aligned(input, 8));
+        }
+#endif
+        input += 16;
+        inputLen -= 16;
+
+        /* Rounds */
+        state = vaeseq_u8(state, key1);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key2);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key3);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key4);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key5);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key6);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key7);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key8);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key9);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key10);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key11);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key12);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key13);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key14);
+        /* AddRoundKey */
+        state = veorq_u8(state, key15);
+
+#if defined(HAVE_UNALIGNED_ACCESS)
+        vst1q_u8(output, state);
+#else
+        if ((uintptr_t)output & 0x7) {
+            vst1q_u8(__builtin_assume_aligned(buf, 16), state);
+            memcpy(output, buf, 16);
+        } else {
+            vst1q_u8(__builtin_assume_aligned(output, 8), state);
+        }
+#endif
+        output += 16;
+    }
+    return SECSuccess;
+}
+
+SECStatus
+arm_aes_decrypt_ecb_256(AESContext *cx, unsigned char *output,
+                        unsigned int *outputLen,
+                        unsigned int maxOutputLen,
+                        const unsigned char *input,
+                        unsigned int inputLen,
+                        unsigned int blocksize)
+{
+#if !defined(HAVE_UNALIGNED_ACCESS)
+    pre_align unsigned char buf[16] post_align;
+#endif
+    uint8x16_t key1, key2, key3, key4, key5, key6, key7, key8, key9, key10;
+    uint8x16_t key11, key12, key13, key14, key15;
+    const PRUint8 *key = (const PRUint8 *)cx->expandedKey;
+
+    if (!inputLen) {
+        return SECSuccess;
+    }
+
+    key1 = vld1q_u8(__builtin_assume_aligned(key, 16));
+    key2 = vld1q_u8(__builtin_assume_aligned(key + 16, 16));
+    key3 = vld1q_u8(__builtin_assume_aligned(key + 32, 16));
+    key4 = vld1q_u8(__builtin_assume_aligned(key + 48, 16));
+    key5 = vld1q_u8(__builtin_assume_aligned(key + 64, 16));
+    key6 = vld1q_u8(__builtin_assume_aligned(key + 80, 16));
+    key7 = vld1q_u8(__builtin_assume_aligned(key + 96, 16));
+    key8 = vld1q_u8(__builtin_assume_aligned(key + 112, 16));
+    key9 = vld1q_u8(__builtin_assume_aligned(key + 128, 16));
+    key10 = vld1q_u8(__builtin_assume_aligned(key + 144, 16));
+    key11 = vld1q_u8(__builtin_assume_aligned(key + 160, 16));
+    key12 = vld1q_u8(__builtin_assume_aligned(key + 176, 16));
+    key13 = vld1q_u8(__builtin_assume_aligned(key + 192, 16));
+    key14 = vld1q_u8(__builtin_assume_aligned(key + 208, 16));
+    key15 = vld1q_u8(__builtin_assume_aligned(key + 224, 16));
+
+    while (inputLen > 0) {
+        uint8x16_t state;
+#if defined(HAVE_UNALIGNED_ACCESS)
+        state = vld1q_u8(input);
+#else
+        if ((uintptr_t)input & 0x7) {
+            memcpy(buf, input, 16);
+            state = vld1q_u8(__builtin_assume_aligned(buf, 16));
+        } else {
+            state = vld1q_u8(__builtin_assume_aligned(input, 8));
+        }
+#endif
+        input += 16;
+        inputLen -= 16;
+
+        /* Rounds */
+        state = vaesdq_u8(state, key15);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key14);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key13);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key12);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key11);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key10);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key9);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key8);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key7);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key6);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key5);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key4);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key3);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key2);
+        /* AddRoundKey */
+        state = veorq_u8(state, key1);
+
+#if defined(HAVE_UNALIGNED_ACCESS)
+        vst1q_u8(output, state);
+#else
+        if ((uintptr_t)output & 0x7) {
+            vst1q_u8(__builtin_assume_aligned(buf, 16), state);
+            memcpy(output, buf, 16);
+        } else {
+            vst1q_u8(__builtin_assume_aligned(output, 8), state);
+        }
+#endif
+        output += 16;
+    }
+
+    return SECSuccess;
+}
+
+SECStatus
+arm_aes_encrypt_cbc_256(AESContext *cx, unsigned char *output,
+                        unsigned int *outputLen,
+                        unsigned int maxOutputLen,
+                        const unsigned char *input,
+                        unsigned int inputLen,
+                        unsigned int blocksize)
+{
+#if !defined(HAVE_UNALIGNED_ACCESS)
+    pre_align unsigned char buf[16] post_align;
+#endif
+    uint8x16_t key1, key2, key3, key4, key5, key6, key7, key8, key9, key10;
+    uint8x16_t key11, key12, key13, key14, key15;
+    uint8x16_t iv;
+    const PRUint8 *key = (const PRUint8 *)cx->expandedKey;
+
+    if (!inputLen) {
+        return SECSuccess;
+    }
+
+    /* iv */
+    iv = vld1q_u8(cx->iv);
+
+    /* expanedKey */
+    key1 = vld1q_u8(__builtin_assume_aligned(key, 16));
+    key2 = vld1q_u8(__builtin_assume_aligned(key + 16, 16));
+    key3 = vld1q_u8(__builtin_assume_aligned(key + 32, 16));
+    key4 = vld1q_u8(__builtin_assume_aligned(key + 48, 16));
+    key5 = vld1q_u8(__builtin_assume_aligned(key + 64, 16));
+    key6 = vld1q_u8(__builtin_assume_aligned(key + 80, 16));
+    key7 = vld1q_u8(__builtin_assume_aligned(key + 96, 16));
+    key8 = vld1q_u8(__builtin_assume_aligned(key + 112, 16));
+    key9 = vld1q_u8(__builtin_assume_aligned(key + 128, 16));
+    key10 = vld1q_u8(__builtin_assume_aligned(key + 144, 16));
+    key11 = vld1q_u8(__builtin_assume_aligned(key + 160, 16));
+    key12 = vld1q_u8(__builtin_assume_aligned(key + 176, 16));
+    key13 = vld1q_u8(__builtin_assume_aligned(key + 192, 16));
+    key14 = vld1q_u8(__builtin_assume_aligned(key + 208, 16));
+    key15 = vld1q_u8(__builtin_assume_aligned(key + 224, 16));
+
+    while (inputLen > 0) {
+        uint8x16_t state;
+#if defined(HAVE_UNALIGNED_ACCESS)
+        state = vld1q_u8(input);
+#else
+        if ((uintptr_t)input & 0x7) {
+            memcpy(buf, input, 16);
+            state = vld1q_u8(__builtin_assume_aligned(buf, 16));
+        } else {
+            state = vld1q_u8(__builtin_assume_aligned(input, 8));
+        }
+#endif
+        input += 16;
+        inputLen -= 16;
+
+        state = veorq_u8(state, iv);
+
+        /* Rounds */
+        state = vaeseq_u8(state, key1);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key2);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key3);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key4);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key5);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key6);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key7);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key8);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key9);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key10);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key11);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key12);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key13);
+        state = vaesmcq_u8(state);
+        state = vaeseq_u8(state, key14);
+        /* AddRoundKey */
+        state = veorq_u8(state, key15);
+
+#if defined(HAVE_UNALIGNED_ACCESS)
+        vst1q_u8(output, state);
+#else
+        if ((uintptr_t)output & 0x7) {
+            vst1q_u8(__builtin_assume_aligned(buf, 16), state);
+            memcpy(output, buf, 16);
+        } else {
+            vst1q_u8(__builtin_assume_aligned(output, 8), state);
+        }
+#endif
+        output += 16;
+        iv = state;
+    }
+    vst1q_u8(__builtin_assume_aligned(cx->iv, 16), iv);
+
+    return SECSuccess;
+}
+
+SECStatus
+arm_aes_decrypt_cbc_256(AESContext *cx, unsigned char *output,
+                        unsigned int *outputLen,
+                        unsigned int maxOutputLen,
+                        const unsigned char *input,
+                        unsigned int inputLen,
+                        unsigned int blocksize)
+{
+#if !defined(HAVE_UNALIGNED_ACCESS)
+    pre_align unsigned char buf[16] post_align;
+#endif
+    uint8x16_t iv;
+    uint8x16_t key1, key2, key3, key4, key5, key6, key7, key8, key9, key10;
+    uint8x16_t key11, key12, key13, key14, key15;
+    const PRUint8 *key = (const PRUint8 *)cx->expandedKey;
+
+    if (!inputLen) {
+        return SECSuccess;
+    }
+
+    /* iv */
+    iv = vld1q_u8(cx->iv);
+
+    /* expanedKey */
+    key1 = vld1q_u8(__builtin_assume_aligned(key, 16));
+    key2 = vld1q_u8(__builtin_assume_aligned(key + 16, 16));
+    key3 = vld1q_u8(__builtin_assume_aligned(key + 32, 16));
+    key4 = vld1q_u8(__builtin_assume_aligned(key + 48, 16));
+    key5 = vld1q_u8(__builtin_assume_aligned(key + 64, 16));
+    key6 = vld1q_u8(__builtin_assume_aligned(key + 80, 16));
+    key7 = vld1q_u8(__builtin_assume_aligned(key + 96, 16));
+    key8 = vld1q_u8(__builtin_assume_aligned(key + 112, 16));
+    key9 = vld1q_u8(__builtin_assume_aligned(key + 128, 16));
+    key10 = vld1q_u8(__builtin_assume_aligned(key + 144, 16));
+    key11 = vld1q_u8(__builtin_assume_aligned(key + 160, 16));
+    key12 = vld1q_u8(__builtin_assume_aligned(key + 176, 16));
+    key13 = vld1q_u8(__builtin_assume_aligned(key + 192, 16));
+    key14 = vld1q_u8(__builtin_assume_aligned(key + 208, 16));
+    key15 = vld1q_u8(__builtin_assume_aligned(key + 224, 16));
+
+    while (inputLen > 0) {
+        uint8x16_t state, old_state;
+#if defined(HAVE_UNALIGNED_ACCESS)
+        state = vld1q_u8(input);
+#else
+        if ((uintptr_t)input & 0x7) {
+            memcpy(buf, input, 16);
+            state = vld1q_u8(__builtin_assume_aligned(buf, 16));
+        } else {
+            state = vld1q_u8(__builtin_assume_aligned(input, 8));
+        }
+#endif
+        old_state = state;
+        input += 16;
+        inputLen -= 16;
+
+        /* Rounds */
+        state = vaesdq_u8(state, key15);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key14);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key13);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key12);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key11);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key10);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key9);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key8);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key7);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key6);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key5);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key4);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key3);
+        state = vaesimcq_u8(state);
+        state = vaesdq_u8(state, key2);
+        /* AddRoundKey */
+        state = veorq_u8(state, key1);
+
+        state = veorq_u8(state, iv);
+
+#if defined(HAVE_UNALIGNED_ACCESS)
+        vst1q_u8(output, state);
+#else
+        if ((uintptr_t)output & 0x7) {
+            vst1q_u8(__builtin_assume_aligned(buf, 16), state);
+            memcpy(output, buf, 16);
+        } else {
+            vst1q_u8(__builtin_assume_aligned(output, 8), state);
+        }
+#endif
+        output += 16;
+
+        iv = old_state;
+    }
+    vst1q_u8(__builtin_assume_aligned(cx->iv, 16), iv);
+
+    return SECSuccess;
+}
+
+#endif
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/freebl/aes-armv8.h
@@ -0,0 +1,103 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+SECStatus arm_aes_encrypt_ecb_128(AESContext *cx, unsigned char *output,
+                                  unsigned int *outputLen,
+                                  unsigned int maxOutputLen,
+                                  const unsigned char *input,
+                                  unsigned int inputLen,
+                                  unsigned int blocksize);
+SECStatus arm_aes_decrypt_ecb_128(AESContext *cx, unsigned char *output,
+                                  unsigned int *outputLen,
+                                  unsigned int maxOutputLen,
+                                  const unsigned char *input,
+                                  unsigned int inputLen,
+                                  unsigned int blocksize);
+SECStatus arm_aes_encrypt_cbc_128(AESContext *cx, unsigned char *output,
+                                  unsigned int *outputLen,
+                                  unsigned int maxOutputLen,
+                                  const unsigned char *input,
+                                  unsigned int inputLen,
+                                  unsigned int blocksize);
+SECStatus arm_aes_decrypt_cbc_128(AESContext *cx, unsigned char *output,
+                                  unsigned int *outputLen,
+                                  unsigned int maxOutputLen,
+                                  const unsigned char *input,
+                                  unsigned int inputLen,
+                                  unsigned int blocksize);
+SECStatus arm_aes_encrypt_ecb_192(AESContext *cx, unsigned char *output,
+                                  unsigned int *outputLen,
+                                  unsigned int maxOutputLen,
+                                  const unsigned char *input,
+                                  unsigned int inputLen,
+                                  unsigned int blocksize);
+SECStatus arm_aes_decrypt_ecb_192(AESContext *cx, unsigned char *output,
+                                  unsigned int *outputLen,
+                                  unsigned int maxOutputLen,
+                                  const unsigned char *input,
+                                  unsigned int inputLen,
+                                  unsigned int blocksize);
+SECStatus arm_aes_encrypt_cbc_192(AESContext *cx, unsigned char *output,
+                                  unsigned int *outputLen,
+                                  unsigned int maxOutputLen,
+                                  const unsigned char *input,
+                                  unsigned int inputLen,
+                                  unsigned int blocksize);
+SECStatus arm_aes_decrypt_cbc_192(AESContext *cx, unsigned char *output,
+                                  unsigned int *outputLen,
+                                  unsigned int maxOutputLen,
+                                  const unsigned char *input,
+                                  unsigned int inputLen,
+                                  unsigned int blocksize);
+SECStatus arm_aes_encrypt_ecb_256(AESContext *cx, unsigned char *output,
+                                  unsigned int *outputLen,
+                                  unsigned int maxOutputLen,
+                                  const unsigned char *input,
+                                  unsigned int inputLen,
+                                  unsigned int blocksize);
+SECStatus arm_aes_decrypt_ecb_256(AESContext *cx, unsigned char *output,
+                                  unsigned int *outputLen,
+                                  unsigned int maxOutputLen,
+                                  const unsigned char *input,
+                                  unsigned int inputLen,
+                                  unsigned int blocksize);
+SECStatus arm_aes_encrypt_cbc_256(AESContext *cx, unsigned char *output,
+                                  unsigned int *outputLen,
+                                  unsigned int maxOutputLen,
+                                  const unsigned char *input,
+                                  unsigned int inputLen,
+                                  unsigned int blocksize);
+SECStatus arm_aes_decrypt_cbc_256(AESContext *cx, unsigned char *output,
+                                  unsigned int *outputLen,
+                                  unsigned int maxOutputLen,
+                                  const unsigned char *input,
+                                  unsigned int inputLen,
+                                  unsigned int blocksize);
+
+#define native_aes_ecb_worker(encrypt, keysize)                          \
+    ((encrypt)                                                           \
+         ? ((keysize) == 16 ? arm_aes_encrypt_ecb_128                    \
+                            : (keysize) == 24 ? arm_aes_encrypt_ecb_192  \
+                                              : arm_aes_encrypt_ecb_256) \
+         : ((keysize) == 16 ? arm_aes_decrypt_ecb_128                    \
+                            : (keysize) == 24 ? arm_aes_decrypt_ecb_192  \
+                                              : arm_aes_decrypt_ecb_256))
+
+#define native_aes_cbc_worker(encrypt, keysize)                          \
+    ((encrypt)                                                           \
+         ? ((keysize) == 16 ? arm_aes_encrypt_cbc_128                    \
+                            : (keysize) == 24 ? arm_aes_encrypt_cbc_192  \
+                                              : arm_aes_encrypt_cbc_256) \
+         : ((keysize) == 16 ? arm_aes_decrypt_cbc_128                    \
+                            : (keysize) == 24 ? arm_aes_decrypt_cbc_192  \
+                                              : arm_aes_decrypt_cbc_256))
+
+#define native_aes_init(encrypt, keysize)           \
+    do {                                            \
+        if (encrypt) {                              \
+            rijndael_key_expansion(cx, key, Nk);    \
+        } else {                                    \
+            rijndael_invkey_expansion(cx, key, Nk); \
+        }                                           \
+    } while (0)
--- a/security/nss/lib/freebl/freebl.gyp
+++ b/security/nss/lib/freebl/freebl.gyp
@@ -128,16 +128,45 @@
       'cflags': [
         '-march=armv8-a+crypto'
       ],
       'cflags_mozilla': [
         '-march=armv8-a+crypto'
       ]
     },
     {
+      'target_name': 'armv8_c_lib',
+      'type': 'static_library',
+      'sources': [
+        'aes-armv8.c',
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ],
+      'conditions': [
+        [ 'target_arch=="arm"', {
+          'cflags': [
+            '-march=armv8-a',
+            '-mfpu=crypto-neon-fp-armv8'
+          ],
+          'cflags_mozilla': [
+            '-march=armv8-a',
+            '-mfpu=crypto-neon-fp-armv8'
+          ],
+        }, 'target_arch=="arm64" or target_arch=="aarch64"', {
+          'cflags': [
+            '-march=armv8-a+crypto'
+          ],
+          'cflags_mozilla': [
+            '-march=armv8-a+crypto'
+          ],
+        }]
+      ]
+    },
+    {
       'target_name': 'freebl',
       'type': 'static_library',
       'sources': [
         'loader.c'
       ],
       'dependencies': [
         '<(DEPTH)/exports.gyp:nss_exports'
       ]
@@ -155,16 +184,20 @@
         '<(DEPTH)/exports.gyp:nss_exports',
         'hw-acc-crypto',
       ],
       'conditions': [
         [ 'target_arch=="ia32" or target_arch=="x64"', {
           'dependencies': [
             'gcm-aes-x86_c_lib',
           ],
+        }, 'target_arch=="arm" or target_arch=="arm64" or target_arch=="aarch64"', {
+          'dependencies': [
+            'armv8_c_lib'
+          ],
         }],
         [ 'target_arch=="arm64" or target_arch=="aarch64"', {
           'dependencies': [
             'gcm-aes-aarch64_c_lib',
           ],
         }],
         [ 'OS=="linux"', {
           'defines!': [
@@ -197,16 +230,20 @@
         '<(DEPTH)/exports.gyp:nss_exports',
         'hw-acc-crypto',
       ],
       'conditions': [
         [ 'target_arch=="ia32" or target_arch=="x64"', {
           'dependencies': [
             'gcm-aes-x86_c_lib',
           ]
+        }, 'target_arch=="arm" or target_arch=="arm64" or target_arch=="aarch64"', {
+          'dependencies': [
+            'armv8_c_lib',
+          ],
         }],
         [ 'target_arch=="arm64" or target_arch=="aarch64"', {
           'dependencies': [
             'gcm-aes-aarch64_c_lib',
           ],
         }],
         [ 'OS!="linux"', {
           'conditions': [
@@ -424,16 +461,22 @@
           }],
           [ 'target_arch=="arm"', {
             'defines': [
               'MP_ASSEMBLY_MULTIPLY',
               'MP_ASSEMBLY_SQUARE',
               'MP_USE_UINT_DIGIT',
               'SHA_NO_LONG_LONG',
               'ARMHF',
+              'USE_HW_AES',
+            ],
+          }],
+          [ 'target_arch=="arm64" or target_arch=="aarch64"', {
+            'defines': [
+              'USE_HW_AES',
             ],
           }],
         ],
       }],
     ],
   },
   'variables': {
     'module': 'nss',
--- a/security/nss/lib/freebl/intel-aes.h
+++ b/security/nss/lib/freebl/intel-aes.h
@@ -95,40 +95,40 @@ SECStatus intel_aes_decrypt_cbc_256(AESC
                                     unsigned int blocksize);
 SECStatus intel_aes_encrypt_ctr_256(CTRContext *cx, unsigned char *output,
                                     unsigned int *outputLen,
                                     unsigned int maxOutputLen,
                                     const unsigned char *input,
                                     unsigned int inputLen,
                                     unsigned int blocksize);
 
-#define intel_aes_ecb_worker(encrypt, keysize)                             \
+#define native_aes_ecb_worker(encrypt, keysize)                            \
     ((encrypt)                                                             \
          ? ((keysize) == 16 ? intel_aes_encrypt_ecb_128                    \
                             : (keysize) == 24 ? intel_aes_encrypt_ecb_192  \
                                               : intel_aes_encrypt_ecb_256) \
          : ((keysize) == 16 ? intel_aes_decrypt_ecb_128                    \
                             : (keysize) == 24 ? intel_aes_decrypt_ecb_192  \
                                               : intel_aes_decrypt_ecb_256))
 
-#define intel_aes_cbc_worker(encrypt, keysize)                             \
+#define native_aes_cbc_worker(encrypt, keysize)                            \
     ((encrypt)                                                             \
          ? ((keysize) == 16 ? intel_aes_encrypt_cbc_128                    \
                             : (keysize) == 24 ? intel_aes_encrypt_cbc_192  \
                                               : intel_aes_encrypt_cbc_256) \
          : ((keysize) == 16 ? intel_aes_decrypt_cbc_128                    \
                             : (keysize) == 24 ? intel_aes_decrypt_cbc_192  \
                                               : intel_aes_decrypt_cbc_256))
 
 #define intel_aes_ctr_worker(nr)                         \
     ((nr) == 10 ? intel_aes_encrypt_ctr_128              \
                 : (nr) == 12 ? intel_aes_encrypt_ctr_192 \
                              : intel_aes_encrypt_ctr_256)
 
-#define intel_aes_init(encrypt, keysize)                          \
+#define native_aes_init(encrypt, keysize)                         \
     do {                                                          \
         if (encrypt) {                                            \
             if (keysize == 16)                                    \
                 intel_aes_encrypt_init_128(key, cx->expandedKey); \
             else if (keysize == 24)                               \
                 intel_aes_encrypt_init_192(key, cx->expandedKey); \
             else                                                  \
                 intel_aes_encrypt_init_256(key, cx->expandedKey); \
--- a/security/nss/lib/freebl/pqg.c
+++ b/security/nss/lib/freebl/pqg.c
@@ -885,17 +885,17 @@ findQfromSeed(
     const SECItem *seed,        /* input.  */
     mp_int *Q,                  /* input. */
     mp_int *Q_,                 /* output. */
     unsigned int *qseed_len,    /* output */
     HASH_HashType *hashtypePtr, /* output. Hash uses */
     pqgGenType *typePtr,        /* output. Generation Type used */
     unsigned int *qgen_counter) /* output. q_counter */
 {
-    HASH_HashType hashtype;
+    HASH_HashType hashtype = HASH_AlgNULL;
     SECItem firstseed = { 0, 0, 0 };
     SECItem qseed = { 0, 0, 0 };
     SECStatus rv;
 
     *qseed_len = 0; /* only set if FIPS186_3_ST_TYPE */
 
     /* handle legacy small DSA first can only be FIPS186_1_TYPE */
     if (L < 1024) {
@@ -1234,17 +1234,17 @@ pqg_ParamGen(unsigned int L, unsigned in
              unsigned int seedBytes, PQGParams **pParams, PQGVerify **pVfy)
 {
     unsigned int n;       /* Per FIPS 186, app 2.2. 186-3 app A.1.1.2 */
     unsigned int seedlen; /* Per FIPS 186-3 app A.1.1.2  (was 'g' 186-1)*/
     unsigned int counter; /* Per FIPS 186, app 2.2. 186-3 app A.1.1.2 */
     unsigned int offset;  /* Per FIPS 186, app 2.2. 186-3 app A.1.1.2 */
     unsigned int outlen;  /* Per FIPS 186-3, appendix A.1.1.2. */
     unsigned int maxCount;
-    HASH_HashType hashtype;
+    HASH_HashType hashtype = HASH_AlgNULL;
     SECItem *seed; /* Per FIPS 186, app 2.2. 186-3 app A.1.1.2 */
     PLArenaPool *arena = NULL;
     PQGParams *params = NULL;
     PQGVerify *verify = NULL;
     PRBool passed;
     SECItem hit = { 0, 0, 0 };
     SECItem firstseed = { 0, 0, 0 };
     SECItem qseed = { 0, 0, 0 };
@@ -1625,18 +1625,18 @@ PQG_VerifyParams(const PQGParams *params
     unsigned int g, n, L, N, offset, outlen;
     mp_int p0, P, Q, G, P_, Q_, G_, r, h;
     mp_err err = MP_OKAY;
     int j;
     unsigned int counter_max = 0; /* handle legacy L < 1024 */
     unsigned int qseed_len;
     unsigned int qgen_counter_ = 0;
     SECItem pseed_ = { 0, 0, 0 };
-    HASH_HashType hashtype;
-    pqgGenType type;
+    HASH_HashType hashtype = HASH_AlgNULL;
+    pqgGenType type = FIPS186_1_TYPE;
 
 #define CHECKPARAM(cond)      \
     if (!(cond)) {            \
         *result = SECFailure; \
         goto cleanup;         \
     }
     if (!params || !vfy || !result) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
--- a/security/nss/lib/freebl/rijndael.c
+++ b/security/nss/lib/freebl/rijndael.c
@@ -15,19 +15,28 @@
 #include "blapi.h"
 #include "rijndael.h"
 
 #include "cts.h"
 #include "ctr.h"
 #include "gcm.h"
 #include "mpi.h"
 
+#if !defined(IS_LITTLE_ENDIAN) && !defined(NSS_X86_OR_X64)
+// not test yet on big endian platform of arm
+#undef USE_HW_AES
+#endif
+
 #ifdef USE_HW_AES
+#ifdef NSS_X86_OR_X64
 #include "intel-aes.h"
+#else
+#include "aes-armv8.h"
 #endif
+#endif /* USE_HW_AES */
 #ifdef INTEL_GCM
 #include "intel-gcm.h"
 #endif /* INTEL_GCM */
 
 /* Forward declarations */
 void rijndael_native_key_expansion(AESContext *cx, const unsigned char *key,
                                    unsigned int Nk);
 void rijndael_native_encryptBlock(AESContext *cx,
@@ -842,58 +851,62 @@ aes_InitContext(AESContext *cx, const un
     if (mode == NSS_AES_CBC && iv == NULL) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
     }
     if (!cx) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
     }
-    use_hw_aes = aesni_support() && (keysize % 8) == 0;
+#if defined(NSS_X86_OR_X64) || defined(USE_HW_AES)
+    use_hw_aes = (aesni_support() || arm_aes_support()) && (keysize % 8) == 0;
+#else
+    use_hw_aes = PR_FALSE;
+#endif
     /* Nb = (block size in bits) / 32 */
     cx->Nb = AES_BLOCK_SIZE / 4;
     /* Nk = (key size in bits) / 32 */
     Nk = keysize / 4;
     /* Obtain number of rounds from "table" */
     cx->Nr = RIJNDAEL_NUM_ROUNDS(Nk, cx->Nb);
     /* copy in the iv, if neccessary */
     if (mode == NSS_AES_CBC) {
         memcpy(cx->iv, iv, AES_BLOCK_SIZE);
 #ifdef USE_HW_AES
         if (use_hw_aes) {
             cx->worker = (freeblCipherFunc)
-                intel_aes_cbc_worker(encrypt, keysize);
+                native_aes_cbc_worker(encrypt, keysize);
         } else
 #endif
         {
             cx->worker = (freeblCipherFunc)(encrypt
                                                 ? &rijndael_encryptCBC
                                                 : &rijndael_decryptCBC);
         }
     } else {
 #ifdef USE_HW_AES
         if (use_hw_aes) {
             cx->worker = (freeblCipherFunc)
-                intel_aes_ecb_worker(encrypt, keysize);
+                native_aes_ecb_worker(encrypt, keysize);
         } else
 #endif
         {
             cx->worker = (freeblCipherFunc)(encrypt
                                                 ? &rijndael_encryptECB
                                                 : &rijndael_decryptECB);
         }
     }
     PORT_Assert((cx->Nb * (cx->Nr + 1)) <= RIJNDAEL_MAX_EXP_KEY_SIZE);
     if ((cx->Nb * (cx->Nr + 1)) > RIJNDAEL_MAX_EXP_KEY_SIZE) {
         PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
         return SECFailure;
     }
 #ifdef USE_HW_AES
     if (use_hw_aes) {
-        intel_aes_init(encrypt, keysize);
+        native_aes_init(encrypt, keysize);
     } else
 #endif
     {
         /* Generate expanded key */
         if (encrypt) {
             if (use_hw_aes && (cx->mode == NSS_AES_GCM || cx->mode == NSS_AES ||
                                cx->mode == NSS_AES_CTR)) {
                 PORT_Assert(keysize == 16 || keysize == 24 || keysize == 32);
--- a/security/nss/lib/softoken/fipstokn.c
+++ b/security/nss/lib/softoken/fipstokn.c
@@ -640,27 +640,47 @@ FC_InitPIN(CK_SESSION_HANDLE hSession,
 CK_RV
 FC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
           CK_ULONG usOldLen, CK_CHAR_PTR pNewPin, CK_ULONG usNewLen)
 {
     CK_RV rv;
 
     CHECK_FORK();
 
-    if ((rv = sftk_fipsCheck()) == CKR_OK &&
-        (rv = sftk_newPinCheck(pNewPin, usNewLen)) == CKR_OK) {
+    rv = sftk_fipsCheck();
+    if (rv != CKR_OK) {
+        goto loser;
+    }
+
+    if (isLevel2 || usNewLen > 0) {
+        rv = sftk_newPinCheck(pNewPin, usNewLen);
+        if (rv != CKR_OK) {
+            goto loser;
+        }
         rv = NSC_SetPIN(hSession, pOldPin, usOldLen, pNewPin, usNewLen);
-        if ((rv == CKR_OK) &&
-            (sftk_SlotIDFromSessionHandle(hSession) == FIPS_SLOT_ID)) {
+        if (rv != CKR_OK) {
+            goto loser;
+        }
+        if (sftk_SlotIDFromSessionHandle(hSession) == FIPS_SLOT_ID) {
             /* if we set the password in level1 we now go
              * to level2. NOTE: we don't allow the user to
              * go from level2 to level1 */
             isLevel2 = PR_TRUE;
         }
+    } else {
+        /* here both old and new passwords are empty, but we need to
+         * call NSC_SetPIN to force rekey the database entries */
+        PORT_Assert(usNewLen == 0);
+        rv = NSC_SetPIN(hSession, pOldPin, usOldLen, pNewPin, usNewLen);
+        if (rv != CKR_OK) {
+            goto loser;
+        }
     }
+
+loser:
     if (sftk_audit_enabled) {
         char msg[128];
         NSSAuditSeverity severity = (rv == CKR_OK) ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
         PR_snprintf(msg, sizeof msg,
                     "C_SetPIN(hSession=0x%08lX)=0x%08lX",
                     (PRUint32)hSession, (PRUint32)rv);
         sftk_LogAuditMessage(severity, NSS_AUDIT_SET_PIN, msg);
     }
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -3895,17 +3895,20 @@ NSC_SetPIN(CK_SESSION_HANDLE hSession, C
     sftk_FreeSession(sp);
     sp = NULL;
 
     /* make sure the pins aren't too long */
     if ((ulNewLen > SFTK_MAX_PIN) || (ulOldLen > SFTK_MAX_PIN)) {
         crv = CKR_PIN_LEN_RANGE;
         goto loser;
     }
-    if (ulNewLen < (CK_ULONG)slot->minimumPinLen) {
+    /* check the length of new pin, unless both old and new passwords
+     * are empty */
+    if ((ulNewLen != 0 || ulOldLen != 0) &&
+        ulNewLen < (CK_ULONG)slot->minimumPinLen) {
         crv = CKR_PIN_LEN_RANGE;
         goto loser;
     }
 
     /* convert to null terminated string */
     PORT_Memcpy(newPinStr, pNewPin, ulNewLen);
     newPinStr[ulNewLen] = 0;
     PORT_Memcpy(oldPinStr, pOldPin, ulOldLen);
--- a/security/nss/lib/softoken/pkcs11i.h
+++ b/security/nss/lib/softoken/pkcs11i.h
@@ -454,17 +454,17 @@ struct SFTKItemTemplateStr {
 /* certdb (high bit == 1) */
 #define SFTK_TOKEN_TYPE_TRUST 0x40000000L
 #define SFTK_TOKEN_TYPE_CRL 0x50000000L
 #define SFTK_TOKEN_TYPE_SMIME 0x60000000L
 #define SFTK_TOKEN_TYPE_CERT 0x70000000L
 
 #define SFTK_TOKEN_KRL_HANDLE (SFTK_TOKEN_MAGIC | SFTK_TOKEN_TYPE_CRL | 1)
 /* how big (in bytes) a password/pin we can deal with */
-#define SFTK_MAX_PIN 255
+#define SFTK_MAX_PIN 500
 /* minimum password/pin length (in Unicode characters) in FIPS mode */
 #define FIPS_MIN_PIN 7
 
 /* slot ID's */
 #define NETSCAPE_SLOT_ID 1
 #define PRIVATE_KEY_SLOT_ID 2
 #define FIPS_SLOT_ID 3
 
--- a/security/nss/mach
+++ b/security/nss/mach
@@ -192,16 +192,23 @@ class coverityAction(argparse.Action):
 
     def cov_is_file_in_source(self, abs_path):
         if os.path.islink(abs_path):
             abs_path = os.path.realpath(abs_path)
         return abs_path
 
     def dump_cov_artifact(self, cov_results, source, output):
         import json
+
+        def relpath(path):
+            '''Build path relative to repository root'''
+            if path.startswith(cwd):
+                return os.path.relpath(path, cwd)
+            return path
+
         # Parse Coverity json into structured issues
         with open(cov_results) as f:
             result = json.load(f)
 
             # Parse the issues to a standard json format
             issues_dict = {'files': {}}
 
             files_list = issues_dict['files']
@@ -218,30 +225,31 @@ class coverityAction(argparse.Action):
                         'category': issue['checkerProperties']['category'],
                         'stateOnServer': issue['stateOnServer'],
                         'stack': []
                     }
                 }
 
                 # Embed all events into extra message
                 for event in issue['events']:
-                    dict_issue['extra']['stack'].append({'file_path': event['strippedFilePathname'],
+                    dict_issue['extra']['stack'].append({'file_path': relpath(event['strippedFilePathname']),
                                                          'line_number': event['lineNumber'],
                                                          'path_type': event['eventTag'],
                                                          'description': event['eventDescription']})
 
                 return dict_issue
 
             for issue in result['issues']:
                 path = self.cov_is_file_in_source(issue['strippedMainEventFilePathname'])
                 if path is None:
                     # Since we skip a result we should log it
                     print('Skipping CID: {0} from file: {1} since it\'s not related with the current patch.'.format(
                         issue['stateOnServer']['cid'], issue['strippedMainEventFilePathname']))
                     continue
+                path = relpath(path)
                 if path in files_list:
                     files_list[path]['warnings'].append(build_element(issue))
                 else:
                     files_list[path] = {'warnings': [build_element(issue)]}
 
             with open(output, 'w') as f:
                 json.dump(issues_dict, f)
 
--- a/uriloader/prefetch/OfflineCacheUpdateParent.cpp
+++ b/uriloader/prefetch/OfflineCacheUpdateParent.cpp
@@ -236,24 +236,16 @@ OfflineCacheUpdateParent::GetUseRemoteSu
 }
 
 NS_IMETHODIMP
 OfflineCacheUpdateParent::SetRemoteSubframes(bool aUseRemoteSubframes) {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-OfflineCacheUpdateParent::GetIsInIsolatedMozBrowserElement(
-    bool* aIsInIsolatedMozBrowserElement) {
-  NS_ENSURE_TRUE(mLoadingPrincipal, NS_ERROR_UNEXPECTED);
-  return mLoadingPrincipal->GetIsInIsolatedMozBrowserElement(
-      aIsInIsolatedMozBrowserElement);
-}
-
-NS_IMETHODIMP
 OfflineCacheUpdateParent::GetScriptableOriginAttributes(
     JSContext* aCx, JS::MutableHandleValue aAttrs) {
   NS_ENSURE_TRUE(mLoadingPrincipal, NS_ERROR_UNEXPECTED);
 
   nsresult rv = mLoadingPrincipal->GetOriginAttributes(aCx, aAttrs);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
--- a/uriloader/prefetch/nsIOfflineCacheUpdate.idl
+++ b/uriloader/prefetch/nsIOfflineCacheUpdate.idl
@@ -218,19 +218,19 @@ interface nsIOfflineCacheUpdateService :
      */
     nsIOfflineCacheUpdate scheduleUpdate(in nsIURI aManifestURI,
                                          in nsIURI aDocumentURI,
                                          in nsIPrincipal aLoadingPrincipal,
                                          in mozIDOMWindow aWindow);
 
     /**
      * Schedule a cache update for a given offline manifest using app cache
-     * bound to the given appID+inIsolatedMozBrowser flag.  If an existing update
-     * is scheduled or running, that update will be returned. Otherwise a new
-     * update will be scheduled.
+     * bound to the given appID flag.  If an existing update is scheduled or
+     * running, that update will be returned. Otherwise a new update will be
+     * scheduled.
      */
     nsIOfflineCacheUpdate scheduleAppUpdate(in nsIURI aManifestURI,
                                             in nsIURI aDocumentURI,
                                             in nsIPrincipal aLoadingPrincipal,
                                             in nsIFile aProfileDir);
 
     /**
      * Schedule a cache update for a manifest when the document finishes
--- a/xpcom/ds/StaticAtoms.py
+++ b/xpcom/ds/StaticAtoms.py
@@ -695,17 +695,16 @@ STATIC_ATOMS = [
     Atom("norolluponanchor", "norolluponanchor"),
     Atom("noBar", "no-bar"),
     Atom("nobr", "nobr"),
     Atom("nodefaultsrc", "nodefaultsrc"),
     Atom("nodeSet", "node-set"),
     Atom("noembed", "noembed"),
     Atom("noframes", "noframes"),
     Atom("nohref", "nohref"),
-    Atom("noisolation", "noisolation"),
     Atom("nomodule", "nomodule"),
     Atom("nonce", "nonce"),
     Atom("none", "none"),
     Atom("noresize", "noresize"),
     Atom("normal", "normal"),
     Atom("normalizeSpace", "normalize-space"),
     Atom("noscript", "noscript"),
     Atom("noshade", "noshade"),