diff --git a/zircon/system/core/devmgr/fshost/BUILD.gn b/zircon/system/core/devmgr/fshost/BUILD.gn
index b766170bfe284e1ef9748200fa0b9b24d80a94c9..0f169c9c1cdf1a6bbf13fa2f818540c6afaeb260 100644
--- a/zircon/system/core/devmgr/fshost/BUILD.gn
+++ b/zircon/system/core/devmgr/fshost/BUILD.gn
@@ -63,7 +63,7 @@ source_set("block-watcher") {
     "$zx/system/ulib/zircon",
     "$zx/system/ulib/zx",
     "$zx/system/ulib/zxcpp",
-    "$zx/system/ulib/zxcrypt",
+    "$zx/system/ulib/zxcrypt:zxcrypt-fdio",
   ]
 }
 
diff --git a/zircon/system/dev/block/zxcrypt/BUILD.gn b/zircon/system/dev/block/zxcrypt/BUILD.gn
index 50b5d08ab23dd99159f34f5e857122f507dcb95c..6a1a4e820b40ba2995672472a24dbcd4f954f3d0 100644
--- a/zircon/system/dev/block/zxcrypt/BUILD.gn
+++ b/zircon/system/dev/block/zxcrypt/BUILD.gn
@@ -12,13 +12,18 @@ driver("zxcrypt") {
     "worker.cpp",
   ]
   configs += [ "$zx/public/gn/config:integer-paranoia" ]
+
+  # Until library loading is fully async, dynamically linking libraries can
+  # deadlock block device drviers. All dependencies for zxcrypt should be
+  # static or already linked by the devhost.  We consider libc, libzircon, and
+  # libdriver safe to depend on dynamically here.
   deps = [
     "$zx/system/banjo/ddk.protocol.block",
     "$zx/system/banjo/ddk.protocol.block.partition",
     "$zx/system/banjo/ddk.protocol.block.volume",
     "$zx/system/fidl/fuchsia-hardware-zxcrypt:c",
     "$zx/system/ulib/bitmap",
-    "$zx/system/ulib/crypto",
+    "$zx/system/ulib/crypto:zircon-crypto.static",
     "$zx/system/ulib/ddk",
     "$zx/system/ulib/ddktl",
     "$zx/system/ulib/fbl",
@@ -26,6 +31,18 @@ driver("zxcrypt") {
     "$zx/system/ulib/zircon",
     "$zx/system/ulib/zx",
     "$zx/system/ulib/zxcpp",
-    "$zx/system/ulib/zxcrypt",
+    "$zx/system/ulib/zxcrypt:zxcrypt-dev.static",
+  ]
+
+  # Make sure we don't accidentally pull in a couple of easily-added dynamic
+  # library dependencies.
+  assert_no_deps = [
+    "$zx/system/ulib/trace-engine",
+    "$zx/system/ulib/crypto:zircon-crypto",
+    # Some day, we'd also like to be able to assert we don't pull in fdio here,
+    # but it is pulled in transitively by //$zx/system/ulib/driver, which is
+    # needed by //$zx/system/ulib/zxcrypt-dev for the symbol
+    # |device_get_protocol|.
+    #"$zx/system/ulib/fdio",
   ]
 }
