Merge "Weaver: use Util.arrayCompare() to compare keys."
diff --git a/apps/boot/README.md b/apps/boot/README.md
index 65744d6..fae7c60 100644
--- a/apps/boot/README.md
+++ b/apps/boot/README.md
@@ -31,10 +31,10 @@
 
 There are four supported lock types:
 
-  - LOCK\_CARRIER
-  - LOCK\_DEVICE
-  - LOCK\_BOOT
-  - LOCK\_OWNER
+  - `LOCK_CARRIER`
+  - `LOCK_DEVICE`
+  - `LOCK_BOOT`
+  - `LOCK_OWNER`
 
 Each lock has a single byte of "lock" storage.  If that byte is 0x0, then it is
 unlocked, or cleared.  If it is non-zero, then the lock is locked.  Any
@@ -44,7 +44,7 @@
 In addition, a lock may have associated metadata which must be supplied during
 lock or unlock, or both.
 
-See ese\_boot\_lock\_\* in include/ese/app/boot.h for the specific interfaces.
+See `ese_boot_lock_*` in include/ese/app/boot.h for the specific interfaces.
 
 
 #### LOCK\_CARRIER
@@ -58,8 +58,8 @@
 
 To provision this lock, device-specific data must be provided in an exact
 format.  An example of this can be found in
-'ese-boot-tool.cpp':collect\_device\_data().  This data is then provided to
-the applet using ese\_boot\_lock\_xset().
+`'ese-boot-tool.cpp':collect_device_data()`.  This data is then provided to
+the applet using `ese_boot_lock_xset()`.
 
 ##### Metadata format for locking/provisioning
 
@@ -77,39 +77,41 @@
 
     \[length||string\]\[...\]
 
-The length is a uint8\_t and the value is appended as a stream of
-uint8\_t values.
+The length is a `uint8_t` and the value is appended as a stream of
+`uint8_t` values.
 
 This data is then prefixed with the desired non-zero lock value before
 being submitted to the applet.  If successful, the applet will have
 stored a SHA256 hash of the device data
 
-Note, LOCK\_CARRIER can only be locked (non-zero lock value) when the
-applet is in 'production' mode.
+Note, `LOCK_CARRIER` can only be locked (non-zero lock value) when the
+applet is not in 'production' mode.
 
 ##### Clearing/unlocking
 
-If LOCK\_CARRIER is set to a non-zero value and the applet is in
+If `LOCK_CARRIER` is set to a non-zero value and the applet is in
 production mode, then clearing the lock value requires authorization.
 
-Authorization comes in the form of a RSA\_SHA256-PKCS#1 signature over
+Authorization comes in the form of a `RSA_SHA256-PKCS#1` signature over
 the provisioned device data SHA256 hash and a supplied montonically
 increasing "nonce".
 
 The nonce value must be higher than the last seen nonce value and the
 signature must validate using public key internally stored in the
-applet (CarrierLock.java:PK\_MOD).
+applet (`CarrierLock.java:PK_MOD`).
 
-To perform a clear, ese\_boot\_lock\_xset() must be called with lock
+To perform a clear, `ese_boot_lock_xset()` must be called with lock
 data that begins with 0x0, to clear the lock, and then contains data of
 the following format:
 
+```
     unlockToken = VERSION || NONCE || SIGNATURE
 
     SIGNATURE = RSA_Sign(SHA256(deviceData))
+```
 
-  - The version is a little endian uint64\_t (8 bytes).
-  - The nonce is a little endian uint64\_t (8 bytes).
+  - The version is a little endian `uint64_t` (8 bytes).
+  - The nonce is a little endian `uint64_t` (8 bytes).
   - The signature is a RSA 2048-bit with SHA-256 PKCS#1 v1.5 (256 bytes).
 
 On unlock, the device data hash is cleared.
@@ -118,11 +120,13 @@
 
 It is possible to test the key with a valid signature but a fake
 internal nonce and fake internal device data using
-ese\_boot\_carrier\_lock\_test().  When using this interface, it
+`ese_boot_carrier_lock_test()`.  When using this interface, it
 expects the same unlock token as in the prior but prefixes with the
 fake data:
 
