Docs: Changes to source.android.com

  - 182097815 Devsite localized content from translation request 89fffe... by Android Partner Docs <noreply@android.com>
  - 182097813 Devsite localized content from translation request be8c28... by Android Partner Docs <noreply@android.com>
  - 182097355 Devsite localized content from translation request 4fe194... by Android Partner Docs <noreply@android.com>
  - 181865621 Fix typo in Retail Demo Mode page by Android Partner Docs <noreply@android.com>
  - 181807349 CDD: Remove redundant requirement on UMS/MTP from 7.7 by Android Partner Docs <noreply@android.com>
  - 181807212 CDD: Clarify the charging specs to refer when a USB type ... by Android Partner Docs <noreply@android.com>
  - 181804909 CDD: Relax CDD for activity switching. by Android Partner Docs <noreply@android.com>
  - 181804579 CDD: Clarify that the AOSP implementation of TEE is a pre... by Android Partner Docs <noreply@android.com>
  - 181804086  by Android Partner Docs <noreply@android.com>
  - 181767441 Devsite localized content from translation request d399d0... by Android Partner Docs <noreply@android.com>
  - 181767313 Devsite localized content from translation request 209cd7... by Android Partner Docs <noreply@android.com>
  - 181624191 Devsite localized content from translation request 66ed20... by Android Partner Docs <noreply@android.com>
  - 181624182 Devsite localized content from translation request 6766af... by Android Partner Docs <noreply@android.com>
  - 181624174 Devsite localized content from translation request 97607c... by Android Partner Docs <noreply@android.com>
  - 181488065 Update CTS/CTS-Verifier downloads for CTS-Jan-2018 Releases by Android Partner Docs <noreply@android.com>
  - 181482740 Break out the FAQs into a separate page now that A/B is i... by Christina Nguyen <cqn@google.com>
  - 181409586 Reverted the old cl/181349324 and re-did the changes usin... by Christina Nguyen <cqn@google.com>
  - 181388377 Devsite localized content from translation request a3ea97... by Android Partner Docs <noreply@android.com>
  - 181387974 Devsite localized content from translation request 70181e... by Android Partner Docs <noreply@android.com>
  - 181387712 Removing unused Git resources file (was previously remove... by Heidi von Markham <hvm@google.com>

PiperOrigin-RevId: 182097815
Change-Id: I4df35e68e1c85e2c29f0438820528f326b097cea
diff --git a/en/compatibility/5.1/android-5.1-cdd.html b/en/compatibility/5.1/android-5.1-cdd.html
index 7744896..3d0fe89 100644
--- a/en/compatibility/5.1/android-5.1-cdd.html
+++ b/en/compatibility/5.1/android-5.1-cdd.html
@@ -3862,9 +3862,6 @@
 orientation) or enable software screen rotation for all apps (including home
 screen), so that the display draws correctly when the device is oriented with
 the port at bottom. Existing and new Android devices are <strong>very strongly encouraged to meet these requirements</strong> so they will be able to upgrade to future platform releases.</li>
-  <li>It MUST allow a USB host connected with the Android device to access the
-contents of the shared storage volume using either USB mass storage or Media
-Transfer Protocol.</li>
   <li>It SHOULD implement the Android Open Accessory (AOA) API and specification as
 documented in the Android SDK documentation, and if it is an Android Handheld
 device it MUST implement the AOA API. Device implementations implementing the
diff --git a/en/compatibility/6.0/android-6.0-cdd.html b/en/compatibility/6.0/android-6.0-cdd.html
index ba8ea51..ab69db8 100644
--- a/en/compatibility/6.0/android-6.0-cdd.html
+++ b/en/compatibility/6.0/android-6.0-cdd.html
@@ -1600,7 +1600,7 @@
 
 <ul>
   <li>MUST display affiliated recents as a group that moves together.</li>
-  <li>MUST support at least up to 20 displayed activities.</li>
+  <li>MUST support at least up to 6 displayed activities.</li>
   <li>MUST at least display the title of 4 activities at a time.</li>
   <li>SHOULD display highlight color, icon, screen title in recents.</li>
   <li>MUST implement the screen pinning behavior [<a href="http://developer.android.com/about/versions/android-5.0.html#ScreenPinning">Resources, 38</a>] and provide the user with a settings menu to toggle the feature.</li>
@@ -3782,12 +3782,12 @@
     <li>MUST have a batching power consumption not worse than 2 mW</li>
   </ul>
   </li>
-  <li>SENSOR_TYPE_ROTATION_VECTOR
+  <li>TYPE_GAME_ROTATION_VECTOR
   <ul>
-    <li>MUST have a batching power consumption not worse than 4 mW</li>
-  </ul>
+    <li>MUST implement a non-wake-up form of this sensor with a buffering capability of at least 300 sensor events.</li>
+    <li>MUST have a batching power consumption not worse than 4 mW.</li>
+    </ul>
   </li>
-  <li>SENSOR_TYPE_GAME_ROTATION_VECTOR MUST implement a non-wake-up form of this sensor with a buffering capability of at least 300 sensor events</li>
   <li>SENSOR_TYPE_SIGNIFICANT_MOTION
   <ul>
     <li>MUST have a power consumption not worse than 0.5 mW when device is static
@@ -3876,9 +3876,9 @@
     on the Android Open Source Project site
     [<a href="https://source.android.com/devices/tech/security/authentication/fingerprint-hal.html">Resources, 96</a>].
   </li>
-  <li>MUST prevent adding a fingerprint without first establishing a chain of trust by
-    having the user confirm existing or add a new device credential (PIN/pattern/password)
-    using the TEE as implemented in the Android Open Source project.</li>
+  <li> MUST prevent adding a fingerprint without first establishing a chain of trust by having the
+user confirm existing or add a new device credential (PIN/pattern/password) that's secured by TEE;
+the Android Open Source Project implementation provides the mechanism in the framework to do so.</li>
   <li>MUST NOT enable 3rd-party applications to distinguish between individual fingerprints.
   </li>
   <li>MUST honor the DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT flag.</li>
@@ -4574,8 +4574,11 @@
 documentation [<a href="http://developer.android.com/reference/android/hardware/usb/UsbConstants.html#USB_CLASS_AUDIO">Resources, 119</a>].</li>
   <li>MUST implement the Android USB host API as documented in the Android SDK, and
 MUST declare support for the hardware feature android.hardware.usb.host [<a href="http://developer.android.com/guide/topics/connectivity/usb/host.html">Resources, 121</a>].</li>
-  <li>SHOULD support the Charging Downstream Port output current range of 1.5 A ~ 5 A
-as specified in the USB Battery Charging Specification, Revision 1.2 [<a href="http://www.usb.org/developers/docs/devclass_docs/BCv1.2_070312.zip">Resources, 120</a>].</li>
+  <li>SHOULD support device charging while in host mode; advertising a source current of at least
+1.5A as specified in the Termination Parameters section of the USB Type-C Cable and Connector
+Specification, Revision 1.2 [<a href="http://www.usb.org/developers/docs/usb_31_021517.zip"></a>]
+for USB Type-C connectors or using Charging Downstream Port(CDP) output current range as specified
+in the USB Battery Charging Specification, Revision 1.2 [<a href="http://www.usb.org/developers/docs/devclass_docs/BCv1.2_070312.zip">Resources, 120</a>] for Micro-AB connectors.</li>
 </ul>
 
 <h2 id="7_8_audio">7.8. Audio</h2>
diff --git a/en/compatibility/cts/downloads.html b/en/compatibility/cts/downloads.html
index 19635ca..ab07ebd 100644
--- a/en/compatibility/cts/downloads.html
+++ b/en/compatibility/cts/downloads.html
@@ -50,96 +50,96 @@
 <h2 id="android-80">Android 8.0</h2>
 <p>Android 8.0 is the release of the development milestone code-named Oreo.
 The source code for the following tests can be synced with the
-'android-cts-8.0_r4' tag in the open-source tree.</p>
+'android-cts-8.0_r5' tag in the open-source tree.</p>
 <ul>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-8.0_r4-linux_x86-arm.zip">Android
-8.0 R4 Compatibility Test Suite (CTS) - ARM</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-8.0_r5-linux_x86-arm.zip">Android
+8.0 R5 Compatibility Test Suite (CTS) - ARM</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-8.0_r4-linux_x86-x86.zip">Android
-8.0 R4 Compatibility Test Suite (CTS) - x86</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-8.0_r5-linux_x86-x86.zip">Android
+8.0 R5 Compatibility Test Suite (CTS) - x86</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-verifier-8.0_r4-linux_x86-arm.zip">Android
-8.0 R4 CTS Verifier - ARM</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-verifier-8.0_r5-linux_x86-arm.zip">Android
+8.0 R5 CTS Verifier - ARM</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-verifier-8.0_r4-linux_x86-x86.zip">Android
-8.0 R4 CTS Verifier - x86</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-verifier-8.0_r5-linux_x86-x86.zip">Android
+8.0 R5 CTS Verifier - x86</a></li>
 </ul>
 
 <h2 id="android-71">Android 7.1</h2>
 <p>Android 7.1 is the release of the development milestone code-named Nougat-MR1.
 The source code for the following tests can be synced with the
-'android-cts-7.1_r12' tag in the open-source tree.</p>
+'android-cts-7.1_r13' tag in the open-source tree.</p>
 <ul>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-7.1_r12-linux_x86-arm.zip">Android
-7.1 R12 Compatibility Test Suite (CTS) - ARM</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-7.1_r13-linux_x86-arm.zip">Android
+7.1 R13 Compatibility Test Suite (CTS) - ARM</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-7.1_r12-linux_x86-x86.zip">Android
-7.1 R12 Compatibility Test Suite (CTS) - x86</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-7.1_r13-linux_x86-x86.zip">Android
+7.1 R13 Compatibility Test Suite (CTS) - x86</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.1_r12-linux_x86-arm.zip">Android
-7.1 R12 CTS Verifier - ARM</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.1_r13-linux_x86-arm.zip">Android
+7.1 R13 CTS Verifier - ARM</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.1_r12-linux_x86-x86.zip">Android
-7.1 R12 CTS Verifier - x86</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.1_r13-linux_x86-x86.zip">Android
+7.1 R13 CTS Verifier - x86</a></li>
 </ul>
 
 <h2 id="android-70">Android 7.0</h2>
 <p>Android 7.0 is the release of the development milestone code-named Nougat.
 The source code for the following tests can be synced with the
-'android-cts-7.0_r16' tag in the open-source tree.</p>
+'android-cts-7.0_r17' tag in the open-source tree.</p>
 <ul>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-7.0_r16-linux_x86-arm.zip">Android
-7.0 R16 Compatibility Test Suite (CTS) - ARM</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-7.0_r17-linux_x86-arm.zip">Android
+7.0 R17 Compatibility Test Suite (CTS) - ARM</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-7.0_r16-linux_x86-x86.zip">Android
-7.0 R16 Compatibility Test Suite (CTS) - x86</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-7.0_r17-linux_x86-x86.zip">Android
+7.0 R17 Compatibility Test Suite (CTS) - x86</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.0_r16-linux_x86-arm.zip">Android
-7.0 R16 CTS Verifier - ARM</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.0_r17-linux_x86-arm.zip">Android
+7.0 R17 CTS Verifier - ARM</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.0_r16-linux_x86-x86.zip">Android
-7.0 R16 CTS Verifier - x86</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.0_r17-linux_x86-x86.zip">Android
+7.0 R17 CTS Verifier - x86</a></li>
 </ul>
 
 <h2 id="android-60">Android 6.0</h2>
 <p>Android 6.0 is the release of the development milestone code-named Marshmallow.
 The source code for the following tests can be synced with the
-'android-cts-6.0_r24' tag in the open-source tree.</p>
+'android-cts-6.0_r25' tag in the open-source tree.</p>
 <ul>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-6.0_r24-linux_x86-arm.zip">Android
-6.0 R24 Compatibility Test Suite (CTS) - ARM</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-6.0_r25-linux_x86-arm.zip">Android
+6.0 R25 Compatibility Test Suite (CTS) - ARM</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-6.0_r24-linux_x86-x86.zip">Android
-6.0 R24 Compatibility Test Suite (CTS) - x86</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-6.0_r25-linux_x86-x86.zip">Android
+6.0 R25 Compatibility Test Suite (CTS) - x86</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-verifier-6.0_r24-linux_x86-arm.zip">Android
-6.0 R24 CTS Verifier - ARM</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-verifier-6.0_r25-linux_x86-arm.zip">Android
+6.0 R25 CTS Verifier - ARM</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-verifier-6.0_r24-linux_x86-x86.zip">Android
-6.0 R24 CTS Verifier - x86</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-verifier-6.0_r25-linux_x86-x86.zip">Android
+6.0 R25 CTS Verifier - x86</a></li>
 </ul>
 
 <h2 id="android-51">Android 5.1</h2>
 <p>Android 5.1 is the release of the development milestone code-named Lollipop-MR1.
 The source code for the following tests can be synced with the
-'android-cts-5.1_r25' tag in the open source tree.</p>
+'android-cts-5.1_r26' tag in the open source tree.</p>
 <ul>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-5.1_r25-linux_x86-arm.zip">Android
-5.1 R25 Compatibility Test Suite (CTS) - ARM</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-5.1_r26-linux_x86-arm.zip">Android
+5.1 R26 Compatibility Test Suite (CTS) - ARM</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-5.1_r25-linux_x86-x86.zip">Android
-5.1 R25 Compatibility Test Suite (CTS) - x86</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-5.1_r26-linux_x86-x86.zip">Android
+5.1 R26 Compatibility Test Suite (CTS) - x86</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-verifier-5.1_r25-linux_x86-arm.zip">Android
-5.1 R25 CTS Verifier - ARM</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-verifier-5.1_r26-linux_x86-arm.zip">Android
+5.1 R26 CTS Verifier - ARM</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-verifier-5.1_r25-linux_x86-x86.zip">Android
-5.1 R25 CTS Verifier - x86</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-verifier-5.1_r26-linux_x86-x86.zip">Android
+5.1 R26 CTS Verifier - x86</a></li>
 </ul>
 
 <h2 id="android-50">Android 5.0</h2>
diff --git a/en/devices/_toc-tech.yaml b/en/devices/_toc-tech.yaml
index 43897c4..77e2419 100644
--- a/en/devices/_toc-tech.yaml
+++ b/en/devices/_toc-tech.yaml
@@ -188,17 +188,23 @@
   - title: Reducing OTA Size
     path: /devices/tech/ota/reduce_size
   - title: A/B System Updates
-    path: /devices/tech/ota/ab_updates
-  - title: Implementing A/B Updates
-    path: /devices/tech/ota/ab_implement
+    section:
+    - title: Overview
+      path: /devices/tech/ota/ab/
+    - title: Implementing A/B Updates
+      path: /devices/tech/ota/ab/ab_implement
+    - title: Frequently Asked Questions
+      path: /devices/tech/ota/ab/ab_faqs
   - title: Non-A/B System Updates
-    path: /devices/tech/ota/nonab_updates
-  - title: Block-Based OTA
-    path: /devices/tech/ota/block
-  - title: Inside OTA Packages
-    path: /devices/tech/ota/inside_packages
-  - title: Device-Specific Code
-    path: /devices/tech/ota/device_code
+    section:
+    - title: Overview
+      path: /devices/tech/ota/nonab/
+    - title: Block-Based OTA
+      path: /devices/tech/ota/nonab/block
+    - title: Inside OTA Packages
+      path: /devices/tech/ota/nonab/inside_packages
+    - title: Device-Specific Code
+      path: /devices/tech/ota/nonab/device_code
 - title: Performance
   section:
   - title: Overview
diff --git a/en/devices/tech/display/retail-mode.html b/en/devices/tech/display/retail-mode.html
index 2928b88..5e12473 100644
--- a/en/devices/tech/display/retail-mode.html
+++ b/en/devices/tech/display/retail-mode.html
@@ -53,7 +53,7 @@
 <h4 id="create-demo-app">Creating the demo application</h4>
 <p>
 Device owner apps do not need elevated privileges or pre-installation on the
-system image. They are mostly implmented like traditional apps, with the
+system image. They are mostly implemented like traditional apps, with the
 following differences:
 </p>
 <ul>
diff --git a/en/devices/tech/ota/ab/ab_faqs.html b/en/devices/tech/ota/ab/ab_faqs.html
new file mode 100644
index 0000000..ff978c3
--- /dev/null
+++ b/en/devices/tech/ota/ab/ab_faqs.html
@@ -0,0 +1,400 @@
+<html devsite>
+  <head>
+    <title>Frequently Asked Questions</title>
+    <meta name="project_path" value="/_project.yaml" />
+    <meta name="book_path" value="/_book.yaml" />
+  </head>
+  <body>
+  <!--
+      Copyright 2018 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+
+      <h3>Has Google used A/B OTAs on any devices?</h3>
+
+        <p>
+          Yes. The marketing name for A/B updates is <em>seamless updates</em>.
+          Pixel and Pixel XL phones from October 2016 shipped with A/B, and
+          all Chromebooks use the same <code>update_engine</code>
+          implementation of A/B. The necessary platform code implementation is
+          public in Android 7.1 and higher.
+        </p>
+
+      <h3>Why are A/B OTAs better?</h3>
+
+      <p>A/B OTAs provide a better user experience when taking updates. Measurements
+      from monthly security updates show this feature has already proven a success: As
+      of May 2017, 95% of Pixel owners are running the latest security update after a
+      month compared to 87% of Nexus users, and Pixel users update sooner than Nexus
+      users. Failures to update blocks during an OTA no longer result in a device that
+      won't boot; until the new system image has successfully booted, Android retains
+      the ability to fall back to the previous working system image.</p>
+
+      <h3>How did A/B affect the 2016 Pixel partition sizes?</h3>
+
+      <p>The following table contains details on the shipping A/B configuration versus
+      the internally-tested non-A/B configuration:</p>
+
+      <table>
+        <tbody>
+          <tr>
+            <th>Pixel partition sizes</th>
+            <th width="33%">A/B</th>
+            <th width="33%">Non-A/B</th>
+          </tr>
+          <tr>
+            <td>Bootloader</td>
+            <td>50*2</td>
+            <td>50</td>
+          </tr>
+          <tr>
+            <td>Boot</td>
+            <td>32*2</td>
+            <td>32</td>
+          </tr>
+          <tr>
+            <td>Recovery</td>
+            <td>0</td>
+            <td>32</td>
+          </tr>
+          <tr>
+            <td>Cache</td>
+            <td>0</td>
+            <td>100</td>
+          </tr>
+          <tr>
+            <td>Radio</td>
+            <td>70*2</td>
+            <td>70</td>
+          </tr>
+          <tr>
+            <td>Vendor</td>
+            <td>300*2</td>
+            <td>300</td>
+          </tr>
+          <tr>
+            <td>System</td>
+            <td>2048*2</td>
+            <td>4096</td>
+          </tr>
+          <tr>
+            <td><strong>Total</strong></td>
+            <td><strong>5000</strong></td>
+            <td><strong>4680</strong></td>
+          </tr>
+        </tbody>
+      </table>
+
+      <p>A/B updates require an increase of only 320 MiB in flash, with a savings of
+      32MiB from removing the recovery partition and another 100MiB preserved by
+      removing the cache partition. This balances the cost of the B partitions for
+      the bootloader, the boot partition, and the radio partition. The vendor
+      partition doubled in size (the vast majority of the size increase). Pixel's
+      A/B system image is half the size of the original non-A/B system image.
+      </p>
+
+      <p>For the Pixel A/B and non-A/B variants tested internally (only A/B shipped),
+      the space used differed by only 320MiB. On a 32GiB device, this is just under
+      1%. For a 16GiB device this would be less than 2%, and for an 8GiB device almost
+      4% (assuming all three devices had the same system image).</p>
+
+      <h3>Why didn't you use SquashFS?</h3>
+
+      <p>We experimented with SquashFS but weren't able to achieve the performance
+      desired for a high-end device. We don't use or recommend SquashFS for handheld
+      devices.</p>
+
+      <p>More specifically, SquashFS provided about 50% size savings on the system
+      partition, but the overwhelming majority of the files that compressed well were
+      the precompiled .odex files. Those files had very high compression ratios
+      (approaching 80%), but the compression ratio for the rest of the system
+      partition was much lower. In addition, SquashFS in Android 7.0 raised the
+      following performance concerns:</p>
+
+      <ul>
+        <li>Pixel has very fast flash compared to earlier devices but not a huge
+          number of spare CPU cycles, so reading fewer bytes from flash but needing
+          more CPU for I/O was a potential bottleneck.</li>
+        <li>I/O changes that perform well on an artificial benchmark run on an
+          unloaded system sometimes don't work well on real-world use cases under
+          real-world load (such as crypto on Nexus 6).</li>
+        <li>Benchmarking showed 85% regressions in some places.</li>
+        </ul>
+
+      <p>As SquashFS matures and adds features to reduce CPU impact (such as a
+      whitelist of commonly-accessed files that shouldn't be compressed), we will
+      continue to evaluate it and offer recommendations to device manufacturers.</p>
+
+      <h3>How did you halve the size of the system partition without SquashFS?</h3>
+
+      <p>Applications are stored in .apk files, which are actually ZIP archives. Each
+      .apk file has inside it one or more .dex files containing portable Dalvik
+      bytecode. An .odex file (optimized .dex) lives separately from the .apk file
+      and can contain machine code specific to the device. If an .odex file is
+      available, Android can run applications at ahead-of-time compiled speeds
+      without having to wait for the code to be compiled each time the application is
+      launched. An .odex file isn't strictly necessary: Android can actually run the
+      .dex code directly via interpretation or Just-In-Time (JIT) compilation, but an
+      .odex file provides the best combination of launch speed and run-time speed if
+      space is available.</p>
+
+      <p>Example: For the installed-files.txt from a Nexus 6P running Android 7.1 with
+      a total system image size of 2628MiB (2755792836 bytes), the breakdown of the
+      largest contributors to overall system image size by file type is as follows:
+      </p>
+
+      <table>
+      <tbody>
+      <tr>
+      <td>.odex</td>
+      <td>1391770312 bytes</td>
+      <td>50.5%</td>
+      </tr>
+      <tr>
+      <td>.apk</td>
+      <td>846878259 bytes</td>
+      <td>30.7%</td>
+      </tr>
+      <tr>
+      <td>.so (native C/C++ code)</td>
+      <td>202162479 bytes</td>
+      <td>7.3%</td>
+      </tr>
+      <tr>
+      <td>.oat files/.art images</td>
+      <td>163892188 bytes</td>
+      <td>5.9%</td>
+      </tr>
+      <tr>
+      <td>Fonts</td>
+      <td>38952361 bytes</td>
+      <td>1.4%</td>
+      </tr>
+      <tr>
+      <td>icu locale data</td>
+      <td>27468687 bytes</td>
+      <td>0.9%</td>
+      </tr>
+      </tbody>
+      </table>
+
+      <p>These figures are similar for other devices too, so on Nexus/Pixel
+      devices, .odex files take up approximately half the system partition. This meant
+      we could continue to use ext4 but write the .odex files to the B partition
+      at the factory and then copy them to <code>/data</code> on first boot. The
+      actual storage used with ext4 A/B is identical to SquashFS A/B, because if we
+      had used SquashFS we would have shipped the preopted .odex files on system_a
+      instead of system_b.</p>
+
+      <h3>Doesn't copying .odex files to /data mean the space saved on /system is
+      lost on /data?</h3>
+
+      <p>Not exactly. On Pixel, most of the space taken by .odex files is for apps,
+      which typically exist on <code>/data</code>. These apps take Google Play
+      updates, so the .apk and .odex files on the system image are unused for most of
+      the life of the device. Such files can be excluded entirely and replaced by
+      small, profile-driven .odex files when the user actually uses each app (thus
+      requiring no space for apps the user doesn't use). For details, refer to the
+      Google I/O 2016 talk <a href="https://www.youtube.com/watch?v=fwMM6g7wpQ8">The
+      Evolution of Art</a>.</p>
+
+      <p>The comparison is difficult for a few key reasons:</p>
+      <ul>
+      <li>Apps updated by Google Play have always had their .odex files on
+      <code>/data</code> as soon as they receive their first update.</li>
+      <li>Apps the user doesn't run don't need an .odex file at all.</li>
+      <li>Profile-driven compilation generates smaller .odex files than ahead-of-time
+      compilation (because the former optimizes only performance-critical code).</li>
+      </ul>
+
+      <p>For details on the tuning options available to OEMs, see
+      <a href="/devices/tech/dalvik/configure.html">Configuring ART</a>.</p>
+
+      <h3>Aren't there two copies of the .odex files on /data?</h3>
+
+      <p>It's a little more complicated ... After the new system image has been
+      written, the new version of dex2oat is run against the new .dex files to
+      generate the new .odex files. This occurs while the old system is still running,
+      so the old and new .odex files are both on <code>/data</code> at the same time.
+      </p>
+
+      <p>The code in OtaDexoptService
+      (<code><a href="https://android.googlesource.com/platform/frameworks/base/+/nougat-mr1-release/services/core/java/com/android/server/pm/OtaDexoptService.java#200" class="external">frameworks/base/+/nougat-mr1-release/services/core/java/com/android/server/pm/OtaDexoptService.java#200</a></code>)
+      calls <code>getAvailableSpace</code> before optimizing each package to avoid
+      over-filling <code>/data</code>. Note that <em>available</em> here is still
+      conservative: it's the amount of space left <em>before</em> hitting the usual
+      system low space threshold (measured as both a percentage and a byte count). So
+      if <code>/data</code> is full, there won't be two copies of every .odex file.
+      The same code also has a BULK_DELETE_THRESHOLD: If the device gets that close
+      to filling the available space (as just described), the .odex files belonging to
+      apps that aren't used are removed. That's another case without two copies of
+      every .odex file.</p>
+
+      <p>In the worst case where <code>/data</code> is completely full, the update
+      waits until the device has rebooted into the new system and no longer needs the
+      old system's .odex files. The PackageManager handles this:
+      (<code><a href="https://android.googlesource.com/platform/frameworks/base/+/nougat-mr1-release/services/core/java/com/android/server/pm/PackageManagerService.java#7215" class="external">frameworks/base/+/nougat-mr1-release/services/core/java/com/android/server/pm/PackageManagerService.java#7215</a></code>). After the new system has
+      successfully booted, <code>installd</code>
+      (<code><a href="https://android.googlesource.com/platform/frameworks/native/+/nougat-mr1-release/cmds/installd/commands.cpp#2192" class="external">frameworks/native/+/nougat-mr1-release/cmds/installd/commands.cpp#2192</a></code>)
+      can remove the .odex files that were used by the old system, returning the
+      device back to the steady state where there's only one copy.</p>
+
+      <p>So, while it is possible that <code>/data</code> contains two copies of all
+      the .odex files, (a) this is temporary and (b) only occurs if you had plenty of
+      free space on <code>/data</code> anyway. Except during an update, there's only
+      one copy. And as part of ART's general robustness features, it will never fill
+      <code>/data</code> with .odex files anyway (because that would be a problem on a
+      non-A/B system too).</p>
+
+      <h3>Doesn't all this writing/copying increase flash wear?</h3>
+
+      <p>Only a small portion of flash is rewritten: a full Pixel system update
+      writes about 2.3GiB. (Apps are also recompiled, but that's true of non-A/B
+      too.) Traditionally, block-based full OTAs wrote a similar amount of data, so
+      flash wear rates should be similar.</p>
+
+      <h3>Does flashing two system partitions increase factory flashing time?</h3>
+
+      <p>No. Pixel didn't increase in system image size (it merely divided the space
+      across two partitions).</p>
+
+      <h3>Doesn't keeping .odex files on B make rebooting after factory data reset
+      slow?</h3>
+
+      <p>Yes. If you've actually used a device, taken an OTA, and performed a factory
+      data reset, the first reboot will be slower than it would otherwise be (1m40s vs
+      40s on a Pixel XL) because the .odex files will have been lost from B after the
+      first OTA and so can't be copied to <code>/data</code>. That's the trade-off.</p>
+
+      <p>Factory data reset should be a rare operation when compared to regular boot
+      so the time taken is less important. (This doesn't affect users or reviewers who
+      get their device from the factory, because in that case the B partition is
+      available.) Use of the JIT compiler means we don't need to recompile
+      <em>everything</em>, so it's not as bad as you might think. It's also possible
+      to mark apps as requiring ahead-of-time compilation using
+      <code>coreApp="true"</code> in the manifest:
+      (<code><a href="https://android.googlesource.com/platform/frameworks/base/+/nougat-mr1-release/packages/SystemUI/AndroidManifest.xml#23" class="external">frameworks/base/+/nougat-mr1-release/packages/SystemUI/AndroidManifest.xml#23</a></code>).
+      This is currently used by <code>system_server</code> because it's not allowed to
+      JIT for security reasons.</p>
+
+      <h3>Doesn't keeping .odex files on /data rather than /system make rebooting
+      after an OTA slow?</h3>
+
+      <p>No. As explained above, the new dex2oat is run while the old system image is
+      still running to generate the files that will be needed by the new system. The
+      update isn't considered available until that work has been done.</p>
+
+      <h3>Can (should) we ship a 32GiB A/B device? 16GiB? 8GiB?</h3>
+
+      <p>32GiB works well as it was proven on Pixel, and 320MiB out of 16GiB means a
+      reduction of 2%. Similarly, 320MiB out of 8GiB a reduction of 4%. Obviously
+      A/B would not be the recommended choice on devices with 4GiB, as the 320MiB
+      overhead is almost 10% of the total available space.</p>
+
+      <h3>Does AVB2.0 require A/B OTAs?</h3>
+
+      <p>No. Android <a href="/security/verifiedboot/">Verified Boot</a> has always
+      required block-based updates, but not necessarily A/B updates.</p>
+
+      <h3>Do A/B OTAs require AVB2.0?</h3>
+
+      <p>No.</p>
+
+      <h3>Do A/B OTAs break AVB2.0's rollback protection?</h3>
+
+      <p>No. There's some confusion here because if an A/B system fails to boot into
+      the new system image it will (after some number of retries determined by your
+      bootloader) automatically revert to the "previous" system image. The key point
+      here though is that "previous" in the A/B sense is actually still the "current"
+      system image. As soon as the device successfully boots a new image, rollback
+      protection kicks in and ensures that you can't go back. But until you've
+      actually successfully booted the new image, rollback protection doesn't
+      consider it to be the current system image.</p>
+
+      <h3>If you're installing an update while the system is running, isn't that
+      slow?</h3>
+
+      <p>With non-A/B updates, the aim is to install the update as quickly as
+      possible because the user is waiting and unable to use their device while the
+      update is applied. With A/B updates, the opposite is true; because the user is
+      still using their device, as little impact as possible is the goal, so the
+      update is deliberately slow. Via logic in the Java system update client (which
+      for Google is GmsCore, the core package provided by GMS), Android also attempts
+      to choose a time when the users aren't using their devices at all. The platform
+      supports pausing/resuming the update, and the client can use that to pause the
+      update if the user starts to use the device and resume it when the device is
+      idle again.</p>
+
+      <p>There are two phases while taking an OTA, shown clearly in the UI as
+      <em>Step 1 of 2</em> and <em>Step 2 of 2</em> under the progress bar. Step 1
+      corresponds with writing the data blocks, while step 2 is pre-compiling the
+      .dex files. These two phases are quite different in terms of performance
+      impact. The first phase is simple I/O. This requires little in the way of
+      resources (RAM, CPU, I/O) because it's just slowly copying blocks around.</p>
+
+      <p>The second phase runs dex2oat to precompile the new system image. This
+      obviously has less clear bounds on its requirements because it compiles actual
+      apps. And there's obviously much more work involved in compiling a large and
+      complex app than a small and simple app; whereas in phase 1 there are no disk
+      blocks that are larger or more complex than others.</p>
+
+      <p>The process is similar to when Google Play installs an app update in the
+      background before showing the <em>5 apps updated</em> notification, as has been
+      done for years.</p>
+
+      <h3>What if a user is actually waiting for the update?</h3>
+
+      <p>The current implementation in GmsCore doesn't distinguish between background
+      updates and user-initiated updates but may do so in the future. In the case
+      where the user explicitly asked for the update to be installed or is watching
+      the update progress screen, we'll prioritize the update work on the assumption
+      that they're actively waiting for it to finish.</p>
+
+      <h3>What happens if there's a failure to apply an update?</h3>
+
+      <p>With non-A/B updates, if an update failed to apply, the user was usually
+      left with an unusable device. The only exception was if the failure occurred
+      before an application had even started (because the package failed to verify,
+      say). With A/B updates, a failure to apply an update does not affect the
+      currently running system. The update can simply be retried later.</p>
+
+      <h3>Which systems on a chip (SoCs) support A/B?</h3>
+
+      <p>As of 2017-03-15, we have the following information:</p>
+      <table class="style0">
+      <tbody>
+      <tr>
+      <td></td>
+      <td><strong>Android 7.x Release</strong></td>
+      <td><strong>Android 8.x Release</strong></td>
+      </tr>
+      <tr>
+      <td><strong>Qualcomm</strong></td>
+      <td>Depending on OEM requests </td>
+      <td>All chipsets will get support</td>
+      </tr>
+      <tr>
+      <td><strong>Mediatek</strong></td>
+      <td>Depending on OEM requests</td>
+      <td>All chipsets will get support</td>
+      </tr>
+      </tbody>
+      </table>
+
+      <p>For details on schedules, check with your SoC contacts. For SoCs not listed
+      above, reach out to your SoC directly.</p>
+
+  </body>
+</html>
\ No newline at end of file
diff --git a/en/devices/tech/ota/ab_implement.html b/en/devices/tech/ota/ab/ab_implement.html
similarity index 97%
rename from en/devices/tech/ota/ab_implement.html
rename to en/devices/tech/ota/ab/ab_implement.html
index 4470c97..14d43c0 100644
--- a/en/devices/tech/ota/ab_implement.html
+++ b/en/devices/tech/ota/ab/ab_implement.html
@@ -27,18 +27,19 @@
 <a href="#kernel">correct parameters</a> to the kernel.</p>
 
 
-<h2 id=bootcontrol>Implementing the boot control HAL</h2>
+<h2 id="bootcontrol">Implementing the boot control HAL</h2>
 <p>A/B-capable bootloaders must implement the <code>boot_control</code> HAL at
-<code><a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/boot_control.h" class="external">hardware/libhardware/include/hardware/boot_control.h</a></code>. You can test implementations using the
+<code><a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/boot_control.h" class="external">hardware/libhardware/include/hardware/boot_control.h</a></code>.
+You can test implementations using the
 <code><a href="https://android.googlesource.com/platform/system/extras/+/master/bootctl/" class="external">system/extras/bootctl</a></code> utility and
 <code><a href="https://android.googlesource.com/platform/system/extras/+/refs/heads/master/tests/bootloader/" class="external">system/extras/tests/bootloader/</a></code>.
 </p>
 
 <p>You must also implement the state machine shown below:</p>
-<img src="images/ab-updates-state-machine.png">
+<img src="/devices/tech/ota/images/ab-updates-state-machine.png">
 <figcaption><strong>Figure 1.</strong> Bootloader state machine</figcaption>
 
-<h2 id=kernel>Setting up the kernel</h2>
+<h2 id="kernel">Setting up the kernel</h2>
 <p>To implement A/B system updates:</p>
 <ol>
 <li>Cherrypick the following kernel patch series (if needed):
@@ -139,7 +140,7 @@
 <code>boot_b</code>, <code>system_a</code>, <code>system_b</code>,
 <code>vendor_a</code>, <code>vendor_b</code>.</p>
 
-<h3 id=cache>Cache</h3>
+<h3 id="cache">Cache</h3>
 
 <p>For non-A/B updates, the cache partition was used to store downloaded OTA
 packages and to stash blocks temporarily while applying updates. There was
@@ -150,7 +151,7 @@
 used) and with streaming A/B there's no need to download the whole OTA package
 before applying it.</p>
 
-<h3 id=recovery>Recovery</h3>
+<h3 id="recovery">Recovery</h3>
 
 <p>The recovery RAM disk is now contained in the <code>boot.img</code> file.
 When going into recovery, the bootloader <strong>cannot</strong> put the
diff --git a/en/devices/tech/ota/ab_updates.html b/en/devices/tech/ota/ab/index.html
similarity index 60%
rename from en/devices/tech/ota/ab_updates.html
rename to en/devices/tech/ota/ab/index.html
index 53a4284..c1b7085 100644
--- a/en/devices/tech/ota/ab_updates.html
+++ b/en/devices/tech/ota/ab/index.html
@@ -6,7 +6,7 @@
   </head>
   <body>
   <!--
-      Copyright 2017 The Android Open Source Project
+      Copyright 2018 The Android Open Source Project
 
       Licensed under the Apache License, Version 2.0 (the "License");
       you may not use this file except in compliance with the License.
@@ -156,7 +156,7 @@
         </li>
         <li>
           Build process and OTA update package generation (described in
-          <a href="/devices/tech/ota/ab_implement.html">Implementing A/B
+          <a href="/devices/tech/ota/ab/ab_implement.html">Implementing A/B
           Updates</a>)
         </li>
       </ul>
@@ -612,381 +612,5 @@
           version.
         </p>
 
-    <h2 id="faq">Frequently asked questions</h2>
-
-      <h3>Has Google used A/B OTAs on any devices?</h3>
-
-        <p>
-          Yes. The marketing name for A/B updates is <em>seamless updates</em>.
-          Pixel and Pixel XL phones from October 2016 shipped with A/B, and
-          all Chromebooks use the same <code>update_engine</code>
-          implementation of A/B. The necessary platform code implementation is
-          public in Android 7.1 and higher.
-        </p>
-
-      <h3>Why are A/B OTAs better?</h3>
-
-      <p>A/B OTAs provide a better user experience when taking updates. Measurements
-      from monthly security updates show this feature has already proven a success: As
-      of May 2017, 95% of Pixel owners are running the latest security update after a
-      month compared to 87% of Nexus users, and Pixel users update sooner than Nexus
-      users. Failures to update blocks during an OTA no longer result in a device that
-      won't boot; until the new system image has successfully booted, Android retains
-      the ability to fall back to the previous working system image.</p>
-
-      <h3>How did A/B affect the 2016 Pixel partition sizes?</h3>
-
-      <p>The following table contains details on the shipping A/B configuration versus
-      the internally-tested non-A/B configuration:</p>
-
-      <table>
-        <tbody>
-          <tr>
-            <th>Pixel partition sizes</th>
-            <th width="33%">A/B</th>
-            <th width="33%">Non-A/B</th>
-          </tr>
-          <tr>
-            <td>Bootloader</td>
-            <td>50*2</td>
-            <td>50</td>
-          </tr>
-          <tr>
-            <td>Boot</td>
-            <td>32*2</td>
-            <td>32</td>
-          </tr>
-          <tr>
-            <td>Recovery</td>
-            <td>0</td>
-            <td>32</td>
-          </tr>
-          <tr>
-            <td>Cache</td>
-            <td>0</td>
-            <td>100</td>
-          </tr>
-          <tr>
-            <td>Radio</td>
-            <td>70*2</td>
-            <td>70</td>
-          </tr>
-          <tr>
-            <td>Vendor</td>
-            <td>300*2</td>
-            <td>300</td>
-          </tr>
-          <tr>
-            <td>System</td>
-            <td>2048*2</td>
-            <td>4096</td>
-          </tr>
-          <tr>
-            <td><strong>Total</strong></td>
-            <td><strong>5000</strong></td>
-            <td><strong>4680</strong></td>
-          </tr>
-        </tbody>
-      </table>
-
-      <p>A/B updates require an increase of only 320 MiB in flash, with a savings of
-      32MiB from removing the recovery partition and another 100MiB preserved by
-      removing the cache partition. This balances the cost of the B partitions for
-      the bootloader, the boot partition, and the radio partition. The vendor
-      partition doubled in size (the vast majority of the size increase). Pixel's
-      A/B system image is half the size of the original non-A/B system image.
-      </p>
-
-      <p>For the Pixel A/B and non-A/B variants tested internally (only A/B shipped),
-      the space used differed by only 320MiB. On a 32GiB device, this is just under
-      1%. For a 16GiB device this would be less than 2%, and for an 8GiB device almost
-      4% (assuming all three devices had the same system image).</p>
-
-      <h3>Why didn't you use SquashFS?</h3>
-
-      <p>We experimented with SquashFS but weren't able to achieve the performance
-      desired for a high-end device. We don't use or recommend SquashFS for handheld
-      devices.</p>
-
-      <p>More specifically, SquashFS provided about 50% size savings on the system
-      partition, but the overwhelming majority of the files that compressed well were
-      the precompiled .odex files. Those files had very high compression ratios
-      (approaching 80%), but the compression ratio for the rest of the system
-      partition was much lower. In addition, SquashFS in Android 7.0 raised the
-      following performance concerns:</p>
-
-      <ul>
-        <li>Pixel has very fast flash compared to earlier devices but not a huge
-          number of spare CPU cycles, so reading fewer bytes from flash but needing
-          more CPU for I/O was a potential bottleneck.</li>
-        <li>I/O changes that perform well on an artificial benchmark run on an
-          unloaded system sometimes don't work well on real-world use cases under
-          real-world load (such as crypto on Nexus 6).</li>
-        <li>Benchmarking showed 85% regressions in some places.</li>
-        </ul>
-
-      <p>As SquashFS matures and adds features to reduce CPU impact (such as a
-      whitelist of commonly-accessed files that shouldn't be compressed), we will
-      continue to evaluate it and offer recommendations to device manufacturers.</p>
-
-      <h3>How did you halve the size of the system partition without SquashFS?</h3>
-
-      <p>Applications are stored in .apk files, which are actually ZIP archives. Each
-      .apk file has inside it one or more .dex files containing portable Dalvik
-      bytecode. An .odex file (optimized .dex) lives separately from the .apk file
-      and can contain machine code specific to the device. If an .odex file is
-      available, Android can run applications at ahead-of-time compiled speeds
-      without having to wait for the code to be compiled each time the application is
-      launched. An .odex file isn't strictly necessary: Android can actually run the
-      .dex code directly via interpretation or Just-In-Time (JIT) compilation, but an
-      .odex file provides the best combination of launch speed and run-time speed if
-      space is available.</p>
-
-      <p>Example: For the installed-files.txt from a Nexus 6P running Android 7.1 with
-      a total system image size of 2628MiB (2755792836 bytes), the breakdown of the
-      largest contributors to overall system image size by file type is as follows:
-      </p>
-
-      <table>
-      <tbody>
-      <tr>
-      <td>.odex</td>
-      <td>1391770312 bytes</td>
-      <td>50.5%</td>
-      </tr>
-      <tr>
-      <td>.apk</td>
-      <td>846878259 bytes</td>
-      <td>30.7%</td>
-      </tr>
-      <tr>
-      <td>.so (native C/C++ code)</td>
-      <td>202162479 bytes</td>
-      <td>7.3%</td>
-      </tr>
-      <tr>
-      <td>.oat files/.art images</td>
-      <td>163892188 bytes</td>
-      <td>5.9%</td>
-      </tr>
-      <tr>
-      <td>Fonts</td>
-      <td>38952361 bytes</td>
-      <td>1.4%</td>
-      </tr>
-      <tr>
-      <td>icu locale data</td>
-      <td>27468687 bytes</td>
-      <td>0.9%</td>
-      </tr>
-      </tbody>
-      </table>
-
-      <p>These figures are similar for other devices too, so on Nexus/Pixel
-      devices, .odex files take up approximately half the system partition. This meant
-      we could continue to use ext4 but write the .odex files to the B partition
-      at the factory and then copy them to <code>/data</code> on first boot. The
-      actual storage used with ext4 A/B is identical to SquashFS A/B, because if we
-      had used SquashFS we would have shipped the preopted .odex files on system_a
-      instead of system_b.</p>
-
-      <h3>Doesn't copying .odex files to /data mean the space saved on /system is
-      lost on /data?</h3>
-
-      <p>Not exactly. On Pixel, most of the space taken by .odex files is for apps,
-      which typically exist on <code>/data</code>. These apps take Google Play
-      updates, so the .apk and .odex files on the system image are unused for most of
-      the life of the device. Such files can be excluded entirely and replaced by
-      small, profile-driven .odex files when the user actually uses each app (thus
-      requiring no space for apps the user doesn't use). For details, refer to the
-      Google I/O 2016 talk <a href="https://www.youtube.com/watch?v=fwMM6g7wpQ8">The
-      Evolution of Art</a>.</p>
-
-      <p>The comparison is difficult for a few key reasons:</p>
-      <ul>
-      <li>Apps updated by Google Play have always had their .odex files on
-      <code>/data</code> as soon as they receive their first update.</li>
-      <li>Apps the user doesn't run don't need an .odex file at all.</li>
-      <li>Profile-driven compilation generates smaller .odex files than ahead-of-time
-      compilation (because the former optimizes only performance-critical code).</li>
-      </ul>
-
-      <p>For details on the tuning options available to OEMs, see
-      <a href="/devices/tech/dalvik/configure.html">Configuring ART</a>.</p>
-
-      <h3>Aren't there two copies of the .odex files on /data?</h3>
-
-      <p>It's a little more complicated ... After the new system image has been
-      written, the new version of dex2oat is run against the new .dex files to
-      generate the new .odex files. This occurs while the old system is still running,
-      so the old and new .odex files are both on <code>/data</code> at the same time.
-      </p>
-
-      <p>The code in OtaDexoptService
-      (<code><a href="https://android.googlesource.com/platform/frameworks/base/+/nougat-mr1-release/services/core/java/com/android/server/pm/OtaDexoptService.java#200" class="external">frameworks/base/+/nougat-mr1-release/services/core/java/com/android/server/pm/OtaDexoptService.java#200</a></code>)
-      calls <code>getAvailableSpace</code> before optimizing each package to avoid
-      over-filling <code>/data</code>. Note that <em>available</em> here is still
-      conservative: it's the amount of space left <em>before</em> hitting the usual
-      system low space threshold (measured as both a percentage and a byte count). So
-      if <code>/data</code> is full, there won't be two copies of every .odex file.
-      The same code also has a BULK_DELETE_THRESHOLD: If the device gets that close
-      to filling the available space (as just described), the .odex files belonging to
-      apps that aren't used are removed. That's another case without two copies of
-      every .odex file.</p>
-
-      <p>In the worst case where <code>/data</code> is completely full, the update
-      waits until the device has rebooted into the new system and no longer needs the
-      old system's .odex files. The PackageManager handles this:
-      (<code><a href="https://android.googlesource.com/platform/frameworks/base/+/nougat-mr1-release/services/core/java/com/android/server/pm/PackageManagerService.java#7215" class="external">frameworks/base/+/nougat-mr1-release/services/core/java/com/android/server/pm/PackageManagerService.java#7215</a></code>). After the new system has
-      successfully booted, <code>installd</code>
-      (<code><a href="https://android.googlesource.com/platform/frameworks/native/+/nougat-mr1-release/cmds/installd/commands.cpp#2192" class="external">frameworks/native/+/nougat-mr1-release/cmds/installd/commands.cpp#2192</a></code>)
-      can remove the .odex files that were used by the old system, returning the
-      device back to the steady state where there's only one copy.</p>
-
-      <p>So, while it is possible that <code>/data</code> contains two copies of all
-      the .odex files, (a) this is temporary and (b) only occurs if you had plenty of
-      free space on <code>/data</code> anyway. Except during an update, there's only
-      one copy. And as part of ART's general robustness features, it will never fill
-      <code>/data</code> with .odex files anyway (because that would be a problem on a
-      non-A/B system too).</p>
-
-      <h3>Doesn't all this writing/copying increase flash wear?</h3>
-
-      <p>Only a small portion of flash is rewritten: a full Pixel system update
-      writes about 2.3GiB. (Apps are also recompiled, but that's true of non-A/B
-      too.) Traditionally, block-based full OTAs wrote a similar amount of data, so
-      flash wear rates should be similar.</p>
-
-      <h3>Does flashing two system partitions increase factory flashing time?</h3>
-
-      <p>No. Pixel didn't increase in system image size (it merely divided the space
-      across two partitions).</p>
-
-      <h3>Doesn't keeping .odex files on B make rebooting after factory data reset
-      slow?</h3>
-
-      <p>Yes. If you've actually used a device, taken an OTA, and performed a factory
-      data reset, the first reboot will be slower than it would otherwise be (1m40s vs
-      40s on a Pixel XL) because the .odex files will have been lost from B after the
-      first OTA and so can't be copied to <code>/data</code>. That's the trade-off.</p>
-
-      <p>Factory data reset should be a rare operation when compared to regular boot
-      so the time taken is less important. (This doesn't affect users or reviewers who
-      get their device from the factory, because in that case the B partition is
-      available.) Use of the JIT compiler means we don't need to recompile
-      <em>everything</em>, so it's not as bad as you might think. It's also possible
-      to mark apps as requiring ahead-of-time compilation using
-      <code>coreApp="true"</code> in the manifest:
-      (<code><a href="https://android.googlesource.com/platform/frameworks/base/+/nougat-mr1-release/packages/SystemUI/AndroidManifest.xml#23" class="external">frameworks/base/+/nougat-mr1-release/packages/SystemUI/AndroidManifest.xml#23</a></code>).
-      This is currently used by <code>system_server</code> because it's not allowed to
-      JIT for security reasons.</p>
-
-      <h3>Doesn't keeping .odex files on /data rather than /system make rebooting
-      after an OTA slow?</h3>
-
-      <p>No. As explained above, the new dex2oat is run while the old system image is
-      still running to generate the files that will be needed by the new system. The
-      update isn't considered available until that work has been done.</p>
-
-      <h3>Can (should) we ship a 32GiB A/B device? 16GiB? 8GiB?</h3>
-
-      <p>32GiB works well as it was proven on Pixel, and 320MiB out of 16GiB means a
-      reduction of 2%. Similarly, 320MiB out of 8GiB a reduction of 4%. Obviously
-      A/B would not be the recommended choice on devices with 4GiB, as the 320MiB
-      overhead is almost 10% of the total available space.</p>
-
-      <h3>Does AVB2.0 require A/B OTAs?</h3>
-
-      <p>No. Android <a href="/security/verifiedboot/">Verified Boot</a> has always
-      required block-based updates, but not necessarily A/B updates.</p>
-
-      <h3>Do A/B OTAs require AVB2.0?</h3>
-
-      <p>No.</p>
-
-      <h3>Do A/B OTAs break AVB2.0's rollback protection?</h3>
-
-      <p>No. There's some confusion here because if an A/B system fails to boot into
-      the new system image it will (after some number of retries determined by your
-      bootloader) automatically revert to the "previous" system image. The key point
-      here though is that "previous" in the A/B sense is actually still the "current"
-      system image. As soon as the device successfully boots a new image, rollback
-      protection kicks in and ensures that you can't go back. But until you've
-      actually successfully booted the new image, rollback protection doesn't
-      consider it to be the current system image.</p>
-
-      <h3>If you're installing an update while the system is running, isn't that
-      slow?</h3>
-
-      <p>With non-A/B updates, the aim is to install the update as quickly as
-      possible because the user is waiting and unable to use their device while the
-      update is applied. With A/B updates, the opposite is true; because the user is
-      still using their device, as little impact as possible is the goal, so the
-      update is deliberately slow. Via logic in the Java system update client (which
-      for Google is GmsCore, the core package provided by GMS), Android also attempts
-      to choose a time when the users aren't using their devices at all. The platform
-      supports pausing/resuming the update, and the client can use that to pause the
-      update if the user starts to use the device and resume it when the device is
-      idle again.</p>
-
-      <p>There are two phases while taking an OTA, shown clearly in the UI as
-      <em>Step 1 of 2</em> and <em>Step 2 of 2</em> under the progress bar. Step 1
-      corresponds with writing the data blocks, while step 2 is pre-compiling the
-      .dex files. These two phases are quite different in terms of performance
-      impact. The first phase is simple I/O. This requires little in the way of
-      resources (RAM, CPU, I/O) because it's just slowly copying blocks around.</p>
-
-      <p>The second phase runs dex2oat to precompile the new system image. This
-      obviously has less clear bounds on its requirements because it compiles actual
-      apps. And there's obviously much more work involved in compiling a large and
-      complex app than a small and simple app; whereas in phase 1 there are no disk
-      blocks that are larger or more complex than others.</p>
-
-      <p>The process is similar to when Google Play installs an app update in the
-      background before showing the <em>5 apps updated</em> notification, as has been
-      done for years.</p>
-
-      <h3>What if a user is actually waiting for the update?</h3>
-
-      <p>The current implementation in GmsCore doesn't distinguish between background
-      updates and user-initiated updates but may do so in the future. In the case
-      where the user explicitly asked for the update to be installed or is watching
-      the update progress screen, we'll prioritize the update work on the assumption
-      that they're actively waiting for it to finish.</p>
-
-      <h3>What happens if there's a failure to apply an update?</h3>
-
-      <p>With non-A/B updates, if an update failed to apply, the user was usually
-      left with an unusable device. The only exception was if the failure occurred
-      before an application had even started (because the package failed to verify,
-      say). With A/B updates, a failure to apply an update does not affect the
-      currently running system. The update can simply be retried later.</p>
-
-      <h3>Which systems on a chip (SoCs) support A/B?</h3>
-
-      <p>As of 2017-03-15, we have the following information:</p>
-      <table class="style0">
-      <tbody>
-      <tr>
-      <td></td>
-      <td><strong>Android 7.x Release</strong></td>
-      <td><strong>Android 8.x Release</strong></td>
-      </tr>
-      <tr>
-      <td><strong>Qualcomm</strong></td>
-      <td>Depending on OEM requests </td>
-      <td>All chipsets will get support</td>
-      </tr>
-      <tr>
-      <td><strong>Mediatek</strong></td>
-      <td>Depending on OEM requests</td>
-      <td>All chipsets will get support</td>
-      </tr>
-      </tbody>
-      </table>
-
-      <p>For details on schedules, check with your SoC contacts. For SoCs not listed
-      above, reach out to your SoC directly.</p>
-
   </body>
 </html>
diff --git a/en/devices/tech/ota/index.html b/en/devices/tech/ota/index.html
index 58737b5..7b7db75 100644
--- a/en/devices/tech/ota/index.html
+++ b/en/devices/tech/ota/index.html
@@ -45,8 +45,8 @@
         network. This is called <em>streaming A/B</em>. A/B updates are also
         know as <em>seamless updates</em>. For more information about OTA
         updates for A/B devices, see
-        <a href="/devices/tech/ota/ab_updates.html">A/B (Seamless) System
-          Update
+        <a href="/devices/tech/ota/ab/index.html">A/B (Seamless) System
+          Updates
         </a>.
       </p>
 
@@ -56,9 +56,9 @@
         Older devices have a special recovery partition containing the software
         needed to unpack a downloaded update package and apply the update to
         the other partitions. For more information, see
-        <a href="/devices/tech/ota/nonab_updates.html">Non-A/B System Updates
+        <a href="/devices/tech/ota/nonab/index.html">Non-A/B System Updates
         </a>.
       </p>
-    
+
   </body>
 </html>
diff --git a/en/devices/tech/ota/block.html b/en/devices/tech/ota/nonab/block.html
similarity index 98%
rename from en/devices/tech/ota/block.html
rename to en/devices/tech/ota/nonab/block.html
index 0306f5e..d308aeb 100644
--- a/en/devices/tech/ota/block.html
+++ b/en/devices/tech/ota/nonab/block.html
@@ -105,7 +105,7 @@
 size as full file OTA updates, and incremental updates can be just a few
 megabytes larger.</p>
 
-<img src="../images/ota_size_comparison.png" alt="comparison of OTA sizes">
+<img src="/devices/tech/images/ota_size_comparison.png" alt="comparison of OTA sizes">
 
 <p class="img-caption"><strong>Figure 1.</strong> Compare Nexus 6 OTA sizes
 between Android 5.0 and Android 5.1 releases (varying target build changes)</p>
diff --git a/en/devices/tech/ota/device_code.html b/en/devices/tech/ota/nonab/device_code.html
similarity index 100%
rename from en/devices/tech/ota/device_code.html
rename to en/devices/tech/ota/nonab/device_code.html
diff --git a/en/devices/tech/ota/nonab_updates.html b/en/devices/tech/ota/nonab/index.html
similarity index 100%
rename from en/devices/tech/ota/nonab_updates.html
rename to en/devices/tech/ota/nonab/index.html
diff --git a/en/devices/tech/ota/inside_packages.html b/en/devices/tech/ota/nonab/inside_packages.html
similarity index 99%
rename from en/devices/tech/ota/inside_packages.html
rename to en/devices/tech/ota/nonab/inside_packages.html
index 2cb23c0..7fef443 100644
--- a/en/devices/tech/ota/inside_packages.html
+++ b/en/devices/tech/ota/nonab/inside_packages.html
@@ -89,7 +89,7 @@
 and <b>false</b> on error. If you want errors to abort execution of the
 script, use the <code>abort()</code> and/or <code>assert()</code> functions.
 The set of functions available in updater can also be extended to provide
-<a href="/devices/tech/ota/device_code.html">device-specific
+<a href="/devices/tech/ota/nonab/device_code.html">device-specific
 functionality</a>.
 
 <dl>
diff --git a/en/devices/tech/ota/sign_builds.html b/en/devices/tech/ota/sign_builds.html
index 0610675..22a9a35 100644
--- a/en/devices/tech/ota/sign_builds.html
+++ b/en/devices/tech/ota/sign_builds.html
@@ -57,7 +57,7 @@
 <code class="devsite-terminal">mkdir ~/.android-certs</code>
 <code class="devsite-terminal">for x in releasekey platform shared media; do \
     ./development/tools/make_key ~/.android-certs/$x "$subject"; \
-done</code>
+  done</code>
 </pre>
 
 <p><code>$subject</code> should be changed to reflect your organization's
diff --git a/en/devices/tech/ota/tools.html b/en/devices/tech/ota/tools.html
index 4ad58d9..cf741c6 100644
--- a/en/devices/tech/ota/tools.html
+++ b/en/devices/tech/ota/tools.html
@@ -81,7 +81,7 @@
 update package is much smaller than the corresponding full update (about 1 MB
 instead of 60 MB).</p>
 <p class="note"><strong>Note:</strong> To generate a
-<a href="/devices/tech/ota/block.html">block-based OTA</a>
+<a href="/devices/tech/ota/nonab/block.html">block-based OTA</a>
 for subsequent updates, pass the <code>--block</code> option to
 <code>ota_from_target_files</code>.</p>
 <p>Distribute an incremental package only to devices running exactly the same
@@ -112,6 +112,6 @@
 language that can do many installation tasks. You can substitute any other
 binary running on the device.</p>
 <p>For details on the updater binary, edify syntax, and builtin functions, see
-<a href="/devices/tech/ota/inside_packages.html">Inside OTA Packages</a>.
+<a href="/devices/tech/ota/nonab/inside_packages.html">Inside OTA Packages</a>.
   </body>
 </html>
diff --git a/en/setup/git-resources.html b/en/setup/git-resources.html
deleted file mode 100644
index 4d5530d..0000000
--- a/en/setup/git-resources.html
+++ /dev/null
@@ -1,47 +0,0 @@
-<html devsite>
-  <head>
-    <title>Learning Git</title>
-    <meta name="project_path" value="/_project.yaml" />
-    <meta name="book_path" value="/_book.yaml" />
-  </head>
-  <body>
-  <!--
-      Copyright 2017 The Android Open Source Project
-
-      Licensed under the Apache License, Version 2.0 (the "License");
-      you may not use this file except in compliance with the License.
-      You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-      Unless required by applicable law or agreed to in writing, software
-      distributed under the License is distributed on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-      See the License for the specific language governing permissions and
-      limitations under the License.
-  -->
-
-
-<p>For further information on Git, check out these excellent off-site resources:</p>
-<ul>
-<li>
-<p><a href="https://training.github.com/">GitHub Training</a></p>
-</li>
-<li>
-<p>The <a href="http://book.git-scm.com">Git Community Book</a> (maintained by Scott Chacon) </p>
-</li>
-<li>
-<p><a href="http://git.or.cz/gitwiki/FrontPage">Git Wiki</a></p>
-</li>
-<li>
-<p><a href="http://www.kernel.org/pub/software/scm/git/docs">Git Manual Page</a> </p>
-</li>
-<li>
-<p><a
-href="https://www.youtube.com/playlist?list=PLttwD7NyH3omQLyVtan0CFOX_UWItX_yG">GitCasts</a>
-(Git how-to videos)</p>
-</li>
-</ul>
-
-  </body>
-</html>
diff --git a/ru/security/bulletin/2016.html b/ru/security/bulletin/2016.html
index 9b4f907..b399aab 100644
--- a/ru/security/bulletin/2016.html
+++ b/ru/security/bulletin/2016.html
@@ -20,7 +20,7 @@
       limitations under the License.
   -->
 
-<p>Здесь собраны бюллетени по безопасности Android за 2016 год. Полный список всех бюллетеней вы найдете на <a href="index.html">главной странице</a>.</p>
+<p>Здесь собраны бюллетени по безопасности Android за 2016 год. Полный список бюллетеней вы найдете на <a href="index.html">главной странице</a>.</p>
 
 <table>
   <colgroup><col width="15%" />
@@ -28,20 +28,15 @@
   <col width="17%" />
   <col width="19%" />
  </colgroup><tbody><tr>
-    <th>Сообщение</th>
-    <th>Язык</th>
+    <th>Бюллетень</th>
+    <th>Языки</th>
     <th>Дата публикации</th>
     <th>Обновление системы безопасности</th>
  </tr>
  <tr>
     <td><a href="2016-12-01.html">Декабрь 2016 г.</a></td>
     <td>
-      <a href="/security/bulletin/2016-12-01.html">English</a> /
-<a href="/security/bulletin/2016-12-01.html?hl=ja">日本語</a> /
-<a href="/security/bulletin/2016-12-01.html?hl=ko">한국어</a> /
-<a href="/security/bulletin/2016-12-01.html?hl=ru">ру́сский</a> /
-<a href="/security/bulletin/2016-12-01.html?hl=zh-cn">中文 (中国)</a> /
-<a href="/security/bulletin/2016-12-01.html?hl=zh-tw">中文 (台灣)</a>
+      <a href="/security/bulletin/2016-12-01.html">English</a>/<a href="/security/bulletin/2016-12-01.html?hl=ja">日本語</a>/<a href="/security/bulletin/2016-12-01.html?hl=ko">한국어</a>/<a href="/security/bulletin/2016-12-01.html?hl=ru">русский</a>/<a href="/security/bulletin/2016-12-01.html?hl=zh-cn">中文 (中国)</a>/<a href="/security/bulletin/2016-12-01.html?hl=zh-tw">中文 (台灣)</a>
     </td>
     <td>5 декабря 2016 г.</td>
     <td>2016-12-01<br />
@@ -50,12 +45,7 @@
 <tr>
     <td><a href="/security/bulletin/2016-11-01.html">Ноябрь 2016 г.</a></td>
     <td>
-      <a href="/security/bulletin/2016-11-01.html">English</a> /
-<a href="/security/bulletin/2016-11-01.html?hl=ja">日本語</a> /
-<a href="/security/bulletin/2016-11-01.html?hl=ko">한국어</a> /
-<a href="/security/bulletin/2016-11-01.html?hl=ru">ру́сский</a> /
-<a href="/security/bulletin/2016-11-01.html?hl=zh-cn">中文 (中国)</a> /
-<a href="/security/bulletin/2016-11-01.html?hl=zh-tw">中文 (台灣)</a>
+      <a href="/security/bulletin/2016-11-01.html">English</a>/<a href="/security/bulletin/2016-11-01.html?hl=ja">日本語</a>/<a href="/security/bulletin/2016-11-01.html?hl=ko">한국어</a>/<a href="/security/bulletin/2016-11-01.html?hl=ru">русский</a>/<a href="/security/bulletin/2016-11-01.html?hl=zh-cn">中文 (中国)</a>/<a href="/security/bulletin/2016-11-01.html?hl=zh-tw">中文 (台灣)</a>
     </td>
     <td>7 ноября 2016 г.</td>
     <td>2016-11-01<br />
@@ -65,12 +55,7 @@
  <tr>
     <td><a href="/security/bulletin/2016-10-01.html">Октябрь 2016 г.</a></td>
     <td>
-      <a href="/security/bulletin/2016-10-01.html">English</a> /
-<a href="/security/bulletin/2016-10-01.html?hl=ja">日本語</a> /
-<a href="/security/bulletin/2016-10-01.html?hl=ko">한국어</a> /
-<a href="/security/bulletin/2016-10-01.html?hl=ru">ру́сский</a> /
-<a href="/security/bulletin/2016-10-01.html?hl=zh-cn">中文 (中国)</a> /
-<a href="/security/bulletin/2016-10-01.html?hl=zh-tw">中文 (台灣)</a>
+      <a href="/security/bulletin/2016-10-01.html">English</a>/<a href="/security/bulletin/2016-10-01.html?hl=ja">日本語</a>/<a href="/security/bulletin/2016-10-01.html?hl=ko">한국어</a>/<a href="/security/bulletin/2016-10-01.html?hl=ru">русский</a>/<a href="/security/bulletin/2016-10-01.html?hl=zh-cn">中文 (中国)</a>/<a href="/security/bulletin/2016-10-01.html?hl=zh-tw">中文 (台灣)</a>
     </td>
     <td>3 октября 2016 г.</td>
     <td>2016-10-01<br />
@@ -79,12 +64,7 @@
  <tr>
     <td><a href="/security/bulletin/2016-09-01.html">Сентябрь 2016 г.</a></td>
     <td>
-      <a href="/security/bulletin/2016-09-01.html">English</a> /
-<a href="/security/bulletin/2016-09-01.html?hl=ja">日本語</a> /
-<a href="/security/bulletin/2016-09-01.html?hl=ko">한국어</a> /
-<a href="/security/bulletin/2016-09-01.html?hl=ru">ру́сский</a> /
-<a href="/security/bulletin/2016-09-01.html?hl=zh-cn">中文 (中国)</a> /
-<a href="/security/bulletin/2016-09-01.html?hl=zh-tw">中文 (台灣)</a>
+      <a href="/security/bulletin/2016-09-01.html">English</a>/<a href="/security/bulletin/2016-09-01.html?hl=ja">日本語</a>/<a href="/security/bulletin/2016-09-01.html?hl=ko">한국어</a>/<a href="/security/bulletin/2016-09-01.html?hl=ru">русский</a>/<a href="/security/bulletin/2016-09-01.html?hl=zh-cn">中文 (中国)</a>/<a href="/security/bulletin/2016-09-01.html?hl=zh-tw">中文 (台灣)</a>
     </td>
     <td>6 сентября 2016 г.</td>
     <td>2016-09-01<br />
@@ -94,12 +74,7 @@
  <tr>
     <td><a href="/security/bulletin/2016-08-01.html">Август 2016 г.</a></td>
     <td>
-      <a href="/security/bulletin/2016-08-01.html">English</a> /
-<a href="/security/bulletin/2016-08-01.html?hl=ja">日本語</a> /
-<a href="/security/bulletin/2016-08-01.html?hl=ko">한국어</a> /
-<a href="/security/bulletin/2016-08-01.html?hl=ru">ру́сский</a> /
-<a href="/security/bulletin/2016-08-01.html?hl=zh-cn">中文 (中国)</a> /
-<a href="/security/bulletin/2016-08-01.html?hl=zh-tw">中文 (台灣)</a>
+      <a href="/security/bulletin/2016-08-01.html">English</a>/<a href="/security/bulletin/2016-08-01.html?hl=ja">日本語</a>/<a href="/security/bulletin/2016-08-01.html?hl=ko">한국어</a>/<a href="/security/bulletin/2016-08-01.html?hl=ru">русский</a>/<a href="/security/bulletin/2016-08-01.html?hl=zh-cn">中文 (中国)</a>/<a href="/security/bulletin/2016-08-01.html?hl=zh-tw">中文 (台灣)</a>
     </td>
     <td>1 августа 2016 г.</td>
     <td>2016-08-01<br />
@@ -108,12 +83,7 @@
  <tr>
     <td><a href="/security/bulletin/2016-07-01.html">Июль 2016 г.</a></td>
     <td>
-      <a href="/security/bulletin/2016-07-01.html">English</a> /
-<a href="/security/bulletin/2016-07-01.html?hl=ja">日本語</a> /
-<a href="/security/bulletin/2016-07-01.html?hl=ko">한국어</a> /
-<a href="/security/bulletin/2016-07-01.html?hl=ru">ру́сский</a> /
-<a href="/security/bulletin/2016-07-01.html?hl=zh-cn">中文 (中国)</a> /
-<a href="/security/bulletin/2016-07-01.html?hl=zh-tw">中文 (台灣)</a>
+      <a href="/security/bulletin/2016-07-01.html">English</a>/<a href="/security/bulletin/2016-07-01.html?hl=ja">日本語</a>/<a href="/security/bulletin/2016-07-01.html?hl=ko">한국어</a>/<a href="/security/bulletin/2016-07-01.html?hl=ru">русский</a>/<a href="/security/bulletin/2016-07-01.html?hl=zh-cn">中文 (中国)</a>/<a href="/security/bulletin/2016-07-01.html?hl=zh-tw">中文 (台灣)</a>
     </td>
     <td>6 июля 2016 г.</td>
     <td>2016-07-01<br />
@@ -122,12 +92,7 @@
  <tr>
     <td><a href="/security/bulletin/2016-06-01.html">Июнь 2016 г.</a></td>
     <td>
-      <a href="/security/bulletin/2016-06-01.html">English</a> /
-<a href="/security/bulletin/2016-06-01.html?hl=ja">日本語</a> /
-<a href="/security/bulletin/2016-06-01.html?hl=ko">한국어</a> /
-<a href="/security/bulletin/2016-06-01.html?hl=ru">ру́сский</a> /
-<a href="/security/bulletin/2016-06-01.html?hl=zh-cn">中文 (中国)</a> /
-<a href="/security/bulletin/2016-06-01.html?hl=zh-tw">中文 (台灣)</a>
+      <a href="/security/bulletin/2016-06-01.html">English</a>/<a href="/security/bulletin/2016-06-01.html?hl=ja">日本語</a>/<a href="/security/bulletin/2016-06-01.html?hl=ko">한국어</a>/<a href="/security/bulletin/2016-06-01.html?hl=ru">русский</a>/<a href="/security/bulletin/2016-06-01.html?hl=zh-cn">中文 (中国)</a>/<a href="/security/bulletin/2016-06-01.html?hl=zh-tw">中文 (台灣)</a>
     </td>
     <td>6 июня 2016 г.</td>
     <td>2016-06-01</td>
@@ -135,12 +100,7 @@
  <tr>
     <td><a href="/security/bulletin/2016-05-01.html">Май 2016 г.</a></td>
     <td>
-      <a href="/security/bulletin/2016-05-01.html">English</a> /
-<a href="/security/bulletin/2016-05-01.html?hl=ja">日本語</a> /
-<a href="/security/bulletin/2016-05-01.html?hl=ko">한국어</a> /
-<a href="/security/bulletin/2016-05-01.html?hl=ru">ру́сский</a> /
-<a href="/security/bulletin/2016-05-01.html?hl=zh-cn">中文 (中国)</a> /
-<a href="/security/bulletin/2016-05-01.html?hl=zh-tw">中文 (台灣)</a>
+      <a href="/security/bulletin/2016-05-01.html">English</a>/<a href="/security/bulletin/2016-05-01.html?hl=ja">日本語</a>/<a href="/security/bulletin/2016-05-01.html?hl=ko">한국어</a>/<a href="/security/bulletin/2016-05-01.html?hl=ru">русский</a>/<a href="/security/bulletin/2016-05-01.html?hl=zh-cn">中文 (中国)</a>/<a href="/security/bulletin/2016-05-01.html?hl=zh-tw">中文 (台灣)</a>
     </td>
     <td>2 мая 2016 г.</td>
     <td>2016-05-01</td>
@@ -148,12 +108,7 @@
  <tr>
     <td><a href="/security/bulletin/2016-04-02.html">Апрель 2016 г.</a></td>
     <td>
-      <a href="/security/bulletin/2016-04-02.html">English</a> /
-<a href="/security/bulletin/2016-04-01.html?hl=ja">日本語</a> /
-<a href="/security/bulletin/2016-04-01.html?hl=ko">한국어</a> /
-<a href="/security/bulletin/2016-04-01.html?hl=ru">ру́сский</a> /
-<a href="/security/bulletin/2016-04-01.html?hl=zh-cn">中文 (中国)</a> /
-<a href="/security/bulletin/2016-04-01.html?hl=zh-tw">中文 (台灣)</a>
+      <a href="/security/bulletin/2016-04-02.html">English</a>/<a href="/security/bulletin/2016-04-01.html?hl=ja">日本語</a>/<a href="/security/bulletin/2016-04-01.html?hl=ko">한국어</a>/<a href="/security/bulletin/2016-04-01.html?hl=ru">русский</a>/<a href="/security/bulletin/2016-04-01.html?hl=zh-cn">中文 (中国)</a>/<a href="/security/bulletin/2016-04-01.html?hl=zh-tw">中文 (台灣)</a>
     </td>
     <td>4 апреля 2016 г.</td>
     <td>2016-04-02</td>
@@ -161,12 +116,7 @@
  <tr>
     <td><a href="/security/bulletin/2016-03-01.html">Март 2016 г.</a></td>
     <td>
-      <a href="/security/bulletin/2016-03-01.html">English</a> /
-<a href="/security/bulletin/2016-03-01.html?hl=ja">日本語</a> /
-<a href="/security/bulletin/2016-03-01.html?hl=ko">한국어</a> /
-<a href="/security/bulletin/2016-03-01.html?hl=ru">ру́сский</a> /
-<a href="/security/bulletin/2016-03-01.html?hl=zh-cn">中文 (中国)</a> /
-<a href="/security/bulletin/2016-03-01.html?hl=zh-tw">中文 (台灣)</a>
+      <a href="/security/bulletin/2016-03-01.html">English</a>/<a href="/security/bulletin/2016-03-01.html?hl=ja">日本語</a>/<a href="/security/bulletin/2016-03-01.html?hl=ko">한국어</a>/<a href="/security/bulletin/2016-03-01.html?hl=ru">русский</a>/<a href="/security/bulletin/2016-03-01.html?hl=zh-cn">中文 (中国)</a>/<a href="/security/bulletin/2016-03-01.html?hl=zh-tw">中文 (台灣)</a>
     </td>
     <td>7 марта 2016 г.</td>
     <td>2016-03-01</td>
@@ -174,12 +124,7 @@
  <tr>
     <td><a href="/security/bulletin/2016-02-01.html">Февраль 2016 г.</a></td>
     <td>
-      <a href="/security/bulletin/2016-02-01.html">English</a> /
-<a href="/security/bulletin/2016-02-01.html?hl=ja">日本語</a> /
-<a href="/security/bulletin/2016-02-01.html?hl=ko">한국어</a> /
-<a href="/security/bulletin/2016-02-01.html?hl=ru">ру́сский</a> /
-<a href="/security/bulletin/2016-02-01.html?hl=zh-cn">中文 (中国)</a> /
-<a href="/security/bulletin/2016-02-01.html?hl=zh-tw">中文 (台灣)</a>
+      <a href="/security/bulletin/2016-02-01.html">English</a>/<a href="/security/bulletin/2016-02-01.html?hl=ja">日本語</a>/<a href="/security/bulletin/2016-02-01.html?hl=ko">한국어</a>/<a href="/security/bulletin/2016-02-01.html?hl=ru">русский</a>/<a href="/security/bulletin/2016-02-01.html?hl=zh-cn">中文 (中国)</a>/<a href="/security/bulletin/2016-02-01.html?hl=zh-tw">中文 (台灣)</a>
     </td>
     <td>1 февраля 2016 г.</td>
     <td>2016-02-01</td>
@@ -187,12 +132,7 @@
  <tr>
     <td><a href="/security/bulletin/2016-01-01.html">Январь 2016 г.</a></td>
     <td>
-      <a href="/security/bulletin/2016-01-01.html">English</a> /
-<a href="/security/bulletin/2016-01-01.html?hl=ja">日本語</a> /
-<a href="/security/bulletin/2016-01-01.html?hl=ko">한국어</a> /
-<a href="/security/bulletin/2016-01-01.html?hl=ru">ру́сский</a> /
-<a href="/security/bulletin/2016-01-01.html?hl=zh-cn">中文 (中国)</a> /
-<a href="/security/bulletin/2016-01-01.html?hl=zh-tw">中文 (台灣)</a>
+      <a href="/security/bulletin/2016-01-01.html">English</a>/<a href="/security/bulletin/2016-01-01.html?hl=ja">日本語</a>/<a href="/security/bulletin/2016-01-01.html?hl=ko">한국어</a>/<a href="/security/bulletin/2016-01-01.html?hl=ru">русский</a>/<a href="/security/bulletin/2016-01-01.html?hl=zh-cn">中文 (中国)</a>/<a href="/security/bulletin/2016-01-01.html?hl=zh-tw">中文 (台灣)</a>
     </td>
     <td>4 января 2016 г.</td>
     <td>2016-01-01</td>
diff --git a/zh-cn/_book.yaml b/zh-cn/_book.yaml
index c8cc466..1a8dabb 100644
--- a/zh-cn/_book.yaml
+++ b/zh-cn/_book.yaml
@@ -398,6 +398,10 @@
         - section:
           - path: /devices/architecture/vndk/
             title: 概览
+          - path: /devices/architecture/vndk/enabling
+            title: 启用 VNDK
+          - path: /devices/architecture/vndk/build-system
+            title: VNDK 编译系统支持
           - path: /devices/architecture/vndk/extensions
             title: VNDK 扩展
           - path: /devices/architecture/vndk/deftool
@@ -885,18 +889,24 @@
           title: 对要发布的版本进行签名
         - path: /devices/tech/ota/reduce_size
           title: 减小 OTA 大小
-        - path: /devices/tech/ota/ab_updates
+        - section:
+          - path: /devices/tech/ota/ab/
+            title: 概览
+          - path: /devices/tech/ota/ab/ab_implement
+            title: 实现 A/B 更新
+          - path: /devices/tech/ota/ab/ab_faqs
+            title: 常见问题解答
           title: A/B 系统更新
-        - path: /devices/tech/ota/ab_implement
-          title: 实现 A/B 更新
-        - path: /devices/tech/ota/nonab_updates
+        - section:
+          - path: /devices/tech/ota/nonab/
+            title: 概览
+          - path: /devices/tech/ota/nonab/block
+            title: 基于块的 OTA
+          - path: /devices/tech/ota/nonab/inside_packages
+            title: OTA 软件包内部探秘
+          - path: /devices/tech/ota/nonab/device_code
+            title: 设备专属代码
           title: 非 A/B 系统更新
-        - path: /devices/tech/ota/block
-          title: 基于块的 OTA
-        - path: /devices/tech/ota/inside_packages
-          title: OTA 软件包内部探秘
-        - path: /devices/tech/ota/device_code
-          title: 设备专属代码
         title: OTA 更新
       - section:
         - path: /devices/tech/perf/
diff --git a/zh-cn/_index.yaml b/zh-cn/_index.yaml
index d8e5ec2..643b85d 100644
--- a/zh-cn/_index.yaml
+++ b/zh-cn/_index.yaml
@@ -54,6 +54,12 @@
       image_path: /images/android_stack.png
   - heading: 新闻
     items:
+    - heading: 1 月安全公告
+      description: >
+        2018 年 1 月的 Android 和 Pixel/Nexus 安全公告已经发布,其中提供了与 1 月安全更新补丁相关的信息。
+      buttons:
+      - label: 2018 年 1 月 2 日
+        path: /security/bulletin/2018-01-01
     - heading: Android 8.1 版说明
       description: >
         Android 8.1 版现已推出,其中提供了许多面向设备制造商以及个人用户的新功能。
@@ -66,12 +72,6 @@
       buttons:
       - label: 2017 年 12 月 5 日
         path: /reference/hidl/
-    - heading: 12 月安全公告
-      description: >
-        2017 年 12 月的 Android 和 Pixel/Nexus 安全公告已经发布,其中提供了与 12 月安全更新补丁相关的信息。
-      buttons:
-      - label: 2017 年 12 月 4 日
-        path: /security/bulletin/2017-12-01
   - classname: devsite-landing-row-100 tf-row-centered
     items:
     - buttons:
diff --git a/zh-cn/compatibility/cts/downloads.html b/zh-cn/compatibility/cts/downloads.html
index ff022bf..7b7cfb8 100644
--- a/zh-cn/compatibility/cts/downloads.html
+++ b/zh-cn/compatibility/cts/downloads.html
@@ -33,66 +33,53 @@
 </ul>
 
 <h2 id="android-80">Android 8.0</h2>
-<p>Android 8.0 是代号为 Oreo 的开发里程碑版本。以下测试的源代码可以与开放源代码树中的“android-cts-8.0_r4”标记同步。</p>
+<p>Android 8.0 是代号为 Oreo 的开发里程碑版本。
+以下测试的源代码可以与开放源代码树中的“android-cts-8.0_r5”标记同步。</p>
 <ul>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-8.0_r4-linux_x86-arm.zip">Android 8.0 R4 兼容性测试套件 (CTS) - ARM</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-8.0_r4-linux_x86-x86.zip">Android 8.0 R4 兼容性测试套件 (CTS) - x86</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-8.0_r4-linux_x86-arm.zip">Android 8.0 R4 CTS 验证程序 - ARM</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-8.0_r4-linux_x86-x86.zip">Android 8.0 R4 CTS 验证程序 - x86</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-8.0_r5-linux_x86-arm.zip">Android 8.0 R5 兼容性测试套件 (CTS) - ARM</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-8.0_r5-linux_x86-x86.zip">Android 8.0 R5 兼容性测试套件 (CTS) - x86</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-8.0_r5-linux_x86-arm.zip">Android 8.0 R5 CTS 验证程序 - ARM</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-8.0_r5-linux_x86-x86.zip">Android 8.0 R5 CTS 验证程序 - x86</a></li>
 </ul>
 
 <h2 id="android-71">Android 7.1</h2>
-<p>Android 7.1 是代号为 Nougat-MR1 的开发里程碑版本。以下测试的源代码可以与开放源代码树中的“android-cts-7.1_r12”标记同步。</p>
+<p>Android 7.1 是代号为 Nougat-MR1 的开发里程碑版本。
+以下测试的源代码可以与开放源代码树中的“android-cts-7.1_r13”标记同步。</p>
 <ul>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-7.1_r12-linux_x86-arm.zip">Android 7.1 R12 兼容性测试套件 (CTS) - ARM</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-7.1_r12-linux_x86-x86.zip">Android
-7.1 R12 兼容性测试套件 (CTS) - x86</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.1_r12-linux_x86-arm.zip">Android
-7.0 R12 CTS 验证程序 - ARM</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.1_r12-linux_x86-x86.zip">Android
-7.1 R12 CTS 验证程序 - x86</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-7.1_r13-linux_x86-arm.zip">Android 7.1 R13 兼容性测试套件 (CTS) - ARM</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-7.1_r13-linux_x86-x86.zip">Android 7.1 R13 兼容性测试套件 (CTS) - x86</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.1_r13-linux_x86-arm.zip">Android 7.1 R13 CTS 验证程序 - ARM</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.1_r13-linux_x86-x86.zip">Android 7.1 R13 CTS 验证程序 - x86</a></li>
 </ul>
 
 <h2 id="android-70">Android 7.0</h2>
 <p>Android 7.0 是代号为 Nougat 的开发里程碑版本。
-以下测试的源代码可以与开放源代码树中的“android-cts-7.0_r16”标记同步。</p>
+以下测试的源代码可以与开放源代码树中的“android-cts-7.0_r17”标记同步。</p>
 <ul>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-7.0_r16-linux_x86-arm.zip">Android
-7.0 R16 兼容性测试套件 (CTS) - ARM</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-7.0_r16-linux_x86-x86.zip">Android
-7.0 R16 兼容性测试套件 (CTS) - x86</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.0_r16-linux_x86-arm.zip">Android
-7.0 R16 CTS 验证程序 - ARM</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.0_r16-linux_x86-x86.zip">Android
-7.0 R16 CTS 验证程序 - x86</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-7.0_r17-linux_x86-arm.zip">Android 7.0 R17 兼容性测试套件 (CTS) - ARM</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-7.0_r17-linux_x86-x86.zip">Android 7.0 R17 兼容性测试套件 (CTS) - x86</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.0_r17-linux_x86-arm.zip">Android 7.0 R17 CTS 验证程序 - ARM</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.0_r17-linux_x86-x86.zip">Android 7.0 R17 CTS 验证程序 - x86</a></li>
 </ul>
 
 <h2 id="android-60">Android 6.0</h2>
 <p>Android 6.0 是代号为 Marshmallow 的开发里程碑版本。
-以下测试的源代码可以与开放源代码树中的“android-cts-6.0_r24”标记同步。</p>
+以下测试的源代码可以与开放源代码树中的“android-cts-6.0_r25”标记同步。</p>
 <ul>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-6.0_r24-linux_x86-arm.zip">Android
-6.0 R24 兼容性测试套件 (CTS) - ARM</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-6.0_r24-linux_x86-x86.zip">Android
-6.0 R24 兼容性测试套件 (CTS) - x86</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-6.0_r24-linux_x86-arm.zip">Android
-6.0 R24 CTS 验证程序 - ARM</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-6.0_r24-linux_x86-x86.zip">Android
-6.0 R24 CTS 验证程序 - x86</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-6.0_r25-linux_x86-arm.zip">Android 6.0 R25 兼容性测试套件 (CTS) - ARM</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-6.0_r25-linux_x86-x86.zip">Android 6.0 R25 兼容性测试套件 (CTS) - x86</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-6.0_r25-linux_x86-arm.zip">Android 6.0 R25 CTS 验证程序 - ARM</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-6.0_r25-linux_x86-x86.zip">Android 6.0 R25 CTS 验证程序 - x86</a></li>
 </ul>
 
 <h2 id="android-51">Android 5.1</h2>
 <p>Android 5.1 是代号为 Lollipop-MR1 的开发里程碑版本。
-以下测试的源代码可以与开放源代码树中的“android-cts-5.1_r25”标记同步。</p>
+以下测试的源代码可以与开放源代码树中的“android-cts-5.1_r26”标记同步。</p>
 <ul>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-5.1_r25-linux_x86-arm.zip">Android
-5.1 R25 兼容性测试套件 (CTS) - ARM</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-5.1_r25-linux_x86-x86.zip">Android
-5.1 R25 兼容性测试套件 (CTS) - x86</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-5.1_r25-linux_x86-arm.zip">Android
-5.1 R25 CTS 验证程序 - ARM</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-5.1_r25-linux_x86-x86.zip">Android
-5.1 R25 CTS 验证程序 - x86</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-5.1_r26-linux_x86-arm.zip">Android 5.1 R26 兼容性测试套件 (CTS) - ARM</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-5.1_r26-linux_x86-x86.zip">Android 5.1 R26 兼容性测试套件 (CTS) - x86</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-5.1_r26-linux_x86-arm.zip">Android 5.1 R26 CTS 验证程序 - ARM</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-5.1_r26-linux_x86-x86.zip">Android 5.1 R26 CTS 验证程序 - x86</a></li>
 </ul>
 
 <h2 id="android-50">Android 5.0</h2>
diff --git a/zh-cn/compatibility/cts/run.html b/zh-cn/compatibility/cts/run.html
index 0269d33..3d80c31 100644
--- a/zh-cn/compatibility/cts/run.html
+++ b/zh-cn/compatibility/cts/run.html
@@ -28,7 +28,7 @@
   <li>至少连接一个设备。
   </li><li>在开始运行 CTS 时,按<strong>主屏幕</strong>按钮将设备设置为显示主屏幕。</li><li>当设备在运行测试时,它不能用于执行任何其他任务,并且必须保持静止状态(以免触发传感器活动),同时要让相机指向某个可以聚焦的对象。
   </li><li>在运行 CTS 时,不要按设备上的任何键。按测试设备上的键或触摸其屏幕会干扰正在运行的测试,并且可能导致测试失败。
-  </li><li>通过运行解压缩 CTS 包所得的文件夹中的 cts-tradefed<em></em> 脚本(例如 <code>$ ./android-cts/tools/cts-tradefed</code>)来启动 CTS 控制台。
+  </li><li><em></em>通过运行解压缩 CTS 包所得的文件夹中的 cts-tradefed 脚本(例如 <code>$ ./android-cts/tools/cts-tradefed</code>)来启动 CTS 控制台。
   </li><li>通过附加以下命令启动默认测试计划(包含所有测试包):<code>run
     cts --plan CTS</code>。这将启动测试兼容性所需的所有 CTS 测试。
       <ul>
@@ -354,7 +354,7 @@
         --result-type<br />
         [pass | fail | timeout | notExecuted]<br />
         [--session/-s &lt;session_id&gt;]</code></td>
-      <td>创建从上一会话衍生的子计划;此选项会生成可用于运行测试子集的子计划。<br /><br /> 唯一的必选项是 <code>--session</code>。其他选项都是可选的,但如果选用这些选项,必须后跟一个值。<code>--result-type</code> 选项是可重复使用的;例如 <code>add subplan --session 0 --result-type passed --result-type
+      <td>创建从上一会话衍生的子计划;此选项会生成可用于运行测试子集的子计划。<br /><br /> 唯一的必选项是 <code>--session</code>。其他选项都是可选的,但如果选用这些选项,必须后跟一个值。<code>--result-type</code> 选项可重复使用;例如 <code>add subplan --session 0 --result-type passed --result-type
         failed</code> 是有效的。</td>
 
     </tr>
diff --git a/zh-cn/compatibility/cts/setup.html b/zh-cn/compatibility/cts/setup.html
index f9e4a1f..cf3a406 100644
--- a/zh-cn/compatibility/cts/setup.html
+++ b/zh-cn/compatibility/cts/setup.html
@@ -114,7 +114,7 @@
 <p>CTS 会使用这些应用来测试特权和权限。要通过测试,您必须将应用预加载到系统映像上的相应目录下,而无需对它们重新签名。</p>
 
 <h3 id="storage_requirements">存储空间要求</h3>
-<p>CTS 媒体压力测试要求将视频剪辑存放在外部存储设备 (<code>/sdcard</code>) 上。大部分剪辑来自 <a href="https://peach.blender.org/">Big Buck Bunny</a>,其版权归 Blender Foundation 所有并采用<a href="http://creativecommons.org/licenses/by/3.0/">知识共享署名 3.0 许可</a>。</p>
+<p>CTS 媒体压力测试要求将视频剪辑存放在外部存储设备 (<code>/sdcard</code>) 上。大部分剪辑来自 <a href="https://peach.blender.org/">Big Buck Bunny</a>,其版权归 Blender Foundation 所有并采用 <a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 许可</a>。</p>
 <p>所需空间取决于设备支持的最大视频播放分辨率(要查看所需分辨率的平台版本,请参阅兼容性定义文档中的第 5 部分)。请注意,被测设备的视频播放功能将通过 <code>android.media.CamcorderProfile</code> API(针对早期 Android 版本)和 <code>android.media.MediaCodecInfo.CodecCapabilities</code> API(针对 Android 5.0)进行检测。</p>
 <p>以下是按最大视频播放分辨率列出的存储空间要求:</p>
 <ul>
diff --git a/zh-cn/compatibility/index.html b/zh-cn/compatibility/index.html
index 0676c81..235d7a5 100644
--- a/zh-cn/compatibility/index.html
+++ b/zh-cn/compatibility/index.html
@@ -48,14 +48,13 @@
 <h2 id="android-compatibility-is-free-and-its-easy">Android 兼容性计划是免费的,而且申请步骤很简单</h2>
 <p>要打造与 Android 兼容的移动设备,请遵循以下三个步骤进行操作:</p>
 <ol>
-<li>获取 <a href="/setup/index.html">Android 软件源代码</a><em></em>。这是要移植到您的硬件的 Android 平台源代码。</li>
-<li>遵循 Android 兼容性定义文档 (CDD)(<em></em>PDF、<a href="/compatibility/android-cdd.pdf">HTML</a>)的要求。<a href="/compatibility/android-cdd.html"></a>CDD 列出了对兼容的 Android 设备的软件和硬件要求。</li>
-<li>通过<a href="/compatibility/cts/">兼容性测试套件 (CTS)</a> 测试。<em></em>在开发过程中随时借助 CTS 评估兼容性。</li> </ol>
+<li><em></em>获取 <a href="/setup/index.html">Android 软件源代码</a>。这是要移植到您的硬件的 Android 平台源代码。</li>
+<li><em></em>遵循 Android 兼容性定义文档 (CDD)(<a href="/compatibility/android-cdd.pdf">PDF</a>、<a href="/compatibility/android-cdd.html">HTML</a>)的要求。CDD 列出了对兼容的 Android 设备的软件和硬件要求。</li>
+<li><em></em>通过<a href="/compatibility/cts/">兼容性测试套件 (CTS)</a> 测试。在开发过程中随时借助 CTS 评估兼容性。</li> </ol>
 
 <p>在符合 CDD 要求且通过 CTS 测试后,您的设备即是与 Android 兼容的设备,这意味着生态系统中的 Android 应用在您的设备上运行时可提供一致的体验。有关 Android 兼容性计划的详细信息,请参阅<a href="overview.html">计划概述</a>。</p>
 
 <h2 id="licensing-gms">申请 Google 移动服务 (GMS) 许可</h2>
-<p>打造 Android 兼容设备后,请考虑申请 Android 上的 Google 移动服务(简称 GMS,由 Google Play、YouTube、Google 地图、Gmail 等 Google 拥有的一系列应用组成)许可。GMS 不是 Android 开放源代码项目的一部分,仅通过 Google 授予许可的方式提供。
-有关如何申请 GMS 许可的信息,请查看<a href="contact-us.html">与我们联系</a>。</p>
+<p>打造 Android 兼容设备后,请考虑申请 Android 上的 Google 移动服务(简称 GMS,由 Google Play、YouTube、Google 地图、Gmail 等 Google 拥有的一系列应用组成)许可。GMS 不是 Android 开放源代码项目的一部分,仅通过 Google 授予许可的方式提供。有关如何申请 GMS 许可的信息,请查看<a href="contact-us.html">与我们联系</a>一文。</p>
 
 </body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/camera/index.html b/zh-cn/devices/camera/index.html
index a1def4a..097e032 100644
--- a/zh-cn/devices/camera/index.html
+++ b/zh-cn/devices/camera/index.html
@@ -40,9 +40,9 @@
 
 <dl>
   <dt>应用框架</dt>
-  <dd>应用代码位于应用框架级别,它利用 <a href="http://developer.android.com/reference/android/hardware/Camera.html">android.hardware.Camera</a> API 来与相机硬件互动。在内部,此代码会调用相应的 JNI 粘合类,以访问与该相机互动的原生代码。</dd>
+  <dd>应用代码位于应用框架级别,它利用 <a href="http://developer.android.com/reference/android/hardware/Camera.html">android.hardware.Camera</a> API 来与相机硬件进行互动。在内部,此代码会调用相应的 JNI 粘合类,以访问与该相机互动的原生代码。</dd>
   <dt>JNI</dt>
-  <dd>与 <a href="http://developer.android.com/reference/android/hardware/Camera.html">android.hardware.Camera</a> 关联的 JNI 代码位于 <code>frameworks/base/core/jni/android_hardware_Camera.cpp</code>。此代码会调用较低级别的原生代码以获取对物理相机的访问权限,并返回用于在框架级别创建 <a href="http://developer.android.com/reference/android/hardware/Camera.html">android.hardware.Camera</a> 对象的数据。</dd>
+  <dd>与 <a href="http://developer.android.com/reference/android/hardware/Camera.html">android.hardware.Camera</a> 关联的 JNI 代码位于 <code>frameworks/base/core/jni/android_hardware_Camera.cpp</code> 中。此代码会调用较低级别的原生代码以获取对物理相机的访问权限,并返回用于在框架级别创建 <a href="http://developer.android.com/reference/android/hardware/Camera.html">android.hardware.Camera</a> 对象的数据。</dd>
   <dt>原生框架</dt><dt>
   </dt><dd>在 <code>frameworks/av/camera/Camera.cpp</code> 中定义的原生框架可提供相当于 <a href="http://developer.android.com/reference/android/hardware/Camera.html">android.hardware.Camera</a> 类的原生类。此类会调用 IPC binder 代理,以获取对相机服务的访问权限。</dd>
   <dt>Binder IPC 代理</dt>
diff --git a/zh-cn/devices/graphics/implement-vsync.html b/zh-cn/devices/graphics/implement-vsync.html
index 7f94096..6789cc8 100644
--- a/zh-cn/devices/graphics/implement-vsync.html
+++ b/zh-cn/devices/graphics/implement-vsync.html
@@ -34,7 +34,7 @@
 
 <p>显式同步是必需的,它提供了一种以同步方式获取和释放 Gralloc 缓冲区的机制。显式同步允许图形缓冲区的生产方和消耗方在完成对缓冲区的处理时发出信号。这允许 Android 异步地将要读取或写入的缓冲区加入队列,并且确定另一个消耗方或生产方当前不需要它们。有关详细信息,请参阅<a href="/devices/graphics/index.html#synchronization_framework">同步框架</a>一文。</p>
 
-<p>显式同步的优点包括设备之间的行为变化较小、调试支持更好,并且测试指标更完善。例如,同步框架输出可以很容易地识别问题区域和根本原因,而集中的 SurfaceFlinger 演示时间戳可以显示何时在系统的正常流程中发生事件。</p>
+<p>显式同步的优点包括不同设备上的行为差异较小、对调试的支持更好,并且测试指标更完善。例如,同步框架输出可以很容易地识别问题区域和根本原因,而集中的 SurfaceFlinger 演示时间戳可以显示何时在系统的正常流程中发生事件。</p>
 
 <p>该通信是通过使用同步栅栏来促进的。在请求用于消耗或生产的缓冲区时,必须使用同步栅栏。同步框架由三个主要构造块组成:<code>sync_timeline</code>、<code>sync_pt</code> 和 <code>sync_fence</code>。</p>
 
@@ -93,7 +93,7 @@
 <li>与 <code>platform/system/core/libsync</code> 中的内核空间进行通信的库。</li>
 </ul></li>
 <li>支持新同步功能的 Hardware Composer HAL(v1.3 或更高版本)。您必须为 HAL 中的 <code>set()</code> 和 <code>prepare()</code> 函数提供适当的同步栅栏作为参数。</li>
-<li>图形驱动程序中的两个与栅栏相关的 GL 扩展程序(<code>EGL_ANDROID_native_fence_sync</code> 和 <code>EGL_ANDROID_wait_sync</code>)以及栅栏支持。</li>
+<li>图形驱动程序中的两个与栅栏相关的 GL 扩展(<code>EGL_ANDROID_native_fence_sync</code> 和 <code>EGL_ANDROID_wait_sync</code>)以及栅栏支持。</li>
 </ul>
 
 <p>例如,要使用支持同步函数的 API,您可以开发具有显示设备缓冲区函数的显示设备驱动程序。在同步框架出现之前,此函数会接收 dma-buf,将这些缓冲区放在显示设备上,并在缓冲区可见时阻塞。例如:</p>
@@ -120,7 +120,7 @@
 </pre>
 
 <h2 id="sync_integration">同步集成</h2>
-<p>本部分将介绍如何将低级同步框架与 Android 框架的不同部分以及与彼此必须通信的驱动程序进行集成。</p>
+<p>本部分将介绍如何将低层级同步框架与 Android 框架的不同部分以及与彼此必须通信的驱动程序进行集成。</p>
 
 <h3 id="integration_conventions">集成规范</h3>
 
@@ -141,18 +141,18 @@
 
 <h3 id="opengl_es_integration">OpenGL ES 集成</h3>
 
-<p>OpenGL ES 同步集成依赖于两个 EGL 扩展程序:</p>
+<p>OpenGL ES 同步集成依赖于两个 EGL 扩展:</p>
 
 <ul>
 <li><code>EGL_ANDROID_native_fence_sync</code>。提供一种在 EGLSyncKHR 对象中包装或创建原生 Android 栅栏文件描述符的方法。</li>
-<li><code>EGL_ANDROID_wait_sync</code>。允许 GPU 端停止而不是在 CPU 中停止,使 GPU 等待 EGLSyncKHR。这与 <code>EGL_KHR_wait_sync</code> 扩展程序基本相同(有关详细信息,请参阅相关规范)。</li>
+<li><code>EGL_ANDROID_wait_sync</code>。允许 GPU 端停止而不是在 CPU 中停止,使 GPU 等待 EGLSyncKHR。这与 <code>EGL_KHR_wait_sync</code> 扩展基本相同(有关详细信息,请参阅相关规范)。</li>
 </ul>
 
-<p>这些扩展程序可以独立使用,并由 libgui 中的编译标记控制。要使用它们,请首先实现 <code>EGL_ANDROID_native_fence_sync</code> 扩展程序以及关联的内核支持。接下来,为驱动程序添加对栅栏的 ANATIONWindow 支持,然后在 libgui 中启用支持以使用 <code>EGL_ANDROID_native_fence_sync</code> 扩展程序。</p>
+<p>这些扩展可以独立使用,并由 libgui 中的编译标记控制。要使用它们,请首先实现 <code>EGL_ANDROID_native_fence_sync</code> 扩展以及关联的内核支持。接下来,为驱动程序添加对栅栏的 ANATIONWindow 支持,然后在 libgui 中启用支持以使用 <code>EGL_ANDROID_native_fence_sync</code> 扩展。</p>
 
-<p>其次,在驱动程序中启用 <code>EGL_ANDROID_wait_sync</code> 扩展程序,并单独打开它。<code>EGL_ANDROID_native_fence_sync</code> 扩展程序包含完全不同的原生栅栏 EGLSync 对象类型,因此适用于现有 EGLSync 对象类型的扩展程序不一定适用于 <code>EGL_ANDROID_native_fence</code> 对象,以避免不必要的交互。</p>
+<p>其次,在驱动程序中启用 <code>EGL_ANDROID_wait_sync</code> 扩展,并单独打开它。<code>EGL_ANDROID_native_fence_sync</code> 扩展包含完全不同的原生栅栏 EGLSync 对象类型,因此适用于现有 EGLSync 对象类型的扩展不一定适用于 <code>EGL_ANDROID_native_fence</code> 对象,以避免不必要的交互。</p>
 
-<p>EGL_ANDROID_native_fence_sync 扩展程序使用相应的原生栅栏文件描述符属性,该属性只能在创建时设置,不能从现有同步对象直接向前查询。该属性可以设置为以下两种模式之一:</p>
+<p>EGL_ANDROID_native_fence_sync 扩展使用相应的原生栅栏文件描述符属性,该属性只能在创建时设置,不能从现有同步对象直接向前查询。该属性可以设置为以下两种模式之一:</p>
 
 <ul>
 <li><em></em>有效的栅栏文件描述符。在 EGLSyncKHR 对象中包装现有的原生 Android 栅栏文件描述符。</li>
diff --git a/zh-cn/devices/tech/debug/gdb.html b/zh-cn/devices/tech/debug/gdb.html
index e4eabfb..cd5222a 100644
--- a/zh-cn/devices/tech/debug/gdb.html
+++ b/zh-cn/devices/tech/debug/gdb.html
@@ -64,7 +64,7 @@
 <p>要调试应用启动,请使用“设置”中的开发者选项,指示应用等待附加 Java 调试程序:</p>
 
 <ol>
-<li>请依次转到“设置”&gt;“开发者选项”&gt;“选择调试应用”,并从列表中选择您的应用,然后按<strong>等待调试程序</strong>。<em></em></li>
+<li>请依次转到“设置”&gt;“开发者选项”&gt;“选择调试应用”,并从列表中选择您的应用,然后按<em></em><strong>等待调试程序</strong>。</li>
 
 <li>启动应用,您可以从启动器启动,也可以在命令行中运行以下命令来启动:<pre class="devsite-terminal devsite-click-to-copy">
 am start -a android.intent.action.MAIN -n <var>APP_NAME</var>/.<var>APP_ACTIVITY</var>
diff --git a/zh-cn/license.html b/zh-cn/license.html
index ed26225..8f5a648 100644
--- a/zh-cn/license.html
+++ b/zh-cn/license.html
@@ -45,8 +45,7 @@
 <ul>
 <li>尽管我们根据 Apache 2.0 许可向您提供文档本身,但请注意,该许可并未涵盖专有商标和品牌特征。</li>
 
-<li>该许可未涵盖 Google 的商标和其他品牌特征(包括 <img src="https://developer.android.com/images/android-logo.png" alt="Android" style="margin:0;padding:0 2px;vertical-align:baseline"/> 这种特殊样式的字体徽标)。
-要了解这种使用情况的相关信息,请参阅<a href="https://developer.android.com/distribute/marketing-tools/brand-guidelines.html">品牌推广指南</a>。</li>
+<li>该许可未涵盖 Google 的商标和其他品牌特征(包括 <img src="https://developer.android.com/images/android-logo.png" alt="Android" style="margin:0;padding:0 2px;vertical-align:baseline"/> 这种特殊样式的字体徽标)。要了解这种使用情况的相关信息,请参阅<a href="https://developer.android.com/distribute/marketing-tools/brand-guidelines.html">品牌推广指南</a>。</li>
 
 <li>在某些情况下,网页中可能会包含该许可未涵盖的内容(例如图片)。在这种情况下,我们会为未许可的内容添加标签。</li>
 
diff --git a/zh-cn/security/advisory/2016-03-18.html b/zh-cn/security/advisory/2016-03-18.html
index 222d71d..7b88cd9 100644
--- a/zh-cn/security/advisory/2016-03-18.html
+++ b/zh-cn/security/advisory/2016-03-18.html
@@ -30,7 +30,7 @@
 
 <p>为了针对该问题提供最后一道防护屏障,我们已在 2016 年 3 月 16 日向合作伙伴提供用于修复该问题的补丁程序。我们正在准备 Nexus 更新版本,近日就会发布。此外,我们还在 Android 开放源代码项目 (AOSP) 代码库中发布了针对该问题的源代码补丁程序。</p>
 
-<h3 id="background">背景信息</h3>
+<h3 id="background">背景</h3>
 
 <p>该问题是上游 Linux 内核中的已知问题,已于 2014 年 4 月得到修复,但直到 2015 年 2 月 2 日才被列为安全修复问题并获派编号 <a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1805">CVE-2015-1805</a>。2016 年 2 月 19 日,C0RE 团队向 Google 发出通知,指出有心人士可能会在 Android 设备上利用这个问题。他们开发的补丁程序会收录到即将发布的每月定期更新中。</p>
 
@@ -117,7 +117,7 @@
 <h2 id="revisions">修订版本</h2>
 
 <ul>
-  <li>2016 年 3 月 18 日:发布了安全建议。
+  <li>2016 年 3 月 18 日:发布了公告。
 </li></ul>
 
 </body></html>
\ No newline at end of file
diff --git a/zh-cn/security/authentication/index.html b/zh-cn/security/authentication/index.html
index 4c52e0a..11afb39 100644
--- a/zh-cn/security/authentication/index.html
+++ b/zh-cn/security/authentication/index.html
@@ -20,147 +20,115 @@
       limitations under the License.
   -->
 
-<h2 id="overview">概述</h2>
-
-<p>Android 6.0 中引入了通过用户身份验证把关的加密密钥的概念。为了实现这一概念,需要两种关键组件协同运作。一种是加密密钥存储和服务提供程序,用于存储加密密钥并提供基于加密密钥的标准加密例程。另一种是任意数量的用户身份验证程序,用于证明相应用户存在并/或已成功通过身份验证。</p>
-
-<p>Android 中的加密密钥存储功能由 Keystore 服务和 Keymaster 提供。(另请参阅由 Keystore 服务提供支持的框架级 <a href="https://developer.android.com/training/articles/keystore.html">Android Keystore 系统</a>的相关信息。)对于 Android 6.0,两个受支持的身份验证组件是 Gatekeeper(用于 PIN 码/解锁图案/密码身份验证)和 Fingerprint(用于指纹身份验证)。这两个组件会通过已经过身份验证的渠道与 Keystore 服务沟通身份验证状态。</p>
+<p>Android 采用通过用户身份验证把关的加密密钥的概念,该概念需要以下组件:</p>
 
 <ul>
-  <li><strong><a href="/security/keystore/index.html">由硬件支持的 Keystore</a>:</strong>加密服务(其中包括由硬件支持的密钥存储加密服务),可能包括可信执行环境 (TEE)。</li>
-  <li><strong><a href="gatekeeper.html">Gatekeeper</a>:</strong> 用于进行 PIN 码、解锁图案和密码身份验证的组件。</li>
-  <li><strong><a href="fingerprint-hal.html">Fingerprint</a>:</strong> 用于进行指纹身份验证的组件。</li>
+<li><strong>加密密钥存储和服务提供程序</strong>。存储加密密钥并基于这些密钥提供标准加密例程。
+Android 支持<a href="/security/keystore/index.html">由硬件支持的 Keystore</a> 和 Keymaster 这两种加密服务,其中包括由硬件支持的密钥存储加密服务,该服务可能包括可信执行环境 (TEE)。</li>
+<li><strong>用户身份验证程序</strong>。证明相应用户存在并/或已成功通过身份验证。Android 支持 <a href="gatekeeper.html">Gatekeeper</a>(用于 PIN 码/解锁图案/密码身份验证)和 <a href="fingerprint-hal.html">Fingerprint</a>(用于指纹身份验证)。这两个组件通过已经过身份验证的渠道与 Keystore 服务沟通身份验证状态。(Keystore 服务还支持框架级 <a href="https://developer.android.com/training/articles/keystore.html" class="external">Android Keystore 系统</a>。)</li>
 </ul>
 
-<h2 id="architecture">架构</h2>
+<p>Gatekeeper 和 Fingerprint 组件能够与 Keystore 及其他组件协同运作,以支持使用由硬件支持的<a href="#authtoken_format">身份验证令牌</a> (AuthToken)。</p>
 
-<p>Gatekeeper 和 Fingerprint 组件能够与 Keystore 及其他组件协同运作,以便支持使用由硬件支持的<a href="#authentication_token_format">身份验证令牌</a>(以下称为“AuthToken”)。</p>
+<h2 id="enrollment">注册</h2>
 
-<h3 id="enrollment">注册</h3>
+<p>在设备恢复出厂设置后首次启动时,所有身份验证程序均会做好接受用户通过凭据注册的准备。用户必须先通过 Gatekeeper 注册一个 PIN 码/解锁图案/密码。该首次注册会随机生成一个 64 位的用户 SID(用户安全标识符),该用户 SID 将用作用户的标识符以及用户加密材料的绑定令牌。该用户 SID 会以加密形式绑定到用户的密码,成功通过 Gatekeeper 的身份验证后,会相应生成 AuthToken,其中包含用于该密码的用户 SID。</p>
 
-<p>在设备恢复出厂设置后首次启动时,所有身份验证程序均会做好接受用户进行凭据注册的准备。</p>
+<p>用户如果想要更改凭据,则必须提供现有凭据。
+如果现有凭据成功通过验证,则与现有凭据关联的用户 SID 将转移到新凭据,这样用户便可以在更改凭据后保留访问密钥。如果用户未提供现有凭据,系统会使用一个完全随机的用户 SID 为其注册一个新凭据。用户可以访问设备,但基于旧用户 SID 创建的密钥将永久丢失。这种情况称为“不可信注册”。<em></em></p>
 
-<p>用户必须先通过 Gatekeeper 注册 PIN 码/解锁图案/密码。这项初始注册会创建一个随机生成的 64 位用户 SID(用户安全标识符,下文中对此进行了介绍),该用户 SID 将用作用户的标识符以及用户加密材料的绑定令牌。该用户 SID 会以加密形式绑定到用户的密码。如下文中详细介绍的,成功通过 Gatekeeper 的身份验证后,将会为相应密码生成包含用户 SID 的 AuthToken。</p>
+<p>一般情况下,Android 框架不允许进行不可信注册,因此大多数用户根本看不到此功能。不过,如果设备管理员或攻击者强制重置密码,则可能会发生这种情况。</p>
 
-<p>用户要更改凭据时,必须提供现有凭据。如果现有凭据成功通过验证,与现有凭据关联的用户 SID 将转移到新凭据。这让用户在更改凭据后能够继续访问自己的密钥。如果用户未提供现有凭据,系统会为其注册一个新凭据,其中包含一个完全随机的用户 SID。用户可以访问设备,但会永久丢失基于旧用户 SID 创建的密钥。这种情况称为“不可信注册”。</p>
+<h2 id="authentication">身份验证</h2>
 
-<p>请注意,在一般情况下,Android 框架不允许进行不可信注册,因此大多数用户根本看不到此功能。不过,如果设备管理员或攻击者强制重置密码,则可能会导致发生这种情况。</p>
-
-<h3 id="authentication">身份验证</h3>
-
-<p>现在,用户已设置凭据并收到了用户 SID,接下来就可以开始进行身份验证了。</p>
-
-<p>在下图中,用户提供 PIN 码、解锁图案、密码或指纹后,身份验证过程便开始了。所有 TEE 组件都共用一个密钥来验证对方的消息。</p>
+<p>用户设置凭据并收到用户 SID 后,便可以开始进行身份验证,身份验证从用户提供 PIN 码、解锁图案、密码或指纹开始。所有 TEE 组件都共用一个密钥来验证对方的消息。</p>
 
 <img src="../images/authentication-flow.png" alt="身份验证流程" id="figure1"/>
-<p class="img-caption"><strong>图 1. </strong> 身份验证流程</p>
-
-<p>以下步骤中的数字对应于上图中的数字,并包括对 Android 操作系统和 TEE 操作系统的引用:</p>
+<figcaption><strong>图 1.</strong> 身份验证流程。</figcaption>
 
 <ol>
-  <li>用户提供 PIN 码、解锁图案、密码或指纹。<code>LockSettingsService</code> 或 <code>FingerprintService</code> 通过 Binder 向 Android 操作系统中的 Gatekeeperd 或 fingerprintd 守护进程发出请求。请注意,在指纹请求发出后,会异步发生指纹身份验证。
-  </li><li>该步骤涉及 <strong></strong>Gatekeeperd(下方选项 1)<strong>或</strong> fingerprintd(下方选项 2),具体取决于用户提供的是 PIN 码/解锁图案/密码还是指纹。
-  <ul>
-    <li>Gatekeeperd 守护进程将在第 1 步中收到的 PIN 码、解锁图案或密码哈希发送到它在 TEE 内的副本 (Gatekeeper)。如果 TEE 内的身份验证成功,TEE 内的 Gatekeeper 会将包含相应用户 SID 并且已使用 AuthToken HMAC 密钥签名的 AuthToken 发送到它在 Android 操作系统中的副本。</li><li>或者,监听指纹事件的 fingerprintd 守护进程将在第 1 步中收到的数据发送到它在 TEE 内的副本 (Fingerprint)。如果 TEE 内的身份验证成功,TEE 内的 Fingerprint 会将已使用 AuthToken HMAC 密钥签名的 AuthToken 发送到它在 Android 操作系统中的副本。</li></ul>
-  </li><li>Gatekeeperd 或 fingerprintd 守护进程收到经过签名的 AuthToken,并通过 Keystore 服务 Binder 接口的扩展程序将 AuthToken 传递到 Keystore 服务。此外,Gatekeeperd 会在设备被重新锁定以及设备密码发生变化时通知 Keystore 服务。
-  </li><li>Keystore 服务将从 Gatekeeperd 和 fingerprintd 收到的 AuthToken 传递给 Keymaster,以便使用与 Gatekeeper 和 Fingerprint Trustlet 共用的密钥验证 AuthToken。Keymaster 会将令牌中的时间戳视为最后一次身份验证的时间,并根据该时间戳做出密钥发布决定(以允许应用使用相应密钥)。
-</li></ol>
+  <li>用户提供 PIN 码、解锁图案、密码或指纹。<code>LockSettingsService</code> 或 <code>FingerprintService</code> 通过 Binder 向相应的守护进程(<code>gatekeeperd</code> 或 <code>fingerprintd</code>)发出请求。指纹身份验证在指纹请求发出后异步进行。</li>
+  <li>守护进程将数据发至其副本,后者生成 AuthToken:
+    <ul>
+    <li>对于 PIN 码/解锁图案/密码身份验证,<code>gatekeeperd</code> 将 PIN 码、解锁图案或密码哈希发送到 TEE 中的 Gatekeeper。如果 TEE 中的身份验证成功,TEE 中的 Gatekeeper 会将包含相应用户 SID(已使用 AuthToken HMAC 密钥签名)的 AuthToken 发送到它在 Android 操作系统中的副本。
+    </li><li>对于指纹身份验证,<code>fingerprintd</code> 会监听指纹事件并将数据发送到 TEE 中的 Fingerprint。如果 TEE 中的身份验证成功,TEE 中的 Fingerprint 会将 AuthToken(已使用 AuthToken HMAC 密钥签名)发送到它在 Android 操作系统中的副本。</li>
+  </ul>
+  </li>
+  <li>守护进程收到经过签名的 AuthToken,并通过 Keystore 服务 Binder 接口的扩展程序将 AuthToken 传递给 Keystore 服务。
+(<code>gatekeeperd</code> 还会在设备被重新锁定以及设备密码发生变化时通知 Keystore 服务。)
+  </li><li>Keystore 服务将 AuthToken 传递给 Keymaster,以便使用与 Gatekeeper 和 Fingerprint Trustlet 共用的密钥验证 AuthToken。Keymaster 会将令牌中的时间戳视为最后一次身份验证的时间,并根据该时间戳做出密钥发布决定(以允许应用使用相应密钥)。</li>
+</ol>
 
-<p class="note"><strong>注意</strong>:每当设备重新启动时,AuthToken 都会作废。</p>
+<aside class="note"><strong>注意</strong>:设备重新启动后,AuthToken 即作废。</aside>
 
-<h2 id="authentication_token_format">身份验证令牌格式</h2>
+<h2 id="authtoken_format">AuthToken 格式</h2>
 
-<p>要共用令牌并在各种语言和组件之间实现兼容性,必须遵循 <a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/hw_auth_token.h"><code>hw_auth_token.h</code></a> 文件中说明的 AuthToken 格式。请参阅以下文件:</p>
-<pre>
-hardware/libhardware/include/hardware/hw_auth_token.h
-</pre>
+<p>为了确保在各种语言和组件之间实现令牌的共用和兼容,<a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/hw_auth_token.h" class="external"><code>hw_auth_token.h</code></a> 中规定了 AuthToken 的格式。
+该格式是一个简单序列化协议,具有以下固定大小的字段:</p>
 
-<p>下表中定义了一个简单序列化协议的必填字段。这些字段具有固定的大小。</p>
-
-<p>字段说明位于该表下方。</p>
 <table>
  <tbody><tr>
-    <th><strong>字段</strong></th>
-    <th><strong>类型</strong></th>
-    <th><strong>必填还是选填</strong></th>
+    <th width="15%">字段</th>
+    <th width="20%">类型</th>
+    <th width="10%">必需</th>
+    <th>说明</th>
  </tr>
  <tr>
     <td>AuthToken 版本</td>
     <td>1 个字节</td>
-    <td>必填</td>
+    <td>是</td>
+    <td>下方所有字段的组代码。</td>
  </tr>
  <tr>
     <td>质询</td>
     <td>64 位未签名整数</td>
-    <td>选填</td>
+    <td>否</td>
+    <td>用于防范重播攻击的随机整数,通常是所请求的加密操作的 ID。目前由交易指纹授权使用。如果质询存在,AuthToken 将仅对包含该相同质询的加密操作有效。</td>
  </tr>
  <tr>
     <td>用户 SID</td>
     <td>64 位未签名整数</td>
-    <td>必填</td>
+    <td>是</td>
+    <td>不重复的用户标识符,以加密形式绑定到与设备身份验证关联的所有密钥。如需了解详情,请参阅 <a href="/security/authentication/gatekeeper.html">Gatekeeper</a>。</td>
  </tr>
  <tr>
-    <td>身份验证程序 ID</td>
+    <td>身份验证程序 ID (ASID)</td>
     <td>64 位未签名整数,按网络字节序保存</td>
-    <td>选填</td>
+    <td>否</td>
+    <td>绑定到特定身份验证程序政策时使用的标识符。所有身份验证程序都有自己的 ASID 值,它们可以根据自己的要求更改该值。</td>
  </tr>
  <tr>
     <td>身份验证程序类型</td>
     <td>32 位未签名整数,按网络字节序保存</td>
-    <td>必填</td>
- </tr>
+    <td>是</td>
+    <td><ul>
+    <li>0x00 代表 Gatekeeper。</li>
+    <li>0x01 代表 Fingerprint。</li>
+    </ul>
+  </td>
+  </tr>
  <tr>
     <td>时间戳</td>
     <td>64 位未签名整数,按网络字节序保存</td>
-    <td>必填</td>
+    <td>是</td>
+    <td>自最近一次系统启动以来已经过的时间(以毫秒为单位)。</td>
  </tr>
  <tr>
     <td>AuthToken HMAC 密钥 (SHA-256)</td>
     <td>256 位 Blob</td>
-    <td>必填</td>
+    <td>是</td>
+    <td>除 HMAC 字段以外所有字段的已加密 SHA-256 MAC。</td>
  </tr>
 </tbody></table>
 
-<h3 id="field_descriptions">字段说明</h3>
-
-<p>本部分对上方 AuthToken 表中的各个字段进行了说明。</p>
-
-<p><strong>AuthToken 版本</strong>:下方所有字段的组代码。</p>
-
-<p><strong>质询</strong>:一个随机整数,用于防范重放攻击。通常是所请求的加密操作的 ID,目前可供交易指纹授权使用。如果质询存在,AuthToken 仅对包含相应质询的加密操作有效。</p>
-
-<p><strong>用户 SID</strong>:不重复的用户标识符,以加密形式绑定到与设备身份验证关联的所有密钥。如需更多信息,请参阅 Gatekeeper 页面。</p>
-
-<p><strong>身份验证程序 ID (ASID)</strong>:绑定到特定身份验证程序政策时使用的标识符。所有身份验证程序都有自己的 ASID 值,它们可以根据自己的要求更改该值。</p>
-
-<p><strong>身份验证程序类型</strong>:Gatekeeper 或 Fingerprint,如下所示:</p>
-<table>
- <tbody><tr>
-    <th><strong>身份验证程序类型</strong></th>
-    <th><strong>身份验证程序名称</strong></th>
- </tr>
- <tr>
-    <td>0x00</td>
-    <td>Gatekeeper</td>
- </tr>
- <tr>
-    <td>0x01</td>
-    <td>Fingerprint</td>
- </tr>
-</tbody></table>
-
-<p><strong>时间戳</strong>:自最近一次系统启动以来已经过的时间(以毫秒数计)。</p>
-
-<p><strong>AuthToken HMAC 密钥</strong>:除 HMAC 字段以外所有字段的已加密 SHA-256 MAC。</p>
-
 <h2 id="device_boot_flow">设备启动流程</h2>
 
-<p>设备每次启动时,都必须生成 AuthToken HMAC 密钥并与所有 TEE 组件(Gatekeeper、Fingerprint 和 Keymaster)共用该密钥。因此,设备每次重新启动时都必须随机生成 HMAC 密钥,以便加强对重放攻击的防范力度。</p>
+<p>每次设备启动时,都必须生成 AuthToken HMAC 密钥并由所有 TEE 组件(Gatekeeper、Fingerprint 和 Keymaster)共用该密钥。因此,为了加强对重播攻击的防范力度,每次设备重新启动时都必须随机生成 HMAC 密钥。</p>
 
-<p>关于与所有组件共用此 HMAC 密钥的协议是一项依赖于平台的实现功能。<strong>在任何情况下都不能</strong>将该密钥设为可在 TEE 以外获得。因此,如果 TEE 操作系统缺少内部进程间通信 (IPC) 机制,并且 TEE 需要通过不可信操作系统传输数据,那么传输操作必须通过安全的密钥交换协议进行。</p>
+<p>关于与所有组件共用此 HMAC 密钥的协议是一项依赖于平台的实现功能。<strong>在任何情况下都不能</strong>将该密钥设为在 TEE 之外可用。如果 TEE 操作系统缺少内部进程间通信 (IPC) 机制,需要通过不可信操作系统传输数据,那么传输操作必须通过安全的密钥交换协议进行。</p>
 
-<p>与 Android 并排运行的 <a href="/security/trusty/index.html">Trusty</a> 操作系统就是一种 TEE,不过也可以使用其他 TEE。Trusty 使用内部 IPC 系统在 Keymaster 和 Fingerprint 或 Gatekeeper 之间直接进行通信。HMAC 密钥单独保存在 Keymaster 内。Fingerprint 和 Gatekeeper 会在每次使用该密钥时向 Keymaster 请求该密钥,而不会保留或缓存该密钥的值。</p>
+<p>与 Android 并排运行的 <a href="/security/trusty/index.html">Trusty</a> 操作系统就是一种 TEE,不过也可以使用其他 TEE。Trusty 使用内部 IPC 机制在 Keymaster 和 Fingerprint 或 Gatekeeper 之间直接进行通信。HMAC 密钥只保存在 Keymaster 中,Fingerprint 和 Gatekeeper 会在每次使用时向 Keymaster 请求该密钥,而不会保留或缓存该密钥的值。</p>
 
-<p>请注意,TEE 中的小程序之间不会进行任何通信,因为 IPC 基础架构中缺少部分 TEE。这还使得 Keystore 服务因知晓系统内的身份验证表而能够快速拒绝注定会失败的请求,从而避免向 TEE 发送会占用大量处理能力的 IPC。</p>
+<p>一些 TEE 缺少 IPC 基础架构,因此 TEE 中的小程序之间不会进行通信。这还使得 Keystore 服务因知晓系统中的身份验证表而能够快速拒绝注定会失败的请求,从而避免向 TEE 发送会占用大量处理能力的 IPC。</p>
 
 </body></html>
\ No newline at end of file
diff --git a/zh-cn/security/encryption/file-based.html b/zh-cn/security/encryption/file-based.html
index ce93f0e..fcd2201 100644
--- a/zh-cn/security/encryption/file-based.html
+++ b/zh-cn/security/encryption/file-based.html
@@ -22,8 +22,12 @@
 
 <p>Android 7.0 及更高版本支持文件级加密 (FBE)。采用文件级加密时,可以使用不同的密钥对不同的文件进行加密,并且可以对这些文件进行单独解密。
 </p>
-<p>本文介绍了如何在新设备上启用文件级加密,以及如何更新系统应用,以充分利用新的 Direct Boot API 并尽可能为用户提供最佳、最安全的体验。
+<p>
+本文介绍了如何在新设备上启用文件级加密,以及如何更新系统应用,以充分利用新的 Direct Boot API 并尽可能为用户提供最佳、最安全的体验。
 </p>
+
+<p class="warning"><strong>警告</strong>:文件级加密目前无法与<a href="/devices/storage/adoptable.html">可合并的存储设备</a>一起使用。在使用文件级加密的设备上,必须将新的存储媒介(如 SD 卡)用作<a href="/devices/storage/traditional.html">传统存储设备</a>。</p>
+
 <h2 id="direct-boot">直接启动</h2>
 <p>借助文件级加密,Android 7.0 中引入了一项称为<a href="https://developer.android.com/training/articles/direct-boot.html">直接启动</a>的新功能。该功能处于启用状态时,已加密设备在启动后将直接进入锁定屏幕。之前,在使用<a href="full-disk.html">全盘加密</a> (FDE) 的已加密设备上,用户在访问任何数据之前都需要先提供凭据,从而导致手机无法执行除最基本操作之外的所有其他操作。例如,闹钟无法运行,无障碍服务不可用,手机无法接电话,而只能进行基本的紧急拨号操作。
 </p>
@@ -47,7 +51,8 @@
 
 <h2 id="examples-and-source">示例和源代码</h2>
 
-<p>Android 提供了文件级加密的参考实现,其中 vold (system/vold) 负责提供用于管理 Android 上的存储设备和存储卷的功能。添加 PDE 会为 vold 提供一些新命令,以便支持对多位用户的 CE 密钥和 DE 密钥进行密钥管理。除了为使用内核中的 <a href="#kernel-support">EXT4 加密</a>功能而进行的核心更改外,许多系统程序包(包括锁定屏幕和 SystemUI)也经过了修改,以支持 FBE 和“直接启动”功能。其中包括:</p>
+<p>
+Android 提供了文件级加密的参考实现,其中 vold (<a href="https://android.googlesource.com/platform/system/vold/">system/vold</a>) 负责提供用于管理 Android 上的存储设备和存储卷的功能。添加 PDE 会为 vold 提供一些新命令,以便支持对多位用户的 CE 密钥和 DE 密钥进行密钥管理。除了为使用内核中的 <a href="#kernel-support">EXT4 加密</a>功能而进行的核心更改外,许多系统程序包(包括锁定屏幕和 SystemUI)也经过了修改,以支持 FBE 和“直接启动”功能。其中包括:</p>
 
 <ul>
 <li>AOSP 拨号器 (packages/apps/Dialer)</li><li>桌面时钟 (packages/apps/DeskClock)</li><li>LatinIME (packages/inputmethods/LatinIME)*</li><li>“设置”应用 (packages/apps/Settings)*</li><li>SystemUI (frameworks/base/packages/SystemUI)*</li></ul>
@@ -105,14 +110,19 @@
 <p>除了对 EXT4 加密提供功能支持外,设备制造商还可以考虑实现加密加速功能,以便加快文件级加密的速度并改善用户体验。
 </p>
 <h3 id="enabling-file-based-encryption">启用文件级加密</h3>
-<p>通过将不带参数的 <code>fileencryption</code> 标记添加到 <code>userdata</code> 分区最后一列的 <code>fstab</code> 行中,可以启用 FBE。要查看示例,请访问 <a href="https://android.googlesource.com/device/lge/bullhead/+/nougat-release/fstab_fbe.bullhead">https://android.googlesource.com/device/lge/bullhead/+/nougat-release/fstab_fbe.bullhead</a>
-</p>
-<p>测试设备上的 FBE 实现情况时,可以指定以下标记:<code>forcefdeorfbe="&lt;path/to/metadata/partition&gt;"</code>
+<p>
+通过将 <code>fileencryption=contents_encryption_mode[:filenames_encryption_mode]</code> 标记添加到 <code>userdata</code> 分区最后一列的 <code>fstab</code> 行中,可以启用 FBE。<code>contents_encryption_mode</code> 参数定义了哪些加密算法用于文件内容的加密,<code>filenames_encryption_mode</code> 参数定义了哪些加密算法用于文件名的加密。
+<code>contents_encryption_mode</code> 只能是 <code>aes-256-xts</code>。
+<code>filenames_encryption_mode</code> 有两个可能的值:<code>aes-256-cts</code> 和 <code>aes-256-heh</code>。如果未指定 <code>filenames_encryption_mode</code>,则使用 <code>aes-256-cts</code> 值。
+</p><p>
+测试设备上的 FBE 实现情况时,可以指定以下标记:<code>forcefdeorfbe="&lt;path/to/metadata/partition&gt;"</code>
 </p>
 <p>此标记会将设备设为使用 FDE,但允许针对开发者转换为 FBE。默认情况下,此标记的行为类似于 <code>forceencrypt</code>,会使设备进入 FDE 模式。不过,它将提供一个调试选项,以便在开发者预览中允许将设备切换到 FBE 模式。另外,还可以使用以下命令在 fastboot  中启用 FBE:</p>
 <p>
-<code>$ fastboot --wipe-and-use-fbe</code>
-</p>
+</p><pre class="devsite-terminal devsite-click-to-copy">
+fastboot --wipe-and-use-fbe
+</pre>
+<p></p>
 <p>此标记仅用于开发目的,可提供一个在实际 FBE 设备发布之前演示 FBE 功能的平台。此标记在将来可能会被弃用。
 </p>
 <h3 id="integrating-with-keymaster">与 Keymaster 集成</h3>
@@ -130,9 +140,7 @@
 <p>EXT4 加密在目录级应用加密政策。首次创建设备的 <code>userdata</code> 分区时,会由 <code>init</code> 脚本应用基本结构和政策。这些脚本将触发创建首位用户(用户 0)的 CE 密钥和 DE 密钥,并定义要使用这些密钥加密哪些目录。创建其他用户和资料时,会生成必要的其他密钥并将其存储在密钥代码库中;接下来会创建它们的凭据和设备存储位置,并且加密政策会将这些密钥关联到相应目录。
 </p>
 <p>在 AOSP 当前提供的文件级加密实现中,加密政策被硬编码到了以下位置:</p>
-<p>
-<code>/system/extras/ext4_utils/ext4_crypt_init_extensions.cpp</code>
-</p>
+<pre class="devsite-click-to-copy">/system/extras/ext4_utils/ext4_crypt_init_extensions.cpp</pre>
 <p>可以在该文件中添加例外情况,以彻底防止特定目录被加密,具体方法是将相应目录添加到 <code>directories_to_exclude</code> 列表中。如果进行了此类修改,设备制造商应添加 <a href="/security/selinux/device-policy.html">SELinux 政策</a>,以便仅向需要使用未加密目录的应用授予访问权限(应排除所有不可信的应用)。
 </p>
 <p>目前唯一可接受的使用这种方法的情况是在支持旧版 OTA 功能方面。
@@ -143,7 +151,7 @@
 <p>为了实现系统应用的快速迁移,新增了两个可在应用级别设置的属性。<code>defaultToDeviceProtectedStorage</code> 属性仅适用于系统应用,<code>directBootAware</code> 属性则适用于所有应用。
 </p>
 
-<pre>
+<pre class="devsite-click-to-copy">
 &lt;application
     android:directBootAware="true"
     android:defaultToDeviceProtectedStorage="true"&gt;
@@ -185,13 +193,17 @@
 <p>在该文件夹中创建一个目录,以便存放 OTA 更新包。
 </p>
 <h2 id="validation">验证</h2>
-<p>为了确保实现的 FBE 功能版本能够按预期工作,需要部署多种 <a href="https://android.googlesource.com/platform/cts/+/nougat-cts-release/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java">CTS 加密测试</a>。
+<p>
+为了确保实现的 FBE 功能版本能够按预期工作,需要部署多种 <a href="https://android.googlesource.com/platform/cts/+/nougat-cts-release/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java">CTS 加密测试</a>。
 </p>
-<p>可以顺利为您的主板编译内核后,请另行为 x86 编译内核并在 QEMU 下运行该内核,然后您就可以使用以下命令通过 <a hre="https://git.kernel.org/cgit/fs/ext2/xfstests-bld.git/plain/quick-start?h=META">xfstest</a> 进行测试了:</p>
-<pre>
-$ kvm-xfstests -c encrypt -g auto
+<p>
+可以顺利为您的主板编译内核后,还需要为 x86 编译内核并在 QEMU 下运行该内核,以便使用以下命令通过 <a hre="https://git.kernel.org/cgit/fs/ext2/xfstests-bld.git/plain/quick-start?h=META">xfstest</a> 进行测试:
+</p>
+<pre class="devsite-terminal devsite-click-to-copy">
+kvm-xfstests -c encrypt -g auto
 </pre>
-<p>此外,设备制造商可以在启用了 FBE 的设备上进行以下手动测试:</p>
+<p>
+此外,设备制造商可以执行这些手动测试。在启用了 FBE 的设备上进行以下手动测试:</p>
 
 <ul>
   <li>检查 <code>ro.crypto.state</code> 是否存在<ul>
@@ -215,9 +227,11 @@
 <h3 id="key-derivation">密钥派生</h3>
 <p>硬盘加密密钥(512 位 AES-XTS 密钥)以加密形式存储:通过另一个存放在 TEE 中的密钥(256 位 AES-GCM 密钥)进行加密。要使用该 TEE 密钥,需要具备以下三项:</p><ul>
 <li>身份验证令牌</li><li>扩展凭据</li><li>secdiscardable hash</li></ul>
-<p>身份验证令牌是一个经过加密和身份验证的令牌,由 <a href="/security/authentication/gatekeeper.html">Gatekeeper</a> 在用户成功登录时生成。<em></em>除非用户提供的身份验证令牌正确无误,否则 TEE 将拒绝用户使用该密钥。如果用户没有任何凭据,则不使用也不需要使用身份验证令牌。
+<p>
+身份验证令牌是一个经过加密和身份验证的令牌,由 <a href="/security/authentication/gatekeeper.html">Gatekeeper</a> 在用户成功登录时生成。<em></em>除非用户提供的身份验证令牌正确无误,否则 TEE 将拒绝用户使用该密钥。如果用户没有任何凭据,则不使用也不需要使用身份验证令牌。
 </p>
-<p>扩展凭据是使用 <code>scrypt</code> 算法进行加盐和扩展处理的用户凭据。<em></em>实际上,凭据在被传递到 <code>vold</code>(以便传递到 <code>scrypt</code>)之前,会在锁定设置服务中接受一次哈希处理。扩展凭据会以加密形式绑定到 TEE 中的相应密钥,并享有适用于 <code>KM_TAG_APPLICATION_ID</code> 的所有保证。如果用户没有凭据,则不使用也不需要使用扩展凭据。
+<p>
+扩展凭据是使用 <code>scrypt</code> 算法进行加盐和扩展处理的用户凭据。<em></em>实际上,凭据在被传递到 <code>vold</code>(以便传递到 <code>scrypt</code>)之前,会在锁定设置服务中接受一次哈希处理。扩展凭据会以加密形式绑定到 TEE 中的相应密钥,并享有适用于 <code>KM_TAG_APPLICATION_ID</code> 的所有保证。如果用户没有凭据,则不使用也不需要使用扩展凭据。
 </p>
 <p><code>secdiscardable hash</code> 是 16 KB 随机文件的 512 位哈希,和用于重建相应密钥的其他信息(例如种子)存储在一起。在相应密钥被删除时,该文件会一并被安全地删除,或以新的方式被加密;采用这种附加的保护措施后,攻击者要恢复相应密钥,必须要先恢复这个被安全删除的文件中的每一个位。secdiscardable hash 同样会以加密形式绑定到 TEE 中的相应密钥,并享有适用于 <code>KM_TAG_APPLICATION_ID</code> 的所有保证。请参阅<a href="/security/keystore/implementer-ref.html">面向 Keystore 实现人员的参考资料</a>。
 
diff --git a/zh-cn/security/encryption/full-disk.html b/zh-cn/security/encryption/full-disk.html
index b06a575..cd7ff21 100644
--- a/zh-cn/security/encryption/full-disk.html
+++ b/zh-cn/security/encryption/full-disk.html
@@ -380,7 +380,7 @@
 </tbody></table>
 <h2 id="init_actions">init 操作</h2>
 
-<pre>
+<pre class="devsite-click-to-copy">
 on post-fs-data
 on nonencrypted
 on property:vold.decrypt=trigger_reset_main
diff --git a/zh-cn/security/index.html b/zh-cn/security/index.html
index b0103c9..cdb4f17 100644
--- a/zh-cn/security/index.html
+++ b/zh-cn/security/index.html
@@ -76,7 +76,7 @@
 <ul>
   <li><strong>Google Play</strong>:Google Play 是一系列服务的总称。借助这些服务,用户可以通过自己的 Android 设备或网络发现、安装和购买应用。Google Play 可让开发者轻松覆盖 Android 用户和潜在客户。此外,Google Play 还提供社区审核、应用<a href="https://developer.android.com/guide/publishing/licensing.html">许可验证</a>、应用安全扫描以及其他安全服务。</li>
   <li><strong>Android 更新</strong>:Android 更新服务可为某些 Android 设备提供新功能和安全更新,其中包括通过网络或无线下载 (OTA) 方式提供的更新。</li>
-  <li><strong>应用服务</strong>:可让 Android 应用使用云功能的框架,例如应用数据和设置<a href="https://developer.android.com/guide/topics/data/backup.html">备份</a>功能,以及用于推送消息的云端至设备消息传递功能 (<a href="https://developers.google.com/cloud-messaging/">C2DM</a>)。</li>
+  <li><strong>应用服务</strong>:可让 Android 应用使用云功能(例如,应用数据和设置<a href="https://developer.android.com/guide/topics/data/backup.html">备份</a>功能,以及用于推送消息的“云端至设备消息传递”(<a href="https://developers.google.com/cloud-messaging/">C2DM</a>) 功能)的框架。</li>
   <li><strong>验证应用</strong>:在用户安装有害应用时发出警告或自动阻止安装;持续扫描设备上的应用,并在发现<a href="https://support.google.com/accounts/answer/2812853">有害应用</a>时发出警告或将其移除。
   </li>
   <li><strong>SafetyNet</strong>:一款旨在保护隐私的入侵检测系统,能够帮助 Google 跟踪和降低已知的安全威胁,并能够发现新的安全威胁。</li>
diff --git a/zh-cn/security/keystore/attestation.html b/zh-cn/security/keystore/attestation.html
new file mode 100644
index 0000000..039e9e4
--- /dev/null
+++ b/zh-cn/security/keystore/attestation.html
@@ -0,0 +1,611 @@
+<html devsite><head>
+    <title>密钥认证和 ID 认证</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          //www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+<p>
+Keystore 提供了一个更安全的位置,让您能够以可控方式创建、存储和使用加密密钥。如果有硬件支持的密钥存储区可用,则使用该存储区比从设备中提取密钥材料更安全,并且 Keymaster 强制执行的限制会更难以打破。
+</p>
+<p>
+不过,仅当已知 Keystore 密钥位于由硬件支持的存储区中时,才能够实现这一点。在 Keymaster 1 中,应用或远程服务器无法可靠地验证是否属于这种情况。Keystore 守护进程加载可用的 Keymaster HAL,并相信 HAL 对于密钥硬件支持的任何判断。
+</p>
+<p>
+为了解决此问题,Keymaster 在 Android 7.0 (Keymaster 2) 中引入了密钥认证,在 Android 8.0 (Keymaster 3) 中引入了 ID 认证。
+</p>
+<p>
+密钥认证旨在提供一种方式,可让您明确地确定某个不对称密钥对是否由硬件支持、该密钥有哪些属性,及其使用具有哪些限制条件。
+</p>
+<p>
+通过 ID 认证,设备可以提供其硬件标识符的证明,例如序列号或 IMEI。
+
+</p><p class="note">为了支持 Keymaster 3 从旧式 C 结构 HAL 转换到根据新硬件接口定义语言 (HIDL) 中的定义生成的 C++ HAL 接口,Android 8.0 中的标记和方法名称已更改。如同所有其他 keymaster 枚举一样,标记现在被定义为 C++ 域化 (scoped) 枚举。例如,标记的前缀从之前的 <code>KM_TAG_</code> 改为现在的 <code>Tag::</code>,而方法采用的是驼峰式大小写形式。除非另有指定,否则以下示例均使用 Keymaster 3 术语。
+</p>
+
+<h2 id="key-attestation">密钥认证</h2>
+<p></p>
+<p>
+为了支持密钥认证,Android 7.1 为 HAL 引入了一系列标记、类型和方法。
+</p>
+<p>
+<strong>标记</strong>
+</p>
+<ul>
+<li><code>Tag::ATTESTATION_CHALLENGE</code></li>
+<li><code>Tag::INCLUDE_UNIQUE_ID</code></li>
+<li><code>Tag::RESET_SINCE_ID_ROTATION</code></li>
+</ul>
+<p>
+<strong>类型</strong>
+</p>
+
+<p><strong>Keymaster 2 及更低版本</strong></p>
+<pre class="devsite-click-to-copy">typedef struct {
+    keymaster_blob_t* entries;
+    size_t entry_count;
+} keymaster_cert_chain_t;
+</pre>
+
+<p>
+<strong><code>AttestKey</code> 方法</strong></p>
+
+<p><strong>Keymaster 3</strong></p>
+<pre class="devsite-click-to-copy">
+    attestKey(vec&lt;uint8_t&gt; keyToAttest, vec&lt;KeyParameter&gt; attestParams)
+        generates(ErrorCode error, vec&lt;vec&lt;uint8_t&gt;&gt; certChain);</pre>
+
+<p><strong>Keymaster 2 及更低版本</strong></p>
+<pre class="devsite-click-to-copy">keymaster_error_t (*attest_key)(const struct keymaster2_device* dev,
+        const keymaster_key_blob_t* key_to_attest,
+        const keymaster_key_param_set_t* attest_params,
+        keymaster_cert_chain_t* cert_chain);
+</pre>
+
+<ul>
+<li><code>dev</code> 是 Keymaster 设备结构。</li>
+<li><code>keyToAttest</code> 是从系统将为其创建认证的 <code>generateKey</code> 返回的密钥 Blob。</li>
+<li><code>attestParams</code> 是认证所需的所有参数的列表。该列表包含 <code>Tag::ATTESTATION_CHALLENGE</code> 和 <code>Tag::RESET_SINCE_ID_ROTATION</code>,以及 <code>Tag::APPLICATION_ID</code> 和 <code>Tag::APPLICATION_DATA</code>。如果在密钥生成过程中指定了后两个参数,则它们是解密密钥 Blob 所必需的参数。</li>
+<li><code>certChain</code> 是输出参数,会返回一个证书数组。条目 0 是认证证书,表示它会对 <code>keyToAttest</code> 中的密钥进行认证,并且包含认证扩展。</li>
+</ul>
+
+<p>
+<code>attestKey</code> 方法被视为对经过认证的密钥进行的公钥操作,因为它可以随时调用,不需要满足授权限制条件。例如,如果经过认证的密钥需要进行用户身份验证才能使用,则该方法可以在不进行用户身份验证的情况下生成认证。
+</p>
+<h3 id="attestation-certificate">认证证书</h3>
+<p>
+认证证书是标准的 X.509 证书,具有可选的认证扩展,其中包含对经过认证的密钥的描述。证书采用出厂配置的<a href="#attestation-keys-and-certificates">认证密钥</a>进行签名,该密钥使用的算法与正在进行认证的密钥相同(例如,RSA 密钥使用 RSA 算法,EC 密钥使用 EC 算法)。
+</p>
+<p>
+认证证书中包含下表所列的字段,且不得包含任何其他字段。某些字段会指定固定的字段值。CTS 测试会验证证书内容是否与所定义的内容完全一致。
+</p>
+<h4 id="certificate-sequence">证书序列</h4>
+<table>
+  <tbody><tr>
+   <th>字段名称(请参见 <a href="https://tools.ietf.org/html/rfc5280">RFC 5280</a>)
+   </th>
+   <th>值</th>
+  </tr>
+  <tr>
+   <td><a href="https://tools.ietf.org/html/rfc5280#section-4.1.1.1">tbsCertificate</a></td>
+   <td><a href="#tbscertificate-sequence">TBSCertificate 序列</a></td>
+  </tr>
+  <tr>
+   <td><a href="https://tools.ietf.org/html/rfc5280#section-4.1.1.2">signatureAlgorithm</a></td>
+   <td>用于签署密钥的算法的 AlgorithmIdentifier:<br />
+       ECDSA 用于 EC 密钥,RSA 用于 RSA 密钥。</td>
+  </tr>
+  <tr>
+   <td><a href="https://tools.ietf.org/html/rfc5280#section-4.1.1.3">signatureValue</a></td>
+   <td>BIT STRING,在 ASN.1 DER 编码的 tbsCertificate 上计算的签名。</td>
+  </tr>
+</tbody></table>
+
+<h4 id="tbscertificate-sequence">TBSCertificate 序列</h4>
+
+<table>
+  <tbody><tr>
+   <th>字段名称(请参见 <a href="https://tools.ietf.org/html/rfc5280">RFC 5280</a>)</th>
+   <th>值</th>
+  </tr>
+  <tr>
+   <td><code>version</code></td>
+   <td>INTEGER 2(表示 v3 证书)</td>
+  </tr>
+  <tr>
+   <td><code>serialNumber</code></td>
+   <td>INTEGER 1(固定值:所有证书上的值都相同)<em></em></td>
+  </tr>
+  <tr>
+   <td><code>signature</code></td>
+   <td>用于签署密钥的算法的 AlgorithmIdentifier:ECDSA 用于 EC 密钥,RSA 用于 RSA 密钥。</td>
+  </tr>
+  <tr>
+   <td><code>issuer</code></td>
+   <td>与批量认证密钥的主题字段相同。</td>
+  </tr>
+  <tr>
+   <td><code>validity</code></td>
+   <td>两个日期的序列,包含 <a href="/security/keystore/tags#active_datetime">Tag::ACTIVE_DATETIME</a> 和 <a href="/security/keystore/tags#usage_expire_datetime">Tag::USAGE_EXPIRE_DATETIME</a> 的值。
+   这些值是自 1970 年 1 月 1 日以来的毫秒数。
+   有关证书中的正确日期表示法,请参阅 <a href="https://tools.ietf.org/html/rfc5280">RFC 5280</a>。<br />
+   如果 <code>Tag::ACTIVE_DATETIME</code> 不存在,则使用 <code>Tag::CREATION_DATETIME</code> 的值。如果 <code>Tag::USAGE_EXPIRE_DATETIME</code> 不存在,则使用批量认证密钥证书的失效日期。</td>
+  </tr>
+  <tr>
+   <td><code>subject</code></td>
+   <td>CN = "Android Keystore Key"(固定值:所有证书上的值都相同)<em></em></td>
+  </tr>
+  <tr>
+   <td><code>subjectPublicKeyInfo</code></td>
+   <td>SubjectPublicKeyInfo,包含经过认证的公钥。</td>
+  </tr>
+  <tr>
+   <td><code>extensions/Key Usage</code></td>
+   <td>digitalSignature:如果密钥具有 <code>KeyPurpose::SIGN</code> 或 <code>KeyPurpose::VERIFY</code> 用途,则设置该值。所有其他位均未设置。</td>
+  </tr>
+  <tr>
+   <td><code>extensions/CRL Distribution Points</code></td>
+   <td>值待定</td>
+  </tr>
+  <tr>
+   <td><code>extensions/"attestation"</code></td>
+   <td>OID 为 1.3.6.1.4.1.11129.2.1.17;内容在下文的“认证扩展”部分中定义。与所有 X.509 证书扩展一样,内容表示为一个 OCTET_STRING,其中包含认证序列的 DER 编码。</td>
+  </tr>
+</tbody></table>
+
+<h3 id="attestation-extension">认证扩展</h3>
+<p>
+认证扩展包含对与密钥相关联的密钥 Keymaster 授权的完整描述,其所采用的结构直接对应于 Android 和 Keymaster HAL 中使用的授权列表。授权列表中的各个标记分别由一个 ASN.1 SEQUENCE 条目表示,通过 Keymaster 标记编号进行显式标记,而类型描述符(4 个高值位)则采用掩码处理。</p>
+<p>例如,在 Keymaster 3 中,<code>Tag::PURPOSE</code> 在 types.hal 中被定义为 <code>ENUM_REP | 1</code>。对于认证扩展,<code>ENUM_REP</code> 值会被移除,但留下标记 <code>1</code>。
+(对于 Keymaster 2 及更低版本,<code>KM_TAG_PURPOSE</code> 在 keymaster_defs.h 中定义。)
+</p>
+<p>
+根据下表所示,值通过一种简单的方式转换为 ASN.1 类型:</p>
+<table>
+  <tbody><tr>
+   <th>Keymaster 类型</th>
+   <th>ASN.1 类型</th>
+  </tr>
+  <tr>
+   <td><code>ENUM</code></td>
+   <td>整数</td>
+  </tr>
+  <tr>
+   <td><code>ENUM_REP</code></td>
+   <td>整数集</td>
+  </tr>
+  <tr>
+   <td><code>UINT</code></td>
+   <td>整数</td>
+  </tr>
+  <tr>
+   <td><code>UINT_REP</code></td>
+   <td>整数集</td>
+  </tr>
+  <tr>
+   <td><code>ULONG</code></td>
+   <td>整数</td>
+  </tr>
+  <tr>
+   <td><code>ULONG_REP</code></td>
+   <td>整数集</td>
+  </tr>
+  <tr>
+   <td><code>DATE</code></td>
+   <td>整数(自 1970 年 1 月 1 日 GMT 00:00:00 以来的毫秒数)</td>
+  </tr>
+  <tr>
+   <td><code>BOOL</code></td>
+   <td>Null(在 Keymaster 中,标记存在表示 true,不存在表示 false。<br />
+       相同的语义适用于 ASN.1 编码)</td>
+  </tr>
+  <tr>
+   <td><code>BIGNUM</code></td>
+   <td>目前未使用该类型,因此未定义任何映射</td>
+  </tr>
+  <tr>
+   <td><code>BYTES</code></td>
+   <td>OCTET_STRING</td>
+  </tr>
+</tbody></table>
+<p class="note">
+<strong>注意</strong>:该架构中省略了某些标记,这些标记不应该包含在认证中。例如,<code>Tag::USER_ID</code> 和 <code>Tag::SECURE_USER_ID</code> 的值在设备外没有意义,而 <code>Tag::MIN_MAC_LENGTH</code> 和 <code>Tag::CALLER_NONCE</code> 对于不对称密钥是无用的。
+</p>
+
+<h4 id="schema">架构</h4>
+<p>
+认证扩展内容由以下 ASN.1 架构描述。
+此示例还包含 Keymaster 3 更新,现在包括 <a href="#id-attestation">ID 认证</a>功能,其以粗体显示且带有注释。
+</p>
+
+<pre class="devsite-click-to-copy">
+KeyDescription ::= SEQUENCE {
+  <strong>attestationVersion         INTEGER,</strong> # KM2 value is 1. KM3 value is 2.
+  attestationSecurityLevel   SecurityLevel,
+  keymasterVersion           INTEGER,
+  keymasterSecurityLevel     SecurityLevel,
+  attestationChallenge       OCTET_STRING,
+  uniqueId                   OCTET_STRING,
+  softwareEnforced           AuthorizationList,
+  teeEnforced                AuthorizationList,
+}
+
+SecurityLevel ::= ENUMERATED {
+  Software                   (0),
+  TrustedEnvironment         (1),
+}
+AuthorizationList ::= SEQUENCE {
+  purpose                    [1] EXPLICIT SET OF INTEGER OPTIONAL,
+  algorithm                  [2] EXPLICIT INTEGER OPTIONAL,
+  keySize                    [3] EXPLICIT INTEGER OPTIONAL.
+  digest                     [5] EXPLICIT SET OF INTEGER OPTIONAL,
+  padding                    [6] EXPLICIT SET OF INTEGER OPTIONAL,
+  ecCurve                    [10] EXPLICIT INTEGER OPTIONAL,
+  rsaPublicExponent          [200] EXPLICIT INTEGER OPTIONAL,
+  activeDateTime             [400] EXPLICIT INTEGER OPTIONAL
+  originationExpireDateTime  [401] EXPLICIT INTEGER OPTIONAL
+  usageExpireDateTime        [402] EXPLICIT INTEGER OPTIONAL
+  noAuthRequired             [503] EXPLICIT NULL OPTIONAL,
+  userAuthType               [504] EXPLICIT INTEGER OPTIONAL,
+  authTimeout                [505] EXPLICIT INTEGER OPTIONAL,
+  allowWhileOnBody           [506] EXPLICIT NULL OPTIONAL,
+  allApplications            [600] EXPLICIT NULL OPTIONAL,
+  applicationId              [601] EXPLICIT OCTET_STRING OPTIONAL,
+  creationDateTime           [701] EXPLICIT INTEGER OPTIONAL,
+  origin                     [702] EXPLICIT INTEGER OPTIONAL,
+  rollbackResistant          [703] EXPLICIT NULL OPTIONAL,
+  rootOfTrust                [704] EXPLICIT RootOfTrust OPTIONAL,
+  osVersion                  [705] EXPLICIT INTEGER OPTIONAL,
+  osPatchLevel               [706] EXPLICIT INTEGER OPTIONAL,
+  <strong>attestationApplicationId   [709] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3
+  <strong>attestationIdBrand         [710] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3
+  <strong>attestationIdDevice        [711] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3
+  <strong>attestationIdProduct       [712] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3
+  <strong>attestationIdSerial        [713] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3
+  <strong>attestationIdImei          [714] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3
+  <strong>attestationIdMeid          [715] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3
+  <strong>attestationIdManufacturer  [716] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3
+  <strong>attestationIdModel         [717] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3
+}
+RootOfTrust ::= SEQUENCE {
+  verifiedBootKey            OCTET_STRING,
+  deviceLocked               BOOLEAN,
+  verifiedBootState          VerifiedBootState,
+}
+
+VerifiedBootState ::= ENUMERATED {
+  Verified                   (0),
+  SelfSigned                 (1),
+  Unverified                 (2),
+  Failed                     (3),
+}</pre>
+
+<h4 id="keydescription-fields">KeyDescription 字段</h4>
+<p>
+keymasterVersion 和 attestationChallenge 字段通过位置(而非标记)进行标识,因此编码形式的标记仅指定字段类型。其余字段采用隐式标记,如架构中所指定。
+</p>
+<table>
+  <tbody><tr>
+   <th>字段名称</th>
+   <th>类型</th>
+   <th>值</th>
+  </tr>
+  <tr>
+   <td><code>attestationVersion</code></td>
+   <td>INTEGER</td>
+   <td>1</td>
+  </tr>
+  <tr>
+   <td><code>attestationSecurity</code></td>
+   <td>SecurityLevel</td>
+   <td>此认证的安全级别。可以对由硬件支持的密钥实现软件认证。如果 Android 系统遭到入侵,则此类认证不可信。</td>
+  </tr>
+  <tr>
+   <td><code>keymasterVersion</code></td>
+   <td>INTEGER</td>
+   <td>Keymaster 设备的版本,例如 0、1 或 2。</td>
+  </tr>
+  <tr>
+   <td><code>keymasterSecurity</code></td>
+   <td>SecurityLevel</td>
+   <td>Keymaster 实现的安全级别。</td>
+  </tr>
+  <tr>
+   <td><code>attestationChallenge</code></td>
+   <td>OCTET_STRING</td>
+   <td><code>Tag::ATTESTATION_CHALLENGE</code> 的值,根据认证请求指定。</td>
+  </tr>
+  <tr>
+   <td><code>uniqueId</code></td>
+   <td>OCTET_STRING</td>
+   <td>可选的唯一 ID,如果密钥具有 <code>Tag::INCLUDE_UNIQUE_ID</code>,则存在该值</td>
+  </tr>
+  <tr>
+   <td><code>softwareEnforced</code></td>
+   <td>AuthorizationList</td>
+   <td>可选值,不会被 TEE 强制执行的 Keymaster 授权(如果存在)。</td>
+  </tr>
+  <tr>
+   <td><code>teeEnforced</code></td>
+   <td>AuthorizationList</td>
+   <td>可选值,会被 TEE 强制执行的 Keymaster 授权(如果存在)。</td>
+  </tr>
+</tbody></table>
+
+<h4 id="authorizationlist-fields">AuthorizationList 字段</h4>
+<p>
+AuthorizationList 字段均为可选字段并通过 Keymaster 标记值来标识,类型位则采用掩码处理。此类字段使用显式标记,因此还包含一个可指明其 ASN.1 类型的标记,这样更易于解析。
+</p>
+<p>
+要详细了解各个字段的值,如果是 Keymaster 3,请参阅 types.hal,如果是 Keymaster 2 及更低版本,请参阅 keymaster_defs.h。通过省略 KM_TAG 前缀并将其余部分更改为驼峰式大小写形式,Keymaster 标记名称被转换为了字段名称,因此 <code>Tag::KEY_SIZE</code> 变成了 <code>keySize</code>。
+</p>
+<p class="note">
+<strong>注意</strong>:types.hal 和 keymaster_defs.h 中的很多标记都未包含在该架构中。因为一些标记不适用于不对称密钥,还有一些标记在设备外没有意义,等等。
+</p>
+
+<h4 id="rootoftrust-fields">RootOfTrust 字段</h4>
+<p>
+RootOfTrust 字段通过位置进行标识。
+</p>
+<table>
+  <tbody><tr>
+   <th>字段名称</th>
+   <th>类型</th>
+   <th>值</th>
+  </tr>
+  <tr>
+   <td><code>verifiedBootKey</code></td>
+   <td>OCTET_STRING</td>
+   <td>用于验证系统映像的密钥的安全哈希。建议使用 SHA-256。</td>
+  </tr>
+  <tr>
+   <td><code>deviceLocked</code></td>
+   <td>BOOLEAN</td>
+   <td>如果引导加载程序已锁定,则该值为 true,这表示只能刷入已签名的映像,并表示验证启动检查已完成。</td>
+  </tr>
+  <tr>
+   <td><code>verifiedBootState</code></td>
+   <td>VerifiedBootState</td>
+   <td>已验证启动的状态。</td>
+  </tr>
+  <tr>
+   <td><code>osVersion</code></td>
+   <td>INTEGER</td>
+   <td>操作系统的当前版本,采用 MMmmss 格式的整数表示,其中 MM 表示主要版本号(两位数),mm 表示次要版本号(两位数),ss 表示两位数的子次要版本号。例如,版本 6.0.1 将表示为 060001</td>
+  </tr>
+  <tr>
+   <td><code>patchMonthYear</code></td>
+   <td>INTEGER</td>
+   <td>最新补丁程序的月份和年份,采用 YYYYMM 格式的整数表示,其中 YYYY 表示四位数年份,MM 表示两位数月份。例如,2016 年 4 月将表示为 201604。</td>
+  </tr>
+</tbody></table>
+<h4 id="verifiedbootstate-values">VerifiedBootState 值</h4>
+<p>
+<code>verifiedBootState</code> 的值具有以下含义:
+</p>
+<table>
+  <tbody><tr>
+   <th>值</th>
+   <th>含义</th>
+  </tr>
+  <tr>
+   <td><code>Verified</code></td>
+   <td>表示实现了从引导加载程序到已验证分区的完整信任链,其中包括引导加载程序、启动分区和所有已验证的分区。<br />
+在此状态下,verifiedBootKey 值是嵌入证书的哈希值,表示不可更改的证书已烧录到 ROM 中。</td>
+  </tr>
+  <tr>
+   <td><code>SelfSigned</code></td>
+   <td>表示已使用嵌入的证书验证启动分区,并且签名有效。在允许启动过程继续之前,引导加载程序会显示一条警告以及公钥的指纹。
+<br />
+在此状态下,verifiedBootKey 值是自签名证书的哈希值。</td>
+  </tr>
+  <tr>
+   <td><code>Unverified</code></td>
+   <td>表示可以随意修改设备。设备完整性由用户进行带外验证。在允许启动过程继续之前,引导加载程序会向用户显示一条警告。<br />
+在此状态下,verifiedBootKey 值为空。</td>
+  </tr>
+  <tr>
+   <td><code>Failed</code></td>
+   <td>表示设备验证失败。实际上,并没有任何认证证书包含此值,因为引导加载程序在此状态下会停止运行。此处包含该值是为了实现完整性。</td>
+  </tr>
+</tbody></table>
+
+<h4 id="securitylevel-values">SecurityLevel 值</h4>
+<p>
+securityLevel 的值具有以下含义:
+</p>
+<table>
+  <tbody><tr>
+   <th>值</th>
+   <th>含义</th>
+  </tr>
+  <tr>
+   <td><code>Software</code></td>
+   <td>创建或管理相关元素(认证或密钥)的代码已在 Android 系统中实现,如果 Android 系统遭到入侵,该代码可能会被更改。</td>
+  </tr>
+  <tr>
+   <td><code>TrustedEnvironment</code></td>
+   <td>创建或管理相关元素(认证或密钥)的代码已在可信执行环境 (TEE) 中实现。如果 TEE 遭到入侵,该代码可能会被更改;不过,TEE 对远程入侵具有很强的抵抗力,并且可以通过直接硬件攻击来适度抵御入侵。</td>
+  </tr>
+</tbody></table>
+<h3 id="unique-id">唯一 ID</h3>
+<p>
+唯一 ID 是一个用于标识设备的 128 位值,但只能在限定时间段内使用。该值通过以下公式计算得出:
+</p>
+
+<pre class="devsite-click-to-copy">
+HMAC_SHA256(T || C || R, HBK)
+</pre>
+
+<p>
+其中:
+</p>
+
+<ul>
+<li><code>T</code> 是“时间计数器值”,通过将 <code>Tag::CREATION_DATETIME</code> 的值除以 2592000000 再舍去所有余数计算得出。<code>T</code> 每 30 天变化一次 (2592000000 = 30 * 24 * 60 * 60 * 1000)。</li>
+<li><code>C</code> 是 <code>Tag::APPLICATION_ID</code> 的值</li>
+<li>如果 attest_key 调用的 attest_params 参数中存在 <code>Tag::RESET_SINCE_ID_ROTATION</code>,则 <code>R</code> 为 1;如果不存在该标记,则为 0。</li>
+<li><code>HBK</code> 是可信执行环境已知的绑定到硬件的唯一密钥,可信执行环境绝不会显示该密钥。该密钥包含至少 128 位的熵,并且对于单个设备是独一无二的(根据 128 位的熵,概率上的唯一性是可接受的)。
+Jack: "128 位的熵" 是否合适??
+serena:可以HBK 应该通过 HMAC 或 AES_CMAC 从融合密钥材料中派生。</li>
+</ul>
+<p>
+将 HMAC_SHA256 输出截断为 128 位。
+</p>
+
+<h3 id="attestation-keys-and-certificates">认证密钥和证书</h3>
+<p>
+两个密钥、一个 RSA 和一个 ECDSA 以及相应的证书链均已安全地部署到设备中。
+</p>
+
+<h2 id="id-attestation">ID 认证</h2>
+
+<p>
+Android 8.0 为使用 Keymaster 3 的设备提供了对 ID 认证的可选支持。通过 ID 认证,设备可以提供其硬件标识符的证明,例如序列号或 IMEI。虽然这是可选功能,但强烈建议所有 Keymaster 3 实现提供对该功能的支持,因为能够证明设备的身份可确保真正的零触摸远程配置等用例更加安全(因为远程端可以确定与它进行对话的是正确的设备,而非假冒其身份的设备)。
+</p>
+<p>
+ID 认证的工作原理如下:在设备出厂之前,创建只有可信执行环境 (TEE) 才能访问的设备硬件标识符的副本。用户可以解锁设备的引导加载程序,并更改系统软件以及 Android 框架所报告的标识符。由 TEE 保存的标识符的副本不会以这种方式被操控,这样可确保设备 ID 认证仅用于证明设备的原始硬件标识符,从而阻止尝试假冒身份的操作。
+</p>
+<p>
+ID 认证的主要 API 表面基于 Keymaster 2 中引入的现有密钥认证机制构建而成。在为 Keymaster 所保存的密钥请求认证证书时,调用程序可能会要求将该设备的硬件标识符包含在认证证书的元数据中。如果密钥保存在 TEE 中,该证书会链接回一个已知的信任根。此类证书的接收方可以验证该证书及其内容(包括硬件标识符)是否由 TEE 所编写。如果调用程序要求在认证证书中包含硬件标识符,TEE 会仅证明其存储区中保存的标识符,正如在工厂车间进行填充一样。
+</p>
+
+<h3 id="storage-properties">存储区属性</h3>
+<p>
+保存设备标识符的存储区需要具有以下属性:
+</p>
+<ul>
+  <li>在设备出厂之前,将设备的原始标识符派生的值复制到存储区中。</li>
+  <li><code>destroyAttestationIds()</code> 方法可以永久破坏该标识符所派生数据的副本。永久破坏意味着数据会被彻底移除,无论是恢复出厂设置还是在设备上执行任何其他程序都无法将其恢复。对于用户已解锁引导加载程序并更改了系统软件以及 Android 框架返回的标识符的设备而言,这一点尤其重要。</li>
+  <li>RMA 设施应该能够生成硬件标识符派生数据的新副本。这样一来,通过 RMA 的设备可以再次执行 ID 认证。必须保护 RMA 设施使用的机制,从而使用户无法自行调用,因为调用该机制会导致用户完成对假冒 ID 的认证。</li>
+  <li>在 TEE 中,除了 Keymaster 可信应用之外的所有代码都无法读取存储区中保存的标识符派生数据。</li>
+  <li>存储区可以防篡改:如果存储区的内容已遭到修改,TEE 会将其视为相应内容的副本已被破坏,并会拒绝尝试进行 ID 认证的所有操作。这通过对存储区执行签名或 MAC 来实现(<a href="#construction">如下所述</a>)。</li>
+  <li>存储区不保存原始标识符。由于 ID 认证涉及到一项质询,因此调用程序始终需要提供要进行认证的标识符。
+  TEE 只需验证这些标识符是否与其原始值相匹配即可。
+  只要存储了原始值的安全哈希(而不是值本身),即可进行此验证。</li>
+</ul>
+
+<h3 id="construction">结构</h3>
+<p>
+要创建具有上述属性的实现,请将 ID 派生的值存储在以下结构 S 中。请勿存储这些 ID 值的其他副本(存储在系统中的正常位置除外),设备所有者可以通过获取 root 权限修改这些值:
+</p>
+
+<pre class="devsite-click-to-copy">S = D || HMAC(HBK, D)</pre>
+<p>
+其中:
+</p>
+<ul>
+  <li><code>D = HMAC(HBK, ID<sub>1</sub>) || HMAC(HBK, ID<sub>2</sub>) || ... ||
+  HMAC(HBK, ID<sub>n</sub>)</code></li>
+  <li><code>HMAC</code> 是具有适当安全哈希的 HMAC 结构(建议使用 SHA-256)</li>
+  <li><code>HBK</code> 是不用于任何其他用途的绑定到硬件的密钥</li>
+  <li><code>ID<sub>1</sub>...ID<sub>n</sub></code> 是原始 ID 值;特定值与特定索引之间的关联取决于实现,因为不同设备将具有不同数量的标识符</li>
+  <li><code>||</code> 表示连接</li>
+</ul>
+<p>
+由于 HMAC 输出具有固定大小,因此不需要标头或其他结构就能够查找单个 ID 哈希或 D 结构的 HMAC。除了检查所提供的值以执行认证之外,实现还需要验证 S,具体方法如下:从 S 中提取 D,计算 HMAC(HBK、D)并将其与 S 中的值进行比较,从而确认没有任何单个 ID 遭到修改/损坏。此外,实现必须对所有单个 ID 元素进行常数时间比较,并对 S 进行验证。比较时间必须是常量,不考虑所提供的 ID 数量以及测试的任何部分是否正确匹配。
+</p>
+<h3 id="hardware-identifiers">硬件标识符</h3>
+<p>
+ID 认证支持以下硬件标识符:
+</p>
+<ol>
+  <li>品牌名称,由 Android 中的 <code>Build.BRAND</code> 返回</li>
+  <li>设备名称,由 Android 中的 <code>Build.DEVICE</code> 返回</li>
+  <li>产品名称,由 Android 中的 <code>Build.PRODUCT</code> 返回</li>
+  <li>制造商名称,由 Android 中的 <code>Build.MANUFACTURER</code> 返回</li>
+  <li>型号名称,由 Android 中的 <code>Build.MODEL</code> 返回</li>
+  <li>序列号</li>
+  <li>所有无线装置的 IMEI</li>
+  <li>所有无线装置的 MEID</li>
+</ol>
+<p>
+为了支持设备 ID 认证,设备需要证明这些标识符。运行 Android 的所有设备都具有前 6 种标识符,它们是此功能正常发挥作用所必需的元素。如果设备具有任何无线装置,那么还需要支持对无线装置的 IMEI 和/或 MEID 的认证。
+</p>
+<p>
+通过执行密钥认证并在请求中添加要认证的设备标识符来请求 ID 认证。这些标识符的标记如下所示:
+</p>
+<ul>
+  <li><code>ATTESTATION_ID_BRAND</code></li>
+  <li><code>ATTESTATION_ID_DEVICE</code></li>
+  <li><code>ATTESTATION_ID_PRODUCT</code></li>
+  <li><code>ATTESTATION_ID_MANUFACTURER</code></li>
+  <li><code>ATTESTATION_ID_MODEL</code></li>
+  <li><code>ATTESTATION_ID_SERIAL</code></li>
+  <li><code>ATTESTATION_ID_IMEI</code></li>
+  <li><code>ATTESTATION_ID_MEID</code></li>
+</ul>
+<p>
+要证明的标识符是采用 UTF-8 编码的字节字符串。此格式也适用于数字标识符。要证明的每个标识符都表示为 UTF-8 编码的字符串。
+</p>
+<p>
+如果该设备不支持 ID 认证(或者之前已调用 <code>destroyAttestationIds()</code> 且该设备不再证明其 ID),则任何包含以上一个或多个标记的密钥认证请求都会失败并显示 <code>ErrorCode::CANNOT_ATTEST_IDS</code>。
+</p>
+<p>
+如果该设备支持 ID 认证,并且密钥认证请求中包含以上一个或多个标记,TEE 会验证带有各个标记的标识符是否与其硬件标识符的副本相匹配。如果有一个或多个标识符不匹配,则整个认证都会失败并显示 <code>ErrorCode::CANNOT_ATTEST_IDS</code>。这种情况也适用于多次带有同一标记的标识符。这在证明 IMEI 时会非常实用(举例而言):一个设备可以配备多个具有多个 IMEI 的无线装置。如果带有每个 <code>ATTESTATION_ID_IMEI</code> 标记的值与设备的其中一个无线装置相匹配,则认证请求有效。这同样适用于所有其他标记。
+</p>
+<p>
+如果认证成功,则使用<a href="#schema">上述架构</a>将经过认证的 ID 添加到已颁发认证证书的<a href="#attestation-extension">认证扩展</a> (OID 1.3.6.1.4.1.11129.2.1.17)。Keymaster 2 认证架构发生的变更以<strong>粗体</strong>显示,并带有注释。
+</p>
+
+<h2 id="java-api">Java API</h2>
+<p>
+本部分仅供参考。Keymaster 实现人员既不实现也不使用 Java API。我们提供 Java API 是为了帮助实现人员了解应用如何使用该功能。系统组件可能会以各种不同方式使用该功能,这就是我们不将本部分作为规范的重要原因。
+</p>
+
+<section class="expandable">
+  <h4 class="showalways">应用开发者如何使用认证</h4>
+<ul>
+<li>创建密钥生成请求,为 EC 或 RSA 密钥对指定密钥别名和密钥生成参数。</li>
+<li>使用 <code>KeyPairGenerator.setAttestationChallenge(byte[])</code> 为请求设置“认证质询”。这样既可以提供质询数据(可能为空),又可以指明是否已请求认证。</li>
+<li>生成密钥对。</li>
+<li>从 <code>AndroidKeyStore</code> 请求证书链。链中的第一个证书是认证证书;其他证书提供可返回且包含根认证密钥的信任链。</li>
+</ul>
+<p>
+下面的示例生成一个密钥对并请求一次认证。
+</p>
+
+<pre class="devsite-click-to-copy">// Create KeyPairGenerator and set generation parameters for an ECDSA key pair
+// using the NIST P-256 curve.  "Key1" is the key alias.
+KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
+    KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
+    keyPairGenerator.initialize(
+         new KeyGenParameterSpec.Builder("Key1", KeyProperties.PURPOSE_SIGN)
+             .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
+             .setDigests(KeyProperties.DIGEST_SHA256,
+                         KeyProperties.DIGEST_SHA384,
+                         KeyProperties.DIGEST_SHA512)
+             // Only permit the private key to be used if the user
+             // authenticated within the last five minutes.
+             .setUserAuthenticationRequired(true)
+             .setUserAuthenticationValidityDurationSeconds(5 * 60)
+             // Request an attestation with challenge "hello world".
+             .setAttestationChallenge("hello world".toBytes());
+             .build());
+// Generate the key pair. This will result in calls to both generate_key() and
+// attest_key() at the keymaster2 HAL.
+KeyPair keyPair = keyPairGenerator.generateKeyPair();
+// Get the certificate chain
+KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+keyStore.load(null);
+Certificate[] certs = keyStore.getCertificateChain("Key1");
+// certs[0] is the attestation certificate. certs[1] signs certs[0], etc.,
+// up to certs[certs.length - 1].
+</pre>
+</section>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/security/keystore/implementer-ref.html b/zh-cn/security/keystore/implementer-ref.html
index 19fabb5..9d42e63 100644
--- a/zh-cn/security/keystore/implementer-ref.html
+++ b/zh-cn/security/keystore/implementer-ref.html
@@ -1,9 +1,9 @@
 <html devsite><head>
-    <title>面向实现人员的参考资料</title>
+    <title>Keymaster 函数</title>
     <meta name="project_path" value="/_project.yaml"/>
     <meta name="book_path" value="/_book.yaml"/>
   </head>
-  <body>
+<body>
   <!--
       Copyright 2017 The Android Open Source Project
 
@@ -19,688 +19,506 @@
       See the License for the specific language governing permissions and
       limitations under the License.
   -->
+<p>本页提供了一些对 Keymaster 硬件抽象层 (HAL) 实现人员很有帮助的详细信息。其中介绍了 API 中的每个函数、提供函数的 Keymaster 版本以及函数的默认实现方法。如需了解标记,请参阅 <a href="/security/keystore/tags">Keymaster 标记</a>页面。</p>
 
-<p>本页中提供了一些对 <a href="index.html">Keymaster</a> HAL 实现人员很有帮助的详细信息,其中介绍了 HAL 中的每个标记和每个函数。</p>
+<p class="note">为了支持 Keymaster 3 从旧式 C 结构 HAL 转换到从采用新的硬件接口定义语言 (HIDL) 的定义生成的 C++ HAL 接口,Android 8.0 中的函数名称已更改。为此,目前函数都采用驼峰式大小写形式。例如,<code>get_key_characteristics</code> 现在是 <code>getKeyCharacteristics</code>。
+</p>
 
-<h2 id="authorization_tags">授权标记</h2>
-
-<p>除非标记说明中另有注明,否则以下所有标记都是在密钥生成期间用于指定密钥特性。</p>
-
-<h3 id="km_tag_purpose">KM_TAG_PURPOSE</h3>
-
-<p>用于指定相应密钥可用于哪些目的。</p>
-
-<p>可能的值是通过以下枚举定义的:</p>
-
-<pre>
-typedef enum {
-    KM_PURPOSE_ENCRYPT = 0,
-    KM_PURPOSE_DECRYPT = 1,
-    KM_PURPOSE_SIGN = 2,
-    KM_PURPOSE_VERIFY = 3,
-} keymaster_purpose_t;
-</pre>
-
-<p>此标记可重复使用。可以生成具有多个值的密钥,不过一项操作只有一个目的。当调用 <a href="#begin">begin</a> 函数来启动某项操作时,要指定操作的目的。如果为操作指定的目的未通过相应密钥授权,操作必须失败并显示 <code>KM_ERROR_INCOMPATIBLE_PURPOSE</code>。</p>
-
-<h3 id="km_tag_algorithm">KM_TAG_ALGORITHM</h3>
-
-<p>用于指定与相应密钥配合使用的加密算法。</p>
-
-<p>可能的值是通过以下枚举定义的:</p>
-
-<pre>
-typedef enum {
-    KM_ALGORITHM_RSA = 1,
-    KM_ALGORITHM_EC = 3,
-    KM_ALGORITHM_AES = 32,
-    KM_ALGORITHM_HMAC = 128,
-} keymaster_algorithm_t;
-</pre>
-
-<p>此标记不可重复使用。</p>
-
-<h3 id="km_tag_key_size">KM_TAG_KEY_SIZE</h3>
-
-<p>用于指定相应密钥的大小(以位数计,按适用于相应密钥算法的一般方式衡量)。例如,对于 RSA 密钥,<code>KM_TAG_KEY_SIZE</code> 用于指定公开模数的大小。对于 AES 密钥,此标记用于指定密钥私密材料的长度。</p>
-
-<p>此标记不可重复使用。</p>
-
-<h3 id="km_tag_block_mode">KM_TAG_BLOCK_MODE</h3>
-
-<p>用于指定可与相应密钥配合使用的分块加密模式。此标记仅与 AES 密钥有关。</p>
-
-<p>可能的值是通过以下枚举定义的:</p>
-
-<pre>
-typedef enum {
-    KM_MODE_ECB = 1,
-    KM_MODE_CBC = 2,
-    KM_MODE_CTR = 3,
-    KM_MODE_GCM = 32,
-} keymaster_block_mode_t;
-</pre>
-
-<p>此标记可重复使用。对于 AES 密钥操作,必须要在 <a href="#begin">begin</a> 的 <code>additional_params</code> 参数中指定模式。如果指定的模式不在相应密钥的关联模式之列,操作必须失败并显示 <code>KM_ERROR_INCOMPATIBLE_BLOCK_MODE</code>。</p>
-
-<h3 id="km_tag_digest">KM_TAG_DIGEST</h3>
-
-<p>用于指定可与相应密钥配合使用以执行签名和验证操作的摘要算法。此标记与 RSA 密钥、ECDSA 密钥和 HMAC 密钥有关。</p>
-
-<p>可能的值是通过以下枚举定义的:</p>
-
-<pre>
-typedef enum {
-    KM_DIGEST_NONE = 0,
-    KM_DIGEST_MD5 = 1,
-    KM_DIGEST_SHA1 = 2,
-    KM_DIGEST_SHA_2_224 = 3,
-    KM_DIGEST_SHA_2_256 = 4,
-    KM_DIGEST_SHA_2_384 = 5,
-    KM_DIGEST_SHA_2_512 = 6,
-}
-keymaster_digest_t;
-</pre>
-
-<p>此标记可重复使用。对于签名和验证操作,必须要在 <a href="#begin">begin</a> 的 <code>additional_params</code> 参数中指定摘要。如果指定的摘要不在相应密钥的关联摘要之列,操作必须失败并显示 <code>KM_ERROR_INCOMPATIBLE_DIGEST</code>。</p>
-
-<h3 id="km_tag_padding">KM_TAG_PADDING</h3>
-
-<p>用于指定可与相应密钥配合使用的填充模式。此标记与 RSA 密钥和 AES 密钥有关。</p>
-
-<p>可能的值是通过以下枚举定义的:</p>
-
-<pre>
-typedef enum {
-    KM_PAD_NONE = 1,
-    KM_PAD_RSA_OAEP = 2,
-    KM_PAD_RSA_PSS = 3,
-    KM_PAD_RSA_PKCS1_1_5_ENCRYPT = 4,
-    KM_PAD_RSA_PKCS1_1_5_SIGN = 5,
-    KM_PAD_PKCS7 = 64,
-} keymaster_padding_t;
-</pre>
-
-<p><code>KM_PAD_RSA_OAEP</code> 和 <code>KM_PAD_RSA_PKCS1_1_5_ENCRYPT</code> 仅用于 RSA 加密/解密密钥,分别用来指定 RSA PKCS#1v2 OAEP 填充和 RSA PKCS#1 v1.5 随机填充。<code>KM_PAD_RSA_PSS</code> 和 <code>KM_PAD_RSA_PKCS1_1_5_SIGN</code> 仅用于 RSA 签名/验证密钥,分别用来指定 RSA PKCS#1v2 PSS 填充和 RSA PKCS#1 v1.5 确定性填充。另外请注意,RSA PSS 填充模式与 <a href="#km_tag_digest">KM_DIGEST_NONE</a> 不兼容。</p>
-
-<p><code>KM_PAD_NONE</code> 可与 RSA 密钥或 AES 密钥配合使用。对于 AES 密钥,如果将 <code>KM_PAD_NONE</code> 与分块模式 ECB 或 CBC 配合使用,并且要加密或解密的数据的长度不是 AES 分块大小的倍数,调用 finish 必须失败并显示 <code>KM_ERROR_INVALID_INPUT_LENGTH</code>。</p>
-
-<p><code>KM_PAD_PKCS7</code> 只能与 AES 密钥以及 ECB 和 CBC 模式配合使用。</p>
-
-<p>此标记可重复使用。在调用 <a href="#begin">begin</a> 时必须指定填充模式。如果指定的模式未针对相应密钥获得授权,操作必须失败并显示 <code>KM_ERROR_INCOMPATIBLE_BLOCK_MODE</code>。</p>
-
-<h3 id="km_tag_caller_nonce">KM_TAG_CALLER_NONCE</h3>
-
-<p>用于指定调用程序可以为需要随机数的操作提供随机数。</p>
-
-<p>此标记为布尔值,因此可能的值为 true(如果此标记存在)和 false(如果此标记不存在)。</p>
-
-<p>此标记仅用于 AES 密钥,并且仅与 CBC、CTR 和 GCM 分块模式有关。如果此标记不存在,实现应拒绝执行向 <a href="#begin">begin</a> 提供 <a href="#km_tag_nonce">KM_TAG_NONCE</a> 的所有操作,并显示 <code>KM_ERROR_CALLER_NONCE_PROHIBITED</code>。</p>
-
-<p>此标记不可重复使用。</p>
-
-<h3 id="km_tag_min_mac_length">KM_TAG_MIN_MAC_LENGTH</h3>
-
-<p>此标记是支持 GCM 模式的 HMAC 密钥和 AES 密钥所必需的标记,用于指定可通过相应密钥请求或验证的 MAC 的最小长度。</p>
-
-<p>此标记的值是 MAC 的最小长度(以位数计)。这个值必须是 8 的倍数。对于 HMAC 密钥,这个值不得小于 64。对于 GCM 密钥,这个值必须介于 96 到 128 之间。</p>
-
-<h3 id="km_tag_rsa_public_exponent">KM_TAG_RSA_PUBLIC_EXPONENT</h3>
-
-<p>用于为 RSA 密钥对指定公开指数的值。此标记仅与 RSA 密钥有关,而且是所有 RSA 密钥都必需的标记。</p>
-
-<p>此标记的值是一个 64 位的未签名整数,并且必须符合 RSA 公开指数方面的要求。由于这个值是由调用程序指定的,因此无法由实现来选择。这个值必须是质数。Trustlet 必须要支持 2^16+1 这个值,而且最好还支持其他合理的值,尤其是 3。如果未指定指数或指定的指数不受支持,密钥生成操作必须失败并显示 <code>KM_ERROR_INVALID_ARGUMENT</code>。</p>
-
-<p>此标记不可重复使用。</p>
-
-<h3 id="km_tag_blob_usage_requirements">KM_TAG_BLOB_USAGE_REQUIREMENTS</h3>
-
-<p>用于指定必须满足哪些系统环境条件才能使用生成的密钥。</p>
-
-<p>可能的值是通过以下枚举定义的:</p>
-
-<pre>
-typedef enum {
-    KM_BLOB_STANDALONE = 0,
-    KM_BLOB_REQUIRES_FILE_SYSTEM = 1,
-} keymaster_key_blob_usage_requirements_t;
-</pre>
-
-<p>可以在密钥生成期间指定此标记,以便要求只有在指定条件下才可以使用生成的密钥。此标记必须要和密钥特性一起返回(通过 <a href="#generate_key">generate_key</a> 和 <a href="#get_key_characteristics">get_key_characteristics</a>)。如果调用程序指定了 <code>KM_TAG_BLOB_USAGE_REQUIREMENTS</code>(值为 <code>KM_BLOB_STANDALONE</code>),Trustlet 必须返回一个可在没有文件系统支持的情况下使用的密钥 Blob。这对于具有已加密磁盘的设备至关重要:在使用 Keymaster 密钥解密磁盘之前,此类设备的文件系统可能一直无法使用。</p>
-
-<p>此标记不可重复使用。</p>
-
-<h3 id="km_tag_bootloader_only">KM_TAG_BOOTLOADER_ONLY</h3>
-
-<p>用于指定只有引导加载程序能够使用相应密钥。</p>
-
-<p>此标记为布尔值,因此可能的值为 true(如果此标记存在)和 false(如果此标记不存在)。</p>
-
-<p>尝试从 Android 系统使用带有 <code>KM_TAG_BOOTLOADER_ONLY</code> 标记的密钥时,操作必须失败并显示 <code>KM_ERROR_INVALID_KEY_BLOB</code>。</p>
-
-<p>此标记不可重复使用。</p>
-
-<h3 id="km_tag_active_datetime">KM_TAG_ACTIVE_DATETIME</h3>
-
-<p>用于指定相应密钥变为有效状态的日期和时间。在此之前,尝试使用相应密钥时,操作必须失败并显示 <code>KM_ERROR_KEY_NOT_YET_VALID</code>。</p>
-
-<p>此标记的值是一个 64 位的整数,表示距 1970 年 1 月 1 日的毫秒数。</p>
-
-<p>此标记不可重复使用。</p>
-
-<h3 id="km_tag_origination_expire_datetime">KM_TAG_ORIGINATION_EXPIRE_DATETIME</h3>
-
-<p>用于指定相应密钥无法再用于签名和加密目的的过期日期和时间。如果向 <a href="#begin">begin</a> 提供的目的是 <a href="#km_tag_purpose">KM_PURPOSE_SIGN</a> 或 <a href="#km_tag_purpose">KM_PURPOSE_ENCRYPT</a>,那么在此之后,尝试使用相应密钥时,操作必须失败并显示 <code>KM_ERROR_KEY_EXPIRED</code>。</p>
-
-<p>此标记的值是一个 64 位的整数,表示距 1970 年 1 月 1 日的毫秒数。</p>
-
-<p>此标记不可重复使用。</p>
-
-<h3 id="km_tag_usage_expire_datetime">KM_TAG_USAGE_EXPIRE_DATETIME</h3>
-
-<p>用于指定相应密钥无法再用于验证和解密目的的过期日期和时间。如果向 <a href="#begin">begin</a> 提供的目的是 <a href="#km_tag_purpose">KM_PURPOSE_VERIFY</a> 或 <a href="#km_tag_purpose">KM_PURPOSE DECRYPT</a>,那么在此之后,尝试使用相应密钥时,操作必须失败并显示 <code>KM_ERROR_KEY_EXPIRED</code>。</p>
-
-<p>此标记的值是一个 64 位的整数,表示距 1970 年 1 月 1 日的毫秒数。</p>
-
-<p>此标记不可重复使用。</p>
-
-<h3 id="km_tag_min_seconds_between_ops">KM_TAG_MIN_SECONDS_BETWEEN_OPS</h3>
-
-<p>用于指定至少必须间隔多长时间才能再次将密钥用于允许的操作。在不限制密钥使用次数可能会给暴力破解攻击以可乘之机的环境中,可以使用此标记来限制密钥的使用次数。</p>
-
-<p>此标记的值是一个 32 位的整数,表示允许的操作之间间隔的秒数。</p>
-
-<p>当有操作使用带有此标记的某个密钥时,计时器应在 <a href="#finish">finish</a> 或 <a href="#abort">abort</a> 调用期间启动。在计时器表明通过 <code>KM_TAG_MIN_SECONDS_BETWEEN_OPS</code> 指定的间隔时间已过去之前收到的所有 <a href="#begin">begin</a> 调用都必须失败并显示 <code>KM_ERROR_KEY_RATE_LIMIT_EXCEEDED</code>。这项要求意味着 Trustlet 必须要为带有此标记的密钥维护一份计时器表格。由于 Keymaster 内存的大小通常有限制,因此该表格可以具有固定的最大大小,并且当该表格被占满时,如果有操作尝试使用带有此标记的密钥,Keymaster 可以使这些操作失败。该表格必须能够容纳至少 32 个使用中的密钥,而且当密钥最小使用间隔到期时,必须主动重复使用该表格中的位置。如果某项操作因该表格已被占满而失败,Keymaster 应返回 <code>KM_ERROR_TOO_MANY_OPERATIONS</code>。</p>
-
-<p>此标记不可重复使用。</p>
-
-<h3 id="km_tag_max_uses_per_boot">KM_TAG_MAX_USES_PER_BOOT</h3>
-
-<p>用于指定在两次系统重启之间可以使用相应密钥的最大次数。这是另一种限制密钥使用次数的机制。</p>
-
-<p>此标记的值是一个 32 位的整数,表示在每次系统启动后可以使用相应密钥的次数。</p>
-
-<p>当有操作使用带有此标记的某个密钥时,与该密钥关联的计数器应在 <a href="#begin">begin</a> 调用期间递增。当密钥计数器超出此标记的值后,所有尝试使用该密钥的后续操作都必须失败并显示 <code>KM_ERROR_MAX_OPS_EXCEEDED</code>,直到设备重启为止。这项要求意味着 Trustlet 必须要为带有此标记的密钥维护一份使用次数计数器表格。由于 Keymaster 内存的大小通常有限制,因此该表格可以具有固定的最大大小,并且当该表格被占满时,如果有操作尝试使用带有此标记的密钥,Keymaster 可以使这些操作失败。该表格必须能够容纳至少 16 个密钥。如果某项操作因该表格已被占满而失败,Keymaster 应返回 <code>KM_ERROR_TOO_MANY_OPERATIONS</code>。</p>
-
-<p>此标记不可重复使用。</p>
-
-<h3 id="km_tag_user_secure_id">KM_TAG_USER_SECURE_ID</h3>
-
-<p>用于指定只能在某个安全的用户身份验证状态下使用相应密钥。此标记与 <a href="#km_tag_no_auth_required">KM_TAG_NO_AUTH_REQUIRED</a> 互斥。</p>
-
-<p>此标记的值是一个 64 位的整数,用于指定在通过 <a href="#km_tag_auth_token">KM_TAG_AUTH_TOKEN</a> 向 <a href="#begin">begin</a> 提供的身份验证令牌中必须存在哪个身份验证政策状态值,身份验证程序才会授权使用相应密钥。如果在调用 <a href="#begin">begin</a> 时未提供身份验证令牌,或提供的身份验证令牌没有匹配的政策状态值,但所用密钥带有此标记,该调用必须失败。</p>
-
-<p>此标记可重复使用。如果提供的值中有任何一个与身份验证令牌中的任何政策状态值一致,身份验证程序即会授权使用相应密钥。否则,操作必须失败并显示 <code>KM_ERROR_KEY_USER_NOT_AUTHENTICATED</code>。</p>
-
-<h3 id="km_tag_no_auth_required">KM_TAG_NO_AUTH_REQUIRED</h3>
-
-<p>用于指定无需进行身份验证即可使用相应密钥。此标记与 <a href="#km_tag_user_secure_id">KM_TAG_USER_SECURE_ID</a> 互斥。</p>
-
-<p>此标记为布尔值,因此可能的值为 true(如果此标记存在)和 false(如果此标记不存在)。</p>
-
-<p>此标记不可重复使用。</p>
-
-<h3 id="km_tag_user_auth_type">KM_TAG_USER_AUTH_TYPE</h3>
-
-<p>用于指定可以使用哪些类型的用户身份验证程序来授权使用相应密钥。请求 Keymaster 执行所用密钥带有此标记的操作时,必须要为 Keymaster 提供一个身份验证令牌,并且该令牌的 <code>authenticator_type</code> 字段必须与此标记中的值一致。准确来说就是,<code>(ntoh(token.authenticator_type) &amp;
-auth_type_tag_value) != 0</code> 必须为 true,其中 <code>ntoh</code> 是一个函数,用于将按网络字节序保存的整数转换成按主机字节序保存的整数,而 <code>auth_type_tag_value</code> 是此标记的值。</p>
-
-<p>此标记的值是以下枚举值的位掩码(32 位整数):</p>
-
-<pre>
-typedef enum {
-    HW_AUTH_NONE = 0,
-    HW_AUTH_PASSWORD = 1 &lt;&lt; 0,
-    HW_AUTH_FINGERPRINT = 1 &lt;&lt; 1,
-    // Additional entries should be powers of 2.
-    HW_AUTH_ANY = UINT32_MAX,
-} hw_authenticator_type_t;
-</pre>
-
-<p>此标记不可重复使用。</p>
-
-<h3 id="km_tag_auth_timeout">KM_TAG_AUTH_TIMEOUT</h3>
-
-<p>用于指定授权在多长时间内使用相应密钥(以秒数计,从通过身份验证开始算起)。如果 <a href="#km_tag_user_secure_id">KM_TAG_USER_SECURE_ID</a> 存在而此标记不存在,那么每次使用相应密钥时都需要通过身份验证(要详细了解各项操作的身份验证流程,请参阅 <a href="#begin">begin</a>)。</p>
-
-<p>此标记的值是一个 32 位的整数,用于指定可在多长时间内使用相应密钥(以秒数计,从使用通过 <a href="#km_tag_mac_length">KM_TAG_USER_AUTH_TYPE</a> 指定的身份验证方法对通过 <a href="#km_tag_user_secure_id">KM_TAG_USER_SECURE_ID</a> 指定的用户成功进行身份验证开始算起)。</p>
-
-<p>此标记不可重复使用。</p>
-
-<h3 id="km_tag_all_applications">KM_TAG_ALL_APPLICATIONS</h3>
-
-<p>预留标记,供将来使用。</p>
-
-<p>此标记不可重复使用。</p>
-
-<h3 id="km_tag_application_id">KM_TAG_APPLICATION_ID</h3>
-
-<p>当提供给 <a href="#generate_key">generate_key</a> 或 <a href="#import_key">import_key</a> 时,此标记用于指定使用相应密钥时必须要提供的数据。具体来说就是,调用 <a href="#export_key">export_key</a> 和 <a href="#get_key_characteristics">get_key_characteristics</a> 时必须要在 <code>client_id</code> 参数中提供相同的值,而调用 <a href="#begin">begin</a> 时则必须要提供此标记以及相同的相关数据(作为 <code>in_params</code> 集的一部分)。如果未收到正确的数据,函数必须返回 <code>KM_ERROR_INVALID_KEY_BLOB</code>。</p>
-
-<p><i></i>此标记的内容必须要以加密形式绑定到相应密钥,这意味着,如果有不轨人士有权访问安全域的所有机密内容,但无权访问此标记的内容,必须要确保他们无法解密相应密钥(在不对此标记的内容进行暴力破解攻击的情况下)。</p>
-
-<p>此标记的值是一个 Blob(任意长度的字节数数组)。</p>
-
-<p>此标记不可重复使用。</p>
-
-<h3 id="km_tag_application_data">KM_TAG_APPLICATION_DATA</h3>
-
-<p>当提供给 <a href="#generate_key">generate_key</a> 或 <a href="#import_key">import_key</a> 时,此标记用于指定使用相应密钥时必须要提供的数据。具体来说就是,调用 <a href="#export_key">export_key</a> 和 <a href="#get_key_characteristics">get_key_characteristics</a> 时必须要在 <code>client_id</code> 参数中提供相同的值,而调用 <a href="#begin">begin</a> 时则必须要提供此标记以及相同的相关数据(作为 <code>in_params</code> 集的一部分)。如果未收到正确的数据,函数必须返回 <code>KM_ERROR_INVALID_KEY_BLOB</code>。</p>
-
-<p><i></i>此标记的内容必须要以加密形式绑定到相应密钥,这意味着,如果有不轨人士有权访问安全域的所有机密内容,但无权访问此标记的内容,必须要确保他们无法解密相应密钥(在不对此标记的内容进行暴力破解攻击的情况下)。</p>
-
-<p>此标记的值是一个 Blob(任意长度的字节数数组)。</p>
-
-<p>此标记不可重复使用。</p>
-
-<h3 id="km_tag_creation_datetime">KM_TAG_CREATION_DATETIME</h3>
-
-<p>用于指定相应密钥的创建日期和时间(以距 1970 年 1 月 1 日的毫秒数计)。此标记为可选标记,仅供参考。</p>
-
-<p>此标记不可重复使用。</p>
-
-<h3 id="km_tag_origin">KM_TAG_ORIGIN</h3>
-
-<p>用于指定相应密钥是在哪里创建的(如果知道)。在生成或导入密钥期间可以不指定此标记,但此标记必须要由 Trustlet 添加到密钥特性中。</p>
-
-<p>可能的值是在 <code>keymaster_origin_t</code> 中定义的:</p>
-
-<pre>
-typedef enum {
-    KM_ORIGIN_GENERATED = 0,
-    KM_ORIGIN_IMPORTED = 2,
-    KM_ORIGIN_UNKNOWN = 3,
-} keymaster_key_origin_t
-</pre>
-
-<p>此标记的值的完整含义不仅取决于值本身,还取决于值是位于由硬件强制执行的特性列表中,还是位于由软件强制执行的特性列表中。</p>
-
-<p><code>KM_ORIGIN_GENERATED</code> 表示相应密钥是由 Keymaster 生成的。如果它位于由硬件强制执行的列表中,那么相应密钥是在安全硬件中生成的,并且已永久绑定到硬件。如果它位于由软件强制执行的列表中,那么相应密钥是在 SoftKeymaster 中生成的,并且没有绑定到硬件。</p>
-
-<p><code>KM_ORIGIN_IMPORTED</code> 表示相应密钥是在 Keymaster 之外生成的,并且导入到了 Keymaster 中。如果它位于由硬件强制执行的列表中,那么相应密钥已永久绑定到硬件,不过可能存在位于安全硬件之外的副本。如果它位于由软件强制执行的列表中,那么相应密钥已导入到 SoftKeymaster 中,并且没有绑定到硬件。</p>
-
-<p><code>KM_ORIGIN_UNKNOWN</code> 应当仅出现在由硬件强制执行的列表中。它表示相应密钥已绑定到硬件,但不知道相应密钥原本就是在安全硬件中生成的,还是导入的。只有在使用 keymaster0 硬件模拟 keymaster1 服务时,才会出现这种情况。</p>
-
-<p>此标记不可重复使用。</p>
-
-<h3 id="km_tag_rollback_resistant">KM_TAG_ROLLBACK_RESISTANT</h3>
-
-<p>用于表明相应密钥可抗回滚,也就是说,当通过 <a href="#delete_key">delete_key</a> 或 <a href="#delete_all_keys">delete_all_keys</a> 删除相应密钥后,可保证相应密钥已被永久删除且无法再使用。如果密钥不带此标记,那么在被删除后,可能能够从备份中恢复。</p>
-
-<p>此标记为布尔值,因此可能的值为 true(如果此标记存在)和 false(如果此标记不存在)。</p>
-
-<p>此标记不可重复使用。</p>
-
-<h3 id="km_tag_root_of_trust">KM_TAG_ROOT_OF_TRUST</h3>
-
-<p>用于指定“信任根”,即经过验证的启动程序在验证操作系统是否已启动时使用的键(如果有)。在任何情况下,都不可以通过密钥特性将此标记提供给 Keymaster,也不可以通过密钥特性从 Keymaster 返回此标记。</p>
-
-<h3 id="km_tag_associated_data">KM_TAG_ASSOCIATED_DATA</h3>
-
-<p>用于提供进行 AES-GCM 加密或解密时使用的“相关数据”。可以将此标记提供给 <a href="#update">update</a>,以便指定在计算 GCM 标记时使用的未加密/解密的数据。</p>
-
-<p>此标记的值是一个 Blob(任意长度的字节数数组)。</p>
-
-<p>此标记不可重复使用。</p>
-
-<h3 id="km_tag_nonce">KM_TAG_NONCE</h3>
-
-<p>用于提供或返回进行 AES GCM、CBC 或 CTR 加密/解密时使用的随机数或初始化矢量 (IV)。在加密和解密操作期间,可以将此标记提供给 <a href="#begin">begin</a>。仅当相应密钥带有 <a href="#km_tag_caller_nonce">KM_TAG_CALLER_NONCE</a> 时,才可以将此标记提供给 <a href="#begin">begin</a>。如果调用程序未提供此标记,Keymaster 将随机生成适当的随机数或 IV 并通过 begin 将其返回。</p>
-
-<p>此标记的值是一个 Blob(任意长度的字节数数组)。所允许的长度取决于模式:GCM 随机数的长度为 12 个字节;CBC IV 和 CTR IV 的长度为 16 个字节。</p>
-
-<p>此标记不可重复使用。</p>
-
-<h3 id="km_tag_auth_token">KM_TAG_AUTH_TOKEN</h3>
-
-<p>用于向 <a href="#begin">begin</a>、<a href="#update">update</a> 或 <a href="#finish">finish</a> 提供身份验证令牌(请参阅“身份验证”页面),以便向要求用户通过身份验证的密钥操作(密钥带有 <a href="#km_tag_user_secure_id">KM_TAG_USER_SECURE_ID</a>)证明相应用户已通过身份验证。</p>
-
-<p>此标记的值是一个包含 <code>hw_auth_token_t</code> 结构的 Blob。</p>
-
-<p>此标记不可重复使用。</p>
-
-<h3 id="km_tag_mac_length">KM_TAG_MAC_LENGTH</h3>
-
-<p>用于提供 MAC 或 GCM 身份验证标记的请求长度(以位数计)。</p>
-
-<p>此标记的值是 MAC 长度(以位数计)。这个值必须是 8 的倍数,并且不得小于与相应密钥关联的 <a href="#km_tag_min_mac_length">KM_TAG_MIN_MAC_LENGTH</a> 的值。</p>
-
-<h2 id="functions">函数</h2>
-
-<h3 id="deprecated_functions">已弃用的函数</h3>
-
-<p>虽然以下函数位于 <code>keymaster1_device_t</code> 定义中,但不应实现这些函数。这些函数的指针应设为 <code>NULL</code>:</p>
-
-<ul>
-  <li><code>generate_keypair</code>
-  </li><li><code>import_keypair</code>
-  </li><li><code>get_keypair_public</code>
-  </li><li><code>delete_keypair</code>
-  </li><li><code>delete_all</code>
-  </li><li><code>sign_data</code>
-  </li><li><code>verify_data</code>
-</li></ul>
-
-<h3 id="general_implementation_guidelines">常规实现准则</h3>
+<h2 id="general_implementation_guidelines">常规实现准则</h2>
 
 <p>以下准则适用于 API 中的所有函数。</p>
 
-<h4 id="input_pointer_parameters">输入指针参数</h4>
+<h3 id="input_pointer_parameters">输入指针参数</h3>
 
-<p>进行指定调用时不使用的输入指针参数可以是 <code>NULL</code>。调用程序无需提供占位符。例如,某些密钥类型和模式可能不会使用 <a href="#begin">begin</a> 的 <code>in_params</code> 参数中的任何值,因此调用程序可以将 <code>in_params</code> 设为 <code>NULL</code> 或提供一个空的参数集。调用程序也可以提供不使用的参数,而 Keymaster 方法不得发出错误。</p>
+<p><strong>版本</strong>:1、2</p>
 
-<p>如果所需的输入参数为 NULL,Keymaster 方法应返回 <code>KM_ERROR_UNEXPECTED_NULL_POINTER</code>。</p>
+<p>进行指定调用时不使用的输入指针参数可以是 <code>NULL</code>。调用程序无需提供占位符。例如,某些密钥类型和模式可能不会使用 <code>inParams</code> 参数中的任何值来调用 <a href="#begin">begin</a>,因此调用程序可以将 <code>inParams</code> 设为 <code>NULL</code> 或提供一个空的参数集。调用程序也可以提供不使用的参数,而 Keymaster 方法不得发出错误。</p>
 
-<h4 id="output_pointer_parameters">输出指针参数</h4>
+<p>如果某必需的输入参数为 NULL,Keymaster 方法应返回 <code>ErrorCode::UNEXPECTED_NULL_POINTER</code>。</p>
 
-<p>与输入指针参数类似,不使用的输出指针参数可以是 <code>NULL</code>。如果某个方法需要在某个输出参数中返回数据,但发现该参数为 <code>NULL</code>,则应返回 <code>KM_ERROR_OUTPUT_PARAMETER_NULL</code>。</p>
+<p>从 Keymaster 3 开始,便已没有指针参数。所有参数均通过值或常量引用传递。</p>
 
-<h4 id="api_misuse">API 滥用</h4>
+<h3 id="output_pointer_parameters">输出指针参数</h3>
 
-<p>调用程序可以通过多种方式提出虽然不合理或很荒谬但技术上并没有错误的请求。在这种情况下,keymaster1 实现无需失败或发出诊断。实现不应诊断以下情况:使用过小的密钥、指定不相关的输入参数、重复使用 IV 或随机数、生成密钥时未指定目的(因此生成的密钥没有用处),以及类似情况。但必须诊断以下情况:缺少必需的参数、指定无效的必需参数,以及类似错误。</p>
+<p><strong>版本</strong>:1、2</p>
+
+<p>与输入指针参数类似,不使用的输出指针参数可以是 <code>NULL</code>。如果某个方法需要在某个输出参数中返回数据,但发现该参数为 <code>NULL</code>,则应返回 <code>ErrorCode::OUTPUT_PARAMETER_NULL</code>。</p>
+<p>从 Keymaster 3 开始,便已没有指针参数。所有参数均通过值或常量引用传递。</p>
+
+<h3 id="api_misuse">API 滥用</h3>
+
+<p><strong>版本</strong>:1、2、3</p>
+
+<p>调用程序可以通过多种方式提出虽然不合理或很荒谬但技术上并没有错误的请求。在这种情况下,Keymaster 实现无需失败或发出诊断。实现不应诊断以下情况:使用过小的密钥、指定不相关的输入参数、重复使用 IV 或随机数、生成密钥时未指定目的(因此生成的密钥没有用处),以及类似情况。但必须诊断以下情况:缺少必需的参数、指定无效的必需参数,以及类似错误。</p>
 
 <p>应用、框架和 Android Keystore 需负责确保对 Keymaster 模块的调用是合理的,而且是有用的。</p>
 
-<h3 id="get_supported_algorithms">get_supported_algorithms</h3>
+<p class="caution">Keymaster 实现应该尝试诊断严重错误,如缺少必需的参数、指定无效的必需参数,以及会破坏 Keymaster 实现完整性的类似错误。</p>
 
-<p>用于返回一个列表,其中包含 Keymaster 硬件实现支持的算法。如果是软件实现,则必须返回一个空列表;如果是混合实现,则必须返回一个仅包含硬件支持的算法的列表。</p>
+<h2 id="functions">函数</h2>
 
-<p>keymaster1 实现必须要支持 RSA、EC、AES 和 HMAC。</p>
+<h3 id="get_hardware_features">getHardwareFeatures</h3>
+<p><strong>版本</strong>:3</p>
 
-<h3 id="get_supported_block_modes">get_supported_block_modes</h3>
+<p>
+全新的 <code>getHardwareFeatures</code> 方法向客户端披露了底层安全硬件的一些重要特征。该方法不需要任何参数,且返回四个值(都是布尔值):</p>
+<ul>
+  <li>如果密钥始终存储在安全硬件(TEE 等)中,则 <code>isSecure</code> 为 <code>true</code>。</li>
+  <li>如果硬件支持采用 NIST 曲线(P-224、P-256、P-384 和 P-521)的椭圆曲线加密,则 <code>supportsEllipticCurve</code> 为 <code>true</code>。</li>
+  <li>如果硬件支持对称加密(包括 AES 和 HMAC),则 <code>supportsSymmetricCryptography</code> 为 <code>true</code>。</li>
+  <li>如果硬件支持生成使用注入安全环境中的密钥进行签名的 Keymaster 公钥认证证书,则 <code>supportsAttestation</code> 为 <code>true</code>。</li>
+</ul>
+<p>
+该方法仅可能返回以下错误代码:<code>ErrorCode:OK</code>、<code>ErrorCode::KEYMASTER_NOT_CONFIGURED</code> 或指示无法与安全硬件通信的错误代码之一。
+</p>
+<pre class="devsite-click-to-copy">
+getHardwareFeatures()
+    generates(bool isSecure, bool supportsEllipticCurve, bool supportsSymmetricCryptography,
+              bool supportsAttestation, bool supportsAllDigests, string keymasterName,
+              string keymasterAuthorName);</pre>
 
-<p>用于返回一个列表,其中包含对于指定的算法和目的,Keymaster 硬件实现支持的 AES 分块模式。</p>
+<h3 id="configure">configure</h3>
+<p><strong>版本</strong>:2</p>
+<p>该函数在 Keymaster 2 中引入,并在 Keymaster 3 中被弃用,因为这些信息已在系统属性文件中提供,制造商实现会在启动期间读取这些文件。</p>
 
-<p>对于不是分块加密算法的 RSA、EC 和 HMAC,无论是任何有效目的,此方法都必须返回一个空列表。如果目的无效,则应导致此方法返回 <code>KM_ERROR_INVALID_PURPOSE</code>。</p>
+<p>配置 Keymaster。该方法在打开设备之后、使用设备之前被调用一次。它用于向 Keymaster 提供 <a href="/security/keystore/tags#os_version">KM_TAG_OS_VERSION</a> 和 <a href="/security/keystore/tags#os_patchlevel">KM_TAG_OS_PATCHLEVEL</a>。
+在该方法被调用之前,所有其他方法会返回 <code>KM_ERROR_KEYMASTER_NOT_CONFIGURED</code>。该方法提供的值仅在每次启动时被 Keymaster 接受一次。之后的调用都会返回 <code>KM_ERROR_OK</code>,但不执行任何操作。</p>
+<p>
+如果 Keymaster 实现在安全的硬件中进行,且提供的操作系统版本和补丁程序级别的值与引导加载程序向安全硬件提供的值不匹配(或者引导加载程序未提供任何值),则该方法会返回 <code>KM_ERROR_INVALID_ARGUMENT</code>,所有其他方法仍然返回 <code>KM_ERROR_KEYMASTER_NOT_CONFIGURED</code>。</p>
+<pre class="devsite-click-to-copy">
+keymaster_error_t (*configure)(const struct keymaster2_device* dev,
+                               const keymaster_key_param_set_t* params);</pre>
 
-<p>keymaster1 实现必须要支持使用 ECB、CBC、CTR 和 GCM 进行 AES 加密和解密。</p>
+<h3 id="add_rng_entropy">addRngEntropy</h3>
 
-<h3 id="get_supported_padding_modes">get_supported_padding_modes</h3>
+<p><strong>版本</strong>:1、2、3</p>
+<p>该函数在 Keymaster 1 中引入(名为 <code>add_rng_entropy</code>),并在 Keymaster 3 中进行了重命名。</p>
 
-<p>用于返回一个列表,其中包含对于指定的算法和目的,Keymaster 硬件实现支持的填充模式。</p>
+<p>该函数将调用程序提供的熵添加到 Keymaster 1 实现生成随机数(用作密钥、IV 等)所用的池中。</p>
 
-<p>HMAC 和 EC 并没有填充这一概念,因此针对所有有效目的,此方法都必须返回一个空列表。如果目的无效,则应导致此方法返回 <code>KM_ERROR_INVALID_PURPOSE</code>。</p>
+<p>Keymaster 实现需要将收到的熵安全地混合到所使用的池中,该池中还必须包含由硬件随机数生成器在内部生成的熵。
+对混合操作的处理应该实现:即使攻击者能够完全控制 <code>addRngEntropy</code> 提供的数位或硬件生成的数位(但不能同时控制这两者),他们在预测从熵池生成的数位方面也不具有明显的优势。</p>
 
-<p>对于 RSA,keymaster1 实现必须要支持:</p>
+<p>尝试估算内部池中的熵的 Keymaster 实现假定 <code>addRngEntropy</code> 提供的数据不包含熵。如果在单次调用中向 Keymaster 实现提供的数据超过 2KiB,则这些实现可能会返回 <code>ErrorCode::INVALID_INPUT_LENGTH</code>。</p>
+
+<h3 id="generate_key">generateKey</h3>
+
+<p><strong>版本</strong>:1、2、3</p>
+<p>该函数在 Keymaster 1 中引入(名为 <code>generate_key</code>),并在 Keymaster 3 中进行了重命名。</p>
+
+<p>该函数会生成一个新的加密密钥,同时指定关联的授权,这些授权会永久绑定到该密钥。Keymaster 实现确保无法通过任何与生成密钥时指定的授权不一致的方式使用密钥。对于安全硬件无法强制执行的授权,安全硬件的义务仅限于确保与密钥关联的无法强制执行的授权不能被修改,以便每次调用 <a href="#get_key_characteristics">getKeyCharacteristics</a> 时都会返回原始值。此外,由 <code>generateKey</code> 返回的特性将授权正确地分配到由硬件强制执行的列表和由软件强制执行的列表。如需了解详情,请参阅 <a href="#get_key_characteristics">getKeyCharacteristics</a>。</p>
+
+<p>向 <code>generateKey</code> 提供的参数取决于要生成的密钥的类型。本部分总结了每种类型密钥的必需和可选标记。<a href="/security/keystore/tags#algorithm">Tag::ALGORITHM</a> 始终为必需的标记,用于指定类型。</p>
+
+<h4 id="generate_key_rsa_keys">RSA 密钥</h4>
+
+<p>以下参数是生成 RSA 密钥所必需的参数。</p>
 
 <ul>
-  <li>非填充式加密、解密、签名和验证。对于非填充式加密和签名,如果消息比公开模数短,实现必须要在消息左侧填充零来补齐。对于非填充式解密和验证,输入长度必须与公开模数的大小一致。
-  </li><li>PKCS#1 v1.5 加密和签名填充模式</li><li>盐最小长度为 20 的 PSS</li><li>OAEP</li></ul>
+  <li><a href="/security/keystore/tags#key_size">Tag::KEY_SIZE</a> 用于指定公开模数的大小(以位计)。如果缺少此参数,该方法会返回 <code>ErrorCode::UNSUPPORTED_KEY_SIZE</code>。支持的值包括 1024、2048、3072 和 4096。最好支持所有为 8 的倍数的密钥大小。</li>
+  <li><a href="/security/keystore/tags#rsa_public_exponent">Tag::RSA_PUBLIC_EXPONENT</a> 用于指定 RSA 公开指数的值。如果缺少此参数,该方法会返回 <code>ErrorCode::INVALID_ARGUMENT</code>。支持的值包括 3 和 65537。最好支持不超过 2^64 的所有质数值。</li>
+</ul>
 
-<p>对于采用 ECB 和 CBC 模式的 AES 算法,keymaster1 实现必须要支持无填充和 PKCS#7 填充。CTR 和 GCM 模式必须仅支持无填充。</p>
-
-<h3 id="get_supported_digests">get_supported_digests</h3>
-
-<p>用于返回一个列表,其中包含对于指定的算法和目的,Keymaster 硬件实现支持的摘要模式。</p>
-
-<p>任何 AES 模式都不支持摘要,也不需要摘要,因此无论是任何有效目的,此方法都必须返回一个空列表。</p>
-
-<p>keymaster1 实现可以只实现一部分已定义的摘要,但必须要提供 SHA-256。强烈建议 keymaster1 实现提供 MD5、SHA1、SHA-224、SHA-256、SHA384 和 SHA512(完整的已定义摘要集)。</p>
-
-<h3 id="get_supported_import_formats">get_supported_import_formats</h3>
-
-<p>用于返回一个列表,其中包含指定算法的 Keymaster 硬件实现支持的导入格式。</p>
-
-<p>keymaster1 实现必须要支持 PKCS#8 格式(无密码保护),以便导入 RSA 密钥对和 EC 密钥对,并且必须要支持以原始格式导入 AES 密钥材料和 HMAC 密钥材料。</p>
-
-<h3 id="get_supported_export_formats">get_supported_export_formats</h3>
-
-<p>用于返回一个列表,其中包含指定算法的 Keymaster 硬件实现支持的导出格式。</p>
-
-<p>keymaster1 实现必须要支持 X.509 格式,以便导出 RSA 公钥和 EC 公钥。不得支持导出私钥或非对称密钥。</p>
-
-<h3 id="add_rng_entropy">add_rng_entropy</h3>
-
-<p>用于将调用程序提供的熵添加到 keymaster1 实现生成随机数(在密钥中使用)、IV 以及其他内容时使用的池中。</p>
-
-<p>Keymaster1 实现必须将收到的熵<strong>安全地</strong>混合到所使用的池中,该池中必须还要包含由硬件随机数生成器在内部生成的熵。混合操作必须具有以下特性:即使攻击者能够完全控制通过 <code>add_rng_entropy</code> 提供的位数或硬件生成的位数(但不能同时控制这两者),他们能够预测出通过熵池生成的位数的概率也不得超过 ½。</p>
-
-<p>尝试估算内部池中的熵的 keymaster1 实现必须假定通过 <code>add_rng_entropy</code> 提供的数据不包含熵。</p>
-
-<h3 id="generate_key">generate_key</h3>
-
-<p>用于生成一个新的加密密钥,同时指定将永久绑定到该密钥的关联授权。keymaster1 实现必须能够确保无法通过任何与生成密钥时指定的授权不一致的方式使用相应密钥。对于安全硬件无法强制执行的授权,安全硬件的义务仅限于确保与相应密钥关联的无法强制执行的授权不能被修改,以便每次调用 <a href="#get_key_characteristics">get_key_characteristics</a> 时都会返回原始值。此外,通过 <code>generate_key</code> 返回的特性必须将授权正确地分配到由硬件强制执行的列表和由软件强制执行的列表中。如需更多详细信息,请参阅 <a href="#get_key_characteristics">get_key_characteristics</a>。</p>
-
-<p>必须要向 <code>generate_key</code> 提供的参数取决于要生成的密钥的类型。这一部分将概括介绍每种类型的密钥必需的标记以及允许使用的标记。<a href="#km_tag_algorithm">KM_TAG_ALGORITHM</a> 始终为必需的标记,用于指定类型。</p>
-
-<h4 id="rsa_keys">RSA 密钥</h4>
-
-<p>以下参数是生成 RSA 密钥时必需的参数。</p>
+<p>以下参数不是生成 RSA 密钥所必需的参数,但如果在缺少这些参数的情况下生成 RSA 密钥,生成的密钥将无法使用。不过,如果缺少这些参数,<code>generateKey</code> 函数不会返回错误。</p>
 
 <ul>
-  <li><a href="#km_tag_key_size">KM_TAG_KEY_SIZE</a> 用于指定公开模数的大小(以位数计)。如果缺少此参数,方法必须返回 <code>KM_ERROR_UNSUPPORTED_KEY_SIZE</code>。必须要支持 1024、2048、3072 和 4096,最好还支持为 8 的倍数的所有密钥大小。
-  </li><li><a href="#km_tag_rsa_public_exponent">KM_TAG_RSA_PUBLIC_EXPONENT</a> 用于指定 RSA 公开指数的值。如果缺少此参数,方法必须返回 <code>KM_ERROR_INVALID_ARGUMENT</code>。实现必须要支持 3 和 65537,最好还支持不超过 2^64 的所有质数值。
-</li></ul>
+  <li><a href="/security/keystore/tags#purpose">Tag::PURPOSE</a> 用于指定允许的目的。
+  对于 RSA 密钥,需要支持采用任意组合的所有目的。</li>
+  <li><a href="/security/keystore/tags#digest">Tag::DIGEST</a> 用于指定可与新密钥配合使用的摘要算法。不支持任何摘要算法的实现需要接受包含不受支持的摘要的密钥生成请求。不受支持的摘要应被放入“由软件强制执行”的列表内的返回的密钥特性中。这是因为相应密钥能够与其他摘要配合使用,但添加摘要会在软件中进行。然后,将调用硬件按 <code>Digest::NONE</code> 摘要算法执行相应操作。</li>
+  <li><a href="/security/keystore/tags#padding">Tag::PADDING</a> 用于指定可与新密钥配合使用的填充模式。如果指定了任何不受支持的摘要算法,则不支持所有摘要算法的实现需要将 <code>PaddingMode::RSA_PSS</code> 和 <code>PaddingMode::RSA_OAEP</code> 放入由软件强制执行的密钥特性列表中。</li>
+</ul>
 
-<p>以下参数不是生成 RSA 密钥时必需的参数,但如果在缺少这些参数的情况下生成 RSA 密钥,生成的密钥将无法使用。如果缺少这些参数,<code>generate_key</code> 函数不应返回错误。</p>
+<h4 id="generate_key_ecdsa_keys">ECDSA 密钥</h4>
+
+<p>只有 <a href="/security/keystore/tags#key_size">Tag::KEY_SIZE</a> 是生成 ECDSA 密钥所必需的参数。此参数用于选择 EC 组。
+支持的值包括 224、256、384 和 521,这些值分别表示 NIST p-224、p-256、p-384 和 p521 曲线。</p>
+
+<p>为了使生成的 ECDSA 密钥可以使用,还需要 <a href="/security/keystore/tags#digest">Tag::DIGEST</a>,但此参数不是生成 ECDSA 密钥所必需的参数。</p>
+
+<h4 id="generate_key_aes_keys">AES 密钥</h4>
+
+<p>只有 <a href="/security/keystore/tags#key_size">Tag::KEY_SIZE</a> 是生成 AES 密钥所必需的参数。如果缺少此参数,该方法会返回 <code>ErrorCode::UNSUPPORTED_KEY_SIZE</code>。支持的值包括 128 和 256,可以选择支持 192 位 AES 密钥。</p>
+
+<p>以下参数仅与 AES 密钥相关,但它们并不是生成 AES 密钥所必需的参数:</p>
 
 <ul>
-  <li><a href="#km_tag_purpose">KM_TAG_PURPOSE</a> 用于指定允许的目的。对于 RSA 密钥,必须要支持采用任意组合的所有目的。
-  </li><li><a href="#km_tag_digest">KM_TAG_DIGEST</a> 用于指定可与新密钥配合使用的摘要算法。不支持任何摘要算法的实现必须要接受包含不受支持的摘要的密钥生成请求。不受支持的摘要应被放入“由软件强制执行”的列表内返回的密钥特性中。这是因为相应密钥能够与其他摘要配合使用,但添加摘要将在软件中进行。然后,将调用硬件按 <code>KM_DIGEST_NONE</code> 摘要算法执行相应操作。</li><li><a href="#km_tag_padding">KM_TAG_PADDING</a> 用于指定可与新密钥配合使用的填充模式。如果未指定任何不受支持的摘要算法,不支持任何摘要算法的实现必须将 <code>KM_PAD_RSA_PSS</code> 和 <code>KM_PAD_RSA_OAEP</code> 放入由软件强制执行的密钥特性列表中。
-</li></ul>
+  <li><code>Tag::BLOCK_MODE</code> 用于指定可与新密钥配合使用的分块模式。</li>
+  <li><code>Tag::PADDING</code> 用于指定可以使用的填充模式。此参数仅与 ECB 和 CBC 模式相关。</li>
+</ul>
 
-<h4 id="ecdsa_keys">ECDSA 密钥</h4>
+<p>如果指定的是 GCM 分块模式,则提供 <a href="/security/keystore/tags#min_mac_length">Tag::MIN_MAC_LENGTH</a>。
+如果缺少此参数,该方法会返回 <code>ErrorCode::MISSING_MIN_MAC_LENGTH</code>。标记的值为 8 的倍数且介于 96 和 128 之间。</p>
 
-<p>只有 <a href="#km_tag_key_size">KM_TAG_KEY_SIZE</a> 是生成 ECDSA 密钥时必需的参数。此参数用于选择 EC 组。实现必须要支持 224、256、384 和 521,这些值分别表示 NIST p-224、p-256、p-384 和 p521 曲线。</p>
+<h4 id="generate_key_hmac_keys">HMAC 密钥</h4>
 
-<p>为了使生成的 ECDSA 密钥可以使用,还需要 <a href="#km_tag_digest">KM_TAG_DIGEST</a>,但此参数不是生成 ECDSA 密钥时必需的参数。</p>
-
-<h4 id="aes_keys">AES 密钥</h4>
-
-<p>只有 <a href="#km_tag_key_size">KM_TAG_KEY_SIZE</a> 是生成 AES 密钥时必需的参数。如果缺少此参数,方法必须返回 <code>KM_ERROR_UNSUPPORTED_KEY_SIZE</code>。必须要支持 128 和 256。建议支持 192 位 AES 密钥。</p>
-
-<p>以下参数仅与 AES 密钥有关,但它们并不是生成 AES 密钥时必需的参数:</p>
+<p>以下参数是生成 HMAC 密钥所必需的参数:</p>
 
 <ul>
-  <li><code>KM_TAG_BLOCK_MODE</code> 用于指定可与新密钥配合使用的分块模式。
-  </li><li><code>KM_TAG_PADDING</code> 用于指定可以使用的填充模式。此参数仅与 ECB 和 CBC 模式有关。
-</li></ul>
-
-<p>如果指定的是 GCM 分块模式,则必须要提供 <a href="#km_tag_min_mac_length">KM_TAG_MIN_MAC_LENGTH</a>。如果缺少此参数,方法必须返回 <code>KM_ERROR_MISSING_MIN_MAC_LENGTH</code>。此标记的值必须是 8 的倍数,并且必须介于 96 到 128 之间。</p>
-
-<h4 id="hmac_keys">HMAC 密钥</h4>
-
-<p>以下参数是生成 HMAC 密钥时必需的参数:</p>
-
-<ul>
-  <li><a href="#km_tag_key_size">KM_TAG_KEY_SIZE</a> 用于指定密钥大小(以位数计)。不得支持小于 64 以及不是 8 的倍数的值。必须要支持介于 64 到 512 之间并且是 8 的倍数的值。可以支持更大的值。
-  </li><li><a href="#km_tag_min_mac_length">KM_TAG_MIN_MAC_LENGTH</a> 用于指定可通过相应密钥生成或验证的 MAC 的最小长度。此参数的值必须是 8 的倍数,并且不得小于 64。
-  </li><li><a href="#km_tag_digest">KM_TAG_DIGEST</a> 用于指定相应密钥的摘要算法。必须且只能指定一种摘要,否则返回 <code>KM_ERROR_UNSUPPORTED_DIGEST</code>。如果 Trustlet 不支持指定的摘要,则返回 <code>KM_ERROR_UNSUPPORTED_DIGEST</code>。</li></ul>
+  <li><a href="/security/keystore/tags#key_size">Tag::KEY_SIZE</a> 用于指定密钥大小(以位计)。不支持小于 64 以及不是 8 的倍数的值。支持介于 64 和 512 之间并且是 8 的倍数的所有值。可以支持更大的值。</li>
+  <li><a href="/security/keystore/tags#min_mac_length">Tag::MIN_MAC_LENGTH</a> 用于指定可通过相应密钥生成或验证的 MAC 的最小长度。此参数的值是 8 的倍数,并且不小于 64。</li>
+  <li><a href="/security/keystore/tags#digest">Tag::DIGEST</a> 用于指定相应密钥的摘要算法。只能指定一种摘要,否则返回 <code>ErrorCode::UNSUPPORTED_DIGEST</code>。
+  如果 Trustlet 不支持指定的摘要,则返回 <code>ErrorCode::UNSUPPORTED_DIGEST</code>。</li>
+</ul>
 
 <h4 id="key_characteristics">密钥特性</h4>
 
-<p>如果特性参数为非 NULL 值,<code>generate_key</code> 必须返回新生成密钥的特性(适当地划分到由硬件强制执行的列表和由软件强制执行的列表中)。要了解哪些特性会划分到哪个列表中,请参阅 <a href="#get_key_characteristics">get_key_characteristics</a>。返回的特性必须要包含为生成密钥而指定的所有参数,<a href="#km_tag_application_id">KM_TAG_APPLICATION_ID</a> 和 <a href="#km_tag_application_data">KM_TAG_APPLICATION_DATA</a> 除外。如果这两个标记包含在密钥参数中,则必须要将其从返回的特性中移除;必须要确保无法通过查看返回的密钥 Blob 找出这两个标记的值。不过,这两个标记必须要以加密形式绑定到密钥 Blob,以便在使用相应密钥时,如果未提供正确的值,使用将会失败。同样,<a href="#km_tag_root_of_trust">KM_TAG_ROOT_OF_TRUST</a> 也必须要以加密形式绑定到相应密钥,但在生成或导入密钥期间可以不指定此标记,并且在任何情况下都不得返回此标记。</p>
+<p>如果特性参数为非 NULL 值,<code>generateKey</code> 会返回新生成密钥的特性(相应划分到由硬件强制执行的列表和由软件强制执行的列表中)。
+要了解哪些特性会划分到哪个列表中,请参阅 <a href="#get_key_characteristics">getKeyCharacteristics</a>。返回的特性包含为生成密钥而指定的所有参数,<a href="/security/keystore/tags#application_id">Tag::APPLICATION_ID</a> 和 <a href="/security/keystore/tags#application_data">Tag::APPLICATION_DATA</a> 除外。如果这两个标记包含在密钥参数中,则将其从返回的特性中移除,以确保无法通过查看返回的密钥 Blob 找出这两个标记的值。不过,这两个标记以加密形式绑定到密钥 Blob,以便在使用相应密钥时,如果未提供正确的值,使用会失败。<a href="/security/keystore/tags#root_of_trust">Tag::ROOT_OF_TRUST</a> 同样会以加密形式绑定到相应密钥,但在生成或导入密钥期间可以不指定此标记,并且在任何情况下都不会返回此标记。</p>
 
-<p>除了收到的标记外,Trustlet 还必须要添加 <a href="#km_tag_origin">KM_TAG_ORIGIN</a>(值为 <code>KM_ORIGIN_GENERATED</code>);如果相应密钥可抗回滚,还要添加 <a href="#km_tag_rollback_resistant">KM_TAG_ROLLBACK_RESISTANT</a>。</p>
+<p>除了收到的标记外,Trustlet 还会添加 <a href="/security/keystore/tags#origin">Tag::ORIGIN</a>(值为 <code>KeyOrigin::GENERATED</code>);如果相应密钥可抗回滚,还要添加 <a href="/security/keystore/tags#rollback_resistant">Tag::ROLLBACK_RESISTANT</a>。</p>
 
 <h4 id="rollback_resistance">抗回滚</h4>
 
-<p>抗回滚意味着,相应密钥通过 <a href="#delete_key">delete_key</a> 或 <a href="#delete_all_keys">delete_all_keys</a> 被删除后,安全硬件将保证它绝对无法再使用。不采用抗回滚的实现通常会将生成或导入的密钥材料作为密钥 Blob(一种经过加密和身份验证的形式)返回给调用程序。当 Keystore 删除密钥 Blob 后,相应密钥将会消失,但之前已设法获取密钥材料的攻击者可能能够将相应密钥材料恢复到设备上。</p>
+<p>抗回滚意味着,密钥在通过 <a href="#delete_key">deleteKey</a> 或 <a href="#delete_all_keys">deleteAllKeys</a> 删除后,安全硬件会保证它绝对无法再使用。不具抗回滚功能的实现通常会将生成或导入的密钥材料作为密钥 Blob(一种经过加密和身份验证的形式)返回给调用程序。当 Keystore 删除密钥 Blob 后,相应密钥将会消失,但之前已设法获取密钥材料的攻击者可能能够将相应密钥材料恢复到设备上。</p>
 
-<p>如果安全硬件保证被删除的密钥以后无法被恢复,那么相应密钥便可抗回滚。安全硬件通常是通过将额外的密钥元数据存储在攻击者无法操控的可信位置来做到这一点。在移动设备上,用于实现这一点的机制通常为 Replay Protected Memory Block (RPMB)。由于可创建的密钥数量基本上没有限制,而用于抗回滚的可信存储空间的大小可能有限制,因此即使无法为新密钥提供抗回滚功能,此方法也必须可以成功。在这种情况下,不得将 <a href="#km_tag_rollback_resistant">KM_TAG_ROLLBACK_RESISTANT</a> 添加到密钥特性中。</p>
+<p>如果安全硬件保证被删除的密钥以后无法被恢复,那么相应密钥便可抗回滚。安全硬件通常是通过将额外的密钥元数据存储在攻击者无法操控的可信位置来做到这一点。在移动设备上,用于实现这一点的机制通常为 Replay Protected Memory Block (RPMB)。由于可创建的密钥数量基本上没有限制,而用于抗回滚的可信存储空间的大小则可能有限制,因此,该方法需要在即使无法为新密钥提供抗回滚功能的情况下同样取得成功。在这种情况下,不得将 <a href="/security/keystore/tags#rollback_resistant">Tag::ROLLBACK_RESISTANT</a> 添加到密钥特性中。</p>
 
-<h3 id="get_key_characteristics">get_key_characteristics</h3>
+<h3 id="get_key_characteristics">getKeyCharacteristics</h3>
 
-<p>用于返回与收到的密钥关联的参数和授权,并且返回的参数和授权会划分为两组:一组由硬件强制执行,一组由软件强制执行。此处的说明同样适用于通过 <a href="#generate_key">generate_key</a> 和 <a href="#import_key">import_key</a> 返回的密钥特性列表。</p>
+<p><strong>版本</strong>:1、2、3</p>
+<p>该函数在 Keymaster 1 中引入(名为 <code>get_key_characteristics</code>),并在 Keymaster 3 中进行了重命名。</p>
 
-<p>如果在密钥生成或导入期间提供了 <code>KM_TAG_APPLICATION_ID</code>,则必须要在 <code>client_id</code> 参数中为此方法提供相同的值。否则,此方法必须返回 <code>KM_ERROR_INVALID_KEY_BLOB</code>。同样,如果在生成或导入密钥期间提供了 <code>KM_TAG_APPLICATION_DATA </code>,则必须要在 <code>app_data</code> 参数中为此方法提供相同的值。</p>
+<p>用于返回与收到的密钥关联的参数和授权,并且返回的参数和授权会划分为两组:一组由硬件强制执行,一组由软件强制执行。此处的说明同样适用于通过 <a href="#generate_key">generateKey</a> 和 <a href="#import_key">importKey</a> 返回的密钥特性列表。</p>
+
+<p>如果在生成或导入密钥期间提供了 <code>Tag::APPLICATION_ID</code>,则在 <code>clientId</code> 参数中为此方法提供相同的值。否则,此方法会返回 <code>ErrorCode::INVALID_KEY_BLOB</code>。同样,如果在生成或导入密钥期间提供了 <code>Tag::APPLICATION_DATA</code>,则在 <code>appData</code> 参数中为此方法提供相同的值。</p>
 
 <p>此方法返回的特性完整地说明了指定密钥的类型和用法。</p>
 
 <p>要确定某个指定标记是属于由硬件强制执行的列表,还是属于由软件强制执行的列表,一般规则是:如果该标记的含义完全由安全硬件来保证,则属于由硬件强制执行的列表,否则属于由软件强制执行的列表。下面列出了可能无法明确确定到底属于哪个列表的具体标记:</p>
 
 <ul>
-  <li><a href="#km_tag_algorithm">KM_TAG_ALGORITHM</a>、<a href="#km_tag_key_size">KM_TAG_KEY_SIZE</a> 和 <a href="#km_tag_rsa_public_exponent">KM_TAG_RSA_PUBLIC_EXPONENT</a> 是密钥的固有属性。任何由硬件来保障安全的密钥都将位于由硬件强制执行的列表中,这是因为诸如“此 RSA 密钥材料仅用作 RSA 密钥”之类的声明由硬件强制执行,原因是硬件将不会以任何其他方式使用相应密钥,而软件无权访问密钥材料并且根本无法使用相应密钥。
-  </li><li>由安全硬件支持的 <a href="#km_tag_digest">KM_TAG_DIGEST</a> 值将位于由硬件支持的列表中。不受支持的摘要则位于由软件支持的列表中。
-  </li><li><a href="#km_tag_padding">KM_TAG_PADDING</a> 的值通常位于由硬件支持的列表中,但如果存在某种特定的填充模式必须要由软件来强制执行的可能性,那么这些值将位于由软件强制执行的列表中。对于允许使用不是由安全硬件支持的摘要算法进行 PSS 或 OAEP 填充的 RSA 密钥,则存在这种可能性。
-  </li><li>仅当用户身份验证由硬件强制执行时,<a href="#km_tag_user_secure_id">KM_TAG_USER_SECURE_ID</a> 和 <a href="#km_tag_mac_length">KM_TAG_USER_AUTH_TYPE</a> 才由硬件强制执行。要使用户身份验证由硬件强制执行,Keymaster Trustlet 和相关身份验证 Trustlet 都必须是安全的,并且必须共用一个用于签署和验证身份验证令牌的 HMAC 密钥。有关详情,请参阅“身份验证”页面。
-  </li><li><a href="#km_tag_active_datetime">KM_TAG_ACTIVE_DATETIME</a>、<a href="#km_tag_origination_expire_datetime">KM_TAG_ORIGINATION_EXPIRE_DATETIME</a> 和 <a href="#km_tag_usage_expire_datetime">KM_TAG_USAGE_EXPIRE_DATETIME</a> 标记要求能够访问可验证的正确挂钟。大多数安全硬件将只能访问由非安全操作系统提供的时间信息,这意味着这些标记由软件强制执行。
-  </li><li>对于绑定到硬件的密钥,<a href="#km_tag_origin">KM_TAG_ORIGIN</a> 始终位于硬件列表中。如果此标记出现在硬件列表中,更高的层级便可据此确定相应密钥是由硬件支持的密钥。
-</li></ul>
+  <li><a href="/security/keystore/tags#algorithm">Tag::ALGORITHM</a>、<a href="/security/keystore/tags#key_size">Tag::KEY_SIZE</a> 和 <a href="/security/keystore/tags#rsa_public_exponent">Tag::RSA_PUBLIC_EXPONENT</a> 是密钥的固有属性。对于任何由硬件来保障安全的密钥,这些标记都将位于由硬件强制执行的列表中。</li>
+  <li>由安全硬件支持的 <a href="/security/keystore/tags#digest">Tag::DIGEST</a> 值位于由硬件支持的列表中。不受支持的摘要则位于由软件支持的列表中。</li>
+  <li><a href="/security/keystore/tags#padding">Tag::PADDING</a> 的值通常位于由硬件支持的列表中,除非存在这样一种可能性,某种特定的填充模式必须要由软件来执行,在这种情况下,这些值将位于由软件强制执行的列表中。如果 RSA 密钥允许使用不是由安全硬件支持的摘要算法进行 PSS 或 OAEP 填充,则存在这种可能性。</li>
+  <li><a href="/security/keystore/tags#user_secure_id">Tag::USER_SECURE_ID</a> 和 <a href="/security/keystore/tags#mac_length">Tag::USER_AUTH_TYPE</a> 仅在用户身份验证由硬件强制执行时,才由硬件强制执行。要让用户身份验证由硬件强制执行,Keymaster Trustlet 和相关的身份验证 Trustlet 都必须是安全的,且共用一个用于签署和验证身份验证令牌的 HMAC 密钥。要了解详情,请参阅<a href="/security/authentication/">身份验证</a>页面。</li>
+  <li><a href="/security/keystore/tags#active_datetime">Tag::ACTIVE_DATETIME</a>、<a href="/security/keystore/tags#origination_expire_datetime">Tag::ORIGINATION_EXPIRE_DATETIME</a> 和 <a href="/security/keystore/tags#usage_expire_datetime">Tag::USAGE_EXPIRE_DATETIME</a> 标记要求能够访问可验证的正确时钟。大多数安全硬件只能访问由非安全操作系统提供的时间信息,这意味着这些标记由软件强制执行。</li>
+  <li>对于绑定到硬件的密钥,<a href="/security/keystore/tags#origin">Tag::ORIGIN</a> 始终位于硬件列表中。如果此标记出现在硬件列表中,更高的层级便可据此确定相应密钥是由硬件支持的。</li>
+</ul>
 
-<h3 id="import_key">import_key</h3>
+<h3 id="import_key">importKey</h3>
 
-<p>用于将密钥材料导入到 Keymaster 硬件中。密钥定义参数和输出特性的处理方式与 <code>generate_key</code> 相同,但存在以下例外情况:</p>
+<p><strong>版本</strong>:1、2、3</p>
+<p>该函数在 Keymaster 1 中引入(名为 <code>import_key</code>),并在 Keymaster 3 中进行了重命名。</p>
+
+<p>用于将密钥材料导入到 Keymaster 硬件中。密钥定义参数和输出特性的处理方式与 <code>generateKey</code> 相同,但存在以下例外情况:</p>
 
 <ul>
-  <li><a href="#km_tag_key_size">KM_TAG_KEY_SIZE</a> 和 <a href="#km_tag_rsa_public_exponent">KM_TAG_RSA_PUBLIC_EXPONENT</a>(仅适用于 RSA 密钥)不是输入参数中必需的标记。如果未收到这两个标记,Trustlet 必须根据收到的密钥材料推导出这两个标记的值,并将适当的标记和值添加到密钥特性中。如果收到了这两个参数,Trustlet 必须根据密钥材料对其进行验证。如果收到的值与密钥材料中的值不一致,此方法必须返回 <code>KM_ERROR_IMPORT_PARAMETER_MISMATCH</code>。</li><li>返回的 <a href="#km_tag_origin">KM_TAG_ORIGIN</a> 必须要具有 <code>KM_ORIGIN_IMPORTED</code> 这个值。</li></ul>
+  <li><a href="/security/keystore/tags#key_size">Tag::KEY_SIZE</a> 和 <a href="/security/keystore/tags#rsa_public_exponent">Tag::RSA_PUBLIC_EXPONENT</a>(仅限 RSA 密钥)不是输入参数中必需的标记。如果未收到这两个标记,Trustlet 会根据收到的密钥材料推导出这两个标记的值,并将适当的标记和值添加到密钥特性中。如果收到了这两个参数,Trustlet 会根据密钥材料对其进行验证。如果收到的值与密钥材料中的值不一致,该方法会返回 <code>ErrorCode::IMPORT_PARAMETER_MISMATCH</code>。</li>
+  <li>返回的 <a href="/security/keystore/tags#origin">Tag::ORIGIN</a> 与 <code>KeyOrigin::IMPORTED</code> 的值相同。</li>
+</ul>
 
-<h3 id="export_key">export_key</h3>
+<h3 id="export_key">exportKey</h3>
+
+<p><strong>版本</strong>:1、2、3</p>
+<p>该函数在 Keymaster 1 中引入(名为 <code>export_key</code>),并在 Keymaster 3 中进行了重命名。</p>
 
 <p>用于从 Keymaster RSA 密钥对或 EC 密钥对中导出公钥。</p>
 
-<p>如果在密钥生成或导入期间提供了 <code>KM_TAG_APPLICATION_ID</code>,则必须要在 <code>client_id</code> 参数中为此方法提供相同的值。否则,此方法必须返回 <code>KM_ERROR_INVALID_KEY_BLOB</code>。同样,如果在生成或导入密钥期间提供了 <code>KM_TAG_APPLICATION_DATA</code>,则必须要在 <code>app_data</code> 参数中为此方法提供相同的值。</p>
+<p>如果在生成或导入密钥期间提供了 <code>Tag::APPLICATION_ID</code>,则在 <code>clientId</code> 参数中为此方法提供相同的值。否则,此方法会返回 <code>ErrorCode::INVALID_KEY_BLOB</code>。同样,如果在生成或导入密钥期间提供了 <code>Tag::APPLICATION_DATA</code>,则在 <code>appData</code> 参数中为此方法提供相同的值。</p>
 
-<h3 id="delete_key">delete_key</h3>
+<h3 id="delete_key">deleteKey</h3>
 
-<p>用于删除收到的密钥。此方法为可选方法,可能只能由提供抗回滚功能的 Keymaster 模块来实现。</p>
+<p><strong>版本</strong>:1、2、3</p>
+<p>该函数在 Keymaster 1 中引入(名为 <code>delete_key</code>),并在 Keymaster 3 中进行了重命名。</p>
 
-<h3 id="delete_all_keys">delete_all_keys</h3>
+<p>用于删除收到的密钥。此方法为可选方法,只能由提供抗回滚功能的 Keymaster 模块来实现。</p>
 
-<p>用于删除所有密钥。此方法为可选方法,可能只能由提供抗回滚功能的 Keymaster 模块来实现。</p>
+<h3 id="delete_all_keys">deleteAllKeys</h3>
+
+<p><strong>版本</strong>:1、2、3</p>
+<p>该函数在 Keymaster 1 中引入(名为 <code>delete_all_keys</code>),并在 Keymaster 3 中进行了重命名。</p>
+
+<p>用于删除所有密钥。此方法为可选方法,只能由提供抗回滚功能的 Keymaster 模块来实现。</p>
+
+<h3 id="destroy_attestation_ids">destroyAttestationIds</h3>
+<p><strong>版本</strong>:3</p>
+<p>
+<code>destroyAttestationIds()</code> 方法用于永久停用新的<a href="/security/keystore/attestation#id-attestation">ID 认证</a>功能(该功能是可选功能,但我们强烈推荐)。如果 TEE 无法确保在调用此方法后永久停用相应的 ID 认证,则一定不得实现 ID 认证,在这种情况下,此方法不执行任何操作并返回 <code>ErrorCode::UNIMPLEMENTED</code>。如果支持 ID 认证,则需要实现此方法且必须永久停用未来尝试进行 ID 认证的所有操作。此方法的调用次数不受限制。如果已永久停用 ID 认证,则此方法不会执行任何操作并返回 <code>ErrorCode::OK</code>。</p>
+<p>
+此方法只可能返回以下错误代码:<code>ErrorCode::UNIMPLEMENTED</code>(如果不支持 ID 认证)、<code>ErrorCode:OK</code>、<code>ErrorCode::KEYMASTER_NOT_CONFIGURED</code> 或指示无法与安全硬件通信的错误代码之一。
+</p>
 
 <h3 id="begin">begin</h3>
 
-<p>用于开始使用指定的密钥和参数(视情况而定)针对指定的目的进行加密操作,并返回与 <a href="#update">update</a> 和 <a href="#finish">finish</a> 配合使用以完成操作的操作句柄。该操作句柄还会在经过身份验证的操作中用作“质询”令牌,并且对于此类操作,该操作句柄必须包含在身份验证令牌的 <code>challenge</code> 字段中。</p>
+<p><strong>版本</strong>:1、2、3</p>
 
-<p>Keymaster 实现必须要支持至少 16 个并行操作。Keystore 最多使用 15 个,留一个给 vold 用于对密码进行加密。当 Keystore 有 15 个操作正在进行(已调用 <code>begin</code>,但尚未调用 <code>finish</code> 或 <code>abort</code>)时,如果收到开始第 16 个操作的请求,它将对最近使用最少的操作调用 <code>abort</code>,以便将进行中的操作减少到 14 个,然后再调用 <code>begin</code> 来开始执行新收到的操作请求。
+<p>使用指定的密钥和参数(视情况而定)针对指定的目的开始执行加密操作,并返回用于与 <a href="#update">update</a> 和 <a href="#finish">finish</a> 配合使用以完成操作的操作句柄。该操作句柄还会在经过身份验证的操作中用作“质询”令牌,并且对于此类操作,该操作句柄包含在身份验证令牌的 <code>challenge</code> 字段中。</p>
 
-</p><p>如果在密钥生成或导入期间指定了 <a href="#km_tag_application_id">KM_TAG_APPLICATION_ID</a> 或 <a href="#km_tag_application_data">KM_TAG_APPLICATION_DATA</a>,那么调用 <code>begin</code> 时必须要包含这两个标记以及最初在此方法的 <code>in_params</code> 参数中指定的值。</p>
+<p>Keymaster 实现支持至少 16 个并行操作。Keystore 最多使用 15 个,留一个给 vold 用于对密码进行加密。当 Keystore 有 15 个操作正在进行(已调用 <code>begin</code>,但尚未调用 <code>finish</code> 或 <code>abort</code>)时,如果 Keystore 收到开始第 16 个操作的请求,它会对最近使用最少的操作调用 <code>abort</code>,以便将进行中的操作减少到 14 个,然后再调用 <code>begin</code> 来开始执行新请求的操作。</p>
 
-<h4 id="authorization_enforcement">密钥授权强制执行</h4>
+<p>如果在生成或导入密钥期间指定了 <a href="/security/keystore/tags#application_id">Tag::APPLICATION_ID</a> 或 <a href="#application_data">Tag::APPLICATION_DATA</a>,那么调用 <code>begin</code> 时会包含这两个标记,标记的值为最初在 <code>inParams</code> 参数中为此方法指定的值。</p>
 
-<p>在执行此方法期间,如果实现将以下密钥授权放入到了“由硬件强制执行的”特性中,并且相应操作不是公钥操作,那么这些授权必须要由 Trustlet 来强制执行。即使不符合授权要求,也必须要允许公钥操作(即使用 RSA 或 EC 密钥进行的 <code>KM_PURPOSE_ENCRYPT</code> 和 <code>KM_PURPOSE_VERIFY</code>)成功完成。</p>
+<h4 id="begin_authorization_enforcement">密钥授权强制执行</h4>
+
+<p>在执行此方法期间,如果实现将以下密钥授权放入到了“由硬件强制执行的”特性中,并且相应操作不是公钥操作,那么这些密钥授权将由 Trustlet 来强制执行。即使不符合授权要求,也会允许公钥操作(即使用 RSA 或 EC 密钥进行的 <code>KeyPurpose::ENCRYPT</code> 和 <code>KeyPurpose::VERIFY</code>)成功完成。</p>
 
 <ul>
-  <li><a href="#km_tag_purpose">KM_TAG_PURPOSE</a> 要求为此方法指定的目的必须要与密钥授权中的某个目的一致,除非请求的操作是公钥操作,即密钥是 RSA 密钥或 EC 密钥,目的是 <code>KM_PURPOSE_ENCRYPT</code> 或 <code>KM_PURPOSE_VERIFY</code>。请注意,<code>KM_PURPOSE_ENCRYPT</code> 对 EC 密钥无效。在这种情况下,begin 应该返回 <code>KM_ERROR_UNSUPPORTED_PURPOSE</code>。
-  </li><li><a href="#km_tag_active_datetime">KM_TAG_ACTIVE_DATETIME</a> 要求与可信 UTC 时间源进行比较。如果当前日期和时间早于此标记的值,方法必须返回 <code>KM_ERROR_KEY_NOT_YET_VALID</code>。</li><li><a href="#km_tag_origination_expire_datetime">KM_TAG_ORIGINATION_EXPIRE_DATETIME</a> 要求与可信 UTC 时间源进行比较。如果当前日期和时间晚于此标记的值,并且目的是 <code>KM_PURPOSE_ENCRYPT</code> 或 <code>KM_PURPOSE_SIGN</code>,方法必须返回 <code>KM_ERROR_KEY_EXPIRED</code>。</li><li><a href="#km_tag_usage_expire_datetime">KM_TAG_USAGE_EXPIRE_DATETIME</a> 要求与可信 UTC 时间源进行比较。如果当前日期和时间晚于此标记的值,并且目的是 <code>KM_PURPOSE_DECRYPT</code> 或 <code>KM_PURPOSE_VERIFY</code>,方法必须返回 <code>KM_ERROR_KEY_EXPIRED</code>。</li><li><a href="#km_tag_min_seconds_between_ops">KM_TAG_MIN_SECONDS_BETWEEN_OPS</a> 要求与指明相应密钥上次使用时间的可信相对计时器进行比较。如果上次使用时间加上此标记的值后小于当前时间,方法必须返回 <code>KM_ERROR_KEY_RATE_LIMIT_EXCEEDED</code>。要查看重要的实现要求,请参阅标记说明。
-  </li><li><a href="#km_tag_max_uses_per_boot">KM_TAG_MAX_USES_PER_BOOT</a> 要求与用于跟踪自系统启动以来相应密钥使用次数的安全计数器进行比较。如果已使用次数超出此标记的值,方法必须返回 <code>KM_ERROR_KEY_MAX_OPS_EXCEEDED</code>。</li><li>仅当相应密钥还有 <a href="#km_tag_auth_timeout">KM_TAG_AUTH_TIMEOUT</a> 时,<a href="#km_tag_user_secure_id">KM_TAG_USER_SECURE_ID</a> 才会由此方法强制执行。如果相应密钥同时具有这两个标记,此方法必须要已在 <code>in_params</code> 中收到 <a href="#km_tag_auth_token">KM_TAG_AUTH_TOKEN</a>,并且该令牌必须有效,也就是说,HMAC 字段可正确验证。此外,相应密钥必须要有至少一个 <a href="#km_tag_user_secure_id">KM_TAG_USER_SECURE_ID</a> 值与令牌中至少一个安全 ID 值一致。最后,相应密钥还必须要有 <a href="#km_tag_mac_length">KM_TAG_USER_AUTH_TYPE</a>,而且此标记必须要与令牌中的身份验证类型一致。如果这些要求中有任何一个不符合,方法必须返回 <code>KM_ERROR_KEY_USER_NOT_AUTHENTICATED</code>。</li><li><a href="#km_tag_caller_nonce">KM_TAG_CALLER_NONCE</a> 允许调用程序指定随机数或初始化矢量 (IV)。如果相应密钥没有此标记,但调用程序为此方法提供了 <a href="#km_tag_nonce">KM_TAG_NONCE</a>,则必须返回 <code>KM_ERROR_CALLER_NONCE_PROHIBITED</code>。
-  </li><li><a href="#km_tag_bootloader_only">KM_TAG_BOOTLOADER_ONLY</a> 用于指定相应密钥只能由引导加载程序使用。如果在引导加载程序执行完毕后调用此方法,并且提供的是仅限引导加载程序使用的密钥,则必须返回 <code>KM_ERROR_INVALID_KEY_BLOB</code>。</li></ul>
+  <li><a href="/security/keystore/tags#purpose">Tag::PURPOSE</a>:除非请求的操作是公钥操作,否则 <code>begin()</code> 调用中指定的目的必须与密钥授权中的某个目的一致。如果指定的目的不一致且操作并非公钥操作,则 <code>begin</code> 会返回 <code>ErrorCode::UNSUPPORTED_PURPOSE</code>。公钥操作是不对称加密或验证操作。</li>
+  <li>只有可信 UTC 时间源可用时才能强制执行 <a href="/security/keystore/tags#active_datetime">Tag::ACTIVE_DATETIME</a>。如果当前日期和时间早于此标记的值,该方法会返回 <code>ErrorCode::KEY_NOT_YET_VALID</code>。</li>
+  <li>只有可信 UTC 时间源可用时才能强制执行 <a href="/security/keystore/tags#origination_expire_datetime">Tag::ORIGINATION_EXPIRE_DATETIME</a>。如果当前日期和时间晚于此标记的值,并且目的是 <code>KeyPurpose::ENCRYPT</code> 或 <code>KeyPurpose::SIGN</code>,该方法会返回 <code>ErrorCode::KEY_EXPIRED</code>。</li>
+  <li>只有可信 UTC 时间源可用时才能强制执行 <a href="/security/keystore/tags#usage_expire_datetime">Tag::USAGE_EXPIRE_DATETIME</a>。如果当前日期和时间晚于此标记的值,并且目的是 <code>KeyPurpose::DECRYPT</code> 或 <code>KeyPurpose::VERIFY</code>,该方法会返回 <code>ErrorCode::KEY_EXPIRED</code>。</li>
+  <li><a href="/security/keystore/tags#min_seconds_between_ops">Tag::MIN_SECONDS_BETWEEN_OPS</a> 会与指明相应密钥上次使用时间的可信相对计时器进行比较。如果上次使用时间加上此标记的值后小于当前时间,该方法会返回 <code>ErrorCode::KEY_RATE_LIMIT_EXCEEDED</code>。要查看重要的实现详情,请参阅<a href="/security/keystore/tags#min_seconds_between_ops">标记说明</a>。</li>
+  <li><a href="/security/keystore/tags#max_uses_per_boot">Tag::MAX_USES_PER_BOOT</a> 会与用于跟踪自系统启动以来相应密钥使用次数的安全计数器进行比较。如果之前的使用次数已超过此标记的值,该方法会返回 <code>ErrorCode::KEY_MAX_OPS_EXCEEDED</code>。</li>
+  <li>仅当相应密钥还有 <a href="/security/keystore/tags#auth_timeout">Tag::AUTH_TIMEOUT</a> 时,<a href="/security/keystore/tags#user_secure_id">Tag::USER_SECURE_ID</a>才会由此方法强制执行。如果相应密钥同时具有这两个标记,此方法必须在 <code>inParams</code> 中收到有效的 <a href="/security/keystore/tags#auth_token">Tag::AUTH_TOKEN</a>。要使身份验证令牌有效,必须满足以下所有条件:
+   <ul>
+     <li>HMAC 字段可正确验证。</li>
+     <li>相应密钥中有至少一个 <a href="/security/keystore/tags#user_secure_id">Tag::USER_SECURE_ID</a> 值与令牌中至少一个安全 ID 值一致。</li>
+     <li>相应密钥具有与令牌中的身份验证类型一致的 <a href="/security/keystore/tags#mac_length">Tag::USER_AUTH_TYPE</a>。</li>
+   </ul>
+  <p>如果上述条件中有任何一个不满足,该方法就会返回 <code>ErrorCode::KEY_USER_NOT_AUTHENTICATED</code>。</p></li>
+  <li><a href="/security/keystore/tags#caller_nonce">Tag::CALLER_NONCE</a> 允许调用程序指定随机数或初始化矢量 (IV)。如果相应密钥没有此标记,但调用程序为此方法提供了 <a href="/security/keystore/tags#nonce">Tag::NONCE</a>,则返回 <code>ErrorCode::CALLER_NONCE_PROHIBITED</code>。</li>
+  <li><a href="/security/keystore/tags#bootloader_only">Tag::BOOTLOADER_ONLY</a> 用于指定相应密钥只能由引导加载程序使用。如果在引导加载程序执行完毕后调用此方法,并且提供的是仅限引导加载程序使用的密钥,则返回 <code>ErrorCode::INVALID_KEY_BLOB</code>。</li>
+</ul>
 
-<h4 id="rsa_keys">RSA 密钥</h4>
+<h4 id="begin_rsa_keys">RSA 密钥</h4>
 
-<p>执行任何 RSA 密钥操作时,都必须要在 <code>in_params</code> 中指定一种且只能指定一种填充模式。如果未指定或指定了多次,方法必须返回 <code>KM_ERROR_UNSUPPORTED_PADDING_MODE</code>。</p>
+<p>执行任何 RSA 密钥操作时,都会在 <code>inParams</code> 中指定一种且只能指定一种填充模式。
+如果未指定或指定了多次,该方法会返回 <code>ErrorCode::UNSUPPORTED_PADDING_MODE</code>。</p>
 
-<p>RSA 签名和验证操作需要摘要,正如使用 OAEP 填充模式进行 RSA 加密和解密操作时一样。对于这些情况,调用程序必须要在 <code>in_params</code> 中指定一种且只能指定一种摘要。如果未指定或指定了多次,方法必须返回 <code>KM_ERROR_UNSUPPORTED_DIGEST</code>。</p>
+<p>RSA 签名和验证操作需要摘要,就像使用 OAEP 填充模式进行 RSA 加密和解密操作一样。在这类情况下,调用程序会在 <code>inParams</code> 中指定一种且只能指定一种摘要。如果未指定或指定了多次,该方法会返回 <code>ErrorCode::UNSUPPORTED_DIGEST</code>。</p>
 
-<p>私钥操作(<code>KM_PURPOSE_DECYPT</code> 和 <code>KM_PURPOSE_SIGN</code>)要求摘要和填充获得授权,也就是说,指定的值必须要在密钥授权中。否则,方法必须视情况返回 <code>KM_ERROR_INCOMPATIBLE_DIGEST</code> 或 <code>KM_ERROR_INCOMPATIBLE_PADDING</code>。公钥操作(<code>KM_PURPOSE_ENCRYPT</code> 和 <code>KM_PURPOSE_VERIFY</code>)可以使用未经授权的摘要或填充。</p>
+<p>私钥操作(<code>KeyPurpose::DECYPT</code> 和 <code>KeyPurpose::SIGN</code>)要求摘要和填充获得授权,也就是说,密钥授权需要包含指定的值。否则,该方法会根据具体情况返回 <code>ErrorCode::INCOMPATIBLE_DIGEST</code> 或 <code>ErrorCode::INCOMPATIBLE_PADDING</code>。公钥操作(<code>KeyPurpose::ENCRYPT</code> 和 <code>KeyPurpose::VERIFY</code>)可以使用未经授权的摘要或填充。</p>
 
-<p>除了 <code>KM_PAD_NONE</code> 之外,所有 RSA 填充模式都仅适用于特定目的。具体来说就是,<code>KM_PAD_RSA_PKCS1_1_5_SIGN</code> 和 <code>KM_PAD_RSA_PSS</code> 仅支持签名和验证,而 <code>KM_PAD_RSA_PKCS1_1_1_5_ENCRYPT</code> 和 <code>KM_PAD_RSA_OAEP</code> 仅支持加密和解密。如果指定的模式不支持指定的目的,方法必须返回 <code>KM_ERROR_UNSUPPORTED_PADDING_MODE</code>。</p>
+<p>除了 <code>PaddingMode::NONE</code> 之外,所有 RSA 填充模式都仅适用于特定目的。具体来说就是,<code>PaddingMode::RSA_PKCS1_1_5_SIGN</code> 和 <code>PaddingMode::RSA_PSS</code> 仅支持签名和验证,而 <code>PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT</code> 和 <code>PaddingMode::RSA_OAEP</code> 仅支持加密和解密。
+如果指定的模式不支持指定的目的,该方法会返回 <code>ErrorCode::UNSUPPORTED_PADDING_MODE</code>。</p>
 
 <p>填充模式与摘要之间存在以下非常重要的相互关系:</p>
 
 <ul>
 
-  <li><code>KM_PAD_NONE</code> 表示将执行“原始”RSA 操作。如果是进行签名或验证,必须要指定 <code>KM_DIGEST_NONE</code> 这种摘要。如果是进行非填充式加密或解密,则不需要摘要。
+  <li><code>PaddingMode::NONE</code> 表示执行“原始”RSA 操作。如果是进行签名或验证,则指定 <code>Digest::NONE</code> 这种摘要。如果是进行非填充式加密或解密,则不需要摘要。</li>
+  <li><code>PaddingMode::RSA_PKCS1_1_5_SIGN</code> 填充需要摘要。摘要可以是 <code>Digest::NONE</code>,在这种情况下,Keymaster 实现无法构建适当的 PKCS#1 v1.5 签名结构,因为它无法添加 DigestInfo 结构。不过,实现会构建 <code>0x00 || 0x01 || PS || 0x00 || M</code>,其中 M 是收到的消息,PS 是填充字符串。RSA 密钥的大小要比消息至少多 11 个字节,否则该方法会返回 <code>ErrorCode::INVALID_INPUT_LENGTH</code>。</li>
+  <li><code>PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT</code> 填充不需要摘要。</li>
+  <li><code>PaddingMode::RSA_PSS</code> 填充需要摘要,并且摘要不能是 <code>Digest::NONE</code>。如果指定了 <code>Digest::NONE</code>,该方法会返回 <code>ErrorCode::INCOMPATIBLE_DIGEST</code>。此外,RSA 密钥的大小必须至少比摘要的输出大小大 2 + D 字节,其中 D 表示摘要的大小(以字节计)。否则,该方法会返回 <code>ErrorCode::INCOMPATIBLE_DIGEST</code>。盐的大小为 D。</li>
+  <li><code>PaddingMode::RSA_OAEP</code> 填充需要摘要,并且摘要不能是 <code>Digest::NONE</code>。如果指定了 <code>Digest::NONE</code>,该方法会返回 <code>ErrorCode::INCOMPATIBLE_DIGEST</code>。</li>
+</ul>
 
-  </li><li><code>KM_PAD_RSA_PKCS1_1_5_SIGN</code> 填充需要摘要。摘要可以是 <code>KM_DIGEST_NONE</code>,在这种情况下,Keymaster 实现将无法构建适当的 PKCS#1 v1.5 签名结构,因为它无法添加 DigestInfo 结构。不过,实现必须要构建 <code>0x00 || 0x01 || PS || 0x00 || M</code>,其中 M 是收到的消息,PS 是填充字符串。RSA 密钥的大小必须要比消息至少多 11 个字节,否则方法必须返回 <code>KM_ERROR_INVALID_INPUT_LENGTH</code>。</li><li><code>KM_PAD_RSA_PKCS1_1_1_5_ENCRYPT</code> 填充不需要摘要。</li><li><code>KM_PAD_RSA_PSS</code> 填充需要摘要,并且摘要不能是 <code>KM_DIGEST_NONE</code>。如果指定的是 <code>KM_DIGEST_NONE</code>,方法必须返回 <code>KM_ERROR_INCOMPATIBLE_DIGEST</code>。此外,RSA 密钥的大小必须要比摘要的输出大小至少多 22 个字节。否则,方法必须返回 <code>KM_ERROR_INCOMPATIBLE_DIGEST</code>。</li><li><code>KM_PAD_RSA_OAEP</code> 填充需要摘要,并且摘要不能是 <code>KM_DIGEST_NONE</code>。如果指定的是 <code>KM_DIGEST_NONE</code>,方法必须返回 <code>KM_ERROR_INCOMPATIBLE_DIGEST</code>。</li></ul>
+<h4 id="begin_ec_keys">EC 密钥</h4>
 
-<h4 id="ec_keys">EC 密钥</h4>
+<p>执行 EC 密钥操作时,会在 <code>inParams</code> 中指定一种且只能指定一种填充模式。
+如果未指定或指定了多次,该方法会返回 <code>ErrorCode::UNSUPPORTED_PADDING_MODE</code>。</p>
 
-<p>执行任何 EC 密钥操作时,都必须要在 <code>in_params</code> 中指定一种且只能指定一种填充模式。如果未指定或指定了多次,则返回 <code>KM_ERROR_UNSUPPORTED_PADDING_MODE</code>。</p>
+<p>私钥操作 (<code>KeyPurpose::SIGN</code>) 要求摘要和填充获得授权,也就是说,密钥授权需要包含指定的值。否则返回 <code>ErrorCode::INCOMPATIBLE_DIGEST</code>。公钥操作 (<code>KeyPurpose::VERIFY</code>) 可以使用未经授权的摘要或填充。</p>
 
-<p>私钥操作 (<code>KM_PURPOSE_SIGN</code>) 要求摘要获得授权,也就是说,指定的值必须要在密钥授权中。否则返回 <code>KM_ERROR_INCOMPATIBLE_DIGEST</code>。公钥操作 (<code>KM_PURPOSE_VERIFY</code>) 可以使用未经授权的摘要或填充。</p>
+<h4 id="begin_aes_keys">AES 密钥</h4>
 
-<h4 id="aes_keys">AES 密钥</h4>
+<p>执行 AES 密钥操作时,会在 <code>inParams</code> 中指定一种且只能指定一种分块模式和填充模式。如果有任何一项未指定或指定了多次,则返回 <code>ErrorCode::UNSUPPORTED_BLOCK_MODE</code> 或 <code>ErrorCode::UNSUPPORTED_PADDING_MODE</code>。指定的模式必须要通过相应密钥授权,否则,该方法会返回 <code>ErrorCode::INCOMPATIBLE_BLOCK_MODE</code> 或 <code>ErrorCode::INCOMPATIBLE_PADDING_MODE</code>。</p>
 
-<p>执行 AES 密钥操作时,必须要在 <code>in_params</code> 中指定一种且只能指定一种分块模式和填充模式。如果有任何一项未指定或指定了多次,则返回 <code>KM_ERROR_UNSUPPORTED_BLOCK_MODE</code> 或 <code>KM_ERROR_UNSUPPORTED_PADDING_MODE</code>。指定的模式必须要已通过相应密钥授权。否则,方法必须返回 <code>KM_ERROR_INCOMPATIBLE_BLOCK_MODE</code> 或 <code>KM_ERROR_INCOMPATIBLE_PADDING_MODE</code>。</p>
+<p>如果分块模式是 <code>BlockMode::GCM</code>,则在 <code>inParams</code> 中指定 <code>Tag::MAC_LENGTH</code>。指定的值是 8 的倍数,并且不大于 128,也不小于密钥授权中 <code>Tag::MIN_MAC_LENGTH</code> 的值。如果 MAC 长度大于 128 或不是 8 的倍数,则返回 <code>ErrorCode::UNSUPPORTED_MAC_LENGTH</code>。如果 MAC 长度小于密钥最小长度,则返回 <code>ErrorCode::INVALID_MAC_LENGTH</code>。</p>
 
-<p>如果分块模式是 <code>KM_MODE_GCM</code>,则必须要在 <code>in_params</code> 中指定 <code>KM_TAG_MAC_LENGTH</code>。指定的值必须是 8 的倍数,并且不得大于 128,也不得小于密钥授权中 <code>KM_TAG_MIN_MAC_LENGTH</code> 的值。如果 MAC 长度大于 128 或不是 8 的倍数,则返回 <code>KM_ERROR_UNSUPPORTED_MAC_LENGTH</code>。如果 MAC 长度小于密钥最小长度,则返回 <code>KM_ERROR_INVALID_MAC_LENGTH</code>。</p>
+<p>如果分块模式是 <code>BlockMode::GCM</code> 或 <code>BlockMode::CTR</code>,那么指定的填充模式必须是 <code>PaddingMode::NONE</code>。如果分块模式是 <code>BlockMode::ECB</code> 或 <code>BlockMode::CBC</code>,那么指定的填充模式可以是 <code>PaddingMode::NONE</code> 或 <code>PaddingMode::PKCS7</code>。如果填充模式不符合这些条件,则返回 <code>ErrorCode::INCOMPATIBLE_PADDING_MODE</code>。</p>
 
-<p>如果分块模式是 <code>KM_MODE_GCM</code> 或 <code>KM_MODE_CTR</code>,那么指定的填充模式必须是 <code>KM_PAD_NONE</code>。如果分块模式是 <code>KM_MODE_ECB</code> 或 <code>KM_MODE_CBC</code>,那么指定的填充模式可以是 <code>KM_PAD_NONE</code> 或 <code>KM_PAD_PKCS7</code>。如果填充模式不符合这些要求,则返回 <code>KM_ERROR_INCOMPATIBLE_PADDING_MODE</code>。</p>
+<p>如果分块模式是 <code>BlockMode::CBC</code>、<code>BlockMode::CTR</code> 或 <code>BlockMode::GCM</code>,则需要初始化矢量或随机数。
+在大多数情况下,调用程序都不应提供 IV 或随机数。在这种情况下,Keymaster 实现会生成一个随机 IV 或随机数,并通过 <code>outParams</code> 中的 <a href="/security/keystore/tags#nonce">Tag::NONCE</a> 将其返回。
+CBC 和 CTR IV 均为 16 个字节。GCM 随机数为 12 个字节。如果密钥授权包含 <a href="/security/keystore/tags#caller_nonce">Tag::CALLER_NONCE</a>,那么调用程序可以通过 <code>inParams</code> 中的 <a href="/security/keystore/tags#nonce">Tag::NONCE</a> 提供 IV/随机数。如果在 <a href="/security/keystore/tags#caller_nonce">Tag::CALLER_NONCE</a> 未获得授权时提供了随机数,则返回 <code>ErrorCode::CALLER_NONCE_PROHIBITED</code>。如果在 <a href="/security/keystore/tags#caller_nonce">Tag::CALLER_NONCE</a> 获得了授权的情况下未提供随机数,则生成一个随机 IV/随机数。</p>
 
-<p>如果分块模式是 <code>KM_MODE_CBC</code>、<code>KM_MODE_CTR</code> 或 <code>KM_MODE_GCM</code>,则需要初始化矢量或随机数。在大多数情况下,调用程序都不应提供 IV 或随机数,而 Keymaster 实现必须要生成一个随机 IV 或随机数,并通过 <code>out_params</code> 中的 <a href="#km_tag_nonce">KM_TAG_NONCE</a> 将其返回。CBC IV 和 CTR IV 均为 16 个字节。GCM 随机数为 12 个字节。如果密钥授权包含 <a href="#km_tag_caller_nonce">KM_TAG_CALLER_NONCE</a>,那么调用程序可以通过 <code>in_params</code> 中的 <a href="#km_tag_nonce">KM_TAG_NONCE</a> 提供 IV/随机数。如果在 <a href="#km_tag_caller_nonce">KM_TAG_CALLER_NONCE</a> 未获得授权时提供了随机数,则返回 <code>KM_ERROR_CALLER_NONCE_PROHIBITED</code>。如果在 <a href="#km_tag_caller_nonce">KM_TAG_CALLER_NONCE</a> 获得了授权的情况下未提供随机数,则生成一个随机 IV/随机数。</p>
+<h4 id="begin_hmac_keys">HMAC 密钥</h4>
 
-<h4 id="hmac_keys">HMAC 密钥</h4>
+<p>执行 HMAC 密钥操作时,会在 <code>inParams</code> 中指定 <code>Tag::MAC_LENGTH</code>。
+指定的值必须是 8 的倍数,并且不大于摘要长度,也不小于密钥授权中 <code>Tag::MIN_MAC_LENGTH</code> 的值。如果 MAC 长度大于摘要长度或不是 8 的倍数,则返回 <code>ErrorCode::UNSUPPORTED_MAC_LENGTH</code>。如果 MAC 长度小于密钥最小长度,则返回 <code>ErrorCode::INVALID_MAC_LENGTH</code>。</p>
 
-<p>执行 HMAC 密钥操作时,必须要在 <code>in_params</code> 中指定 <code>KM_TAG_MAC_LENGTH</code>。指定的值必须是 8 的倍数,并且不得大于摘要长度,也不得小于密钥授权中 <code>KM_TAG_MIN_MAC_LENGTH</code> 的值。如果 MAC 长度大于摘要长度或不是 8 的倍数,则返回 <code>KM_ERROR_UNSUPPORTED_MAC_LENGTH</code>。如果 MAC 长度小于密钥最小长度,则返回 <code>KM_ERROR_INVALID_MAC_LENGTH</code>。</p>
+<h3 id="update">更新</h3>
 
-<h3 id="update">update</h3>
+<p><strong>版本</strong>:1、2、3</p>
 
-<p>用于提供要在通过 <a href="#begin">begin</a> 开始且正在进行的操作中处理的数据。操作是通过 <code>operation_handle</code> 参数指定的。</p>
+<p>用于提供要在通过 <a href="#begin">begin</a> 开始且正在进行的操作中处理的数据。
+操作是通过 <code>operationHandle</code> 参数指定的。</p>
 
-<p>为了更灵活地处理缓冲区,此方法的实现可以选择不消耗完收到的数据。调用程序负责执行循环操作,以便在后续调用中馈送其余数据。必须要在 <code>input_consumed</code> 参数中返回所消耗的输入数据量。实现必须始终消耗至少一个字节,除非相应操作无法再接受更多字节;如果收到了零个以上的字节,但消耗了零字节,调用程序会将此视为错误并中止相应操作。</p>
+<p>为了更灵活地处理缓冲区,此方法的实现可以选择不消耗完收到的数据。调用程序负责执行循环操作,以便在后续调用中馈送其余数据。在 <code>inputConsumed</code> 参数中返回所消耗的输入数据量。
+实现始终消耗至少一个字节,除非相应操作无法再接受更多字节;如果收到了零个以上的字节,但消耗了零字节,调用程序会将此视为错误并中止相应操作。</p>
 
-<p>实现还可以选择返回多少数据(作为 update 的结果)。这仅与加密和解密操作有关,因为在调用 <a href="#finish">finish</a> 之前,签名和验证操作不会返回任何数据。建议尽早返回数据,而不是缓冲数据。</p>
+<p>实现还可以选择返回多少数据(作为 update 的结果)。这仅与加密和解密操作有关,因为在调用 <a href="#finish">finish</a> 之前,签名和验证操作不会返回任何数据。
+尽早返回数据,而不是缓冲数据。</p>
 
 <h4 id="error_handling">错误处理</h4>
 
-<p>如果此方法返回除 <code>KM_ERROR_OK</code> 之外的错误代码,那么相应操作将被中止,操作句柄也必须变为无效。如果以后再将该句柄与此方法、<a href="#finish">finish</a> 或 <a href="#abort">abort</a> 配合使用,都必须返回 <code>KM_ERROR_INVALID_OPERATION_HANDLE</code>。</p>
+<p>如果此方法返回除 <code>ErrorCode::OK</code> 之外的错误代码,那么相应操作会被中止,操作句柄也会变为无效。如果以后再将该句柄与此方法、<a href="#finish">finish</a> 或 <a href="#abort">abort</a> 配合使用,都会返回 <code>ErrorCode::INVALID_OPERATION_HANDLE</code>。</p>
 
-<h4 id="authorization_enforcement">密钥授权强制执行</h4>
+<h4 id="update_authorization_enforcement">密钥授权强制执行</h4>
 
-<p>密钥授权强制执行主要在 <a href="#begin">begin</a> 中进行。不过,密钥存在以下情况时例外:</p>
+<p>密钥授权强制执行主要在 <a href="#begin">begin</a> 中进行。
+不过,密钥存在以下情况时例外:</p>
 
 <ul>
-  <li>有一个或多个 <a href="#km_tag_user_secure_id">KM_TAG_USER_SECURE_ID</a>,并且</li><li>没有 <a href="#km_tag_auth_timeout">KM_TAG_AUTH_TIMEOUT</a>
-</li></ul>
+  <li>一个或多个 <a href="/security/keystore/tags#user_secure_id">Tag::USER_SECURE_IDs</a>,且</li>
+  <li>没有 <a href="/security/keystore/tags#auth_timeout">Tag::AUTH_TIMEOUT</a></li>
+</ul>
 
-<p>在这种情况下,密钥需要针对各项操作的授权,并且 update 方法必须要在 <code>in_params</code> 参数中收到 <a href="#km_tag_auth_token">KM_TAG_AUTH_TOKEN</a>。该令牌必须有效(HMAC 必须验证),必须包含匹配的安全用户 ID,必须与密钥的 <a href="#km_tag_mac_length">KM_TAG_USER_AUTH_TYPE</a> 匹配,并且必须包含质询字段中当前操作的操作句柄。如果不符合这些要求,则返回 <code>KM_ERROR_KEY_USER_NOT_AUTHENTICATED</code>。</p>
+<p>在这种情况下,密钥需要针对各项操作的授权,并且 update 方法会在 <code>inParams</code> 参数中收到 <a href="/security/keystore/tags#auth_token">Tag::AUTH_TOKEN</a>。HMAC 会验证该令牌有效且包含匹配的安全用户 ID,与密钥的 <a href="/security/keystore/tags#mac_length">Tag::USER_AUTH_TYPE</a> 匹配,并且包含质询字段中当前操作的操作句柄。如果不符合这些条件,则返回 <code>ErrorCode::KEY_USER_NOT_AUTHENTICATED</code>。</p>
 
-<p>调用程序必须要在每次调用 <a href="#update">update</a> 和 <a href="#finish">finish</a> 时提供身份验证令牌。实现只需对该令牌验证一次(如果它倾向于这么做)。</p>
+<p>调用程序会在每次调用 <a href="#update">update</a> 和 <a href="#finish">finish</a> 时提供身份验证令牌。实现只需对该令牌验证一次(如果它倾向于这么做)。</p>
 
-<h4 id="rsa_keys">RSA 密钥</h4>
+<h4 id="update_rsa_keys">RSA 密钥</h4>
 
-<p>对于使用 <code>KM_DIGEST_NONE</code> 的签名和验证操作,此方法必须要在单次 update 中接受要签署或验证的整个分块。此方法不能只消耗分块的一部分。不过,如果调用程序选择在多次 update 中提供数据,此方法仍必须要在多次 update 中接受相应数据。如果调用程序提供的要签署的数据多于可以消耗的数据(数据长度超出 RSA 密钥大小),则返回 <code>KM_ERROR_INVALID_INPUT_LENGTH</code>。</p>
+<p>对于使用 <code>Digest::NONE</code> 的签名和验证操作,此方法会在单次 update 中接受要签署或验证的整个分块。此方法不会只消耗分块的一部分。不过,如果调用程序选择在多次 update 中提供数据,此方法会接受相应数据。
+如果调用程序提供的要签署的数据多于可以消耗的数据(数据长度超出 RSA 密钥大小),则返回 <code>ErrorCode::INVALID_INPUT_LENGTH</code>。</p>
 
-<h4 id="ecdsa_keys">ECDSA 密钥</h4>
+<h4 id="update_ecdsa_keys">ECDSA 密钥</h4>
 
-<p>对于使用 <code>KM_DIGEST_NONE</code> 的签名和验证操作,此方法必须要在单次 update 中接受要签署或验证的整个分块。此方法不能只消耗分块的一部分。</p>
+<p>对于使用 <code>Digest::NONE</code> 的签名和验证操作,此方法会在单次 update 中接受要签署或验证的整个分块。此方法不会只消耗分块的一部分。</p>
 
-<p>不过,如果调用程序选择在多次 update 中提供数据,此方法仍必须要在多次 update 中接受相应数据。如果调用程序提供的要签署的数据多于可以消耗的数据,则应以静默方式截断这些数据。(这与处理在类似 RSA 操作中提供的超量数据不同,因为此方法与旧版客户端兼容。)</p>
+<p>不过,如果调用程序选择在多次 update 中提供数据,此方法会接受相应数据。如果调用程序提供的要签署的数据多于可以消耗的数据,则以静默方式截断这些数据。(这与处理在类似 RSA 操作中提供的超量数据不同,因为此方法与旧版客户端兼容。)</p>
 
-<h4 id="aes_keys">AES 密钥</h4>
+<h4 id="update_aes_keys">AES 密钥</h4>
 
-<p>AES GCM 模式支持通过 <code>in_params</code> 参数中的 <a href="#km_tag_associated_data">KM_TAG_ASSOCIATED_DATA</a> 标记提供的“相关身份验证数据”。可以在重复调用(如果数据太大而无法在单个分块中发送,那么重复调用非常重要)中提供相关数据,但必须始终先于要加密或解密的数据提供。update 调用可以同时接收相关数据以及要加密/解密的数据,但后续 update 中不得包含相关数据。如果调用程序已在某次调用 update 时提供了要加密/解密的数据,若再次向 update 调用提供相关数据,则返回 <code>KM_ERROR_INVALID_TAG</code>。</p>
+<p>AES GCM 模式支持通过 <code>inParams</code> 参数中的 <a href="/security/keystore/tags#associated_data">Tag::ASSOCIATED_DATA</a> 标记提供的“相关身份验证数据”。
+可以在重复调用(如果数据太大而无法在单个分块中发送,那么重复调用非常重要)中提供相关数据,但始终先于要加密或解密的数据提供。update 调用可以同时接收相关数据以及要加密/解密的数据,但后续 update 中不会包含相关数据。如果调用程序已在某次调用 update 时提供了要加密/解密的数据,若再次向 update 调用提供相关数据,则返回 <code>ErrorCode::INVALID_TAG</code>。</p>
 
-<p>对于 GCM 加密,此标记会通过 <a href="#finish">finish</a> 附加到密文中。在解密期间,向上一次 update 调用提供的数据的最后 <code>KM_TAG_MAC_LENGTH</code> 个字节就是此标记。由于 <a href="#update">update</a> 的指定调用无法得知自己是否为最后一次调用,因此它必须处理除标记长度之外的所有数据,并缓冲可能的标记数据以便在调用 <a href="#finish">finish</a> 期间进行处理。</p>
+<p>对于 GCM 加密,此标记会通过 <a href="#finish">finish</a> 附加到密文中。在解密期间,向上一次 update 调用提供的数据的最后 <code>Tag::MAC_LENGTH</code> 个字节就是此标记。由于 <a href="#update">update</a> 的指定调用无法得知自己是否为最后一次调用,因此它会处理除标记长度之外的所有数据,并缓冲调用 <a href="#finish">finish</a> 期间可能用到的标记数据。</p>
 
 <h3 id="finish">finish</h3>
 
+<p><strong>版本</strong>:1、2、3</p>
+
 <p>用于完成通过 <a href="#begin">begin</a> 开始且正在进行的操作,负责处理通过 <a href="#update">update</a> 提供的所有尚未处理的数据。</p>
 
-<p>此方法是操作期间调用的最后一个方法,因此必须返回所有处理后的数据。</p>
+<p>此方法是操作期间调用的最后一个方法,因此会返回所有处理后的数据。</p>
 
-<p>无论是成功完成还是返回错误,此方法都会结束相应操作,从而使收到的操作句柄无效。如果以后再将该句柄与此方法、<a href="#update">update</a> 或 <a href="#abort">abort</a> 配合使用,都必须返回 <code>KM_ERROR_INVALID_OPERATION_HANDLE</code>。</p>
+<p>无论是成功完成还是返回错误,此方法都会结束相应操作,从而使收到的操作句柄无效。如果以后再将该句柄与此方法、<a href="#update">update</a> 或 <a href="#abort">abort</a> 配合使用,都会返回 <code>ErrorCode::INVALID_OPERATION_HANDLE</code>。</p>
 
 <p>签名操作将返回签名作为输出。验证操作将接受 <code>signature</code> 参数中的签名,并且不会返回任何输出。</p>
 
-<h4 id="authorization_enforcement">密钥授权强制执行</h4>
+<h4 id="finish_authorization_enforcement">密钥授权强制执行</h4>
 
 <p>密钥授权强制执行主要在 <a href="#begin">begin</a> 中进行。不过,密钥存在以下情况时例外:</p>
 
 <ul>
-  <li>有一个或多个 <a href="#km_tag_user_secure_id">KM_TAG_USER_SECURE_ID</a>,并且</li><li>没有 <a href="#km_tag_auth_timeout">KM_TAG_AUTH_TIMEOUT</a>
-</li></ul>
+  <li>一个或多个 <a href="/security/keystore/tags#user_secure_id">Tag::USER_SECURE_IDs</a>,且</li>
+  <li>没有 <a href="/security/keystore/tags#auth_timeout">Tag::AUTH_TIMEOUT</a></li>
+</ul>
 
-<p>在这种情况下,密钥需要针对各项操作的授权,并且 update 方法必须要在 <code>in_params</code> 参数中收到 <a href="#km_tag_auth_token">KM_TAG_AUTH_TOKEN</a>。该令牌必须有效(HMAC 必须验证),必须包含匹配的安全用户 ID,必须与密钥的 <a href="#km_tag_mac_length">KM_TAG_USER_AUTH_TYPE</a> 匹配,并且必须包含质询字段中当前操作的操作句柄。如果不符合这些要求,则返回 <code>KM_ERROR_KEY_USER_NOT_AUTHENTICATED</code>。</p>
+<p>在这种情况下,密钥需要针对各项操作的授权,并且 update 方法会在 <code>inParams</code> 参数中收到 <a href="/security/keystore/tags#auth_token">Tag::AUTH_TOKEN</a>。HMAC 会验证该令牌有效且包含匹配的安全用户 ID,与密钥的 <a href="/security/keystore/tags#mac_length">Tag::USER_AUTH_TYPE</a> 匹配,并且包含质询字段中当前操作的操作句柄。如果不符合这些条件,则返回 <code>ErrorCode::KEY_USER_NOT_AUTHENTICATED</code>。</p>
 
-<p>调用程序必须要在每次调用 <a href="#update">update</a> 和 <a href="#finish">finish</a> 时提供身份验证令牌。实现只需对该令牌验证一次(如果它倾向于这么做)。</p>
+<p>调用程序会在每次调用 <a href="#update">update</a> 和 <a href="#finish">finish</a> 时提供身份验证令牌。实现只需对该令牌验证一次(如果它倾向于这么做)。</p>
 
-<h4 id="rsa_keys">RSA 密钥</h4>
+<h4 id="finish_rsa_keys">RSA 密钥</h4>
 
 <p>有一些附加要求,具体取决于填充模式:</p>
 
 <ul>
-  <li><strong>KM_PAD_NONE</strong>:对于非填充式签名和加密操作,如果收到的数据比密钥短,那么在签名/加密之前,必须要在数据左侧填充零来补齐。如果数据与密钥一样长度,但数值较大,则返回 <code>KM_ERROR_INVALID_ARGUMENT</code>。对于验证和解密操作,数据必须与密钥一样长。否则返回 <code>KM_ERROR_INVALID_INPUT_LENGTH.</code>
-  </li><li><strong>KM_PAD_RSA_PSS</strong>:对于 PSS 填充式签名操作,PSS 盐不得短于 20 个字节,并且必须是随机生成的。盐可以更长;参考实现使用的是长度最大的盐。调用 <a href="#begin">begin</a> 时在 <code>input_params</code> 中使用 <a href="#km_tag_digest">KM_TAG_DIGEST</a> 指定的摘要将用作 PSS 摘要算法,而 SHA1 将用作 MGF1 摘要算法。
-  </li><li><strong>KM_PAD_RSA_OAEP</strong>:调用 <a href="#begin">begin</a> 时在 <code>input_params</code> 中使用 <a href="#km_tag_digest">KM_TAG_DIGEST</a> 指定的摘要将用作 OAEP 摘要算法,而 SHA1 将用作 MGF1 摘要算法。
-</li></ul>
+  <li><code>PaddingMode::NONE</code>:对于非填充式签名和加密操作,如果收到的数据比密钥短,那么在签名/加密之前,在数据左侧填充零来补齐。如果数据与密钥一样长度,但数值较大,则返回 <code>ErrorCode::INVALID_ARGUMENT</code>。对于验证和解密操作,数据必须与密钥一样长。否则返回 <code>ErrorCode::INVALID_INPUT_LENGTH.</code></li>
+  <li><code>PaddingMode::RSA_PSS</code>:对于 PSS 填充式签名操作,PSS 盐不得短于 20 个字节,并且是随机生成的。
+  盐可以更长;参考实现使用的是长度最大的盐。
+  调用 <a href="#begin">begin</a> 时在 <code>inputParams</code> 中使用 <a href="/security/keystore/tags#digest">Tag::DIGEST</a> 指定的摘要会用作 PSS 摘要算法,而 SHA1 会用作 MGF1 摘要算法。</li>
+  <li><code>PaddingMode::RSA_OAEP</code>:调用 <a href="#begin">begin</a> 时在 <code>inputParams</code> 中使用 <a href="/security/keystore/tags#digest">Tag::DIGEST</a> 指定的摘要会用作 OAEP 摘要算法,而 SHA1 会用作 MGF1 摘要算法。</li>
+</ul>
 
-<h4 id="ecdsa_keys">ECDSA 密钥</h4>
+<h4 id="finish_ecdsa_keys">ECDSA 密钥</h4>
 
 <p>如果为非填充式签名或验证操作提供的数据太长,则要将其截断。</p>
 
-<h4 id="aes_keys">AES 密钥</h4>
+<h4 id="finish_aes_keys">AES 密钥</h4>
 
-<p>有一些附加要求,具体取决于分块模式:</p>
+<p>有一些附加条件,具体取决于分块模式:</p>
 
 <ul>
-  <li><strong>KM_MODE_ECB</strong> 或 <strong>KM_MODE_CBC</strong>:如果填充模式是 <code>KM_PAD_NONE</code>,并且数据长度不是 AES 分块大小的倍数,则返回 <code>KM_ERROR_INVALID_INPUT_LENGTH</code>。如果填充模式是 <code>KM_PAD_PKCS7</code>,则按照 PKCS#7 规范填充数据。请注意,PKCS#7 要求,如果数据长度是分块长度的倍数,则必须要添加一个额外的填充分块。
-  </li><li><strong>KM_MODE_GCM</strong>:在加密期间,处理所有明文之后,会计算此标记(<a href="#km_tag_mac_length">KM_TAG_MAC_LENGTH</a> 个字节)并将其附加到返回的密文。在解密期间,会将最后 <a href="#km_tag_mac_length">KM_TAG_MAC_LENGTH</a> 个字节作为标记处理。如果标记验证失败,则返回 <code>KM_ERROR_VERIFICATION_FAILED</code>。</li></ul>
+  <li><code>BlockMode::ECB</code> 或 <code>BlockMode::CBC</code>:如果填充模式是 <code>PaddingMode::NONE</code>,并且数据长度不是 AES 分块大小的倍数,则返回 <code>ErrorCode::INVALID_INPUT_LENGTH</code>。如果填充模式是 <code>PaddingMode::PKCS7</code>,则按照 PKCS#7 规范填充数据。
+  请注意,PKCS#7 建议,如果数据长度是分块长度的倍数,则添加一个额外的填充分块。</li>
+  <li><code>BlockMode::GCM</code>:在加密期间,处理所有明文之后,会计算此标记(<a href="/security/keystore/tags#mac_length">Tag::MAC_LENGTH</a> 个字节)并将其附加到返回的密文。在解密期间,会将最后 <a href="/security/keystore/tags#mac_length">Tag::MAC_LENGTH</a> 个字节作为标记处理。如果标记验证失败,则返回 <code>ErrorCode::VERIFICATION_FAILED</code>。</li>
+</ul>
 
 <h3 id="abort">abort</h3>
 
-<p>用于中止正在进行的操作。在调用 abort 之后,如果后续再将收到的操作句柄与 <a href="#update">update</a>、<a href="#finish">finish</a> 或 <a href="#abort">abort</a> 配合使用,则返回 <code>KM_ERROR_INVALID_OPERATION_HANDLE</code>。</p>
+<p><strong>版本</strong>:1、2、3</p>
+
+<p>用于中止正在进行的操作。在调用 abort 之后,如果后续再将收到的操作句柄与 <a href="#update">update</a>、<a href="#finish">finish</a> 或 <a href="#abort">abort</a> 配合使用,则返回 <code>ErrorCode::INVALID_OPERATION_HANDLE</code>。</p>
+
+<h3 id="get_supported_algorithms">get_supported_algorithms</h3>
+
+<p><strong>版本</strong>:1</p>
+
+<p>用于返回一个列表,其中包含 Keymaster 硬件实现支持的算法。如果是软件实现,则返回一个空列表;如果是混合实现,则返回一个仅包含硬件支持的算法的列表。</p>
+
+<p>Keymaster 1 实现支持 RSA、EC、AES 和 HMAC。</p>
+
+<h3 id="get_supported_block_modes">get_supported_block_modes</h3>
+
+<p><strong>版本</strong>:1</p>
+
+<p>用于返回一个列表,其中包含对于指定的算法和目的,Keymaster 硬件实现支持的 AES 分块模式。</p>
+
+<p>对于不是分块加密算法的 RSA、EC 和 HMAC,无论是任何有效目的,此方法都会返回一个空列表。如果目的无效,则应导致此方法返回 <code>ErrorCode::INVALID_PURPOSE</code>。</p>
+
+<p>Keymaster 1 实现支持使用 ECB、CBC、CTR 和 GCM 进行 AES 加密和解密。</p>
+
+<h3 id="get_supported_padding_modes">get_supported_padding_modes</h3>
+
+<p><strong>版本</strong>:1</p>
+
+<p>用于返回一个列表,其中包含对于指定的算法和目的,Keymaster 硬件实现支持的填充模式。</p>
+
+<p>HMAC 和 EC 并没有填充这一概念,因此针对所有有效目的,此方法都会返回一个空列表。如果目的无效,则应导致此方法返回 <code>ErrorCode::INVALID_PURPOSE</code>。</p>
+
+<p>对于 RSA,Keymaster 1 实现支持:</p>
+
+<ul>
+  <li>非填充式加密、解密、签名和验证。对于非填充式加密和签名,如果消息比公开模数短,实现必须要在消息左侧填充零来补齐。对于非填充式解密和验证,输入长度必须与公开模数的大小一致。</li>
+  <li>PKCS#1 v1.5 加密和签名填充模式</li>
+  <li>盐最小长度为 20 的 PSS</li>
+  <li>OAEP</li>
+</ul>
+
+<p>对于采用 ECB 和 CBC 模式的 AES 算法,Keymaster 1 实现支持无填充和 PKCS#7 填充。CTR 和 GCM 模式仅支持无填充。</p>
+
+<h3 id="get_supported_digests">get_supported_digests</h3>
+
+<p><strong>版本</strong>:1</p>
+
+<p>用于返回一个列表,其中包含对于指定的算法和目的,Keymaster 硬件实现支持的摘要模式。</p>
+
+<p>任何 AES 模式都不支持摘要,也不需要摘要,因此无论是任何有效目的,此方法都会返回一个空列表。</p>
+
+<p>Keymaster 1 实现可以只实现一部分已定义的摘要。实现会提供 SHA-256,且可以提供 MD5、SHA1、SHA-224、SHA-256、SHA384 和 SHA512(完整的已定义摘要集)。</p>
+
+<h3 id="get_supported_import_formats">get_supported_import_formats</h3>
+
+<p><strong>版本</strong>:1</p>
+
+<p>用于返回一个列表,其中包含指定算法的 Keymaster 硬件实现支持的导入格式。</p>
+
+<p>Keymaster 1 实现支持 PKCS#8 格式(无密码保护),以便导入 RSA 密钥对和 EC 密钥对,并且支持以原始格式导入 AES 密钥材料和 HMAC 密钥材料。</p>
+
+<h3 id="get_supported_export_formats">get_supported_export_formats</h3>
+
+<p><strong>版本</strong>:1</p>
+
+<p>用于返回一个列表,其中包含指定算法的 Keymaster 硬件实现支持的导出格式。</p>
+
+<p>Keymaster1 实现支持 X.509 格式,以便导出 RSA 公钥和 EC 公钥。不支持导出私钥或非对称密钥。</p>
+
+<h2 id="historical-functions">历史函数</h2>
+
+<h3 id="km0">Keymaster 0</h3>
+<p>
+以下函数属于最初的 Keymaster 0 定义。它们出现在 Keymaster 1 结构 keymaster1_device_t 中。不过,Keymaster 1.0 中并没有实现这些函数,且它们的函数指针设为了 NULL。
+</p>
+<ul>
+<li><code>generate_keypair</code></li>
+<li><code>import_keypair</code></li>
+<li><code>get_keypair_public</code></li>
+<li><code>delete_keypair</code></li>
+<li><code>delete_all</code></li>
+<li><code>sign_data</code></li>
+<li><code>Verify_data</code></li>
+</ul>
+
+<h3 id="km1">Keymaster 1</h3>
+<p>以下函数属于 Keymaster 1 定义,但在 Keymaster 2 中已被移除,一同被移除的还有上述 Keymaster 0 函数。
+</p>
+<ul>
+  <li><code>get_supported_algorithms</code></li>
+  <li><code>get_supported_block_modes</code></li>
+  <li><code>get_supported_padding_modes</code></li>
+  <li><code>get_supported_digests</code></li>
+  <li><code> get_supported_import_formats</code></li>
+  <li><code>get_supported_export_formats</code></li>
+</ul>
+
+<h3 id="km2">Keymaster 2</h3>
+<p>以下函数属于 Keymaster 2 定义,但在 Keymaster 3 中已被移除,一同被移除的还有上述 Keymaster 1 函数。
+</p>
+<ul>
+  <li><code>configure</code></li>
+</ul>
 
 </body></html>
\ No newline at end of file
diff --git a/zh-cn/security/keystore/index.html b/zh-cn/security/keystore/index.html
index a586cbe..11f00ad 100644
--- a/zh-cn/security/keystore/index.html
+++ b/zh-cn/security/keystore/index.html
@@ -22,27 +22,46 @@
 
 <p>借助系统芯片 (SoC) 中提供的可信执行环境,Android 设备可以为 Android 操作系统、平台服务甚至是第三方应用提供由硬件支持的强大安全服务。寻求 Android 专用扩展程序的开发者应访问 <a href="https://developer.android.com/reference/android/security/keystore/KeyGenParameterSpec.html">android.security.keystore</a>。</p>
 
-<p>Keystore 在 Android 6.0 中得到了<a href="features.html">显著增强</a>,不仅增加了对称加密基元(AES 和 HMAC),还增加了针对由硬件支持的密钥的访问控制系统。访问控制在密钥生成期间指定,并会在密钥的整个生命周期内被强制执行。可以将密钥限定为仅在用户通过身份验证后才可使用,并且只能用于指定的目的或只有在具有指定的加密参数时才可使用。如需更多信息,请参阅<a href="implementer-ref.html">面向实现人员的参考资料</a>。</p>
-
 <p>在 Android 6.0 之前的版本中,Android 已有一个非常简单的由硬件支持的加密服务 API(由 0.2 和 0.3 版的 Keymaster 硬件抽象层 (HAL) 提供)。该 Keystore 能够提供数字签名和验证操作,以及不对称签名密钥对的生成和导入操作。该 API 在许多设备上都已实现,但有许多安全目标无法只通过一个签名 API 来轻松达成。Android 6.0 中的 Keystore 在该 Keystore API 的基础上进行了扩展,能够提供更广泛的功能。</p>
 
+<p>在 Android 6.0 中,Keystore 不仅增加了<a href="/security/keystore/features.html">对称加密基元</a>(AES 和 HMAC),还增加了针对由硬件支持的密钥的访问控制系统。访问控制在密钥生成期间指定,并会在密钥的整个生命周期内被强制执行。可以将密钥限定为仅在用户通过身份验证后才可使用,并且只能用于指定的目的或只有在具有指定的加密参数时才可使用。要了解详情,请参阅<a href="/security/keystore/tags">授权标记</a>和<a href="/security/keystore/implementer-ref">函数</a>页面。</p>
+
+<p>
+在 Android 7.0 中,Keymaster 2 增加了对密钥认证和版本绑定的支持。
+<a href="/security/keystore/attestation">密钥认证</a>提供公钥证书,这些证书中包含密钥及其访问控制的详细描述,以使密钥存在于安全硬件中并使其配置可以远程验证。
+</p>
+<p>
+<a href="/security/keystore/version-binding">版本绑定</a>将密钥绑定至操作系统和补丁程序级别版本。这样可确保在旧版系统或 TEE 软件中发现漏洞的攻击者无法将设备回滚到易受攻击的版本,也无法使用在较新版本中创建的密钥。此外,在已经升级到更新的版本或补丁程序级别的设备上使用指定版本和补丁程序级别的密钥时,需要先升级该密钥才能使用,因为该密钥的旧版本已失效。当设备升级时,密钥会随着设备一起“升级”,但是将设备恢复到任何一个旧版本都会导致密钥无法使用。
+</p>
+
+<p>
+在 Android 8.0 中,Keymaster 3 从旧式 C 结构硬件抽象层 (HAL) 转换到了从采用新的硬件接口定义语言 (HIDL) 的定义生成的 C++ HAL 接口。在此变更过程中,很多参数类型发生了变化,尽管这些类型和方法与旧的类型和 HAL 结构体方法具有一对一的对应关系。要了解详情,请参阅<a href="/security/keystore/implementer-ref">函数</a>页面。
+</p>
+<p>
+除了此接口修订之外,Android 8.0 还扩展了 Keymaster 2 的认证功能,以支持 <a href="/security/keystore/attestation#id-attestation">ID 认证</a>。
+ID 认证提供了一种受限且可选的机制来严格认证硬件标识符,例如设备序列号、产品名称和手机 ID (IMEI/MEID)。要实现此附加功能,需更改 ASN.1 认证架构以添加 ID 认证。Keymaster 实现需要通过某种安全方式来检索相关的数据项,还需要定义一种安全永久地停用该功能的机制。
+</p>
+
 <h2 id="goals">目标</h2>
 
-<p>Android 6.0 Keystore API 和底层 Keymaster 1.0 HAL 的目标是提供一套基本的但足以满足需求的加密基元,以便使用访问受控且由硬件支持的密钥实现相关协议。</p>
+<p>Android Keystore API 和底层 Keymaster HAL 提供了一套基本的但足以满足需求的加密基元,以便使用访问受控且由硬件支持的密钥实现相关协议。</p>
 
 <p>除了扩大加密基元的范围外,Android 6.0 中的 Keystore 还增加了以下内容:</p>
 
 <ul>
-  <li>一种使用控制方案:用于限制密钥的使用,并降低因滥用密钥而导致安全性受损的风险</li><li>一种访问控制方案:用于限定只有指定的用户和客户端能够使用相应密钥,并且只能在定义的时间范围内使用</li></ul>
+  <li>一个使用控制方案,用于限制密钥的使用,并降低因滥用密钥而损害安全性的风险</li>
+  <li>一个访问控制方案,用于限定只有指定的用户和客户端能够使用相应密钥,并且只能在规定的时间范围内使用</li>
+</ul>
 
 <h2 id="architecture">架构</h2>
 
-<p>Keymaster HAL 是由原始设备制造商 (OEM) 提供的动态加载库,Keystore 服务使用它来提供由硬件支持的加密服务。HAL 实现不得在用户空间(甚至是内核空间)中执行任何敏感操作。敏感操作会被委派给通过某个内核接口连接的安全处理器。最终的架构如下所示:</p>
+<p>Keymaster HAL 是由原始设备制造商 (OEM) 提供的动态加载库,Keystore 服务使用它来提供由硬件支持的加密服务。为了确保安全性,HAL 实现不会在用户空间(甚至是内核空间)中执行任何敏感操作。敏感操作会被分配给通过某个内核接口连接的安全处理器。
+最终的架构如下所示:</p>
 
 <div align="center">
-  <img src="../images/access-to-keymaster.png" alt="访问 Keymaster" id="figure1"/>
+  <img src="/security/images/access-to-keymaster.png" alt="访问 Keymaster" id="figure1"/>
 </div>
-<p class="img-caption"><strong>图 1. </strong> 访问 Keymaster</p>
+<p class="img-caption"><strong>图 1.</strong> 访问 Keymaster</p>
 
 <p>在 Android 设备中,Keymaster HAL 的“客户端”包含多个层(例如,应用、框架、Keystore 守护进程),但在本文档中可以将其忽略。这意味着,所介绍的 Keymaster HAL API 为底层 API,供平台内部组件使用,不面向应用开发者提供。<a href="https://developer.android.com/reference/android/security/keystore/KeyGenParameterSpec.html">Android 开发者网站</a>对更高层 API(第 23 层 API)进行了介绍。</p>
 
@@ -50,6 +69,69 @@
 
 <h2 id="compatibility_with_previous_versions">与之前版本的兼容性</h2>
 
-<p>Keymaster v1.0 HAL 与之前发布的 HAL(例如,Keymaster v0.2 和 v0.3)完全不兼容。为了在采用旧版 Keymaster HAL 且搭载的 Android 版本低于 Marshmallow 的设备上实现互用性,Keystore 提供了一个可通过调用现有硬件库来实现 1.0 HAL 的适配器。但结果是,它并不能提供 1.0 HAL 中的全部功能。尤其是,它仅支持 RSA 和 ECDSA 算法,而且所有密钥授权强制执行都将由该适配器在非安全域中进行。</p>
+<p>Keymaster 1 HAL 与之前发布的 HAL(例如,Keymaster 0.2 和 0.3)完全不兼容。为了在运行 Android 5.0 及更早版本(采用旧版 Keymaster HAL)的设备上实现互用性,Keystore 提供了一个可通过调用现有硬件库来实现 Keymaster 1 HAL 的适配器,但最终仍不能提供 Keymaster 1 HAL 中的全部功能。特别是,它仅支持 RSA 和 ECDSA 算法,而且所有密钥授权强制执行都由该适配器在非安全域中进行。</p>
+
+<p>
+Keymaster 2 通过移除 <code>get_supported_*</code> 方法并允许 <code>finish()</code> 方法接受输入,进一步简化了 HAL 接口。在可一次性获得所有输入的情况下,这样可以减少到 TEE 的往返次数,并简化 AEAD 解密的实现过程。
+</p>
+
+<p>
+在 Android 8.0 中,Keymaster 3 从旧式 C 结构 HAL 转换到了从采用新的硬件接口定义语言 (HIDL) 的定义生成的 C++ HAL 接口。通过对生成的 <code>IKeymasterDevice</code> 类进行子类化并实现纯虚方法创建了新式 HAL 实现。在此变更过程中,很多参数类型发生了变化,尽管这些类型和方法与旧的类型和 HAL 结构体方法具有一对一的对应关系。</p>
+
+<h3 id="hidl-overview">HIDL 概览</h3>
+
+<p>
+硬件接口定义语言 (HIDL) 提供了一种独立于实现语言的机制来指定硬件接口。HIDL 工具目前支持生成 C++ 和 Java 接口。大多数可信执行环境 (TEE) 实现人员应该都会发现 C++ 工具更加方便,因此本文档仅讨论 C++ 表示法。
+</p>
+<p>
+HIDL 接口由一组方法组成,表示如下:
+</p>
+<pre class="devsite-click-to-copy">
+	methodName(<var>INPUT ARGUMENTS</var>) generates (<var>RESULT ARGUMENTS</var>);
+</pre>
+<p>
+有很多不同的预定义类型,而 HAL 可以定义新的枚举和结构类型。要详细了解 HIDL,请参阅<a href="/reference/">“参考”部分</a>。
+</p>
+<p>
+下面显示了 Keymaster 3 <code>IKeymasterDevice.hal</code> 中的一个示例方法:
+</p>
+
+<pre class="devsite-click-to-copy">generateKey(vec&lt;KeyParameter&gt; keyParams)
+        generates(ErrorCode error, vec&lt;uint8_t&gt; keyBlob,
+                  KeyCharacteristics keyCharacteristics);</pre>
+<p>
+这相当于 keymaster2 HAL 中的以下方法:
+</p>
+
+<pre class="devsite-click-to-copy">keymaster_error_t (*generate_key)(
+        const struct keymaster2_device* dev,
+        const keymaster_key_param_set_t* params,
+        keymaster_key_blob_t* key_blob,
+        keymaster_key_characteristics_t* characteristics);
+</pre>
+<p>
+在 HIDL 版本中,由于 <code>dev</code> 参数采用隐式形式,因此已被移除。<code>params</code> 参数不再是包含引用了一组 <code>key_parameter_t</code> 对象的指针的结构体,而是包含 <code>KeyParameter</code> 对象的 <code>vec</code>(矢量)。返回值在“<code>generates</code>”子句中列出,其中包含密钥 Blob 的 <code>uint8_t</code> 值的矢量。
+</p>
+<p>
+由 HIDL 编译器生成的 C++ 虚拟方法为:
+</p>
+
+<pre class="devsite-click-to-copy">
+Return&lt;void&gt; generateKey(const hidl_vec&lt;KeyParameter&gt;&amp; keyParams,
+                         generateKey_cb _hidl_cb) override;
+</pre>
+<p>
+其中,<code>generate_cb</code> 是一个函数指针,定义如下:
+</p>
+
+<pre class="devsite-click-to-copy">std::function&lt;void(ErrorCode error, const hidl_vec&lt;uint8_t&gt;&amp; keyBlob,
+                   const KeyCharacteristics&amp; keyCharacteristics)&gt;
+</pre>
+<p>
+也就是说,<code>generate_cb</code> 是一个将接受 generate 子句中列出的返回值的函数。HAL 实现类会覆盖此 <code>generateKey</code> 方法并调用 <code>generate_cb</code> 函数指针,以将操作结果返回给调用程序。请注意,该函数指针调用是<strong>同步的</strong>。调用程序调用 <code>generateKey</code>,同时 <code>generateKey</code> 调用所提供的函数指针,该指针在完成执行操作后将控件返回到 <code>generateKey</code> 实现,而后该实现又返回到调用程序。
+</p>
+<p>
+要查看详细示例,请参阅 <code>hardware/interfaces/keymaster/3.0/default/KeymasterDevice.cpp</code> 中的默认实现。
+该默认实现可向后兼容采用旧式 keymaster0、keymaster1 或 keymaster2 HAL 的设备。</p>
 
 </body></html>
\ No newline at end of file
diff --git a/zh-cn/security/keystore/tags.html b/zh-cn/security/keystore/tags.html
index c6e5807..f96024c 100644
--- a/zh-cn/security/keystore/tags.html
+++ b/zh-cn/security/keystore/tags.html
@@ -206,14 +206,14 @@
 
 <p>用于指定授权在多长时间内使用相应密钥(以秒数计,从通过身份验证开始算起)。如果 <a href="#user_secure_id">Tag::USER_SECURE_ID</a> 存在而此标记不存在,那么每次使用相应密钥时都需要通过身份验证(要详细了解各项操作的身份验证流程,请参阅 <a href="/security/keystore/implementer-ref#begin">begin</a>)。</p>
 
-<p>此标记的值是一个 32 位的整数,用于指定可在多长时间内使用相应密钥(以秒数计,从使用通过 <a href="#mac_length">Tag::USER_AUTH_TYPE</a> 指定的身份验证方法对通过 <a href="#user_secure_id">Tag::USER_SECURE_ID</a> 指定的用户成功进行身份验证开始算起)。</p>
+<p>此标记的值是一个 32 位的整数,用于指定可在多长时间内使用相应密钥(以秒数计,从使用通过 <a href="#user_secure_id">Tag::USER_AUTH_TYPE</a> 指定的身份验证方法对通过 <a href="#mac_length">Tag::USER_SECURE_ID</a> 指定的用户成功进行身份验证开始算起)。</p>
 
 <h2 id="auth_token">Tag::AUTH_TOKEN</h2>
 
 <p><strong>版本</strong>:1、2、3</p>
 <p><strong>是否可重复使用</strong>?否</p>
 
-<p>用于向 <a href="/security/keystore/implementer-ref#begin">begin</a>、<a href="/security/keystore/implementer-ref#update">update</a> 或 <a href="/security/keystore/implementer-ref#finish">finish</a> 提供<a href="/security/keystore/authentication/#authentication_token_format">身份验证令牌</a>,以便向要求用户通过身份验证的密钥操作(密钥带有 <a href="#user_secure_id">Tag::USER_SECURE_ID</a>)证明相应用户已通过身份验证。</p>
+<p>用于向 <a href="/security/keystore/authentication/#authentication_token_format">begin</a>、<a href="/security/keystore/implementer-ref#begin">update</a> 或 <a href="/security/keystore/implementer-ref#update">finish</a> 提供<a href="/security/keystore/implementer-ref#finish">身份验证令牌</a>,以便向要求用户通过身份验证的密钥操作(密钥带有 <a href="#user_secure_id">Tag::USER_SECURE_ID</a>)证明相应用户已通过身份验证。</p>
 
 <p>此标记的值是一个包含 <code>hw_auth_token_t</code> 结构的 Blob。</p>
 
@@ -275,7 +275,7 @@
 } keymaster_block_mode_t;
 </pre>
 
-<p>此标记可重复使用,对于 AES 密钥操作,要在 <a href="/security/keystore/implementer-ref#begin">begin</a> 的 <code>additionalParams</code> 参数中指定模式。
+<p>此标记可重复使用;对于 AES 密钥操作,要在 <a href="/security/keystore/implementer-ref#begin">begin</a> 的 <code>additionalParams</code> 参数中指定模式。
 如果指定的模式不在相应密钥的关联模式之列,操作会失败并显示 <code>ErrorCode::INCOMPATIBLE_BLOCK_MODE</code>。</p>
 
 <h2 id="bootloader_only">Tag::BOOTLOADER_ONLY</h2>
@@ -455,7 +455,7 @@
 <p><strong>版本</strong>:1、2、3</p>
 <p><strong>是否可重复使用</strong>?否</p>
 
-<p>用于提供或返回进行 AES GCM、CBC 或 CTR 加密/解密时使用的随机数或初始化矢量 (IV)。在加密和解密操作期间,可以将此标记提供给 <a href="/security/keystore/implementer-ref#begin">begin</a>。仅当相应密钥带有 <a href="#caller_nonce">Tag::CALLER_NONCE</a> 时,才将此标记提供给 <a href="/security/keystore/implementer-ref#begin">begin</a> 。如果调用程序未提供此标记,Keymaster 将随机生成适当的随机数或 IV 并通过 begin 将其返回。</p>
+<p>用于提供或返回进行 AES GCM、CBC 或 CTR 加密/解密时使用的随机数或初始化矢量 (IV)。在加密和解密操作期间,可以将此标记提供给 <a href="/security/keystore/implementer-ref#begin">begin</a>。仅当相应密钥带有 <a href="/security/keystore/implementer-ref#begin">Tag::CALLER_NONCE</a> 时,才将此标记提供给 <a href="#caller_nonce">begin</a>。如果调用程序未提供此标记,Keymaster 将随机生成适当的随机数或 IV 并通过 begin 将其返回。</p>
 
 <p>此标记的值是一个 Blob(任意长度的字节数数组)。所允许的长度取决于模式:GCM 随机数的长度为 12 个字节;CBC IV 和 CTR IV 的长度为 16 个字节。</p>
 
@@ -694,7 +694,7 @@
 
 <p>用于指定只能在某个安全的用户身份验证状态下使用相应密钥。此标记与 <a href="#no_auth_required">Tag::NO_AUTH_REQUIRED</a> 互斥。</p>
 
-<p>此标记的值是一个 64 位的整数,用于指定在通过 <a href="#auth_token">Tag::AUTH_TOKEN</a> 向 <a href="/security/keystore/implementer-ref#begin">begin</a> 提供的身份验证令牌中必须存在哪个身份验证政策状态值,身份验证程序才会授权使用相应密钥。如果在调用 <a href="/security/keystore/implementer-ref#begin">begin</a> 时未提供身份验证令牌,或提供的身份验证令牌没有匹配的政策状态值,但所用密钥带有此标记,则该调用失败。</p>
+<p>此标记的值是一个 64 位的整数,用于指定在通过 <a href="/security/keystore/implementer-ref#begin">Tag::AUTH_TOKEN</a> 向 <a href="#auth_token">begin</a> 提供的身份验证令牌中必须存在哪个身份验证政策状态值,身份验证程序才会授权使用相应密钥。如果在调用 <a href="/security/keystore/implementer-ref#begin">begin</a> 时未提供身份验证令牌,或提供的身份验证令牌没有匹配的政策状态值,但所用密钥带有此标记,则该调用失败。</p>
 
 <p>此标记可重复使用。如果提供的值中有任何一个与身份验证令牌中的任何政策状态值一致,身份验证程序即会授权使用相应密钥。否则,操作会失败并显示 <code>ErrorCode::KEY_USER_NOT_AUTHENTICATED</code>。</p>
 
diff --git a/zh-cn/security/keystore/version-binding.html b/zh-cn/security/keystore/version-binding.html
new file mode 100644
index 0000000..f3c10ab
--- /dev/null
+++ b/zh-cn/security/keystore/version-binding.html
@@ -0,0 +1,106 @@
+<html devsite><head>
+    <title>版本绑定</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          //www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>
+在 Keymaster 1 中,所有 Keymaster 密钥都以加密形式绑定至设备的信任根或已验证的启动密钥。<em></em>在 Keymaster 2 及更高版本中,所有密钥也绑定至系统映像的操作系统和补丁程序级别。这样可确保在旧版系统或 TEE 软件中发现漏洞的攻击者无法将设备回滚到易受攻击的版本,也无法使用在较新版本中创建的密钥。此外,在已经升级到更新的版本或补丁程序级别的设备上使用指定版本和补丁程序级别的密钥时,需要先升级该密钥才能使用,因为该密钥的旧版本已失效。这样一来,当设备升级时,密钥会随着设备一起“升级”,但是将设备恢复到任何一个旧版本都会导致密钥无法使用。
+</p>
+
+<h2 id="hal-changes">HAL 变更</h2>
+<p>
+为了支持版本绑定和版本认证,Android 7.1 添加了 <code>Tag::OS_VERSION</code> 和 <code>Tag::OS_PATCHLEVEL</code> 标记以及 <code>configure</code> 和 <code>upgradeKey</code> 方法。版本标记由 Keymaster 2 及更高版本的实现自动添加到所有新生成的(或更新后的)密钥。此外,如果尝试使用的密钥所具有的操作系统版本或补丁程序级别与当前系统的操作系统版本或补丁程序级别不匹配,操作会被拒绝并显示 <code>ErrorCode::KEY_REQUIRES_UPGRADE</code>。
+</p>
+<p>
+<code>Tag::OS_VERSION</code> 是一个 <code>UINT</code>,它以 MMmmss 格式表示 Android 系统版本的主要、次要和子次要部分,其中 MM 表示主要版本,mm 表示次要版本,ss 表示子次要版本。例如,6.1.2 将表示为 060102。
+</p>
+<p>
+<code>Tag::OS_PATCHLEVEL</code> 是一个 <code>UINT</code>,它以 YYYYMM 格式表示系统上次更新的年份和月份,其中 YYYY 表示四位数的年份,MM 表示两位数的月份。例如,2016 年 3 月将表示为 201603。
+</p>
+
+<h3 id="upgrade_key">UpgradeKey</h3>
+<p>
+为了使密钥升级到系统映像的新操作系统版本和补丁程序级别,Android 7.1 向 HAL 添加了 <code>upgradeKey</code> 方法:
+</p>
+
+<p><strong>Keymaster 3</strong></p>
+<pre class="devsite-click-to-copy">
+    upgradeKey(vec<uint8_t> keyBlobToUpgrade, vec<keyparameter> upgradeParams)
+        generates(ErrorCode error, vec<uint8_t> upgradedKeyBlob);</uint8_t></keyparameter></uint8_t></pre>
+<p><strong>Keymaster 2</strong></p>
+<pre class="devsite-click-to-copy">
+keymaster_error_t (*upgrade_key)(const struct keymaster2_device* dev,
+    const keymaster_key_blob_t* key_to_upgrade,
+    const keymaster_key_param_set_t* upgrade_params,
+    keymaster_key_blob_t* upgraded_key);
+</pre>
+
+<ul>
+  <li><code>dev</code> 是设备结构</li>
+  <li><code>keyBlobToUpgrade</code> 是需要进行升级的密钥</li>
+  <li><code>upgradeParams</code> 是升级密钥所需的参数。这将包括 <code>Tag::APPLICATION_ID</code> 和 <code>Tag::APPLICATION_DATA</code>,如果在密钥生成期间提供了这两个参数,则它们是解密密钥 Blob 所必需的参数。</li>
+  <li><code>upgradedKeyBlob</code> 是输出参数,用于返回新的密钥 Blob。</li>
+</ul>
+
+<p>
+如果使用无法解析或无效的密钥 Blob 调用 <code>upgradeKey</code>,则会返回 <code>ErrorCode::INVALID_KEY_BLOB</code>。如果使用补丁程序级别高于当前系统的补丁程序级别的密钥调用该方法,则会返回 <code>ErrorCode::INVALID_ARGUMENT</code>。如果使用操作系统版本高于当前系统的操作系统版本(当前系统的操作系统版本为非零值)的密钥调用该方法,则会返回 <code>ErrorCode::INVALID_ARGUMENT</code>。允许操作系统版本从非零升级为零。如果在与安全域进行通信时发生错误,该方法会返回相应的错误值(例如 <code>ErrorCode::SECURE_HW_ACCESS_DENIED</code>、<code>ErrorCode::SECURE_HW_BUSY</code> 等)。在其他情况下,它会返回 <code>ErrorCode::OK</code> 并在 <code>upgradedKeyBlob</code> 中返回一个新的密钥 Blob。
+</p>
+<p>
+<code>keyBlobToUpgrade</code> 在调用 <code>upgradeKey</code> 后仍然有效,理论上,如果设备降级,还可以再次使用。但在实际操作中,Keystore 通常在调用 <code>upgradeKey</code> 后很快就会对 <code>keyBlobToUpgrade</code> Blob 调用 <code>deleteKey</code>。如果 <code>keyBlobToUpgrade</code> 具有 <code>Tag::ROLLBACK_RESISTANT</code> 标记,则 <code>upgradedKeyBlob</code> 也应该包含该标记(并且应该可抗回滚)。
+</p>
+
+<h2 id="secure-configuration">安全配置</h2>
+
+<p class="note">
+<strong>注意</strong>:Keymaster 3 移除了 Keymaster 2 方法 <code>configure</code>。之前通过 <code>configure</code> 提供给 Keymaster HAL 的信息已在系统属性文件中提供,制造商实现会在启动期间读取这些文件。
+</p>
+<p>
+要实现版本绑定,Keymaster TA 需要以一种方式安全接收当前的操作系统版本和补丁程序级别(版本信息),并确保所接收的信息与运行系统的相关信息严格匹配。
+</p>
+<p>
+为了确保将版本信息安全传递到 TA,启动映像标头中添加了 <code><a href="https://android.googlesource.com/platform/system/core/+/master/mkbootimg/bootimg.h#48">os_version
+field</a></code>。启动映像构建脚本会自动填充此字段。原始设备制造商 (OEM) 和 Keymaster TA 实现人员需要相互协作来修改设备引导加载程序,以便从启动映像中提取版本信息,并在非安全系统启动之前将其传递到 TA。这样可确保攻击者无法干扰向 TA 提供版本信息。
+</p>
+
+<p>
+此外,您还需要确保系统映像与启动映像具有相同的版本信息。为此,Keymaster HAL 中添加了 configure 方法:
+</p>
+
+<pre class="devsite-click-to-copy">keymaster_error_t (*configure)(const struct keymaster2_device* dev,
+	const keymaster_key_param_set_t* params);
+</pre>
+
+<p>
+<code>params</code> 参数包含 <code>Tag::OS_VERSION</code> 和 <code>Tag::OS_PATCHLEVEL</code>。Keymaster2 客户端会在打开 HAL 之后、调用任何其他方法之前调用此方法。如果在调用 configure 之前调用了任何其他方法,TA 会返回 <code>ErrorCode::KEYMASTER_NOT_CONFIGURED</code>。
+</p>
+
+<p>
+在设备启动后首次调用 <code>configure</code> 时,该方法应该验证所提供的版本信息是否与引导加载程序提供的版本信息一致。如果版本信息不一致,则 <code>configure</code> 会返回 <code>ErrorCode::INVALID_ARGUMENT</code>,所有其他 Keymaster 方法会继续返回 <code>ErrorCode::KEYMASTER_NOT_CONFIGURED</code>。如果信息一致,<code>configure</code> 会返回 <code>ErrorCode::OK</code>,其他 Keymaster 方法开始正常运行。
+</p>
+
+<p>
+对 <code>configure</code> 的后续调用与首次调用返回的值相同,而且不会更改 Keymaster 的状态。请注意,此过程会要求所有 OTA 同时更新系统映像和启动映像;为了使版本信息保持同步,不能单独更新这两种映像。
+</p>
+
+<p>
+由于将调用 <code>configure</code> 的系统的内容需要经过验证,攻击者可利用这一短暂的窗口期机会来破坏系统映像,并强制其提供与启动映像一致的版本信息,但这并不是系统的真实版本信息。不过,对启动映像的验证、对系统映像内容的 dm-verity 验证以及在系统启动早期调用 <code>configure</code> 这三项相结合,会让攻击者很难利用这个机会。
+</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/security/overview/acknowledgements.html b/zh-cn/security/overview/acknowledgements.html
index bac45db..fd01332 100644
--- a/zh-cn/security/overview/acknowledgements.html
+++ b/zh-cn/security/overview/acknowledgements.html
@@ -60,8 +60,8 @@
    <td>CVE-2017-0650</td>
   </tr>
   <tr>
-   <td>阿里巴巴移动安全团队的 Baozeng Ding (<a href="https://twitter.com/sploving">@sploving</a>)</td>
-   <td>CVE-2017-0463、CVE-2017-0506、CVE-2017-0711、CVE-2017-0741、CVE-2017-0742、CVE-2017-0751、CVE-2017-0796、CVE-2017-0798、CVE-2017-0800、CVE-2017-0827、CVE-2017-0843、CVE-2017-0864、CVE-2017-11000、CVE-2017-11059</td>
+   <td>阿里巴巴移动安全团队的 Baozeng Ding (<a href="https://twitter.com/sploving1">@sploving1</a>)</td>
+   <td>CVE-2017-0463、CVE-2017-0506、CVE-2017-0711、CVE-2017-0741、CVE-2017-0742、CVE-2017-0751、CVE-2017-0796、CVE-2017-0798、CVE-2017-0800、CVE-2017-0827、CVE-2017-0843、CVE-2017-0864、CVE-2017-9703、CVE-2017-9708、CVE-2017-11000、CVE-2017-11059、CVE-2017-13170</td>
   </tr>
   <tr>
    <td>Ben Actis (<a href="https://twitter.com/ben_ra">@Ben_RA</a>)</td>
@@ -73,11 +73,11 @@
   </tr>
   <tr>
    <td>Android 安全团队的 Billy Lau</td>
-   <td>CVE-2017-0335、CVE-2017-0336、CVE-2017-0338、CVE-2017-0460、CVE-2017-8263、CVE-2017-9682</td>
+   <td>CVE-2017-0335、CVE-2017-0336、CVE-2017-0338、CVE-2017-0460、CVE-2017-8263、CVE-2017-9682、CVE-2017-13162</td>
   </tr>
   <tr>
    <td><a href="http://www.ms509.com/">MS509Team</a> 的 Bo Liu</td>
-   <td>CVE-2017-0490、CVE-2017-0601、CVE-2017-0639、CVE-2017-0645、CVE-2017-0784</td>
+   <td>CVE-2017-0490、CVE-2017-0601、CVE-2017-0639、CVE-2017-0645、CVE-2017-0784、CVE-2017-11042</td>
   </tr>
   <tr>
    <td>阿里巴巴移动安全团队的 Chao Yang</td>
@@ -85,11 +85,11 @@
   </tr>
   <tr>
    <td>百度安全实验室的包沉浮</td>
-   <td>CVE-2016-8417、CVE-2016-10236、CVE-2017-0728、CVE-2017-0738、CVE-2017-0766、CVE-2017-0794、CVE-2017-9681、CVE-2017-9684、CVE-2017-9693、CVE-2017-9694、CVE-2017-9715、CVE-2017-9717、CVE-2017-9720、CVE-2017-11001、CVE-2017-10999, CVE-2017-11057、CVE-2017-11060、CVE-2017-11061、CVE-2017-11064</td>
+   <td>CVE-2016-8417、CVE-2016-10236、CVE-2017-0728、CVE-2017-0738、CVE-2017-0766、CVE-2017-0794、CVE-2017-9681、CVE-2017-9684、CVE-2017-9693、CVE-2017-9694、CVE-2017-9715、CVE-2017-9717、CVE-2017-9720、CVE-2017-11001、CVE-2017-10999、CVE-2017-11057、CVE-2017-11060、CVE-2017-11061、CVE-2017-11064、CVE-2017-11089、CVE-2017-11090</td>
   </tr>
   <tr>
    <td>阿里巴巴移动安全团队的 Chengming Yang</td>
-   <td>CVE-2016-10280、CVE-2016-10281、CVE-2017-0463、CVE-2017-0506、CVE-2017-0565、CVE-2017-0711、CVE-2017-0741、CVE-2017-0742、CVE-2017-0751、CVE-2017-0796、CVE-2017-0798、CVE-2017-0800、CVE-2017-0827、CVE-2017-0843、CVE-2017-0864、CVE-2017-9696、CVE-2017-9702、CVE-2017-11000、CVE-2017-11059、CVE-2017-11089、CVE-2017-11090</td>
+   <td>CVE-2016-10280、CVE-2016-10281、CVE-2017-0463、CVE-2017-0506、CVE-2017-0565、CVE-2017-0711、CVE-2017-0741、CVE-2017-0742、CVE-2017-0751、CVE-2017-0796、CVE-2017-0798、CVE-2017-0800、CVE-2017-0827、CVE-2017-0843、CVE-2017-0864、CVE-2017-9696、CVE-2017-9702、CVE-2017-9708、CVE-2017-11000、CVE-2017-11059、CVE-2017-13170</td>
   </tr>
   <tr>
    <td>佐治亚理工学院的 Chenxiong Qian</td>
@@ -97,7 +97,7 @@
   </tr>
   <tr>
    <td><a href="https://c0reteam.org/">C0RE 团队</a>的 <a href="mailto:zc1991@mail.ustc.edu.cn">Chi Zhang</a></td>
-   <td>CVE-2017-0666、CVE-2017-0681、CVE-2017-0684、CVE-2017-0765、CVE-2017-0836、CVE-2017-0857</td>
+   <td>CVE-2017-0666、CVE-2017-0681、CVE-2017-0684、CVE-2017-0765、CVE-2017-0836、CVE-2017-0857、CVE-2017-0880、CVE-2017-13166</td>
   </tr>
   <tr>
    <td><a href="http://c0reteam.org/">C0RE 团队</a>的 Chiachih Wu (<a href="https://twitter.com/chiachih_wu">@chiachih_wu</a>)</td>
@@ -116,6 +116,10 @@
    <td>CVE-2017-0807</td>
   </tr>
   <tr>
+   <td>华为公司的 Cusas</td>
+   <td>CVE-2017-0870</td>
+  </tr>
+  <tr>
    <td><a href="http://c0reteam.org/">C0RE 团队</a>的 <a href="mailto:shaodacheng2016@gmail.com">Dacheng Shao</a></td>
    <td>CVE-2017-0483、CVE-2017-0739、CVE-2017-0769、CVE-2017-0801</td>
   </tr>
@@ -125,7 +129,7 @@
   </tr>
   <tr>
    <td>Copperhead Security 的 Daniel Micay</td>
-   <td>CVE-2017-0397、CVE-2017-0405、CVE-2017-0410、CVE-2017-0826</td>
+   <td>CVE-2017-0397、CVE-2017-0405、CVE-2017-0410、CVE-2017-0826、CVE-2017-13160</td>
   </tr>
   <tr>
    <td>腾讯玄武实验室的 Daxing Guo (<a href="https://twitter.com/freener0">@freener0</a>)</td>
@@ -145,7 +149,7 @@
   </tr>
   <tr>
    <td><a href="http://www.linkedin.com/in/dzima">Dzmitry Lukyanenka</a></td>
-   <td>CVE-2017-0414、CVE-2017-0703、CVE-2017-0808</td>
+   <td>CVE-2017-0414、CVE-2017-0703、CVE-2017-0808、CVE-2017-13157、CVE-2017-13158、CVE-2017-13159</td>
   </tr>
   <tr>
    <td>趋势科技的徐健</td>
@@ -161,7 +165,11 @@
   </tr>
   <tr>
    <td><a href="http://www.ms509.com/">MS509Team</a> 的 En He (<a href="http://twitter.com/heeeeen4x">@heeeeen4x</a>)</td>
-   <td>CVE-2017-0394、CVE-2017-0490、CVE-2017-0601、CVE-2017-0639、CVE-2017-0645、CVE-2017-0784</td>
+   <td>CVE-2017-0394、CVE-2017-0490、CVE-2017-0601、CVE-2017-0639、CVE-2017-0645、CVE-2017-0784、CVE-2017-11042</td>
+  </tr>
+  <tr>
+    <td><a href="https://www.guardsquare.com/en">GuardSquare</a> 的 Eric Lafortune</td>
+    <td>CVE-2017-13156</td>
   </tr>
   <tr>
    <td><a href="https://twrp.me/">Team Win Recovery Project</a> 的 Ethan Yonker</td>
@@ -181,7 +189,7 @@
   </tr>
   <tr>
    <td>奇虎 360 科技有限公司 IceSword 实验室的 Gengjia Chen (<a href="https://twitter.com/chengjia4574">@chengjia4574</a>)</td>
-   <td>CVE-2016-8464、CVE-2016-10285、CVE-2016-10288、CVE-2016-10290、CVE-2016-10294、CVE-2016-10295、CVE-2016-10296、CVE-2017-0329、CVE-2017-0332、CVE-2017-0432、CVE-2017-0434、CVE-2017-0446、CVE-2017-0447、CVE-2017-0500、CVE-2017-0501、CVE-2017-0502、CVE-2017-0503、CVE-2017-0509、CVE-2017-0524、CVE-2017-0529、CVE-2017-0536、CVE-2017-0566、CVE-2017-0573、CVE-2017-0581、CVE-2017-0616、CVE-2017-0617、CVE-2017-0624、CVE-2017-0649、CVE-2017-0744、CVE-2017-6426、CVE-2017-8243、CVE-2017-8266、CVE-2017-8270、CVE-2017-9691、CVE-2017-10997</td>
+   <td>CVE-2016-8464、CVE-2016-10285、CVE-2016-10288、CVE-2016-10290、CVE-2016-10294、CVE-2016-10295、CVE-2016-10296、CVE-2017-0329、CVE-2017-0332、CVE-2017-0432、CVE-2017-0434、CVE-2017-0446、CVE-2017-0447、CVE-2017-0500、CVE-2017-0501、CVE-2017-0502、CVE-2017-0503、CVE-2017-0509、CVE-2017-0524、CVE-2017-0529、CVE-2017-0536、CVE-2017-0566、CVE-2017-0573、CVE-2017-0581、CVE-2017-0616、CVE-2017-0617、CVE-2017-0624、CVE-2017-0649、CVE-2017-0744、CVE-2017-6426、CVE-2017-8243、CVE-2017-8244、CVE-2017-8266、CVE-2017-8270、CVE-2017-9691、CVE-2017-10997</td>
   </tr>
   <tr>
    <td>腾讯电脑管家的郑文选 (<a href="https://twitter.com/virtualseekers">@VirtualSeekers</a>)</td>
@@ -197,7 +205,7 @@
   </tr>
   <tr>
    <td><a href="http://www.360.com/">奇虎 360 科技有限公司</a> Alpha 团队的龚广 (<a href="http://twitter.com/oldfresher">@oldfresher</a>)</td>
-   <td>CVE-2016-8415、CVE-2016-8419、CVE-2016-8420、CVE-2016-8421、CVE-2016-8454、CVE-2016-8455、CVE-2016-8456、CVE-2016-8457、CVE-2016-8465、CVE-2016-8476、CVE-2016-10283、CVE-2017-0387、CVE-2017-0415、CVE-2017-0437、CVE-2017-0438、CVE-2017-0439、CVE-2017-0441、CVE-2017-0442、CVE-2017-0443、CVE-2017-0453、CVE-2017-0454、CVE-2017-0461、CVE-2017-0464、CVE-2017-0547、CVE-2017-0567、CVE-2017-0574、CVE-2017-0575、CVE-2017-0577、CVE-2017-0580、CVE-2017-0584、CVE-2017-0692、CVE-2017-0694、CVE-2017-0727、CVE-2017-0748、CVE-2017-0771、CVE-2017-0774、CVE-2017-0775、CVE-2017-0786、CVE-2017-0787、CVE-2017-0788、CVE-2017-0789、CVE-2017-0790、CVE-2017-0791、CVE-2017-0792、CVE-2017-0825、CVE-2017-6424</td>
+   <td>CVE-2016-8415、CVE-2016-8419、CVE-2016-8420、CVE-2016-8421、CVE-2016-8454、CVE-2016-8455、CVE-2016-8456、CVE-2016-8457、CVE-2016-8465、CVE-2016-8476、CVE-2016-10283、CVE-2017-0387、CVE-2017-0415、CVE-2017-0437、CVE-2017-0438、CVE-2017-0439、CVE-2017-0441、CVE-2017-0442、CVE-2017-0443、CVE-2017-0453、CVE-2017-0454、CVE-2017-0461、CVE-2017-0464、CVE-2017-0547、CVE-2017-0567、CVE-2017-0574、CVE-2017-0575、CVE-2017-0577、CVE-2017-0580、CVE-2017-0584、CVE-2017-0692、CVE-2017-0694、CVE-2017-0727、CVE-2017-0748、CVE-2017-0771、CVE-2017-0774、CVE-2017-0775、CVE-2017-0786、CVE-2017-0787、CVE-2017-0788、CVE-2017-0789、CVE-2017-0790、CVE-2017-0791、CVE-2017-0792、CVE-2017-0825、CVE-2017-6424、CVE-2017-14904</td>
   </tr>
   <tr>
    <td>新加坡理工大学 (SIT) 的 Guangdong Bai</td>
@@ -208,8 +216,12 @@
    <td>CVE-2017-0593</td>
   </tr>
   <tr>
+   <td>King Team 的 Guo Haoran</td>
+   <td>CVE-2017-13172</td>
+  </tr>
+  <tr>
    <td><a href="http://c0reteam.org/">C0RE 团队</a>的 <a href="mailto:arnow117@gmail.com">Hanxiang Wen</a></td>
-   <td>CVE-2017-0400、CVE-2017-0418、CVE-2017-0479、CVE-2017-0480、CVE-2017-0665、CVE-2017-0681、CVE-2017-0737</td>
+   <td>CVE-2017-0400、CVE-2017-0418、CVE-2017-0479、CVE-2017-0480、CVE-2017-0665、CVE-2017-0681、CVE-2017-0737、CVE-2017-14904</td>
   </tr>
   <tr>
    <td>奇虎 360 科技有限公司 Alpha 团队的 Hao Chen</td>
@@ -224,8 +236,8 @@
    <td>CVE-2017-0481</td>
   </tr>
   <tr>
-   <td><a href="http://c0reteam.org/">C0RE 团队</a>的 <a href="mailto:hlhan@bupt.edu.cn">Hongli Han</a></td>
-   <td>CVE-2017-0384、CVE-2017-0385、CVE-2017-0731、CVE-2017-0739</td>
+   <td><a href="http://c0reteam.org/">C0RE 团队</a>的 <a href="mailto:hlhan@bupt.edu.cn">Hongli Han</a> (<a href="https://twitter.com/HexB1n">@HexB1n</a>)</td>
+   <td>CVE-2017-0384、CVE-2017-0385、CVE-2017-0731、CVE-2017-0739、CVE-2017-13154、CVE-2017-6276</td>
   </tr>
   <tr>
    <td>奇虎 360 Qex 团队的 hujianfei</td>
@@ -256,12 +268,16 @@
    <td>CVE-2017-0422</td>
   </tr>
   <tr>
+   <td>King Team 的 Jeremy Huang (<a href="https://twitter.com/bittorrent3389">@bittorrent3389</a>)</td>
+   <td>CVE-2017-13172</td>
+  </tr>
+  <tr>
    <td><a href="https://skyeye.360safe.com/">奇虎 360 天眼实验室</a>的 Jianjun Dai (<a href="https://twitter.com/Jioun_dai">@Jioun_dai</a>)</td>
    <td>CVE-2017-0478、CVE-2017-0541、CVE-2017-0559</td>
   </tr>
   <tr>
    <td>奇虎 360 IceSword 实验室的 Jianqiang Zhao (<a href="https://twitter.com/jianqiangzhao">@jianqiangzhao</a>)</td>
-   <td>CVE-2016-5346、CVE-2016-8416、CVE-2016-8475、CVE-2016-8478、CVE-2017-0445、CVE-2017-0458、CVE-2017-0459、CVE-2017-0518、CVE-2017-0519、CVE-2017-0533、CVE-2017-0534、CVE-2017-0862、CVE-2017-6425、CVE-2017-8233、CVE-2017-8261、CVE-2017-8268</td>
+   <td>CVE-2016-5346、CVE-2016-8416、CVE-2016-8475、CVE-2016-8478、CVE-2017-0445、CVE-2017-0458、CVE-2017-0459、CVE-2017-0518、CVE-2017-0519、CVE-2017-0533、CVE-2017-0534、CVE-2017-0862、CVE-2017-6425、CVE-2017-8233、CVE-2017-8261、CVE-2017-8268、CVE-2017-9718、CVE-2017-1000380</td>
   </tr>
   <tr>
    <td>Census Consulting Inc. 的 Joey Brand</td>
@@ -300,6 +316,10 @@
    <td>CVE-2017-0647</td>
   </tr>
   <tr>
+   <td><a href="https://microlab.red/">Lorenzo Nicolodi</a></td>
+   <td>CVE-2017-13165</td>
+  </tr>
+  <tr>
    <td><a href="http://c0reteam.org/">C0RE 团队</a>的 <a href="mailto:zlbzlb815@163.com">Lubo Zhang</a></td>
    <td>CVE-2016-8479、CVE-2017-0564、CVE-2017-7368</td>
   </tr>
@@ -329,7 +349,7 @@
   </tr>
   <tr>
    <td><a href="https://github.com/michalbednarski">Michal Bednarski</a></td>
-   <td>CVE-2017-0598、CVE-2017-0806</td>
+   <td>CVE-2017-0598、CVE-2017-0806、CVE-2017-0871</td>
   </tr>
   <tr>
    <td>特斯拉汽车公司产品安全团队的 Mike Anderson (<a href="https://twitter.com/manderbot">@manderbot</a>)</td>
@@ -337,7 +357,7 @@
   </tr>
   <tr>
    <td><a href="http://c0reteam.org/">C0RE 团队</a>的 Mingjian Zhou (<a href="https://twitter.com/Mingjian_Zhou">@Mingjian_Zhou</a>)</td>
-   <td>CVE-2017-0383、CVE-2017-0417、CVE-2017-0418、CVE-2017-0425、CVE-2017-0450、CVE-2017-0479、CVE-2017-0480、CVE-2017-0483、CVE-2017-0665、CVE-2017-0666、CVE-2017-0681、CVE-2017-0684、CVE-2017-0731、CVE-2017-0737、CVE-2017-0739、CVE-2017-0765、CVE-2017-0768、CVE-2017-0769、CVE-2017-0779、CVE-2017-0801、CVE-2017-0812、CVE-2017-0815、CVE-2017-0816、CVE-2017-0836、CVE-2017-0840、CVE-2017-0857</td>
+   <td>CVE-2017-0383、CVE-2017-0417、CVE-2017-0418、CVE-2017-0425、CVE-2017-0450、CVE-2017-0479、CVE-2017-0480、CVE-2017-0483、CVE-2017-0665、CVE-2017-0666、CVE-2017-0681、CVE-2017-0684、CVE-2017-0731、CVE-2017-0737、CVE-2017-0739、CVE-2017-0765、CVE-2017-0768、CVE-2017-0769、CVE-2017-0779、CVE-2017-0801、CVE-2017-0812、CVE-2017-0815、CVE-2017-0816、CVE-2017-0836、CVE-2017-0837、CVE-2017-0840、CVE-2017-0857、CVE-2017-8080、CVE-2017-6276、CVE-2017-13152、CVE-2017-13154、CVE-2017-13166、CVE-2017-13169、CVE-2017-14904</td>
   </tr>
   <tr>
    <td>Monk Avel</td>
@@ -401,11 +421,11 @@
   </tr>
   <tr>
    <td>奇虎 360 科技有限公司 IceSword 实验室的 <a href="http://weibo.com/jfpan">pjf</a></td>
-   <td>CVE-2016-5346、CVE-2016-8416、CVE-2016-8464、CVE-2016-8475、CVE-2016-8478、CVE-2016-10285、CVE-2016-10288、CVE-2016-10290、CVE-2016-10294、CVE-2016-10295、CVE-2016-10296、CVE-2017-0329、CVE-2017-0332、CVE-2017-0432、CVE-2017-0434、CVE-2017-0445、CVE-2017-0446、CVE-2017-0447、CVE-2017-0458、CVE-2017-0459、CVE-2017-0500、CVE-2017-0501、CVE-2017-0502、CVE-2017-0503、CVE-2017-0509、CVE-2017-0518、CVE-2017-0519、CVE-2017-0524、CVE-2017-0529、CVE-2017-0533、CVE-2017-0534、CVE-2017-0536、CVE-2017-0566、CVE-2017-0573、CVE-2017-0581、CVE-2017-0616、CVE-2017-0617、CVE-2017-0624、CVE-2017-0649、CVE-2017-0744、CVE-2017-0862、CVE-2017-6425、CVE-2017-6426、CVE-2017-8233、CVE-2017-8243、CVE-2017-8261、CVE-2017-8266、CVE-2017-8268、CVE-2017-8270、CVE-2017-9691、CVE-2017-10997</td>
+   <td>CVE-2016-5346、CVE-2016-8416、CVE-2016-8464、CVE-2016-8475、CVE-2016-8478、CVE-2016-10285、CVE-2016-10288、CVE-2016-10290、CVE-2016-10294、CVE-2016-10295、CVE-2016-10296、CVE-2017-0329、CVE-2017-0332、CVE-2017-0432、CVE-2017-0434、CVE-2017-0445、CVE-2017-0446、CVE-2017-0447、CVE-2017-0458、CVE-2017-0459、CVE-2017-0500、CVE-2017-0501、CVE-2017-0502、CVE-2017-0503、CVE-2017-0509、CVE-2017-0518、CVE-2017-0519、CVE-2017-0524、CVE-2017-0529、CVE-2017-0533、CVE-2017-0534、CVE-2017-0536、CVE-2017-0566、CVE-2017-0573、CVE-2017-0581、CVE-2017-0616、CVE-2017-0617、CVE-2017-0624、CVE-2017-0649、CVE-2017-0744、CVE-2017-0862、CVE-2017-6425、CVE-2017-6426、CVE-2017-8233、CVE-2017-8243、CVE-2017-8244、CVE-2017-8261、CVE-2017-8266、CVE-2017-8268、CVE-2017-8270、CVE-2017-9691、CVE-2017-9718、CVE-2017-10997、CVE-2017-1000380</td>
   </tr>
   <tr>
    <td>腾讯科恩实验室的何淇丹 (<a href="https://twitter.com/flanker_hqd">@flanker_hqd</a>)</td>
-   <td>CVE-2017-0325、CVE-2017-0337、CVE-2017-0382、CVE-2017-0427、CVE-2017-0476、CVE-2017-0544、CVE-2017-0861、CVE-2017-0866</td>
+   <td>CVE-2017-0325、CVE-2017-0337、CVE-2017-0382、CVE-2017-0427、CVE-2017-0476、CVE-2017-0544、CVE-2017-0861、CVE-2017-0866、CVE-2017-13167、CVE-2017-15868</td>
   </tr>
   <tr>
    <td>奇虎 360 的 Qing Zhang</td>
@@ -421,7 +441,7 @@
   </tr>
   <tr>
    <td>HCL 科技公司 Aleph 研究团队的 Roee Hay (<a href="https://twitter.com/roeehay">@roeehay</a>)</td>
-   <td>CVE-2016-10277、CVE-2017-0563、CVE-2017-0582、CVE-2017-0648、CVE-2017-0829</td>
+   <td>CVE-2016-10277、CVE-2017-0563、CVE-2017-0582、CVE-2017-0648、CVE-2017-0829、CVE-2017-13174</td>
   </tr>
   <tr>
    <td>IBM X-Force 安全研究团队的 Roee Hay</td>
@@ -437,11 +457,11 @@
   </tr>
   <tr>
    <td>加州大学圣巴巴拉分校 Shellphish Grill 团队的 salls (<a href="https://twitter.com/chris_salls">@chris_salls</a>)</td>
-   <td>CVE-2017-0505</td>
+   <td>CVE-2017-0505、CVE-2017-13168</td>
   </tr>
   <tr>
    <td><a href="mailto:sbauer@plzdonthack.me">Scott Bauer</a> (<a href="https://twitter.com/ScottyBauer1">@ScottyBauer1</a>)</td>
-   <td>CVE-2016-10274、CVE-2017-0339、CVE-2017-0405、CVE-2017-0504、CVE-2017-0516、CVE-2017-0521、CVE-2017-0562、CVE-2017-0576、CVE-2017-0705、CVE-2017-8259、CVE-2017-8260、CVE-2017-9680、CVE-2017-11053</td>
+   <td>CVE-2016-10274、CVE-2017-0339、CVE-2017-0405、CVE-2017-0504、CVE-2017-0516、CVE-2017-0521、CVE-2017-0562、CVE-2017-0576、CVE-2017-0705、CVE-2017-8259、CVE-2017-8260、CVE-2017-9680、CVE-2017-11053、CVE-2017-13160</td>
   </tr>
   <tr>
    <td>Sean Beaupre (<a href="https://twitter.com/firewaterdevs">@firewaterdevs</a>)</td>
@@ -549,13 +569,17 @@
   </tr>
   <tr>
    <td>360 Marvel 团队的 Xingyuan Lin</td>
-   <td>CVE-2017-0627</td>
+   <td>CVE-2017-0627、CVE-2017-13163</td>
   </tr>
   <tr>
    <td><a href="http://c0reteam.org/">C0RE 团队</a>的 Xuxian Jiang</td>
    <td>CVE-2016-8425、CVE-2016-8426、CVE-2016-8430、CVE-2016-8431、CVE-2016-8432、CVE-2016-8449、CVE-2016-8435、CVE-2016-8479、CVE-2016-8480、CVE-2016-8481、CVE-2016-8482、CVE-2016-10291、CVE-2017-0326、CVE-2017-0333、CVE-2017-0383、CVE-2017-0384、CVE-2017-0385、CVE-2017-0398、CVE-2017-0400、CVE-2017-0401、CVE-2017-0402、CVE-2017-0417、CVE-2017-0418、CVE-2017-0425、CVE-2017-0428、CVE-2017-0429、CVE-2017-0435、CVE-2017-0436、CVE-2017-0444、CVE-2017-0448、CVE-2017-0450、CVE-2017-0479、CVE-2017-0480、CVE-2017-0483、CVE-2017-0526、CVE-2017-0527、CVE-2017-0651、CVE-2017-0665、CVE-2017-0666、CVE-2017-0681、CVE-2017-0684、CVE-2017-0709、CVE-2017-0731、CVE-2017-0737、CVE-2017-0739、CVE-2017-0765、CVE-2017-0768、CVE-2017-0769、CVE-2017-0779、CVE-2017-0801、CVE-2017-7368、CVE-2017-8264、CVE-2017-10661</td>
   </tr>
   <tr>
+   <td><a href="https://xtn-lab.com/">XTN</a></td>
+   <td>CVE-2017-13165</td>
+  </tr>
+  <tr>
    <td>华为公司 SCC Eagleye 团队的 Yan Zhou</td>
    <td>CVE-2017-9678</td>
   </tr>
@@ -569,11 +593,11 @@
   </tr>
   <tr>
    <td>奇虎 360 科技有限公司 Vulpecker 团队的 <a href="mailto:huahuaisadog@gmail.com">Yang Dai</a></td>
-   <td>CVE-2017-0795、CVE-2017-0799、CVE-2017-0804、CVE-2017-0803</td>
+   <td>CVE-2017-0795、CVE-2017-0799、CVE-2017-0804、CVE-2017-0803、CVE-2017-6262、CVE-2017-6263、CVE-2017-6280</td>
   </tr>
   <tr>
    <td>阿里巴巴移动安全团队的 Yang Song</td>
-   <td>CVE-2016-10280、CVE-2016-10281、CVE-2017-0463、CVE-2017-0506、CVE-2017-0565、CVE-2017-0711、CVE-2017-0741、CVE-2017-0742、CVE-2017-0751、CVE-2017-0796、CVE-2017-0798、CVE-2017-0800、CVE-2017-0827、CVE-2017-0842、CVE-2017-0843、CVE-2017-0864、CVE-2017-11000、CVE-2017-11059</td>
+   <td>CVE-2016-10280、CVE-2016-10281、CVE-2017-0463、CVE-2017-0506、CVE-2017-0565、CVE-2017-0711、CVE-2017-0741、CVE-2017-0742、CVE-2017-0751、CVE-2017-0796、CVE-2017-0798、CVE-2017-0800、CVE-2017-0827、CVE-2017-0842、CVE-2017-0843、CVE-2017-0864、CVE-2017-11000、CVE-2017-11059、CVE-2017-9703、CVE-2017-9708、CVE-2017-13170</td>
   </tr>
   <tr>
    <td>EURECOM 加州大学圣巴巴拉分校 Shellphish Grill 团队的 Yanick Fratantonio</td>
@@ -588,8 +612,12 @@
    <td>CVE-2016-8431、CVE-2016-8432、CVE-2016-8435、CVE-2016-8480</td>
   </tr>
   <tr>
+   <td>蚂蚁金服巴斯光年安全实验室的 Yaoguang Chen</td>
+   <td>CVE-2017-13171</td>
+  </tr>
+  <tr>
    <td>阿里巴巴的王勇 (<a href="https://twitter.com/ThomasKing2014">@ThomasKing2014</a>)</td>
-   <td>CVE-2017-0404、CVE-2017-0588、CVE-2017-0842</td>
+   <td>CVE-2017-0404、CVE-2017-0588、CVE-2017-0842、CVE-2017-13164、CVE-2017-9708、CVE-2017-13170</td>
   </tr>
   <tr>
    <td>奇虎 360 科技有限公司 IceSword 实验室的 Yonggang Guo (<a href="https://twitter.com/guoygang">@guoygang</a>)</td>
@@ -605,11 +633,11 @@
   </tr>
   <tr>
    <td>奇虎 360 科技有限公司 Vulpecker 团队的 Yu Pan</td>
-   <td>CVE-2016-10282、CVE-2017-0517、CVE-2017-0532、CVE-2017-0615、CVE-2017-0618、CVE-2017-0625、CVE-2017-0795、CVE-2017-0799、CVE-2017-0804、CVE-2017-0803</td>
+   <td>CVE-2016-10282、CVE-2017-0517、CVE-2017-0532、CVE-2017-0615、CVE-2017-0618、CVE-2017-0625、CVE-2017-0795、CVE-2017-0799、CVE-2017-0804、CVE-2017-0803、CVE-2017-6262、CVE-2017-6263、CVE-2017-6280</td>
   </tr>
   <tr>
    <td><a href="http://c0reteam.org/">C0RE 团队</a>的 <a href="mailto:computernik@gmail.com">Yuan-Tsung Lo</a></td>
-   <td>CVE-2016-8425、CVE-2016-8426、CVE-2016-8430、CVE-2016-8431、CVE-2016-8432、CVE-2016-8435、CVE-2016-8449、CVE-2016-8479、CVE-2016-8480、CVE-2016-8481、CVE-2016-8482、CVE-2016-10291、CVE-2017-0326、CVE-2017-0333、CVE-2017-0428、CVE-2017-0429、CVE-2017-0435、CVE-2017-0436、CVE-2017-0444、CVE-2017-0448、CVE-2017-0526、CVE-2017-0527、CVE-2017-6264、CVE-2017-6274、CVE-2017-6275、CVE-2017-0651、CVE-2017-0709、CVE-2017-0824、CVE-2017-7368、CVE-2017-8264、CVE-2017-10661</td>
+   <td>CVE-2016-8425、CVE-2016-8426、CVE-2016-8430、CVE-2016-8431、CVE-2016-8432、CVE-2016-8435、CVE-2016-8449、CVE-2016-8479、CVE-2016-8480、CVE-2016-8481、CVE-2016-8482、CVE-2016-10291、CVE-2017-0326、CVE-2017-0333、CVE-2017-0428、CVE-2017-0429、CVE-2017-0435、CVE-2017-0436、CVE-2017-0444、CVE-2017-0448、CVE-2017-0526、CVE-2017-0527、CVE-2017-6264、CVE-2017-6274、CVE-2017-6275、CVE-2017-0651、CVE-2017-0709、CVE-2017-0824、CVE-2017-7368、CVE-2017-8264、CVE-2017-10661、CVE-2017-14903</td>
   </tr>
   <tr>
    <td><a href="http://xlab.tencent.com/">腾讯玄武实验室</a>的 Yuebin Sun</td>
@@ -649,7 +677,7 @@
   </tr>
   <tr>
    <td>奇虎 360 科技有限公司成都安全响应中心的 <a href="https://weibo.com/ele7enxxh">Zinuo Han</a></td>
-   <td>CVE-2017-0475、CVE-2017-0497、CVE-2017-0548、CVE-2017-0678、CVE-2017-0691、CVE-2017-0700、CVE-2017-0714、CVE-2017-0718、CVE-2017-0719、CVE-2017-0720、CVE-2017-0722、CVE-2017-0725、CVE-2017-0745、CVE-2017-0760、CVE-2017-0761、CVE-2017-0764、CVE-2017-0776、CVE-2017-0777、CVE-2017-0778、CVE-2017-0813、CVE-2017-0814、CVE-2017-0820、CVE-2017-0823、CVE-2017-0850、CVE-2017-0858</td>
+   <td>CVE-2017-0475、CVE-2017-0497、CVE-2017-0548、CVE-2017-0678、CVE-2017-0691、CVE-2017-0700、CVE-2017-0714、CVE-2017-0718、CVE-2017-0719、CVE-2017-0720、CVE-2017-0722、CVE-2017-0725、CVE-2017-0745、CVE-2017-0760、CVE-2017-0761、CVE-2017-0764、CVE-2017-0776、CVE-2017-0777、CVE-2017-0778、CVE-2017-0813、CVE-2017-0814、CVE-2017-0820、CVE-2017-0823、CVE-2017-0850、CVE-2017-0858、CVE-2017-0879</td>
   </tr>
   <tr>
    <td>Google 的 Zubin Mithra</td>
@@ -657,6 +685,12 @@
   </tr>
 </tbody></table>
 
+<h4 id="2017-additional-contributions">其他贡献</h4>
+<p>此外,还要感谢以下人员对 Android 安全性做出的贡献:</p>
+ <ul>
+  <li>William Roberts (<a href="mailto:william.c.roberts@intel.com">william.c.roberts@intel.com</a>)</li>
+ </ul>
+
 <h2 id="2016">2016 年</h2>
 
 <div style="LINE-HEIGHT:25px;">
@@ -950,7 +984,7 @@
 
 <p>William Roberts (<a href="mailto:william.c.roberts@intel.com">william.c.roberts@intel.com</a>)</p>
 
-<p><a href="http://www.trendmicro.com">趋势科技</a><a href="http://blog.trendmicro.com/trendlabs-security-intelligence/category/mobile/">移动威胁响应团队</a>的<a href="http://weibo.com/wishlinux">吴潍浠</a> (<a href="https://twitter.com/wish_wu">@wish_wu</a>)</p>
+<p><a href="http://www.trendmicro.com">趋势科技</a>的<a href="http://blog.trendmicro.com/trendlabs-security-intelligence/category/mobile/">移动威胁响应团队</a>的<a href="http://weibo.com/wishlinux">吴潍浠</a> (<a href="https://twitter.com/wish_wu">@wish_wu</a>)</p>
 
 <p><a href="http://c0reteam.org">C0RE 团队</a>的 <a href="mailto:wisedd@gmail.com">Xiaodong Wang</a></p>
 
@@ -1055,7 +1089,7 @@
 
 <p>趋势科技的 Jack Tang (@jacktang310)</p>
 
-<p><a href="https://twitter.com/indiecom">德克萨斯州大学奥斯汀分校</a>的 jgor (<a href="http://security.utexas.edu/">@indiecom</a>)</p>
+<p><a href="http://security.utexas.edu/">德克萨斯州大学奥斯汀分校</a>的 jgor (<a href="https://twitter.com/indiecom">@indiecom</a>)</p>
 
 <p>阿根廷布宜诺斯艾利斯 Dr. Manuel Sadosky 基金会 Programa STIC 的 Joaquín Rinaudo (@xeroxnir)</p>
 
@@ -1138,9 +1172,7 @@
 
 <p><a href="http://www.search-lab.hu/">Search-Lab Ltd.</a> 的 Imre Rad</p>
 
-<p><a href="http://thejh.net/">Jann Horn</a><a href="https://android-review.googlesource.com/#/c/98197/">
-<img style="vertical-align:middle;" src="../images/tiny-robot.png" alt="绿色机器人补丁程序符号" title="此人贡献了有助于提高 Android 安全性的代码"/>
-</a></p>
+<p><a href="http://thejh.net/">Jann Horn</a> <a href="https://android-review.googlesource.com/#/c/98197/"><img style="vertical-align:middle;" src="../images/tiny-robot.png" alt="绿色机器人补丁程序符号" title="此人贡献了有助于提高 Android 安全性的代码"/></a></p>
 
 <p><a href="http://www.bluebox.com/">Bluebox Security</a> 的 Jeff Forristal</p>
 
@@ -1160,9 +1192,7 @@
 
 <p>犹他大学的 <a href="http://www.cs.utah.edu/~rsas/">Raimondas Sasnauskas</a></p>
 
-<p>美国国家安全局<a href="https://www.nsa.gov/research/ia_research/">可信系统研究团队</a>的 Robert Craig
-<a href="https://android-review.googlesource.com/#/q/owner:%22Robert+Craig+%253Crpcraig%2540tycho.ncsc.mil%253E%22+status:merged">
-<img style="vertical-align:middle" src="../images/tiny-robot.png" alt="补丁程序符号" title="此人贡献了有助于提高 Android 安全性的代码"/></a></p>
+<p>美国国家安全局<a href="https://www.nsa.gov/research/ia_research/">可信系统研究团队</a>的 Robert Craig <a href="https://android-review.googlesource.com/#/q/owner:%22Robert+Craig+%253Crpcraig%2540tycho.ncsc.mil%253E%22+status:merged"><img style="vertical-align:middle" src="../images/tiny-robot.png" alt="补丁程序符号" title="此人贡献了有助于提高 Android 安全性的代码"/></a></p>
 
 <p><a href="http://www.samsung.com">三星移动</a></p>
 
@@ -1177,9 +1207,7 @@
 <p><a href="https://www.sit.fraunhofer.de/">Fraunhofer SIT</a> 移动安全测试实验室的 Stephan Huber (<a href="mailto:Stephan.Huber@sit.fraunhofer.de">Stephan.Huber@sit.fraunhofer.de</a>)
 </p>
 
-<p>美国国家安全局<a href="https://www.nsa.gov/research/ia_research/">可信系统研究团队</a>的 Stephen Smalley
-<a href="https://android-review.googlesource.com/#/q/owner:%22Stephen+Smalley+%253Csds%2540tycho.nsa.gov%253E%22+status:merged">
-<img style="vertical-align:middle" src="../images/tiny-robot.png" alt="补丁程序符号" title="此人贡献了有助于提高 Android 安全性的代码"/></a></p>
+<p>美国国家安全局<a href="https://www.nsa.gov/research/ia_research/">可信系统研究团队</a>的 Stephen Smalley <a href="https://android-review.googlesource.com/#/q/owner:%22Stephen+Smalley+%253Csds%2540tycho.nsa.gov%253E%22+status:merged"><img style="vertical-align:middle" src="../images/tiny-robot.png" alt="补丁程序符号" title="此人贡献了有助于提高 Android 安全性的代码"/></a></p>
 
 <p>EC SPRIDE 达姆施塔特工业大学<a href="http://sseblog.ec-spride.de/">安全软件工程团队</a>的 Steven Arzt (<a href="mailto:Steven.Arzt@ec-spride.de">Steven.Arzt@ec-spride.de</a>)</p>
 
@@ -1199,10 +1227,7 @@
 
 <p><a href="https://www.facebook.com">Facebook</a> 的 <a href="http://www.shackleton.io/">Will Shackleton</a></p>
 
-<p><a href="http://www.linkedin.com/in/billcroberts">
-William Roberts</a> (<a href="mailto:bill.c.roberts@gmail.com">bill.c.roberts@gmail.com</a>)
-<a href="https://android-review.googlesource.com/#/q/owner:bill.c.roberts%2540gmail.com+status:merged">
-<img style="vertical-align:middle" src="../images/tiny-robot.png" alt="补丁程序符号" title="此人贡献了有助于提高 Android 安全性的代码"/></a></p>
+<p><a href="http://www.linkedin.com/in/billcroberts">William Roberts</a> (<a href="mailto:bill.c.roberts@gmail.com">bill.c.roberts@gmail.com</a>) <a href="https://android-review.googlesource.com/#/q/owner:bill.c.roberts%2540gmail.com+status:merged"><img style="vertical-align:middle" src="../images/tiny-robot.png" alt="补丁程序符号" title="此人贡献了有助于提高 Android 安全性的代码"/></a></p>
 
 <p>印第安纳大学布卢明顿分校的 <a href="http://www.informatics.indiana.edu/xw7/">Xiaofeng Wang</a> (<a href="mailto:xw7@indiana.edu">xw7@indiana.edu</a>)</p>
 
@@ -1212,7 +1237,7 @@
 
 <p>印第安纳大学布卢明顿分校的 Yeonjoon Lee (<a href="mailto:luc2yj@gmail.com">luc2yj@gmail.com</a>)</p>
 
-<p><a href="http://www.androbugs.com">林禹成</a> (<a href="https://twitter.com/AndroBugs">@AndroBugs)</a></p>
+<p><a href="http://www.androbugs.com">林禹成</a> (<a href="https://twitter.com/AndroBugs">@AndroBugs</a>)</p>
 
 <p><a href="http://xteam.baidu.com">百度 X-Team</a> 的 Zhang Dong Hui (<a href="http://weibo.com/shineastdh">shineastdh</a>)</p>
 
@@ -1226,9 +1251,7 @@
 
 <p><a href="http://appliedcybersecurity.com/">Applied Cybersecurity LLC</a> 的 Jon Sawyer (<a href="mailto:jon@cunninglogic.com">jon@cunninglogic.com</a>)</p>
 
-<p><a href="http://www.accuvant.com/">Accuvant LABS</a> 的 Joshua J. Drake (<a href="https://twitter.com/jduck">@jduck</a>)
-<a href="https://android-review.googlesource.com/#/q/change:72228+OR+change:72229">
-<img style="vertical-align:middle" src="../images/patchreward.png" alt="补丁程序奖励符号" title="此人符合参加补丁程序奖励计划的条件!"/></a></p>
+<p><a href="http://www.accuvant.com/">Accuvant LABS</a> 的 Joshua J. Drake (<a href="https://twitter.com/jduck">@jduck</a>) <a href="https://android-review.googlesource.com/#/q/change:72228+OR+change:72229"><img style="vertical-align:middle" src="../images/patchreward.png" alt="补丁程序奖励符号" title="此人符合参加补丁程序奖励计划的条件!"/></a></p>
 
 <p>Kan Yuan</p>
 
@@ -1246,20 +1269,13 @@
 
 <p><a href="https://securityresear.ch/">Roee Hay</a>(<a href="https://twitter.com/roeehay">@roeehay</a>、<a href="mailto:roeehay@gmail.com">roeehay@gmail.com</a>)</p>
 
-<p>美国国家安全局<a href="https://www.nsa.gov/research/ia_research/">可信系统研究团队</a>的 Robert Craig
-<a href="https://android-review.googlesource.com/#/q/owner:%22Robert+Craig+%253Crpcraig%2540tycho.ncsc.mil%253E%22+status:merged">
-<img style="vertical-align:middle" src="../images/tiny-robot.png" alt="补丁程序符号" title="此人贡献了有助于提高 Android 安全性的代码"/></a></p>
+<p>美国国家安全局<a href="https://www.nsa.gov/research/ia_research/">可信系统研究团队</a>的 Robert Craig <a href="https://android-review.googlesource.com/#/q/owner:%22Robert+Craig+%253Crpcraig%2540tycho.ncsc.mil%253E%22+status:merged"><img style="vertical-align:middle" src="../images/tiny-robot.png" alt="补丁程序符号" title="此人贡献了有助于提高 Android 安全性的代码"/></a></p>
 
 <p>IOActive 的 Ruben Santamarta (<a href="https://twitter.com/reversemode">@reversemode</a>)</p>
 
-<p>美国国家安全局<a href="https://www.nsa.gov/research/ia_research/">可信系统研究团队</a>的 Stephen Smalley
-<a href="https://android-review.googlesource.com/#/q/owner:%22Stephen+Smalley+%253Csds%2540tycho.nsa.gov%253E%22+status:merged">
-<img style="vertical-align:middle" src="../images/tiny-robot.png" alt="补丁程序符号" title="此人贡献了有助于提高 Android 安全性的代码"/></a></p>
+<p>美国国家安全局<a href="https://www.nsa.gov/research/ia_research/">可信系统研究团队</a>的 Stephen Smalley <a href="https://android-review.googlesource.com/#/q/owner:%22Stephen+Smalley+%253Csds%2540tycho.nsa.gov%253E%22+status:merged"><img style="vertical-align:middle" src="../images/tiny-robot.png" alt="补丁程序符号" title="此人贡献了有助于提高 Android 安全性的代码"/></a></p>
 
-<p><a href="http://www.linkedin.com/in/billcroberts">
-William Roberts</a> (<a href="mailto:bill.c.roberts@gmail.com">bill.c.roberts@gmail.com</a>)
-<a href="https://android-review.googlesource.com/#/q/owner:bill.c.roberts%2540gmail.com+status:merged">
-<img style="vertical-align:middle" src="../images/tiny-robot.png" alt="补丁程序符号" title="此人贡献了有助于提高 Android 安全性的代码"/></a></p>
+<p><a href="http://www.linkedin.com/in/billcroberts">William Roberts</a> (<a href="mailto:bill.c.roberts@gmail.com">bill.c.roberts@gmail.com</a>) <a href="https://android-review.googlesource.com/#/q/owner:bill.c.roberts%2540gmail.com+status:merged"><img style="vertical-align:middle" src="../images/tiny-robot.png" alt="补丁程序符号" title="此人贡献了有助于提高 Android 安全性的代码"/></a></p>
 
 <p>印第安纳大学布卢明顿分校的 Xiaorui Pan (<a href="mailto:eagle200467@gmail.com">eagle200467@gmail.com</a>)</p>
 
@@ -1277,20 +1293,13 @@
 
 <p>柏林工业大学的 Ravishankar Borgaonkari (<a href="https://twitter.com/raviborgaonkar">@raviborgaonkar</a>)</p>
 
-<p>美国国家安全局<a href="https://www.nsa.gov/research/ia_research/">可信系统研究团队</a>的 Robert Craig
-<a href="https://android-review.googlesource.com/#/q/owner:%22Robert+Craig+%253Crpcraig%2540tycho.ncsc.mil%253E%22+status:merged">
-<img style="vertical-align:middle" src="../images/tiny-robot.png" alt="补丁程序符号" title="此人贡献了有助于提高 Android 安全性的代码"/></a></p>
+<p>美国国家安全局<a href="https://www.nsa.gov/research/ia_research/">可信系统研究团队</a>的 Robert Craig <a href="https://android-review.googlesource.com/#/q/owner:%22Robert+Craig+%253Crpcraig%2540tycho.ncsc.mil%253E%22+status:merged"><img style="vertical-align:middle" src="../images/tiny-robot.png" alt="补丁程序符号" title="此人贡献了有助于提高 Android 安全性的代码"/></a></p>
 
 <p><a href="https://securityresear.ch/">Roee Hay</a>(<a href="https://twitter.com/roeehay">@roeehay</a>、<a href="mailto:roeehay@gmail.com">roeehay@gmail.com</a>)</p>
 
-<p>美国国家安全局<a href="https://www.nsa.gov/research/ia_research/">可信系统研究团队</a>的 Stephen Smalley
-<a href="https://android-review.googlesource.com/#/q/owner:%22Stephen+Smalley+%253Csds%2540tycho.nsa.gov%253E%22+status:merged">
-<img style="vertical-align:middle" src="../images/tiny-robot.png" alt="补丁程序符号" title="此人贡献了有助于提高 Android 安全性的代码"/></a></p>
+<p>美国国家安全局<a href="https://www.nsa.gov/research/ia_research/">可信系统研究团队</a>的 Stephen Smalley <a href="https://android-review.googlesource.com/#/q/owner:%22Stephen+Smalley+%253Csds%2540tycho.nsa.gov%253E%22+status:merged"><img style="vertical-align:middle" src="../images/tiny-robot.png" alt="补丁程序符号" title="此人贡献了有助于提高 Android 安全性的代码"/></a></p>
 
-<p><a href="http://www.linkedin.com/in/billcroberts">
-William Roberts</a> (<a href="mailto:bill.c.roberts@gmail.com">bill.c.roberts@gmail.com</a>)
-<a href="https://android-review.googlesource.com/#/q/owner:bill.c.roberts%2540gmail.com+status:merged">
-<img style="vertical-align:middle" src="../images/tiny-robot.png" alt="补丁程序符号" title="此人贡献了有助于提高 Android 安全性的代码"/></a></p>
+<p><a href="http://www.linkedin.com/in/billcroberts">William Roberts</a> (<a href="mailto:bill.c.roberts@gmail.com">bill.c.roberts@gmail.com</a>) <a href="https://android-review.googlesource.com/#/q/owner:bill.c.roberts%2540gmail.com+status:merged"><img style="vertical-align:middle" src="../images/tiny-robot.png" alt="补丁程序符号" title="此人贡献了有助于提高 Android 安全性的代码"/></a></p>
 
 </div>
 
diff --git a/zh-cn/security/overview/app-security.html b/zh-cn/security/overview/app-security.html
index 0f69ae7..c3a184a 100644
--- a/zh-cn/security/overview/app-security.html
+++ b/zh-cn/security/overview/app-security.html
@@ -25,20 +25,21 @@
 <p>Android 应用的主要构造块包括:</p>
 <ul>
   <li>
-    <p><strong>AndroidManifest.xml</strong>:<a href="https://developer.android.com/guide/topics/manifest/manifest-intro.html">AndroidManifest.xml</a> 是控制文件,用于告诉系统如何处理应用中的所有顶级组件(具体来说就是下面介绍的活动、服务、广播接收器和内容提供程序)。该文件还用于指定需要哪些权限。</p>
+    <p><strong>AndroidManifest.xml</strong>:<a href="https://developer.android.com/guide/topics/manifest/manifest-intro.html">AndroidManifest.xml</a> 是控制文件,用于告诉系统如何处理应用中的所有顶层组件(具体来说就是下面介绍的活动、服务、广播接收器和内容提供程序)。该文件还用于指定需要哪些权限。</p>
   </li>
   <li>
-    <p><strong>活动</strong>:一般情况下,<a href="https://developer.android.com/guide/topics/fundamentals/activities.html">活动</a>是指聚焦于用户的单个任务的代码。活动通常包括向用户显示界面,但并不一定会这样,有些活动就从不显示界面。通常情况下,应用的入口点是应用的其中一项活动。</p>
+    <p><strong>活动</strong>:一般情况下,<a href="https://developer.android.com/guide/topics/fundamentals/activities.html">活动</a>是指以用户为中心的单个任务的代码。活动通常包括向用户显示界面,但并不一定会这样,有些活动就从不显示界面。通常情况下,应用的入口点是应用的其中一项活动。</p>
   </li>
   <li>
     <p><strong>服务</strong>:<a href="https://developer.android.com/guide/topics/fundamentals/services.html">服务</a>是指在后台运行的代码的主体。服务可以在自己的进程中运行,也可以在其他应用的进程中运行。其他组件会“绑定”到某项服务,并通过远程过程调用来调用该服务的方法。比如媒体播放器就是一项服务:即使用户退出媒体选择界面,也可能仍然希望音乐继续播放。即使界面已关闭,服务也可使音乐继续播放。</p>
   </li>
   <li>
-    <p><strong>广播接收器</strong>:<a href="https://developer.android.com/reference/android/content/BroadcastReceiver.html">BroadcastReceiver</a> 是在操作系统或其他应用发出称为 <a href="https://developer.android.com/reference/android/content/Intent.html">Intent</a> 的 IPC 机制时实例化的对象。例如,应用可以注册一个接收器来接收电量不足消息,并可以根据该信息改变自己的行为。</p>
+    <p><strong>广播接收器</strong>:<a href="https://developer.android.com/reference/android/content/BroadcastReceiver.html">BroadcastReceiver</a> 是一种在操作系统或其他应用发出称为 <a href="https://developer.android.com/reference/android/content/Intent.html">Intent</a> 的 IPC 机制时实例化的对象。例如,应用可以注册一个接收器来接收电量不足消息,并可以根据该信息改变自己的行为。</p>
   </li>
 </ul>
 <h2 id="the-android-permission-model-accessing-protected-apis">Android 权限模式:访问受保护的 API</h2>
-<p>Android 上的所有应用均在应用沙盒(本文档的前面对其进行了介绍)内运行。默认情况下,Android 应用只能访问有限的系统资源。系统负责管理 Android 应用对资源的访问权限。如果资源使用不当或被恶意使用,可能会给用户体验、网络或设备上的数据带来不利影响。</p>
+<p>Android 上的所有应用均在<a href="/security/overview/kernel-security#the-application-sandbox">应用沙盒</a>内运行。
+默认情况下,Android 应用只能访问有限的系统资源。系统负责管理 Android 应用对资源的访问权限。如果资源使用不当或被恶意使用,可能会给用户体验、网络或设备上的数据带来不利影响。</p>
 <p>这些限制是通过多种不同的形式实现的。有些功能会因 Android 有意未提供针对敏感功能的 API(例如,Android 中没有用于直接操控 SIM 卡的 Android API)而受到限制。在某些情况下,角色分离能够提供一种安全措施,就像按应用隔离存储空间一样。在其他情况下,敏感 API 旨在供可信应用使用,并由一种称为“权限”的安全机制进行保护。</p>
 <p>这些受保护的 API 包括:</p>
 <ul>
@@ -123,7 +124,8 @@
 <h2 id="certificate-authorities">证书授权中心</h2>
 <p>Android 中收录了一组已安装的系统证书授权中心,这些授权中心在整个系统范围内均可信。在 Android 7.0 之前的版本中,设备制造商可以修改其设备上搭载的 CA 组。不过,运行 7.0 及更高版本的设备将具有一组统一的系统 CA,并且不再允许设备制造商对其进行修改。
 </p>
-<p>要作为新的公共 CA 添加到 Android 收录的 CA 组中,相应 CA 必须要完成 <a href="https://wiki.mozilla.org/CA:How_to_apply">Mozilla CA 收录流程</a>,然后提交一项针对 Android 的功能请求 (<a href="https://code.google.com/p/android/issues/entry">https://code.google.com/p/android/issues/entry</a>),以便请求添加到 <a href="https://android.googlesource.com/">Android 开放源代码项目</a> (AOSP) 收录的 Android CA 组中。
+<p>
+一个 CA 若要作为新的公共 CA 添加到 Android 收录的 CA 组中,则该 CA 必须完成 <a href="https://wiki.mozilla.org/CA:How_to_apply">Mozilla CA 收录流程</a>,然后提交一项针对 Android 的功能请求 (<a href="https://code.google.com/p/android/issues/entry">https://code.google.com/p/android/issues/entry</a>),以便将其添加到 <a href="https://android.googlesource.com/">Android 开放源代码项目</a> (AOSP) 收录的 Android CA 组中。
 </p>
 <p>此外还有一些设备专用 CA,这些 CA 不应被收录到 AOSP CA 核心组中,例如,安全访问运营商基础架构组件(例如,短信/彩信网关)时可能需要的运营商私有 CA。建议设备制造商将私有 CA 仅收录在需要信任这些 CA 的组件/应用中。如需更多详细信息,请参阅<a href="https://developer.android.com/preview/features/security-config.html">网络安全配置</a>。
 </p>
@@ -132,7 +134,7 @@
 <p>在 Google Play 上,应用签名可以将 Google 对开发者的信任和开发者对自己的应用的信任联系在一起。开发者知道自己的应用是以未经修改的形式提供给 Android 设备的,并且开发者可以对自己的应用的行为负责。</p>
 <p>在 Android 上,应用签名是将应用放入其应用沙盒的第一步。已签名的应用证书定义了哪个用户 ID 与哪个应用相关联;不同的应用要以不同的用户 ID 运行。应用签名可确保一个应用无法访问任何其他应用,通过明确定义的 IPC 进行访问时除外。</p>
 <p>当应用(APK 文件)安装到 Android 设备上时,软件包管理器会验证 APK 是否已经过适当签名(已使用 APK 中包含的证书签名)。如果该证书(或更准确地说,证书中的公钥)与为设备上的任何其他 APK 签名时使用的密钥一致,那么这个新 APK 可以选择在清单中指定它将与其他以类似方式签名的 APK 共用一个 UID。</p>
-<p>应用可以由第三方(原始设备制造商(OEM)、运营商、其他相关方)签名,也可以自行签名。Android 提供了使用自签名证书进行代码签名的功能,而开发者无需外部协助或许可即可生成自签名证书。应用并非必须由核心机构签名。Android 目前不对应用证书进行 CA 认证。</p>
+<p>应用可以由第三方(原始设备制造商 (OEM)、运营商、其他相关方)签名,也可以自行签名。Android 提供了使用自签名证书进行代码签名的功能,而开发者无需外部协助或许可即可生成自签名证书。应用并非必须由核心机构签名。Android 目前不对应用证书进行 CA 认证。</p>
 <p>应用还可以在“签名”保护级别声明安全权限,以便仅限使用同一个密钥签名的应用访问它们,同时维持单独的 UID 和应用沙盒。通过<a href="https://developer.android.com/guide/topics/manifest/manifest-element.html#uid">共用 UID 功能</a>,可以与共用的应用沙盒建立更紧密的联系,这是因为借助该功能,使用同一个开发者密钥签名的两个或更多应用可以在其清单中声明共用的 UID。</p>
 <h2 id="app-verification">应用验证</h2>
 <p>Android 4.2 及更高版本均支持应用验证。用户可以选择启用“验证应用”,并在安装应用之前由应用验证程序对其进行评估。如果用户尝试安装的应用可能有害,应用验证功能可以提醒用户;如果应用的危害性非常大,应用验证功能可以阻止安装。</p>
diff --git a/zh-cn/security/overview/kernel-security.html b/zh-cn/security/overview/kernel-security.html
index 7ad6ddf..f2c32f0 100644
--- a/zh-cn/security/overview/kernel-security.html
+++ b/zh-cn/security/overview/kernel-security.html
@@ -81,6 +81,6 @@
 <p>设备管理员可以要求使用密码和/或密码复杂度规则。</p>
 <h2 id="device-administration">设备管理</h2>
 <p>Android 2.2 及更高版本提供 Android Device Administration API,该 API 在系统级别提供设备管理功能。例如,内置的 Android 电子邮件应用可以使用该 API 来改善 Exchange 支持。通过电子邮件应用,Exchange 管理员可以跨设备强制执行密码政策(其中密码包括字母数字密码或数字 PIN 码)。管理员还可以远程清除(即恢复出厂默认设置)丢失或被盗手机上的数据。</p>
-<p>除了在 Android 系统自带的应用中使用外,该 API 还可供提供设备管理解决方案的第三方使用。如需关于该 API 的详细信息,请参阅<a href="https://developer.android.com/guide/topics/admin/device-admin.html">设备管理</a>。</p>
+<p>除了在 Android 系统自带的应用中使用外,该 API 还可供提供设备管理解决方案的第三方使用。如需详细了解该 API,请参阅<a href="https://developer.android.com/guide/topics/admin/device-admin.html">设备管理</a>。</p>
 
 </body></html>
\ No newline at end of file
diff --git a/zh-cn/security/overview/updates-resources.html b/zh-cn/security/overview/updates-resources.html
index 818cba8..9b32924 100644
--- a/zh-cn/security/overview/updates-resources.html
+++ b/zh-cn/security/overview/updates-resources.html
@@ -20,8 +20,6 @@
       limitations under the License.
   -->
 
-<h2 id="android_security_bug_lifecycle">Android 安全错误生命周期</h2>
-
 <p>Android 安全团队负责管理在 Android 平台中发现的以及在 Android 设备绑定的众多核心 Android 应用中发现的安全漏洞。</p>
 
 <p>Android 安全团队会通过内部研究找出安全漏洞,并会对第三方报告的错误采取应对措施。外部错误的来源包括:通过 <a href="https://issuetracker.google.com/issues/new?component=190951">Android 安全问题模板</a>报告的问题、已发布和预发布的学术研究、上游开放源代码项目维护人员、来自设备制造商合作伙伴的通知,以及博客或社交媒体中发布的已公开披露的问题。</p>
@@ -39,68 +37,116 @@
 <h3 id="process_types">进程类型</h3>
 <p>下表涵盖了各类进程的定义。进程类型可以按应用或进程的类型来定义,也可以按进程的运行区域来定义。下表按照权限从小到大的顺序排列。</p>
 <table>
- <tbody><tr>
-    <th>进程类型</th>
-    <th>类型定义</th>
- </tr>
- <tr>
-    <td>受限进程</td>
-    <td>在高度受限的 SELinux 域中运行的进程。<br />或<br />受限程度远远超过普通应用的进程。</td>
- </tr>
- <tr>
-    <td>非特权进程</td>
-    <td>第三方应用或进程。<br />或<br />在 SELinux <code>untrusted_app</code> 域中运行的应用或进程。</td>
- </tr>
- <tr>
-    <td>特权进程</td>
-    <td>功能受 SELinux <code>untrusted_app</code> 域限制的应用或进程。<br />或<br />拥有第三方应用无法获得的重要权限的应用或进程。</td>
- </tr>
- <tr>
-    <td>内核</td>
-    <td>属于内核一部分的功能,或在与内核相同的 CPU 环境中运行的功能(例如,设备驱动程序)。</td>
- </tr>
- <tr>
-    <td>可信执行环境 (TEE)</td>
-    <td>一种受保护的组件,甚至可以抵御恶意内核的攻击。</td>
- </tr>
+  <colgroup><col width="30%" />
+  <col width="70%" />
+  </colgroup><tbody><tr>
+   <th>进程类型</th>
+   <th>类型定义</th>
+  </tr>
+  <tr>
+   <td>受限进程</td>
+   <td>在高度受限的 SELinux 域中运行的进程。<br />
+   或<br />
+   受限程度远远超过普通应用的进程。</td>
+  </tr>
+  <tr>
+   <td>非特权进程</td>
+   <td>第三方应用或进程。<br />
+   或<br />
+   在 SELinux <code>untrusted_app</code> 域中运行的应用或进程。</td>
+  </tr>
+  <tr>
+   <td>特权进程</td>
+   <td>功能受 SELinux <code>untrusted_app</code> 域限制的应用或进程。<br />
+   或<br />
+   拥有第三方应用无法获得的重要权限的应用或进程。</td>
+  </tr>
+  <tr>
+   <td>可信计算基 (TCB)</td>
+   <td>一种功能,具有以下特征:属于内核一部分、在与内核相同的 CPU 环境(如设备驱动程序)中运行、可以直接访问内核内存(如设备上的硬件组件),或者是被认为等同于内核的几种用户服务中的一种:<code>init</code>、<code>ueventd</code> 和 <code>vold</code>。</td>
+  </tr>
+  <tr>
+   <td>可信执行环境 (TEE)</td>
+   <td>一种受保护的组件,甚至可以抵御恶意内核的攻击。</td>
+  </tr>
 </tbody></table>
 
 <h3 id="severity">严重程度</h3>
 
 <p>错误的严重程度通常能够反映错误被成功利用后可能造成的潜在危害。可以按照以下条件判断严重程度:</p>
 <table>
- <tbody><tr>
-    <th>分级</th>
-    <th>被成功利用的后果</th>
- </tr>
- <tr>
-    <td><strong>严重</strong></td>
-    <td>
-          <ul>
-             <li>攻击者可以在特权进程中远程执行任意代码</li><li>设备永久损坏(只有重新刷写整个操作系统才能修复设备)</li><li>攻击者可以在未经授权的情况下访问受 TEE 保护的数据</li><li>设备遭到远程发起的永久性拒绝服务攻击(设备无法再使用:完全永久性损坏,或需要重新刷写整个操作系统)</li></ul>
-    </td>
- </tr>
- <tr>
-     <td><strong>高</strong></td>
-     <td>
-          <ul>
-             <li>攻击者可以在非特权进程中远程执行任意代码</li><li>攻击者可以远程访问受保护的数据(通常仅限本地安装的应用在请求并获得权限后才可以访问的数据,或仅限特权进程访问的数据)</li><li>攻击者可以远程绕过用户互动要求(攻击者能够访问通常需要由用户发起的功能或需要获得用户许可后方可使用的功能)</li><li>攻击者可以从本地在特权进程中执行任意代码</li><li>设备遭到从本地发起的永久性拒绝服务攻击(设备无法再使用:完全永久性损坏,或需要重新刷写整个操作系统)</li><li>攻击者可以全面深入地绕过内核级防护功能,或利用缓解技术存在的漏洞</li><li>设备遭到远程发起的设备暂时性拒绝服务攻击(远程挂起或重新启动设备)</li><li>攻击者可以从本地绕过针对任何开发者或针对任何安全设置修改的用户互动要求</li><li>攻击者可以全面绕过将应用数据与其他应用隔离开来的操作系统保护功能</li><li>攻击者可以绕过锁定屏幕</li></ul>
-    </td>
- </tr>
- <tr>
-     <td><strong>中</strong></td>
-     <td>
-          <ul>
-             <li>攻击者可以在受限进程中远程执行任意代码</li><li>攻击者可以从本地绕过用户互动要求(攻击者能够访问通常需要由用户发起的功能或需要获得用户许可后方可使用的功能)</li><li>设备遭到从本地发起的暂时性拒绝服务攻击(设备需要恢复出厂设置)</li><li>攻击者可以全面深入地绕过用户级防护功能,或在特权进程中利用缓解技术存在的漏洞</li><li>攻击者可以远程访问不受保护的数据(通常可供本地安装的所有应用访问的数据)</li><li>攻击者可以绕过设备保护功能/恢复出厂设置保护功能</li></ul>
-    </td>
- </tr>
- <tr>
-     <td><strong>低</strong></td>
-     <td>
-          <ul>
-             <li>攻击者可以全面深入地绕过用户级防护功能,或在非特权进程中利用缓解技术存在的漏洞</li><li>设备遭到从本地发起的暂时性拒绝服务攻击(可通过以下方法解决:使设备启动到安全模式并移除存在问题的应用;或者如果设备不支持安全模式,则将设备恢复出厂设置)</li></ul>
-     </td>
- </tr>
+  <tbody><tr>
+   <th>分级</th>
+   <th>被成功利用的后果</th>
+  </tr>
+  <tr>
+   <td><strong>严重</strong></td>
+   <td>
+     <ul>
+       <li>在 TEE 中执行任意代码</li>
+       <li>攻击者可以在特权进程或 TCB 中远程执行任意代码</li>
+       <li>设备遭到远程发起的永久性拒绝服务攻击(设备无法再使用:完全永久性损坏,或需要重新刷写整个操作系统)</li>
+       <li>攻击者可以远程绕过与软件包安装或等效行为相关的用户互动要求</li>
+       <li>攻击者可以绕过安全启动</li>
+     </ul>
+   </td>
+  </tr>
+  <tr>
+   <td><strong>高</strong></td>
+   <td>
+     <ul>
+      <li>攻击者可以在非特权进程中远程执行任意代码</li>
+      <li>攻击者可以从本地在特权进程或 TCB 中执行任意代码</li>
+      <li>攻击者可以在未经授权的情况下访问受 TEE 保护的数据</li>
+      <li>攻击者可以远程访问受保护的数据(通常仅限本地安装的应用在请求并获得权限后才可以访问的数据,或仅限特权进程访问的数据)</li>
+      <li>设备遭到从本地发起的永久性拒绝服务攻击(设备无法再使用:完全永久性损坏,或需要重新刷写整个操作系统)</li>
+      <li>设备遭到远程发起的设备暂时性拒绝服务攻击(远程挂起或重新启动设备)</li>
+      <li>攻击者可以远程绕过用户互动要求(攻击者能够访问通常需要由用户发起的功能或需要获得用户许可后方可使用的功能)</li>
+      <li>攻击者可以从本地绕过针对任何开发者或针对任何安全设置修改的用户互动要求</li>
+      <li>攻击者可以全面绕过将应用数据与其他应用隔离开来的操作系统保护功能</li>
+      <li>攻击者可以全面绕过将用户或个人资料彼此隔离开来的操作系统保护功能</li>
+      <li>在标准 TLS 中造成可受到中间人攻击的加密漏洞</li>
+      <li>攻击者可以绕过锁定屏幕</li>
+     </ul>
+   </td>
+  </tr>
+  <tr>
+   <td><strong>中</strong></td>
+   <td>
+     <ul>
+      <li>攻击者可以在受限进程中远程执行任意代码</li>
+      <li>攻击者可以从本地在非特权进程中执行任意代码</li>
+      <li>攻击者可以全面深入地绕过防护功能,或在特权进程、TCB 或 TEE 中利用缓解技术存在的漏洞进行攻击</li>
+      <li>绕过对受限进程的限制</li>
+      <li>攻击者可以远程访问不受保护的数据(通常可供本地安装的所有应用访问的数据)</li>
+      <li>攻击者可以从本地访问受保护的数据(通常仅限本地安装的应用在请求并获得权限后才可以访问的数据,或仅限特权进程访问的数据)</li>
+      <li>攻击者可以从本地绕过用户互动要求(攻击者能够访问通常需要由用户发起的功能或需要获得用户许可后方可使用的功能)</li>
+      <li>设备遭到从本地发起的永久性拒绝服务攻击(设备需要恢复出厂设置)</li>
+      <li>在标准加密基元(并非 TLS 中使用的基元)中造成可导致明文泄露的加密漏洞</li>
+      <li>攻击者可以绕过设备保护功能/恢复出厂设置保护功能</li>
+      <li>攻击者可以绕过运营商的限制</li>
+      <li>有针对性地阻止对应急服务的访问</li>
+     </ul>
+   </td>
+  </tr>
+  <tr>
+   <td><strong>低</strong></td>
+   <td>
+     <ul>
+      <li>攻击者可以从本地在受限进程中执行任意代码</li>
+      <li>在非标准使用中造成加密漏洞</li>
+      <li>攻击者可以全面深入地绕过用户级防护功能,或在非特权进程中利用缓解技术存在的漏洞进行攻击</li>
+     </ul>
+   </td>
+  </tr>
+  <tr>
+   <td><strong>无安全影响 (NSI)</strong></td>
+   <td>
+     <ul>
+       <li>漏洞的影响已被一个或多个分级调节方式或特定于版本的架构更改减弱,因此有效严重程度已降至“低”以下,但底层代码问题可能仍然存在</li>
+     </ul>
+   </td>
+  </tr>
 </tbody></table>
 
 <h4 id="local_vs_remote">本地和远程</h4>
@@ -110,33 +156,49 @@
 <p>本地攻击需要受害者安装应用才能得逞。为了进行严重程度分级,Android 安全团队还会将现实攻击向量视为本地攻击。这包括只能被实际接触到设备的攻击者利用的错误,例如锁定屏幕中的错误,或需要插入 USB 数据线的错误。Android 安全团队还会将基于 NFC 的攻击视为本地攻击。</p>
 
 <h3 id="rating_modifiers">分级调节方式</h3>
-<p>虽然通常可以轻松确定安全漏洞的严重程度,但分级可能会因具体情况而异。</p>
+<p>尽管通常可以轻松确定安全漏洞的严重程度,但分级可能会因具体情况而异。</p>
 <table>
- <tbody><tr>
-    <th>原因</th>
-    <th>影响</th>
- </tr>
- <tr>
-    <td>需要作为特权进程运行才能执行攻击</td>
-    <td>严重程度降低 1 级</td>
- </tr>
- <tr>
-    <td>漏洞特有的详细信息会限制相应问题造成的影响</td>
-    <td>严重程度降低 1 级</td>
- </tr>
+  <tbody><tr>
+   <th>原因</th>
+   <th>影响</th>
+  </tr>
+  <tr>
+   <td>需要作为特权进程运行才能执行攻击</td>
+   <td>严重程度降低 1 级</td>
+  </tr>
+  <tr>
+   <td>漏洞特有的详细信息限制了相应问题的影响大小</td>
+   <td>严重程度降低 1 级</td>
+  </tr>
+  <tr>
+   <td>编译器或平台配置缓解了源代码中的漏洞</td>
+   <td>如果底层漏洞的严重程度为“中”或更高,则实际严重程度为“中”</td>
+  </tr>
+  <tr>
+   <td>需要防篡改的物理访问</td>
+   <td>严重程度降低 2 级</td>
+  </tr>
+  <tr>
+   <td>如果任何 SELinux 域都无法在 Google 提供的 SEPolicy 下执行操作</td>
+   <td>无安全影响</td>
+  </tr>
 </tbody></table>
 
+<p class="note">
+<strong>注意</strong>:可能不会为被评估为“低”或“NSI”的问题发出 CVE。
+</p>
+
 <h3 id="affected_component">受影响的组件</h3>
 
 <p>开发团队负责根据错误所在的组件来修复错误。该组件可能是 Android 平台的核心组件、原始设备制造商 (OEM) 提供的内核驱动程序,或 Nexus 设备上某个预先加载的应用。</p>
 
 <p>AOSP 代码中的错误由 Android 工程团队负责修复。严重程度为“低”的错误、特定组件内的错误或者已经是众所周知的错误可以直接在已公开发布的 AOSP master 分支中进行修复;除此之外的其他错误都会先在我们的内部代码库中进行修复。</p>
 
-<p>组件也是会影响用户如何获取更新的一种因素。如果是框架或内核存在的错误,用户将需要使用无线下载 (OTA) 的固件更新,每个原始设备制造商 (OEM) 都需要推送此类更新。如果是 Google Play 中发布的应用或库(例如,Lollipop 及更高版本中的 Gmail、Google Play 服务、WebView)存在的错误,可以通过 Google Play 向 Android 用户发送更新。</p>
+<p>组件也是会影响用户如何获取更新的一种因素。如果是框架或内核存在的错误,用户将需要使用无线下载 (OTA) 的固件更新,每个原始设备制造商 (OEM) 都需要推送此类更新。如果是 Google Play 中发布的应用或库(例如,Lollipop 及更高版本中的 Gmail、Google Play 服务、WebView)存在的错误,则可以通过 Google Play 向 Android 用户发送更新。</p>
 
 <h2 id="notifying_partners">通知合作伙伴</h2>
 
-<p>当 AOSP 内严重程度为“中”或更高的安全漏洞得到修复后,我们会将问题详细信息通知 Android 合作伙伴,并至少提供针对 3 种最新 Android 版本的补丁程序。Android 安全团队目前提供针对 Android 4.4 版 (KitKat)、5.0 版 (Lollipop)、5.1 版 (Lollipop MR1) 以及 6.0 版 (Marshmallow) 的补丁程序。具体会针对哪些最新版本提供补丁程序会随着每个新 Android 版本的发布而发生变化。</p>
+<p>AOSP 中的安全漏洞在 Android 安全公告中得到修复后,我们会将问题详细信息通知给 Android 合作伙伴,并提供相应的补丁程序。Android 安全团队目前针对 Android 4.4 版 (KitKat) 及更高版本提供补丁程序。具体会针对哪些版本提供补丁程序会随着每个新 Android 版本的发布而发生变化。</p>
 
 <h2 id="releasing_code_to_aosp">向 AOSP 发布代码</h2>
 
diff --git a/zh-cn/security/selinux/concepts.html b/zh-cn/security/selinux/concepts.html
index 3eaf564..a2c57f9 100644
--- a/zh-cn/security/selinux/concepts.html
+++ b/zh-cn/security/selinux/concepts.html
@@ -68,25 +68,27 @@
 </li></ul>
 
 <p>使用政策规则时将遵循的结构示例:</p>
-<code>allow appdomain app_data_file:file rw_file_perms;</code>
+<pre class="devsite-click-to-copy">
+allow appdomain app_data_file:file rw_file_perms;
+</pre>
 
 <p>这表示所有应用域都可以读取和写入带有 app_data_file 标签的文件。请注意,该规则依赖于在 global_macros 文件中定义的宏,您还可以在 te_macros 文件中找到一些其他非常实用的宏。这两个文件均位于 AOSP 源代码树的 <a href="https://android.googlesource.com/platform/system/sepolicy/">system/sepolicy</a> 目录中,其中提供了一些适用于常见的类、权限和规则分组的宏。应尽可能使用这些宏,以便降低因相关权限被拒而导致失败的可能性。</p>
 
 <p><em></em>除了在规则中逐个列出域或类型之外,还可以通过属性引用一组域或类型。简单来说,属性是一组域或类型的名称。每个域或类型都可以与任意数量的属性相关联。当编写的规则指定了某个属性名称时,该名称会自动扩展为列出与该属性关联的所有域或类型。<em></em><em></em>例如,domain 属性与所有进程域相关联,file_type 属性与所有文件类型相关联。</p>
 
-<p>使用上述语法可以创建构成 SELinux 政策基本内容的 avc 规则。规则采用以下形式:</p><pre>
-&lt;rule variant&gt; &lt;source_types&gt; &lt;target_types&gt; : &lt;classes&gt; &lt;permissions&gt;
+<p>使用上述语法可以创建构成 SELinux 政策基本内容的 avc 规则。规则采用以下形式:</p><pre class="devsite-click-to-copy">
+<var>RULE_VARIANT SOURCE_TYPES TARGET_TYPES</var> : <var>CLASSES PERMISSIONS</var>
 </pre>
 
 <p><em></em><em></em><em></em><em></em>该规则指明了,当带有任何 source_types 标签的主体尝试对某个对象执行与任何 permissions 对应的操作时,如果该对象包含带有任何 target_types 标签的任何 classes 类,会发生什么情况。这些规则的一个最常见示例是 allow 规则,例如:</p>
 
-<pre>
+<pre class="devsite-click-to-copy">
 allow domain null_device:chr_file { open };
 </pre>
 
 <p><em></em><em></em><em></em><em></em>该规则允许具有与“domain”属性关联的任何域的进程对 target_type 标签为“null_device”的“chr_file”类(字符设备文件)的对象执行“open”权限所描述的操作。在实际中,该规则可能会扩展为包含其他权限:</p>
 
-<pre>
+<pre class="devsite-click-to-copy">
 allow domain null_device:chr_file { getattr open read ioctl lock append write};
 </pre>
 
diff --git a/zh-cn/security/selinux/customize.html b/zh-cn/security/selinux/customize.html
index 2b96e18..3b11092 100644
--- a/zh-cn/security/selinux/customize.html
+++ b/zh-cn/security/selinux/customize.html
@@ -22,6 +22,8 @@
 
 <p>集成这一基本级别的功能并全面分析结果后,您可以添加自己的政策设置,以便涵盖自己对 Android 操作系统进行的自定义。当然,这些政策仍必须要满足 <a href="/compatibility/index.html">Android 兼容性计划</a>的要求,并且不会移除默认的 SELinux 设置。</p>
 
+<aside class="note"><strong>注意</strong>:要详细了解如何在 Android 8.0 中自定义 SELinux,请参阅 <a href="/security/selinux/images/SELinux_Treble.pdf">SELinux for Android 8.0</a>。</aside>
+
 <p>制造商不得移除现有的安全设置,否则可能会破坏 Android SELinux 实现及其管控的应用。这包括可能需要进行改进以符合政策并正常运行的第三方应用。应用必须无需进行任何修改即可继续在启用了 SELinux 的设备上正常运行。</p>
 
 <p>当开始着手自定义 SELinux 时,制造商应记得做以下事情:</p>
@@ -34,7 +36,7 @@
 <ul>
   <li>创建不兼容的政策</li><li>允许对最终用户政策进行自定义</li><li>允许对 MDM 政策进行自定义</li><li>恐吓违反政策的用户</li><li>添加后门程序</li></ul>
 
-<p><em></em>如需查看具体要求,请参阅 <a href="/compatibility/android-cdd.pdf">Android 兼容性定义文档</a>中的“内核安全功能”部分。</p>
+<p>如需查看具体要求,请参阅 <a href="/compatibility/android-cdd.pdf">Android 兼容性定义文档</a>中的“内核安全功能”部分。<em></em></p>
 
 <p>SELinux 采用白名单方法,这意味着只能授予政策中明确允许的访问权限。由于 Android 的默认 SELinux 政策已经支持 Android 开放源代码项目,因此原始设备制造商 (OEM) 无需以任何方式修改 SELinux 设置。如果他们要自定义 SELinux 设置,则应格外谨慎,以免破坏现有应用。以下是我们建议的做法:</p>
 
@@ -62,7 +64,7 @@
 
 <p>在以下示例中,所有域都被授予从 <code>/dev/null</code> 读取数据或向其写入数据的权限以及从 <code>/dev/zero</code> 读取数据的权限。</p>
 
-<pre>
+<pre class="devsite-click-to-copy">
 # Allow read / write access to /dev/null
 allow domain null_device:chr_file { getattr open read ioctl lock append write};
 
@@ -72,7 +74,7 @@
 
 <p>可以使用 SELinux <code>*_file_perms</code> 宏编写相同的声明(代码非常简短):</p>
 
-<pre>
+<pre class="devsite-click-to-copy">
 # Allow read / write access to /dev/null
 allow domain null_device:chr_file rw_file_perms;
 
@@ -84,7 +86,7 @@
 
 <p>以下是一个完整的 DHCP 政策示例,我们将在下文中对其进行分析:</p>
 
-<pre>
+<pre class="devsite-click-to-copy">
 type dhcp, domain;
 permissive dhcp;
 type dhcp_exec, exec_type, file_type;
@@ -117,7 +119,7 @@
 
 <p>下面我们来分析一下该示例:</p>
 
-<p>在第一行(即类型声明)中,该政策声明 DHCP 守护进程将沿用基本的安全政策 (<code>domain</code>)。从前面的声明示例中,我们知道 DHCP 可以从 <code>/dev/null.</code> 读取数据以及向其写入数据。</p>
+<p>在第一行(即类型声明)中,该政策声明 DHCP 守护进程将沿用基本的安全政策 (<code>domain</code>)。从前面的声明示例中,我们知道 DHCP 可以从 <code>/dev/null</code> 读取数据以及向其写入数据。</p>
 
 <p>在第二行中,DHCP 被声明为宽容域。</p>
 
@@ -235,13 +237,15 @@
 
 <h2 id="neverallow">neverallow 规则</h2>
 
-<p>SELinux <code>neverallow</code> 规则用于禁止在任何情况下都不应该发生的行为。通过<a href="/compatibility/index.html">兼容性</a>测试,现在各种合作伙伴设备上都会强制执行 SELinux <code>neverallow</code> 规则。</p>
+<p>SELinux <code>neverallow</code> 规则用于禁止在任何情况下都不应该发生的行为。
+通过<a href="/compatibility/index.html">兼容性</a>测试,现在各种合作伙伴设备上都会强制执行 SELinux <code>neverallow</code> 规则。</p>
 
 <p>以下准则旨在协助制造商在自定义过程中避免与 <code>neverallow</code> 规则相关的错误。此处使用的规则编号与 Android 5.1 中使用的编号一致,并且会因版本而异。</p>
 
 <p>规则 48:<code>neverallow { domain -debuggerd -vold -dumpstate
 -system_server } self:capability sys_ptrace;</code><br />请参阅 <code>ptrace</code> 的帮助页面。<code>sys_ptrace</code> 功能用于授予对任何进程执行 <code>ptrace</code> 命令的权限。拥有该权限后,可以对其他进程进行广泛的控制。应该只有该规则中列出的指定系统组件享有该权限。如果需要该功能,则通常表明存在的某些内容不适用于面向用户的版本或存在不需要的功能。请移除不必要的组件。</p>
 
-<p>规则 76:<code>neverallow { domain -appdomain -dumpstate -shell -system_server -zygote } { file_type -system_file -exec_type }:file execute;</code><br />该规则旨在防止执行系统中的任意代码。具体来说就是,该规则声明仅执行 <code>/system</code> 中的代码,以便通过验证启动等机制实现安全保证。通常情况下,当遇到与这个 <code>neverallow</code> 规则相关的问题时,最好的解决办法是将违规代码移到 <code>/system</code> 分区。</p>
+<p>规则 76:<code>neverallow { domain -appdomain -dumpstate -shell -system_server -zygote } { file_type -system_file -exec_type }:file execute;</code><br />该规则旨在防止执行系统中的任意代码。具体来说就是,该规则声明仅执行 <code>/system</code> 中的代码,以便通过验证启动等机制实现安全保证。
+通常情况下,当遇到与这个 <code>neverallow</code> 规则相关的问题时,最好的解决办法是将违规代码移到 <code>/system</code> 分区。</p>
 
 </body></html>
\ No newline at end of file
diff --git a/zh-cn/security/selinux/device-policy.html b/zh-cn/security/selinux/device-policy.html
index 9f2708d..6a391ec 100644
--- a/zh-cn/security/selinux/device-policy.html
+++ b/zh-cn/security/selinux/device-policy.html
@@ -22,6 +22,8 @@
 
 <p>Android 开放源代码项目 (AOSP) 针对所有 Android 设备中常用的应用和服务提供了一个可靠实用的基本政策。AOSP 的贡献者会定期完善该政策。该核心政策应占设备上最终政策的 90-95%,而剩下的 5-10% 则为设备专用自定义政策。本文重点介绍了这些设备专用自定义政策、如何编写设备专用政策,以及在编写此类政策时要避免的一些陷阱。</p>
 
+<aside class="note"><strong>注意</strong>:要详细了解如何在 Android 8.0 中编写 SELinux 政策,请参阅 <a href="/security/selinux/images/SELinux_Treble.pdf">SELinux for Android 8.0</a>。</aside>
+
 <h2 id="device_bringup">设备启动</h2>
 
 <p>在编写设备专用政策时,请按顺序执行以下步骤。</p>
@@ -39,7 +41,9 @@
 
 <p>在此之后,通过以下命令确认宽容模式:</p>
 
-<p><code>adb getenforce</code></p>
+<pre class="devsite-terminal devsite-click-to-copy">
+adb getenforce
+</pre>
 
 <p>将处于全局宽容模式的时间设为两周比较合理。在解决大多数拒绝事件之后,返回到强制模式,并在出现错误时加以解决。对于仍然不断出现拒绝事件的域或仍处于密集开发阶段的服务,可以暂时使其进入宽容模式,但要尽快使其返回到强制模式。</p>
 
@@ -60,7 +64,7 @@
 
 <p>核心服务生成的拒绝事件通常是通过为文件添加标签来解决的。例如:</p>
 
-<pre class="no-pretty-print">
+<pre>
 avc: denied { open } for pid=1003 comm=”mediaserver” path="/dev/kgsl-3d0”
 dev="tmpfs" scontext=u:r:mediaserver:s0 tcontext=u:object_r:device:s0
 tclass=chr_file permissive=1
@@ -92,7 +96,7 @@
 
 <p>该服务是在设备的 <code>init.&lt;target&gt;.rc</code> 文件中启动的,如下所示:</p>
 
-<pre class="no-pretty-print">
+<pre class="devsite-click-to-copy">
 service foo /system/bin/foo
     class core
 </pre>
@@ -102,7 +106,7 @@
 
       <p>创建包含以下内容的文件 <code>device/&lt;oem&gt;/&lt;target&gt;/sepolicy/foo.te</code>:</p>
 
-<pre class="no-pretty-print">
+<pre class="devsite-click-to-copy">
 # foo service
 type foo, domain;
 type foo_exec, exec_type, file_type;
@@ -118,7 +122,7 @@
       <p>将以下内容添加到 <code>device/&lt;oem&gt;/&lt;target&gt;/sepolicy/
          file_contexts</code>:</p>
 
-<pre class="no-pretty-print">
+<pre class="devsite-click-to-copy">
 /system/bin/foo   u:object_r:foo_exec:s0
 </pre>
 
@@ -145,7 +149,7 @@
 
 <p>以下示例规则类似于锁着前门,但开着窗户:</p>
 
-<p><code>allow { domain -untrusted_app } scary_debug_device:chr_file rw_file_perms</code>。</p>
+<pre>allow { domain -untrusted_app } scary_debug_device:chr_file rw_file_perms</pre>
 
 <p>该规则的意图很明确:除了第三方应用之外,其他所有应用都可以访问调试设备。</p>
 
@@ -182,12 +186,4 @@
 
 <p><code> dac_override</code> 拒绝事件意味着违规进程正在尝试使用错误的 unix user/group/world 权限访问某个文件。正确的解决方案几乎从不授予 <code>dac_override</code> 权限,而是<a href="https://android-review.googlesource.com/#/c/174530/5/update_engine.te@11">更改相应文件或进程的 unix 权限</a>。有些域(例如 init、vold 和 installd)确实需要能够替换 unix 文件权限才能访问其他进程的文件。要查看更深入的讲解,请访问 <a href="http://danwalsh.livejournal.com/69478.html">Dan Walsh 的博客</a>。</p>
 
-<h2 id="additional_resources">其他资源</h2>
-
-<p>如果要提问或提出代码审核请求,<a href="http://seandroid.bitbucket.org/ForMoreInformation.html">SEAndroid 论坛</a>是一个的绝佳场所。</p>
-
-<p>AOSP 提供了关于 <a href="index.html">Android 上的 SELinux</a> 的简要介绍。</p>
-
-<p>如需更深入的说明,请点击<a href="http://seandroid.bitbucket.org/">此处</a>。</p>
-
 </body></html>
\ No newline at end of file
diff --git a/zh-cn/security/selinux/implement.html b/zh-cn/security/selinux/implement.html
index 69abd1c..19bf984 100644
--- a/zh-cn/security/selinux/implement.html
+++ b/zh-cn/security/selinux/implement.html
@@ -20,7 +20,9 @@
       limitations under the License.
   -->
 
-<p>SELinux 设为了“默认拒绝”模式,也就是说,对于在内核中存在钩子的每一次访问,都必须获得政策的明确许可。这意味着政策文件中包含规则、类型、类、权限等方面的大量信息。关于 SELinux 的完整注意事项不在本文档的讨论范围之内,现在您必须要了解的是在启动新的 Android 设备时如何编写政策规则。目前有大量关于 SELinux 的信息可供您参考。关于建议的资源,请参阅<a href="/security/selinux#supporting_documentation">支持文档</a>。</p>
+<p>SELinux 被设置为“默认拒绝”模式,这表示,对于在内核中存在钩子的每一次访问,都必须获得政策的明确许可。这意味着政策文件中包含规则、类型、类、权限等方面的大量信息。关于 SELinux 的完整注意事项不在本文档的讨论范围之内,现在您必须要了解的是在启动新的 Android 设备时如何编写政策规则。目前有大量关于 SELinux 的信息可供您参考。关于建议的资源,请参阅<a href="/security/selinux#supporting_documentation">支持文档</a>。</p>
+
+<aside class="note"><strong>注意</strong>:要详细了解如何在 Android 8.0 中实现 SELinux,请参阅 <a href="/security/selinux/images/SELinux_Treble.pdf">SELinux for Android 8.0</a>。</aside>
 
 <h2 id="summary_of_steps">步骤总结</h2>
 
@@ -31,7 +33,7 @@
   </li><li>为通过 <code>init</code> 启动的每项服务(进程或守护进程)分配专用的域。
   </li><li>通过以下方式标识这些服务:<ul>
     <li>查看 init.&lt;device&gt;.rc 文件并找到所有服务。
-    </li><li>检查 <code>dmesg</code> 输出中以下形式的警告:“init:  Warning!  Service name needs a SELinux domain defined; please fix!”(init:警告!服务名称需要一个已定义的 SELinux 域;请更正!)。<em></em>
+    </li><li>检查 <code>dmesg</code> 输出中以下形式的警告:“init: Warning! Service name needs a SELin ux domain defined; please fix!”(init:警告!服务名称需要一个已定义的 SELinux 域;请更正!)<em></em>。
     </li><li>检查 <code>ps -Z | grep init</code> 输出,看看哪些服务正在 init 域中运行。
   </li></ul>
   </li><li>为所有新进程、驱动程序、套接字等添加标签。需要为所有对象添加适当的标签,以确保它们能够与您应用的政策正确交互。请参阅 AOSP 中使用的标签,以便在创建标签名称时参考。
@@ -55,18 +57,18 @@
 <ul>
   <li><em></em>新的 SELinux 政策源代码 (*.te) 文件 - 位于 <root>/device/manufacturer/device-name/sepolicy 目录中。这些文件用于定义域及其标签。在编译到单个 SELinux 内核政策文件时,新的政策文件会与现有的政策文件组合在一起。
 <p class="caution"><strong>重要提示</strong>:请勿更改 Android 开放源代码项目提供的 app.te 文件,否则可能会破坏所有第三方应用。</p>
-  </root></li><li><em></em>更新后的 BoardConfig.mk Makefile - 位于<device-name>包含 sepolicy 子目录的目录中。如果初始实现中没有 sepolicy 子目录,那么在该子目录创建之后,必须更新 BoardConfig.mk makefile,以引用该子目录。
+  </root></li><li><em></em>更新后的 BoardConfig.mk makefile - 位于<device-name>包含 sepolicy 子目录的目录中。如果初始实现中没有 sepolicy 子目录,那么在该子目录创建之后,必须更新 BoardConfig.mk makefile,以引用该子目录。
   </device-name></li><li><em></em>file_contexts - 位于 sepolicy 子目录中。该文件用于为文件分配标签,并且可供多种用户空间组件使用。在创建新政策时,请创建或更新该文件,以便为文件分配新标签。要应用新的 file_contexts,您必须重新构建文件系统映像,或对要重新添加标签的文件运行 <code>restorecon</code>。在升级时,对 file_contexts 所做的更改会在升级过程中自动应用于系统和用户数据分区。此外,还可以通过以下方式使这些更改在升级过程中自动应用于其他分区:在以允许读写的方式装载相应分区后,将 restorecon_recursive 调用添加到 init.<em>board</em>.rc 文件中。
   </li><li><em></em>genfs_contexts - 位于 sepolicy 子目录中。该文件用于为不支持扩展属性的文件系统(例如,proc 或 vfat)分配标签。此配置会作为内核政策的一部分进行加载,但更改可能对核心内 inode 无效。要全面应用更改,需要重新启动设备,或卸载后重新装载文件系统。此外,通过使用 context=mount 选项,还可以为装载的特定系统文件(例如 vfat)分配特定标签。
-  </li><li><em></em>property_contexts - 位于 sepolicy 子目录中。该文件用于为 Android 系统属性分配标签,以便控制哪些进程可以设置这些属性。在启动期间以及 selinux.reload_policy 属性每次被设为 1 时,init 进程都会读取此配置。
-  </li><li><em></em>service_contexts - 位于 sepolicy 子目录中。该文件用于为 Android Binder 服务分配标签,以便控制哪些进行可以为相应服务添加(注册)和查找(查询)Binder 引用。在启动期间以及 selinux.reload_policy 属性每次被设为 1 时,servicemanager 进程都会读取此配置。
-  </li><li><em></em>seapp_contexts - 位于 sepolicy 子目录中。该文件用于为应用进程和 /data/data 目录分配标签。在每次应用启动时,Zygote 进程都会读取此配置;在启动期间以及 selinux.reload_policy 属性每次被设为 1 时,installd 都会读取此配置。
+  </li><li><em></em>property_contexts - 位于 sepolicy 子目录中。该文件用于为 Android 系统属性分配标签,以便控制哪些进程可以设置这些属性。在启动期间,init 进程会读取此配置。
+  </li><li><em></em>service_contexts - 位于 sepolicy 子目录中。该文件用于为 Android Binder 服务分配标签,以便控制哪些进行可以为相应服务添加(注册)和查找(查询)Binder 引用。在启动期间,servicemanager 进程会读取此配置。
+  </li><li><em></em>seapp_contexts - 位于 sepolicy 子目录中。该文件用于为应用进程和 /data/data 目录分配标签。在每次应用启动时,zygote 进程都会读取此配置;在启动期间,installd 会读取此配置。
   </li><li><em></em>mac_permissions.xml - 位于 sepolicy 子目录中。该文件用于根据应用签名和应用软件包名称(后者可选)为应用分配 seinfo 标记。然后,分配的 seinfo 标记可在 seapp_contexts 文件中用作密钥,以便为带有该 seinfo 标记的所有应用分配特定标签。在启动期间,system_server 会读取此配置。
 </li></ul>
 
 <p>接下来,只需在 sepolicy 子目录和各个政策文件创建之后,更新 BoardConfig.mk Makefile(位于包含 sepolicy 子目录的目录中)以引用该子目录和这些政策文件即可,如下所示。BOARD_SEPOLICY 变量及其含义记录在 system/sepolicy/README 文件中。</p>
 
-<pre>
+<pre class="devsite-click-to-copy">
 BOARD_SEPOLICY_DIRS += \
         &lt;root&gt;/device/manufacturer/device-name/sepolicy
 
@@ -106,20 +108,30 @@
   <li>在内核中启用 SELinux:
 <code>CONFIG_SECURITY_SELINUX=y</code>
   </li><li>更改 kernel_cmdline 参数,以便:<br />
-<code>BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive</code>。
+<pre class="devsite-click-to-copy">
+BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
+</pre>
 <br />
 这仅适用于初始制定设备政策的情况。在拥有初始引导程序政策后,请移除此参数,以便将设备恢复强制模式,否则设备将无法通过 CTS 验证。</li><li>以宽容模式启动系统,看看在启动时会遇到哪些拒绝事件:<br />
 在 Ubuntu 14.04 或更高版本中:<br />
-<code>adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/<em>board</em>/root/sepolicy</code>
+<pre class="devsite-terminal devsite-click-to-copy">
+adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/<var>BOARD</var>/root/sepolicy
+</pre>
 <br />
-在 Ubuntu 12.04 中:
-<code>adb shell su -c dmesg | grep denied | audit2allow</code>
+在 Ubuntu 12.04 中:<br />
+<pre class="devsite-terminal devsite-click-to-copy">
+adb shell su -c dmesg | grep denied | audit2allow
+</pre>
   </li><li>评估输出。如需查看相关说明和工具,请参阅<a href="validate.html">验证</a>。
   </li><li>标识设备以及需要添加标签的其他新文件。
   </li><li>为您的对象使用现有标签或新标签。查看 *_contexts 文件,了解之前是如何为内容添加标签的,然后根据对标签含义的了解分配一个新标签。这最好是一个能够融入到政策中的现有标签,但有时需要使用新标签,并且还需要关于访问该标签的规则。
   </li><li>标识应该拥有自己的安全域的域/进程。可能需要为其中每个域/进程从头开始编写政策。例如,从 <code>init</code> 衍生的所有服务都应该有自己的安全域。可以通过以下命令查看保持运行的服务(不过所有服务都需要如此处理):<br />
-<code>$ adb shell su -c ps -Z | grep init</code><br />
-<code>$ adb shell su -c dmesg | grep 'avc: '</code>
+<pre class="devsite-terminal devsite-click-to-copy">
+adb shell su -c ps -Z | grep init
+</pre>
+<pre class="devsite-terminal devsite-click-to-copy">
+adb shell su -c dmesg | grep 'avc: '
+</pre>
   </li><li>查看 init.&lt;device&gt;.rc,以找出所有没有类型的服务。应提早为此类服务提供域,以避免向 init 添加规则或将 <code>init</code> 访问权限与其自身政策中的访问权限混淆。
   </li><li>将 <code>BOARD_CONFIG.mk</code> 设为使用 <code>BOARD_SEPOLICY_*</code> 变量。如需关于如何进行此项设置的详细信息,请参阅 system/sepolicy 中的 README。
   </li><li>检查 init.&lt;device&gt;.rc 和 fstab.&lt;device&gt; 文件,确保每一次使用“mount”都对应一个添加了适当标签的文件系统,或者指定了 context= mount 选项。
diff --git a/zh-cn/security/selinux/index.html b/zh-cn/security/selinux/index.html
index b163e3d..5545238 100644
--- a/zh-cn/security/selinux/index.html
+++ b/zh-cn/security/selinux/index.html
@@ -20,48 +20,59 @@
       limitations under the License.
   -->
 
-<h2 id="introduction">简介</h2>
-
 <p>Android 安全模型部分基于应用沙盒的概念。每个应用都在自己的沙盒内运行。在 Android 4.3 之前的版本中,这些沙盒是通过为每个应用创建独一无二的 Linux UID(在应用安装时创建)来定义的。从 Android 4.3 版起,安全增强型 Linux (SELinux) 开始用于进一步定义 Android 应用沙盒的边界。</p>
 
+<aside class="note"><strong>注意</strong>:要详细了解 Android 8.0 SELinux,请参阅 <a href="/security/selinux/images/SELinux_Treble.pdf">SELinux for Android 8.0</a>。</aside>
+
 <p>作为 Android <a href="/security/index.html">安全模型</a>的一部分,Android 使用 SELinux 对所有进程强制执行强制访问控制 (MAC),其中包括以 Root/超级用户权限运行的进程(也称为 Linux 功能)。SELinux 能够限制特权进程并能够自动创建安全政策,从而可提升 Android 的安全性。</p>
 
-<p>很多公司和组织都为此做出了卓越的贡献;<a href="https://android.googlesource.com/">android.googlesource.com</a> 上公开了所有 Android 代码和贡献者,以供所有人查看。借助 SELinux,Android 可以更好地保护和限制系统服务、控制对应用数据和系统日志的访问、降低恶意软件的影响,并保护用户免遭移动设备上的代码可能存在的缺陷的影响。</p>
+<p>很多公司和组织都为 SELinux 做出了贡献;<a href="https://android.googlesource.com/" class="external">android.googlesource.com</a>(也称为 Android 开放源代码项目 (AOSP))上公开了他们所做的贡献,以供所有人查看。借助 SELinux,Android 可以更好地保护和限制系统服务、控制对应用数据和系统日志的访问、降低恶意软件的影响,并保护用户免遭移动设备上的代码可能存在的缺陷的影响。</p>
 
-<p>Android 中包含 SELinux(处于强制模式)和默认适用于整个 <a href="https://android.googlesource.com/">Android 开放源代码项目</a>的相应安全政策。在强制模式下,非法操作会被阻止,并且所有尝试进行的违规行为都会被内核记录到 <code>dmesg</code> 和 <code>logcat</code> 中。Android 设备制造商应收集与错误相关的信息,以便在实施其软件和 SELinux 政策之前先对其进行优化。</p>
+<p>Android 中包含 SELinux(处于强制模式)和默认适用于整个 AOSP 的相应安全政策。在强制模式下,非法操作会被阻止,并且尝试进行的所有违规行为都会被内核记录到 <code>dmesg</code> 和 <code>logcat</code> 中。Android 设备制造商应收集与错误相关的信息,以便在实施其软件和 SELinux 政策之前先对其进行优化。</p>
 
 <h2 id="background">背景</h2>
-
-<p>SELinux 采用默认拒绝的方式运行。任何未经明确允许的行为都会被拒绝。SELinux 可以采用以下任一种全局模式运行:宽容模式和强制模式。在宽容模式下,权限拒绝事件会被记录下来,但不会被强制执行;在强制模式下,拒绝事件会被记录下来,并且会被强制执行。此外,SELinux 还支持特定域宽容模式。在这种模式下,可将特定域(进程)设为宽容域,同时使系统的其余部分处于全局强制模式。域简单来说就是安全政策中用于标识一个进程或一组进程的标签,安全政策会以相同的方式对待使用相同域作为标签的所有进程。借助特定域宽容模式,可逐渐将 SELinux 应用于系统中越来越多的部分。此外,借助特定域宽容模式,还可以为新服务制定政策,同时确保系统的其余部分处于强制模式。</p>
-
-<p>在 Android 5.0 (L) 版本中,Android 开始全面强制执行 SELinux。这基于 4.3 版中的宽容模式和 4.4 中的部分强制模式。简而言之,Android 正在从对有限的一组关键域(<code>installd</code>、<code>netd</code>、<code>vold</code> 和 <code>zygote</code>)强制执行 SELinux 转为对所有域(超过 60 个域)强制执行 SELinux。这意味着,制造商必须要更好地了解并扩展其 SELinux 实现,以便提供兼容的设备。请注意:</p>
-
+<p>SELinux 按照默认拒绝的原则运行:任何未经明确允许的行为都会被拒绝。SELinux 可按两种全局模式之一运行:</p>
 <ul>
-<li>在 5.0 版中,所有域均处于强制模式</li>
-<li><code>init</code> 以外的任何进程都不应在 <code>init</code> 域中运行</li>
-<li>如果出现任何常规拒绝事件(对于 block_device、socket_device、default_service 等),都表示设备需要一个特殊域</li>
+<li><em></em>宽容模式:权限拒绝事件会被记录下来,但不会被强制执行。</li>
+<li><em></em>强制模式:权限拒绝事件会被记录下来<strong>并</strong>强制执行。</li>
 </ul>
 
-<h2 id="supporting_documentation">支持文档</h2>
+<p>此外,SELinux 还支持基于域的宽容模式。在这种模式下,可将特定域(进程)设为宽容模式,同时使系统的其余部分处于强制全局模式。<em></em>域简单来说就是安全政策中用于标识一个进程或一组进程的标签,安全政策会以相同的方式对待所有具有相同域标签的进程。借助基于域的宽容模式,可逐渐将 SELinux 应用于系统中越来越多的部分,还可以为新服务制定政策(同时确保系统的其余部分处于强制模式)。</p>
 
-<p>如需关于如何构建实用政策的详细信息,请参阅以下文档:</p>
+<p>基于 Android 4.3(宽容模式)和 Android 4.4(部分强制模式)的 Android 5.0 版本,开始全面强制执行 SELinux。
+通过此项变更,Android 已从对有限的一组关键域(<code>installd</code>、<code>netd</code>、<code>vold</code> 和 <code>zygote</code>)强制执行 SELinux 转为对所有域(超过 60 个域)强制执行 SELinux。具体而言:</p>
 
-<p><a href="http://seandroid.bitbucket.org/PapersandPresentations.html">http://seandroid.bitbucket.org/PapersandPresentations.html</a></p>
+<ul>
+<li>在 Android 5.x 及更高版本中,所有域均处于强制模式。</li>
+<li><code>init</code> 以外的任何进程都不应在 <code>init</code> 域中运行。</li>
+<li>如果出现任何常规拒绝事件(对于 <code>block_device</code>、<code>socket_device</code>、<code>default_service</code> 等),都表示设备需要一个特殊域。</li>
+</ul>
+<p>因此,制造商需要更好地了解并扩展其 SELinux 实现,以便提供兼容的设备。</p>
 
-<p><a href="https://www.codeproject.com/Articles/806904/Android-Security-Customization-with-SEAndroid">https://www.codeproject.com/Articles/806904/Android-Security-Customization-with-SEAndroid</a></p>
+<h2 id="supporting_documentation">其他资源</h2>
 
-<p><a href="https://events.linuxfoundation.org/sites/events/files/slides/abs2014_seforandroid_smalley.pdf">https://events.linuxfoundation.org/sites/events/files/slides/abs2014_seforandroid_smalley.pdf</a></p>
+<p>如需关于构建实用 SELinux 政策的帮助,请参阅以下资源:</p>
 
-<p><a href="https://www.internetsociety.org/sites/default/files/02_4.pdf">https://www.internetsociety.org/sites/default/files/02_4.pdf</a></p>
+<ul><li><a href="https://events.linuxfoundation.org/sites/events/files/slides/abs2014_seforandroid_smalley.pdf" class="external">
+Security Enhancements for Linux(针对 Linux 的安全增强功能)</a></li>
 
-<p><a href="http://freecomputerbooks.com/books/The_SELinux_Notebook-4th_Edition.pdf">http://freecomputerbooks.com/books/The_SELinux_Notebook-4th_Edition.pdf</a></p>
+<li><a href="http://www.cs.columbia.edu/~lierranli/coms6998-7Spring2014/papers/SEAndroid-NDSS2013.pdf" class="external">
+Security Enhanced (SE) Android: Bringing Flexible MAC to Android(安全增强 (SE) Android:在 Android 中引入灵活 MAC)</a></li>
 
-<p><a href="http://selinuxproject.org/page/ObjectClassesPerms">http://selinuxproject.org/page/ObjectClassesPerms</a></p>
+<li><a href="http://freecomputerbooks.com/books/The_SELinux_Notebook-4th_Edition.pdf" class="external">
+The SELinux Notebook, 4th Edition(SELinux 手册第 4 版)</a></li>
 
-<p><a href="https://www.nsa.gov/resources/everyone/digital-media-center/publications/research-papers/assets/files/implementing-selinux-as-linux-security-module-report.pdf">https://www.nsa.gov/resources/everyone/digital-media-center/publications/research-papers/assets/files/implementing-selinux-as-linux-security-module-report.pdf</a></p>
+<li><a href="http://selinuxproject.org/page/ObjectClassesPerms" class="external">
+SELinux Object Classes and Permissions Reference(SELinux 对象类和权限参考)</a></li>
 
-<p><a href="https://www.nsa.gov/resources/everyone/digital-media-center/publications/research-papers/assets/files/configuring-selinux-policy-report.pdf">https://www.nsa.gov/resources/everyone/digital-media-center/publications/research-papers/assets/files/configuring-selinux-policy-report.pdf</a></p>
+<li><a href="https://www.nsa.gov/resources/everyone/digital-media-center/publications/research-papers/assets/files/implementing-selinux-as-linux-security-module-report.pdf" class="external">
+Implementing SELinux as a Linux Security Module(将 SELinux 作为 Linux 安全模块实现)</a></li>
 
-<p><a href="https://www.gnu.org/software/m4/manual/index.html">https://www.gnu.org/software/m4/manual/index.html</a></p>
+<li><a href="https://www.nsa.gov/resources/everyone/digital-media-center/publications/research-papers/assets/files/configuring-selinux-policy-report.pdf" class="external">
+Configuring the SELinux Policy(配置 SELinux 政策)</a></li>
+
+<li><a href="https://www.gnu.org/software/m4/manual/index.html" class="external">
+GNU M4 - GNU Macro Processor Manual(GNU M4 - GNU 宏处理器手册)</a></li>
+</ul>
 
 </body></html>
\ No newline at end of file
diff --git a/zh-cn/security/selinux/validate.html b/zh-cn/security/selinux/validate.html
index 7db99c9..701feef 100644
--- a/zh-cn/security/selinux/validate.html
+++ b/zh-cn/security/selinux/validate.html
@@ -61,9 +61,9 @@
 
 <ul>
   <li><em></em>操作 - 试图进行的操作使用括号突出显示:<code>read write</code> 或 <code>setenforce</code>。
-  </li><li><em></em>操作方 - <code>scontext</code>(来源环境)条目表示操作方,在该示例中是<code> rmt_storage</code> 守护进程。
-  </li><li><em></em>对象 - <code>tcontext</code>(目标环境)条目表示正在对哪个对象执行操作,在该示例中是 kmem。
-  </li><li><em></em>结果 - <code>tclass</code>(目标类别)条目表示操作对象的类型,在该示例中是 <code>chr_file</code>(字符设备)。
+  </li><li><em></em>操作方 - <code>scontext</code>(来源环境)条目表示操作方;在该示例中为<code> rmt_storage</code> 守护进程。
+  </li><li><em></em>对象 - <code>tcontext</code>(目标环境)条目表示正在对哪个对象执行操作;在该示例中为 kmem。
+  </li><li><em></em>结果 - <code>tclass</code>(目标类别)条目表示当前操作对象的类型;在该示例中为 <code>chr_file</code>(字符设备)。
 </li></ul>
 
 <h2 id="switching_to_permissive">切换到宽容模式</h2>
diff --git a/zh-cn/security/trusty/index.html b/zh-cn/security/trusty/index.html
index 71a2436..344f41d 100644
--- a/zh-cn/security/trusty/index.html
+++ b/zh-cn/security/trusty/index.html
@@ -84,10 +84,10 @@
 <a href="https://android.googlesource.com/kernel/common/+/android-trusty-3.18">https://android.googlesource.com/kernel/common/+/android-trusty-3.18</a></p>
 
 <p>要实现 Trusty,请运行以下命令(假设 Android 工具链已位于路径中):</p>
-<pre>
-$ repo init -u https://android.googlesource.com/trusty/manifest
-$ repo sync
-$ make -j24 generic-arm64
+<pre class="devsite-click-to-copy">
+<code class="devsite-terminal">repo init -u https://android.googlesource.com/trusty/manifest</code>
+<code class="devsite-terminal">repo sync</code>
+<code class="devsite-terminal">make -j24 generic-arm64</code>
 </pre>
 
 <p>您可以从 <code>device/*/*/project/*</code> 中选择其他受支持的编译目标</p>
diff --git a/zh-cn/security/verifiedboot/verified-boot.html b/zh-cn/security/verifiedboot/verified-boot.html
index 4068f77..06107d0 100644
--- a/zh-cn/security/verifiedboot/verified-boot.html
+++ b/zh-cn/security/verifiedboot/verified-boot.html
@@ -133,14 +133,20 @@
     <td><code>flashing lock</code></td>
     <td>
       <ul>
-        <li>先提示用户确认,在用户确认之后清除数据</li><li>清除引导加载程序可读取的防写位,指明设备已解锁</li></ul>
+        <li>先提示用户确认,在用户确认之后清除数据。
+        </li><li>清除防写位以锁定设备。
+            由于该位可防写,因此只有引导加载程序可以对其进行更改。
+      </li></ul>
     </td>
  </tr>
  <tr>
     <td><code>flashing unlock</code></td>
     <td>
       <ul>
-        <li>如果用户尚未启用解锁设备设置,则中止解锁</li><li>先提示用户确认,在用户确认之后清除数据</li><li>设置引导加载程序可读取的防写位,指明设备已解锁</li></ul>
+        <li>如果用户尚未启用解锁设备设置,则中止解锁</li><li>先提示用户确认,在用户确认之后清除数据
+        </li><li>设置防写位以解锁设备。
+            由于该位可防写,因此只有引导加载程序可以对其进行更改。
+      </li></ul>
     </td>
  </tr>
 </tbody></table>
@@ -278,7 +284,7 @@
 
 <p>Android 可验证启动映像上的签名是一条经过 ASN.1 DER 编码的消息,可以使用与 <a href="https://android.googlesource.com/platform/bootable/recovery/+/f4a6ab27b335b69fbc419a9c1ef263004b561265/asn1_decoder.cpp">platform/bootable/recovery/asn1_decoder.cpp</a> 中提供的解码器类似的解码器对该消息进行解析<br />消息格式如下:</p>
 
-<pre>
+<pre class="devsite-click-to-copy">
 AndroidVerifiedBootSignature DEFINITIONS ::=
      BEGIN
           FormatVersion ::= INTEGER