Below is a mock C++ code snippet for a custom KeyMint or Keymaster HAL implementation that re-registers a factory-provisioned key into Android Keystore2 at boot time.
This is useful when:
- A key was pre-provisioned at the factory into QSFS/SPU
- Its Android-side metadata was deleted (e.g.,
/data/misc/keystore/) - You want to rebind it to an alias and make it available again to apps
🛠️ 🔧 Mock HAL Code: Re-register Pre-Provisioned Key
📁 File: KeymasterDevice.cpp
📦 Layer: Android KeyMint HAL or vendor Keymaster HAL
⚙️ Context: Called during boot or HAL initialize() function
cppCopyEdit#include <keymaster/key_blob.h>
#include <keymaster/key_store.h>
#include <keymaster/logger.h>
#include <keymint_support/authorization_set.h>
// Assumes existence of device-specific SPU API
#include "provisioned_key_loader.h" // Your internal OEM API
namespace vendor {
namespace mycompany {
namespace keymaster {
bool reRegisterFactoryProvisionedKey(const std::string& alias) {
LOG_I("🔁 Re-registering factory key: %s", alias.c_str());
// 1. Load the key from secure storage (QSFS/SPU)
SecureKeyBlob spu_blob;
if (!loadKeyFromSpu("provisioned_key_id_001", &spu_blob)) {
LOG_E("❌ Failed to load key from SPU");
return false;
}
// 2. Define key characteristics (match what was provisioned)
AuthorizationSet auths;
auths.push_back(TAG_ALGORITHM, Algorithm::RSA);
auths.push_back(TAG_PURPOSE, KeyPurpose::SIGN | KeyPurpose::VERIFY);
auths.push_back(TAG_KEY_SIZE, 2048);
auths.push_back(TAG_ORIGIN, KeyOrigin::PROVISIONED);
auths.push_back(TAG_ROLLBACK_RESISTANT);
auths.push_back(TAG_NO_AUTH_REQUIRED);
auths.push_back(TAG_ALIAS, alias); // Set target alias for Keystore
// 3. Wrap into Android-compatible KeyBlob
KeyBlob wrapped_blob;
if (!wrapKey(spu_blob, auths, &wrapped_blob)) {
LOG_E("❌ Key wrapping failed");
return false;
}
// 4. Register with Keystore2 (via service or internal DB)
if (!registerKeyWithKeystore2(alias, wrapped_blob, auths)) {
LOG_E("❌ Failed to register alias with Keystore2");
return false;
}
LOG_I("✅ Key '%s' successfully re-registered", alias.c_str());
return true;
}
} // namespace keymaster
} // namespace mycompany
} // namespace vendor
🧠 Key Components Explained
| Step | What It Does |
|---|---|
loadKeyFromSpu() | Vendor-specific function to load a key from QSFS/SPU based on internal ID |
AuthorizationSet | Defines the key’s capabilities and constraints |
wrapKey() | Prepares a KeyBlob structure (optional signing or encryption) |
registerKeyWithKeystore2() | Inserts alias and blob into Keystore2’s key table (e.g., /data/misc/keystore2/) or via HAL callback |
📦 Optional: Use Keystore2 Binder Interface to Register
If your HAL is separate from Keystore2 service, use Android’s binder service to push the key:
cppCopyEditsp<IKeystoreService> ks = getKeystoreService();
ks->importKey(
/* alias */ "shared_key",
/* blob */ wrapped_blob,
/* metadata */ auths,
/* uid */ AID_SYSTEM
);
✅ What This Achieves
| ✅ Outcome | ✅ Benefit |
|---|---|
| Rebinds factory key → usable alias | Avoids complete key regeneration |
| Recovers deleted metadata | Enables post-reset secure boot logic |
| Centralizes key reuse policy | Enables sharing across system components (attestation, secure logging, etc.) |
flowchart of the re-registration flow (HAL → TEE → Keystore2)

Here’s a mock init.rc trigger that automatically runs a key re-registration routine during early device boot, typically used in OEM firmware or custom AOSP builds.
This integrates your C++ re-registration logic (from the HAL) into the Android boot process via init.rc.
📦 📁 File: init.keyrestore.rc
rcCopyEdit# init.keyrestore.rc
on early-boot
# Start the service that re-registers factory-provisioned keys
start keyrestore
service keyrestore /vendor/bin/keyrestore_daemon
class main
user system
group system
oneshot
seclabel u:r:system_server:s0
disabled
oneshot
⚙️ How It Works
| Part | Explanation |
|---|---|
on early-boot | Triggered before Zygote, when HALs and KeyMint are being initialized |
service keyrestore | Launches a binary (/vendor/bin/keyrestore_daemon) that contains your HAL-based key re-registration logic |
class main | Ensures it runs in the main boot class |
oneshot | Ensures it runs only once on boot |
seclabel | Ensures proper SELinux domain (e.g., system_server or hal_keymaster) |
🛠️ What /vendor/bin/keyrestore_daemon Does
This binary:
- Links to your
KeymasterDevice.cpplogic - Calls
reRegisterFactoryProvisionedKey("alias") - Logs to
logcatordmesgon success/failure - Optionally signals system services that key is ready
✅ AOSP Integration
To integrate this into your AOSP or OEM firmware:
- 📁 Place this RC file in: php-templateCopyEdit
device/<vendor>/<product>/init.keyrestore.rc - 📜 Add it to your BoardConfig: makeCopyEdit
PRODUCT_COPY_FILES += \ device/<vendor>/<product>/init.keyrestore.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/init.keyrestore.rc - 🔗 Ensure
/vendor/bin/keyrestore_daemonis part of yourPRODUCT_PACKAGES
🧠 Summary
| Goal | Action |
|---|---|
| Auto re-register keys on boot | ✅ Trigger HAL logic from init.rc |
| Boot timing | ✅ Runs before apps need access |
| Permissions | ✅ Controlled by SELinux & UID |
| Custom ROM support | ✅ Fully compatible with AOSP builds |
Would you like:
- A template for the
keyrestore_daemon.cppbinary? - An SELinux policy rule for this service?
- A combined AOSP patch (RC + daemon + HAL code)?
Let me know how you’d like to continue.