+```
     testVector = LAST_NONCE || DEVICE_DATA || unlockToken
+```
 
   - The last nonce is the value the nonce is compared against (8 bytes).
   - Device data is a replacement for the internally stored SHA-256
@@ -137,8 +141,8 @@
 by an enterprise administrator to control lock policy for managed
 devices.
 
-As LOCK\_DEVICE has not metadata, it can be set and retrieved using
-ese\_boot\_lock\_set() and ese\_boot\_lock\_get().
+As `LOCK_DEVICE` has not metadata, it can be set and retrieved using
+`ese_boot_lock_set()` and `ese_boot_lock_get()`.
 
 #### LOCK\_BOOT
 
@@ -146,35 +150,35 @@
 only boot verified system software or not.  When the lock value
 is cleared (0x0), the bootloader will boot anything.  When the lock
 value is non-zero, it should only boot software that is signed by a key
-stored in the bootloader except if LOCK\_OWNER is set.  Discussion of
-LOCK\_OWNER will follow.
+stored in the bootloader except if `LOCK_OWNER` is set.  Discussion of
+`LOCK_OWNER` will follow.
 
-LOCK\_BOOT can only be toggled when in the bootloader/fastboot and if
-both LOCK\_CARRIER and LOCK\_DEVICE are cleared/unlocked.
+`LOCK_BOOT` can only be toggled when in the bootloader/fastboot and if
+both `LOCK_CARRIER` and `LOCK_DEVICE` are cleared/unlocked.
 
-As with LOCK\_DEVICE, LOCK\_BOOT has no metadata so it does not need the
+As with `LOCK_DEVICE`, `LOCK_BOOT` has no metadata so it does not need the
 extended accessors.
 
 #### LOCK\_OWNER
 
 The owner lock is used by the bootloader to support an alternative
-OS signing key provided by the device owner.  LOCK\_OWNER can only be
-toggled if LOCK\_BOOT is cleared.  LOCK\_OWNER does not require
+OS signing key provided by the device owner.  `LOCK_OWNER` can only be
+toggled if `LOCK_BOOT` is cleared. `LOCK_OWNER` does not require
 any metadata to unlock, but to lock, it requires a blob of up to 2048
 bytes be provided.  This is just secure storage for use by the
-bootloader.  LOCK\_OWNER may be toggled in the bootloader or the
-operating system.  This allows an unlocked device (LOCK\_BOOT=0x0) to
+bootloader.  `LOCK_OWNER` may be toggled in the bootloader or the
+operating system.  This allows an unlocked device (`LOCK_BOOT=0x0`) to
 install an owner key using fastboot or using software on the operating
 system itself.
 
-Before LOCK\_OWNER's key should be honored by the bootloader, LOCK\_BOOT
+Before `LOCK_OWNER`'s key should be honored by the bootloader, `LOCK_BOOT`
 should be set (in the bootloader) to enforce use of the key and to keep
 malicious software in the operating system from changing it.
 
 (Note, that the owner key should not be treated as equivalent to the
 bootloader's internally stored key in that the device user should have a
 means of knowing if an owner key is in use, but the requirement for the
-device to be unlocked implies both physical access the LOCK\_DEVICE
+device to be unlocked implies both physical access the `LOCK_DEVICE`
 being cleared.)
 
 
@@ -187,15 +191,15 @@
 version in order to take advantage of mistakes in the older, verified
 code.
 
-Rollback indices, or versions, may be stored securely by the bootloader
+Rollback index values, or versions, may be stored securely by the bootloader
 to prevent these problems.  The Verified Boot Storage applet provides
 eight 64-bit slots for storing a value.  They may be read at any time,
 but they may only be written to when the device is in the bootloader (or
 fastboot).
 
 Rollback storage is written to using
-ese\_boot\_rollback\_index\_write() and read using
-ese\_boot\_rollback\_index\_read().
+`ese_boot_rollback_index_write()` and read using
+`ese_boot_rollback_index_read()`.
 
 ### Applet state
 
@@ -210,11 +214,11 @@
 CarrierLock verification.  This allows the factory tools to run in any
 mode and properly configure a default lock state.
 
