162306a36Sopenharmony_ci===============
262306a36Sopenharmony_ciNVDIMM Security
362306a36Sopenharmony_ci===============
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci1. Introduction
662306a36Sopenharmony_ci---------------
762306a36Sopenharmony_ci
862306a36Sopenharmony_ciWith the introduction of Intel Device Specific Methods (DSM) v1.8
962306a36Sopenharmony_cispecification [1], security DSMs are introduced. The spec added the following
1062306a36Sopenharmony_cisecurity DSMs: "get security state", "set passphrase", "disable passphrase",
1162306a36Sopenharmony_ci"unlock unit", "freeze lock", "secure erase", and "overwrite". A security_ops
1262306a36Sopenharmony_cidata structure has been added to struct dimm in order to support the security
1362306a36Sopenharmony_cioperations and generic APIs are exposed to allow vendor neutral operations.
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci2. Sysfs Interface
1662306a36Sopenharmony_ci------------------
1762306a36Sopenharmony_ciThe "security" sysfs attribute is provided in the nvdimm sysfs directory. For
1862306a36Sopenharmony_ciexample:
1962306a36Sopenharmony_ci/sys/devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0012:00/ndbus0/nmem0/security
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ciThe "show" attribute of that attribute will display the security state for
2262306a36Sopenharmony_cithat DIMM. The following states are available: disabled, unlocked, locked,
2362306a36Sopenharmony_cifrozen, and overwrite. If security is not supported, the sysfs attribute
2462306a36Sopenharmony_ciwill not be visible.
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ciThe "store" attribute takes several commands when it is being written to
2762306a36Sopenharmony_ciin order to support some of the security functionalities:
2862306a36Sopenharmony_ciupdate <old_keyid> <new_keyid> - enable or update passphrase.
2962306a36Sopenharmony_cidisable <keyid> - disable enabled security and remove key.
3062306a36Sopenharmony_cifreeze - freeze changing of security states.
3162306a36Sopenharmony_cierase <keyid> - delete existing user encryption key.
3262306a36Sopenharmony_cioverwrite <keyid> - wipe the entire nvdimm.
3362306a36Sopenharmony_cimaster_update <keyid> <new_keyid> - enable or update master passphrase.
3462306a36Sopenharmony_cimaster_erase <keyid> - delete existing user encryption key.
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci3. Key Management
3762306a36Sopenharmony_ci-----------------
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ciThe key is associated to the payload by the DIMM id. For example:
4062306a36Sopenharmony_ci# cat /sys/devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0012:00/ndbus0/nmem0/nfit/id
4162306a36Sopenharmony_ci8089-a2-1740-00000133
4262306a36Sopenharmony_ciThe DIMM id would be provided along with the key payload (passphrase) to
4362306a36Sopenharmony_cithe kernel.
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ciThe security keys are managed on the basis of a single key per DIMM. The
4662306a36Sopenharmony_cikey "passphrase" is expected to be 32bytes long. This is similar to the ATA
4762306a36Sopenharmony_cisecurity specification [2]. A key is initially acquired via the request_key()
4862306a36Sopenharmony_cikernel API call during nvdimm unlock. It is up to the user to make sure that
4962306a36Sopenharmony_ciall the keys are in the kernel user keyring for unlock.
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ciA nvdimm encrypted-key of format enc32 has the description format of:
5262306a36Sopenharmony_cinvdimm:<bus-provider-specific-unique-id>
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ciSee file ``Documentation/security/keys/trusted-encrypted.rst`` for creating
5562306a36Sopenharmony_ciencrypted-keys of enc32 format. TPM usage with a master trusted key is
5662306a36Sopenharmony_cipreferred for sealing the encrypted-keys.
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci4. Unlocking
5962306a36Sopenharmony_ci------------
6062306a36Sopenharmony_ciWhen the DIMMs are being enumerated by the kernel, the kernel will attempt to
6162306a36Sopenharmony_ciretrieve the key from the kernel user keyring. This is the only time
6262306a36Sopenharmony_cia locked DIMM can be unlocked. Once unlocked, the DIMM will remain unlocked
6362306a36Sopenharmony_ciuntil reboot. Typically an entity (i.e. shell script) will inject all the
6462306a36Sopenharmony_cirelevant encrypted-keys into the kernel user keyring during the initramfs phase.
6562306a36Sopenharmony_ciThis provides the unlock function access to all the related keys that contain
6662306a36Sopenharmony_cithe passphrase for the respective nvdimms.  It is also recommended that the
6762306a36Sopenharmony_cikeys are injected before libnvdimm is loaded by modprobe.
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci5. Update
7062306a36Sopenharmony_ci---------
7162306a36Sopenharmony_ciWhen doing an update, it is expected that the existing key is removed from
7262306a36Sopenharmony_cithe kernel user keyring and reinjected as different (old) key. It's irrelevant
7362306a36Sopenharmony_ciwhat the key description is for the old key since we are only interested in the
7462306a36Sopenharmony_cikeyid when doing the update operation. It is also expected that the new key
7562306a36Sopenharmony_ciis injected with the description format described from earlier in this
7662306a36Sopenharmony_cidocument.  The update command written to the sysfs attribute will be with
7762306a36Sopenharmony_cithe format:
7862306a36Sopenharmony_ciupdate <old keyid> <new keyid>
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ciIf there is no old keyid due to a security enabling, then a 0 should be
8162306a36Sopenharmony_cipassed in.
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci6. Freeze
8462306a36Sopenharmony_ci---------
8562306a36Sopenharmony_ciThe freeze operation does not require any keys. The security config can be
8662306a36Sopenharmony_cifrozen by a user with root privilege.
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci7. Disable
8962306a36Sopenharmony_ci----------
9062306a36Sopenharmony_ciThe security disable command format is:
9162306a36Sopenharmony_cidisable <keyid>
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ciAn key with the current passphrase payload that is tied to the nvdimm should be
9462306a36Sopenharmony_ciin the kernel user keyring.
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci8. Secure Erase
9762306a36Sopenharmony_ci---------------
9862306a36Sopenharmony_ciThe command format for doing a secure erase is:
9962306a36Sopenharmony_cierase <keyid>
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ciAn key with the current passphrase payload that is tied to the nvdimm should be
10262306a36Sopenharmony_ciin the kernel user keyring.
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci9. Overwrite
10562306a36Sopenharmony_ci------------
10662306a36Sopenharmony_ciThe command format for doing an overwrite is:
10762306a36Sopenharmony_cioverwrite <keyid>
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ciOverwrite can be done without a key if security is not enabled. A key serial
11062306a36Sopenharmony_ciof 0 can be passed in to indicate no key.
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ciThe sysfs attribute "security" can be polled to wait on overwrite completion.
11362306a36Sopenharmony_ciOverwrite can last tens of minutes or more depending on nvdimm size.
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ciAn encrypted-key with the current user passphrase that is tied to the nvdimm
11662306a36Sopenharmony_cishould be injected and its keyid should be passed in via sysfs.
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci10. Master Update
11962306a36Sopenharmony_ci-----------------
12062306a36Sopenharmony_ciThe command format for doing a master update is:
12162306a36Sopenharmony_ciupdate <old keyid> <new keyid>
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ciThe operating mechanism for master update is identical to update except the
12462306a36Sopenharmony_cimaster passphrase key is passed to the kernel. The master passphrase key
12562306a36Sopenharmony_ciis just another encrypted-key.
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ciThis command is only available when security is disabled.
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci11. Master Erase
13062306a36Sopenharmony_ci----------------
13162306a36Sopenharmony_ciThe command format for doing a master erase is:
13262306a36Sopenharmony_cimaster_erase <current keyid>
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ciThis command has the same operating mechanism as erase except the master
13562306a36Sopenharmony_cipassphrase key is passed to the kernel. The master passphrase key is just
13662306a36Sopenharmony_cianother encrypted-key.
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ciThis command is only available when the master security is enabled, indicated
13962306a36Sopenharmony_ciby the extended security status.
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci[1]: https://pmem.io/documents/NVDIMM_DSM_Interface-V1.8.pdf
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci[2]: http://www.t13.org/documents/UploadedDocuments/docs2006/e05179r4-ACS-SecurityClarifications.pdf
144