diff --git a/zircon/system/ulib/BUILD.gn b/zircon/system/ulib/BUILD.gn
index 8615d6b1fe7ffd99a22da182523b70a6665fc7fa..e2addc857f131dc377b6e96589e8090fc697cca4 100644
--- a/zircon/system/ulib/BUILD.gn
+++ b/zircon/system/ulib/BUILD.gn
@@ -135,7 +135,8 @@ group("ulib") {
     "zircon-internal",
     "zx",
     "zxcpp",
-    "zxcrypt",
+    "zxcrypt:zxcrypt-dev",
+    "zxcrypt:zxcrypt-fdio",
     "zxio",
     "zxs",
     "zxtest",
diff --git a/zircon/system/ulib/crypto/BUILD.gn b/zircon/system/ulib/crypto/BUILD.gn
index f0546052faf8e6e9f1528bbd619f45a340045727..99b118600a4acd2ab31fcf0b0123f9a6bc7385d7 100644
--- a/zircon/system/ulib/crypto/BUILD.gn
+++ b/zircon/system/ulib/crypto/BUILD.gn
@@ -33,7 +33,6 @@ library("zircon-crypto") {
   deps = [
     "$zx/system/ulib/explicit-memory",
     "$zx/system/ulib/fbl",
-    "$zx/system/ulib/fdio",
     "$zx/system/ulib/zircon",
     "$zx/system/ulib/zircon-internal",
     "$zx/system/ulib/zxcpp",
diff --git a/zircon/system/ulib/paver/BUILD.gn b/zircon/system/ulib/paver/BUILD.gn
index eecea0846ad151cfacc05fad5b39208e940bef97..0a1d4135e7dc2c355a9c009938069e7d812d4aa7 100644
--- a/zircon/system/ulib/paver/BUILD.gn
+++ b/zircon/system/ulib/paver/BUILD.gn
@@ -38,7 +38,7 @@ library("paver") {
     "$zx/system/ulib/zircon",
     "$zx/system/ulib/zx",
     "$zx/system/ulib/zxcpp",
-    "$zx/system/ulib/zxcrypt",
+    "$zx/system/ulib/zxcrypt:zxcrypt-fdio",
     "$zx/third_party/ulib/cksum",
     "$zx/third_party/ulib/lz4",
     "$zx/third_party/ulib/uboringssl",
diff --git a/zircon/system/ulib/pretty/BUILD.gn b/zircon/system/ulib/pretty/BUILD.gn
index 0acc3648cfcd19c3bc619d759a6125bc0db2795a..068a64a791507bbdbc02eb1a22ae8464412ee73e 100644
--- a/zircon/system/ulib/pretty/BUILD.gn
+++ b/zircon/system/ulib/pretty/BUILD.gn
@@ -17,11 +17,6 @@ library("pretty") {
   if (!is_kernel) {
     sources += [ "hexdump.c" ]
   }
-  if (!is_kernel && is_fuchsia) {
-    deps = [
-      "$zx/system/ulib/fdio",
-    ]
-  }
 }
 
 test("pretty-test") {
@@ -30,6 +25,7 @@ test("pretty-test") {
   ]
   deps = [
     ":pretty",
+    "$zx/system/ulib/fdio",
     "$zx/system/ulib/unittest",
   ]
 }
diff --git a/zircon/system/ulib/unittest/BUILD.gn b/zircon/system/ulib/unittest/BUILD.gn
index 6000aea9b89a53a82f37d474d1069d8a2f1c7ae9..ad35626106f82c8ad14e9d6c4345c7553aac466d 100644
--- a/zircon/system/ulib/unittest/BUILD.gn
+++ b/zircon/system/ulib/unittest/BUILD.gn
@@ -15,6 +15,7 @@ library("unittest") {
     "watchdog.cpp",
   ]
   deps = [
+    "$zx/system/ulib/fdio",
     "$zx/system/ulib/pretty",
   ]
   if (is_fuchsia) {
diff --git a/zircon/system/ulib/zxcrypt/BUILD.gn b/zircon/system/ulib/zxcrypt/BUILD.gn
index 11e3a354588e94cb5892bf9f4fe63185f672709f..ae17c7662f43eaf5827460dd9f228c4889c4aec1 100644
--- a/zircon/system/ulib/zxcrypt/BUILD.gn
+++ b/zircon/system/ulib/zxcrypt/BUILD.gn
@@ -2,37 +2,65 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-library("zxcrypt") {
+library("zxcrypt-dev") {
   shared = true
+  static = true
   sources = [
     "ddk-volume.cpp",
-    "fdio-volume.cpp",
     "volume.cpp",
   ]
+
   public_deps = [
-    # <zxcrypt/volume.h> has #include <crypto/aead.h>.
+    # <zxcrypt/volume.h> has #include <crypto/aead.h> (among others).
     "$zx/system/ulib/crypto:headers",
 
-    # <zxcrypt/volume.h> has #include <ddk/device.h>.
+    # <zxcrypt/ddk-volume.h> has #include <ddk/device.h>.
     "$zx/system/ulib/ddk:headers",
   ]
+
   configs += [ "$zx/public/gn/config:integer-paranoia" ]
+
+  # To minimize the set of libraries that we depend on that need to be loaded
+  # from /boot/lib in early boot, we statically link most of our dependencies.
   deps = [
     "$zx/system/banjo/ddk.protocol.block",
     "$zx/system/banjo/ddk.protocol.block.volume",
+    "$zx/system/ulib/crypto:zircon-crypto.static",
+    "$zx/system/ulib/ddk",
+    "$zx/system/ulib/driver",
+    "$zx/system/ulib/fbl",
+    "$zx/system/ulib/fs-management:headers", # only used for zxcrypt_magic
+    "$zx/system/ulib/sync",
+    "$zx/system/ulib/zircon",
+    "$zx/system/ulib/zircon-internal",
+    "$zx/system/ulib/zx",
+    "$zx/system/ulib/zxcpp",
+    "$zx/third_party/ulib/uboringssl",
+  ]
+}
+
+library("zxcrypt-fdio") {
+  shared = true
+  sources = [
+    "fdio-volume.cpp",
+    "volume.cpp",
+  ]
+  public_deps = [
+    # <zxcrypt/volume.h> has #include <crypto/aead.h> (among others).
+    "$zx/system/ulib/crypto:headers",
+  ]
+  configs += [ "$zx/public/gn/config:integer-paranoia" ]
+  deps = [
     "$zx/system/fidl/fuchsia-device:c",
     "$zx/system/fidl/fuchsia-hardware-block:c",
     "$zx/system/fidl/fuchsia-hardware-block-volume:c",
     "$zx/system/fidl/fuchsia-hardware-zxcrypt:c",
     "$zx/system/ulib/crypto",
-    "$zx/system/ulib/ddk",
-    "$zx/system/ulib/driver",
     "$zx/system/ulib/fbl",
     "$zx/system/ulib/fdio",
-    "$zx/system/ulib/fs-management",
+    "$zx/system/ulib/fs-management:headers", # only used for zxcrypt_magic
     "$zx/system/ulib/fzl",
     "$zx/system/ulib/kms-stateless",
-    "$zx/system/ulib/pretty",
     "$zx/system/ulib/ramdevice-client:static",
     "$zx/system/ulib/sync",
     "$zx/system/ulib/zircon",
diff --git a/zircon/system/utest/zxcrypt/BUILD.gn b/zircon/system/utest/zxcrypt/BUILD.gn
index 9f13ad199dcbdc04e767450cd415b72648e77ea9..661d0ebe533ed75799c607c3a41a5d91302e93d2 100644
--- a/zircon/system/utest/zxcrypt/BUILD.gn
+++ b/zircon/system/utest/zxcrypt/BUILD.gn
@@ -36,7 +36,7 @@ test("zxcrypt") {
     "$zx/system/ulib/zircon-internal",
     "$zx/system/ulib/zx",
     "$zx/system/ulib/zxcpp",
-    "$zx/system/ulib/zxcrypt",
+    "$zx/system/ulib/zxcrypt:zxcrypt-fdio",
     "$zx/third_party/ulib/cryptolib",
     "$zx/third_party/ulib/uboringssl",
   ]
diff --git a/zircon/third_party/ulib/uboringssl/BUILD.gn b/zircon/third_party/ulib/uboringssl/BUILD.gn
index 853b4a0feec431dae384256ba5072f83577d9d99..6bd4b7a0cc0d284465f6df05db8d09f4fe1ccb66 100644
--- a/zircon/third_party/ulib/uboringssl/BUILD.gn
+++ b/zircon/third_party/ulib/uboringssl/BUILD.gn
@@ -28,7 +28,6 @@ library("uboringssl") {
 
     if (is_fuchsia) {
       deps = [
-        "$zx/system/ulib/fdio",
         "$zx/system/ulib/zircon",
       ]
     } else {