-To transition to "production", a call to ese\_boot\_set\_production(true)
+To transition to "production", a call to `ese_boot_set_production(true)`
 is necessary.
 
 To check the state and collect debugging information, the call
-ese\_boot\_get\_state() will return the current bootloader value,
+`ese_boot_get_state()` will return the current bootloader value,
 the production state, any errors codes from lock initialization, and the
 contents of lock storage.
 
@@ -223,15 +227,15 @@
 After the applet is installed, a flow as follows would prepare the
 applet for use:
 
-  - ese\_boot\_session\_init();
-  - ese\_boot\_session\_open();
-  - ese\_boot\_session\_lock\_xset(LOCK\_OWNER, {0, ...});
-  - ese\_boot\_session\_lock\_set(LOCK\_BOOT, 0x1);
-  - ese\_boot\_session\_lock\_set(LOCK\_DEVICE, 0x1);
+  - `ese_boot_session_init();`
+  - `ese_boot_session_open();`
+  - `ese_boot_session_lock_xset(LOCK_OWNER, {0, ...});`
+  - `ese_boot_session_lock_set(LOCK_BOOT, 0x1);`
+  - `ese_boot_session_lock_set(LOCK_DEVICE, 0x1);`
   - [collect device data]
-  - ese\_boot\_session\_lock\_set(LOCK\_CARRIER, {1, deviceData});
-  - ese\_boot\_session\_set\_production(true);
-  - ese\_boot\_session\_close();
+  - `ese_boot_session_lock_set(LOCK_CARRIER, {1, deviceData});`
+  - `ese_boot_session_set_production(true);`
+  - `ese_boot_session_close();`
 
 ### Additional details
 
@@ -246,31 +250,141 @@
 
 #### Error results
 
-EseAppResult is an enum that all ese\_boot\_\* functions return.  The
+EseAppResult is an enum that all `ese_boot_*` functions return.  The
 enum only covers the lower 16-bits.  The upper 16-bits are reserved for
 passing applet and secure element OS status for debugging and analysis.
-When the lower 16-bits are ESE\_APP\_RESULT\_ERROR\_APPLET, then the
+When the lower 16-bits are `ESE_APP_RESULT_ERROR_APPLET`, then the
 upper bytes will be the applet code. That code can then be
 cross-referenced in the applet by function and code.  If the lower
-bytes are ESE\_APP\_RESULT\_ERROR\_OS, then the status code are the
+bytes are `ESE_APP_RESULT_ERROR_OS`, then the status code are the
 ISO7816 code from an uncaught exception or OS-level error.
 
 ##### Cooldown
 
-ESE\_APP\_RESULT\_ERROR\_COOLDOWN indicates that the secure element needs to
+`ESE_APP_RESULT_ERROR_COOLDOWN` indicates that the secure element needs to
 stay powered on for a period of time -- either at the end of use or before the
 requested command can be serviced.  As the behavior is implementation specific,
 the only effective option is to keep the secure element powered for the number of
-seconds specified by the response uint32\_t.
+seconds specified by the response `uint32_t`.
 
 For chips that support it, like the one this applet is being tested on, the
-cooldown time can be requested with a special APDU to ese\_transceive():
+cooldown time can be requested with a special APDU to `ese_transceive()`:
 
+```
     FFE10000
+```
 
-In response, a 6 byte response will contain a uint32\_t and a successful status
-code (90 00).  The unsigned little-endian integer indicates how many seconds
+In response, a 6 byte response will contain a `uint32_t` and a successful status
+code (`90 00`).  The unsigned little-endian integer indicates how many seconds
 the chip needs to stay powered and unused to cooldown.  If this happens before
 the locks or rollback storage can be read, the bootloader will need to
 determine a safe delay or recovery path until boot can proceed securely.
 
+## Examples
+
+There are many ways to integrate this library and the associated applet.
+Below are some concrete examples to guide standard approach.
+
+### Configuration in factory
+
+- Install configure the secure element and install the applets  
+(outside of the scope of this document).
+- Boot to an environment to run the ese-boot-tool.
+- Leave the inBootloader() signal asserted (recommended but not required).
+- Configure the desired lock states:
+  - `# ese-boot-tool lock set carrier 1 modem-imei-string`
+  - `# ese-boot-tool lock set device 1`
+  - `# ese-boot-tool lock set boot 1`
+  - `# ese-boot-tool lock set owner 0`
+- To move from factory mode to production mode call:
+  - `# ese-boot-tool production set true`
+
+### Configuration during repair
+
+- Boot to an environment to run the ese-boot-tool.
+- Leave inBootloader() signal asserted or implement the steps below in  
+  the bootloader.
+- Transition out of production mode:
+  - `# ese-boot-tool production set false`
+- If a `LOCK_CARRIER` problem is being repaired, it is possible to reset the  
+  internal nonce counter and all lock state with the command below.  A full  
+  lock reset is not expected in most cases.
+  - `# ese-boot-tool lock reset`
+- Reconfigure the lock states:
+  - `# ese-boot-tool lock set carrier 1 modem-imei-string`
+  - `# ese-boot-tool lock set device 1`
+  - `# ese-boot-tool lock set boot 1`
+  - `# ese-boot-tool lock set owner 0`
+    (To clear data from the owner lock, set owner 1 must be called with  
+     4096 00s.)
+- Then move back to production mode:
+  - `# ese-boot-tool production set true`
+
+### Use during boot
+
+Do not load any non-repair or non-factory OS without clearing the inBootloader
+signal as the applet may be transitioned out of production mode and/or the
+rollback state may be changed.
+
+#### Checking rollback values
+
+- Read and write rollback values as per libavb using the API
+  - `ese_boot_rollback_index_write()`
+  - `ese_boot_rollback_index_read()`
+- Prior to leaving the bootloader, clear the inBootloader signal.
+
+As rollback index values can only be written when inBootloader signal is set,
+it is critical to clear it when leaving the bootloader.
+
+#### Checking locks
+
+The pseudo-code and comments below should outline the basic algorithm, but it
+does not include integration into libavb or include use of rollback index
+value checking:
+
+```
+// Read LOCK_BOOT
+ese_boot_lock_get(session, kEseBootLockIdBoot, &lockBoot);
+
+if (lockBoot != 0x0) {  // Boot is LOCKED.
+    // Read the LOCK_OWNER
+    ese_boot_lock_xget(session, kEseBootLockIdOwner, &lockOwner);
+    if (lockOwner != 0x0) {  // Owner is LOCKED
+      // Get the lock owner value with metadata.
+      // This is done as a second stage to avoid wasted copying when it
+      // is not locked.
+      uint8_t ownerData[kEseBootOwnerKeyMax + 1];
+      ese_boot_lock_xget(session, kEseBootLockIdOwner, ownerData
+                         sizeof(ownerData), &ownerDataUsed);
+      // lockOwner == ownerData[0]
+      // Parse the stored metadata into a key as per your bootloader
+      // design.
+      SomeBootKey key;
+      parseDeviceOwnerKeyForBooting(ownerData + 1, ownerDataUsed, &key);
+      // Boot using the supplied owner key
+      // (E.g., as part of avb_validate_vbmeta_public_key())
+      setDeviceOwnerKeyForBooting(&key);
+      continueBootFlow();
+} else {  // Boot is UNLOCKED (0x0)
+    // Perform the boot flow.
+    setBootIsUnverified();
+    continueBootFlow();
+}
+```
+
+### In fastboot
+
+- `LOCK_BOOT` may be toggled by a fastboot command.  If the conditions of  
+  unlock are not allowed by applet policy, it will fail.
+- `LOCK_OWNER`may be toggled and set a boot key from a fastboot command  
+  or from an unlocked OS image.
+- If the verified boot design dictates that rollback indices are clear on  
+  lock/unlock, this can be done by calling
+  - `ese_boot_rollback_index_write()` on each slot with the value of 0.
+
+Note, `LOCK_DEVICE` and `LOCK_CARRIER` should not need to be used by fastboot.
+
+For debugging and support, it may be desirable to connect the
+`ese_boot_get_state()` to allow fastboot to return the current value of
+production, inbootloader, and the lock metadata.
+