Synopsis
wd-security [--help] status|unlock|change-pw|erase device
Description
Manage password protection of Western Digital external drives supported by the proprietary WD Security software.
Common Options
The following options are supported by the main executable and all sub-commands.
- --help, -h
-
Show help.
- --verbose, -v
-
Increase verbosity.
Sub-Commands
- version
-
Show version information.
- help [SUB-COMMAND]
-
Show overview of available sub-commands or usage of a specific SUB-COMMAND.
- status [OPTIONS] device
-
Show encryption status of device.
- OPTIONS
-
- --is-locked
-
Suppress normal output and exit with zero status if device is locked, nonzero otherwise.
- unlock [OPTIONS] device
-
Unlock device.
The password will be prompted for and converted to UTF-16LE to ensure compatibility with the proprietary WD Security software.
- OPTIONS
-
- --password password
-
Use password as the unlock password. The supplied password may not be empty and will be converted to UTF-16LE encoding.
- --key-file filename
-
Use contents of filename as password. The entire file will be read and used as-is for the password.
- --salt salt
-
Use salt as the password salt. The supplied salt will be converted to UTF-16LE. Overrides the password salt stored in the Handy Store Security Block, if it exists, or the default password salt.
- --salt-file filename
-
Use the contents of filename as the password salt. The entire file will be read and used as-is for the password salt. Overrides the password salt stored in the Handy Store Security Block, if it exists, or the default password salt.
- --iterations iterations
-
Perform iterations hash iterations to generate the Key Encryption Key (KEK). Overrides the iterations stored in the Handy Store Security Block, if it exists, or the default iterations.
- --write-handy-store
-
If device is successfully unlocked, write the password salt and iterations to the Handy Store Security Block. This is useful when the values in the current Security Block do not represent the correct values needed to unlock the device. For example, if the proprietary WD Security software was used to change the password when the password salt and iterations were other than the defaults. See Broken behavior when changing password below for an explanation.
- --use-backup
-
Read salt and iterations from the backup Handy Store Security Block.
- --no-backup
-
Do not write the backup Handy Store Security Block, when --write-handy-store is used.
- --rescan
-
If device is successfully unlocked, notify the kernel that the partition table should be re-read.
- --no-wdp-utils
-
Don’t try to detect whether wdpassport-utils.py was used to generate the Handy Store Security Block or enable compatibility quirks.
- --wdp-utils
-
Force-enable compatibility quirks for wdpassport-utils.py.
- change-pw [OPTIONS] device
-
Enable/disable/change encryption status of device.
The old and/or new passwords will be prompted for, as appropriate and converted to UTF-16LE to ensure compatibility with the proprietary WD Security software.
- OPTIONS
-
- --disable
-
Disable password protection.
- --no-clear
-
By default, when password protection is disabled, the Handy Store Security Block will be cleared. This switch will prevent that operation.
- --password password
-
Use password as the current password. The supplied password may not be empty and will be converted to UTF-16LE encoding.
- --key-file filename
-
Use contents of filename as the current password. The entire file will be read and used as-is for the password.
- --new-password password
-
Use password as the new password. The supplied password may not be empty and will be converted to UTF-16LE encoding.
- --new-key-file filename
-
Use contents of filename as the new password. The entire file will be read and used as-is for the password.
- --hint hint
-
Set hint as the new password hint in the Handy Store Security Block.
- --salt salt
-
Use salt as the password salt. The supplied salt will be converted to UTF-16LE. Overrides the password salt stored in the Handy Store Security Block, if it exists, or the default password salt.
NoteTruncated or zero-padded to 8-bytes if enabling password protection. - --salt-file filename
-
Use the contents of filename as the password salt. The entire file will be read and used as-is for the password salt. Overrides the password salt stored in the Handy Store Security Block, if it exists, or the default password salt.
NoteTruncated or zero-padded to 8-bytes if enabling password protection. - --iterations iterations
-
Perform iterations hash iterations to generate the Key Encryption Key (KEK). Overrides the iterations stored in the Handy Store Security Block, if it exists, or the default iterations.
NoteClamped to 32-bits if enabling password protection. - --iter-time milliseconds
-
Calculate a value for hash iterations such that the generation of the Key Encryption Key (KEK) will consume milliseconds ms. The default is
2000ms. - --use-backup
-
Read salt and iterations from the backup Handy Store Security Block.
- --no-backup
-
Do not write the backup Handy Store Security Block.
- --no-wdp-utils
-
Don’t try to detect whether wdpassport-utils.py was used to generate the Handy Store Security Block or enable compatibility quirks.
- --wdp-utils
-
Force-enable compatibility quirks for wdpassport-utils.py.
- erase [OPTIONS] device
-
Securely erase device.
This is accomplished by causing the device to install a new Device Encryption Key (DEK). Every device should be erased at least once, to replace the possibly insecure factory Device Encryption Key (DEK). See “got HW crypto?”.
CautionAll information on device will become lost and completely unrecoverable. - OPTIONS
-
- --no-clear
-
By default, when performing a secure erase, the Handy Store Security Block will be cleared. This switch will prevent that operation.
- --cipher cipher
-
Use the cipher named cipher.
- --cipher-id id
-
Use cipher with id id.
- --combine
-
Request mixing encryption key with on-device Random Number Generator.
- --key-file filename
-
Use the contents of filename as the encryption key supplied to device. <key-size> bytes will be read from filename and used as-is for the encryption key.
- --key-size bytes
-
Force encryption key size to be bytes bytes. Overrides the value reported by the device.
- handy-store [OPTIONS] info|set|show …
-
Show or manipulate the Handy Store. See Handy Store.
- config [OPTIONS] device
-
Show or manipulate configuration parameters of device.
Two SCSI mode pages are used to store Device Configuration parameters and Device Operations parameters. These parameters may be displayed and, if the device allows, modified.
- OPTIONS
-
- --disable-ap
- --no-disable-ap
-
Set the
DisAPbit in the Device Configuration mode page, or clear it. The meaning of this setting is unknown. - --disable-cdrom
- --no-disable-cdrom
-
Disable, or enable, the emulated CDROM device. (
DisCDbit in the Device Configuration mode page) - --disable-ses
- --no-disable-ses
-
Disable, or enable, the SCSI Enclosure Services support. (
DisSESbit in the Device Configuration mode page) - --disable-wl
- --no-disable-wl
-
Set the
DisWLbit in the Device Configuration mode page, or clear it. The meaning of this setting is unknown. - --2tb-limit
- --no-2tb-limit
-
Limit, or not, the reported drive capacity to two terabytes (2TB). (
2TBLbit in the Device Configuration mode page) - --cd-media-valid
- --no-cd-media-valid
-
Set the
CDMValidbit in the Device Operations mode page, or clear it. The meaning of this setting is unknown. - --enable-cd-eject
- --no-enable-cd-eject
-
Set the
ENCDEJbit in the Device Operations mode page, or clear it. The meaning of this setting is unknown. - --esata15
- --no-esata15
-
Set the
ESATA15bit in the Device Operations mode page, or clear it. The meaning of this setting is unknown. Perhaps intended to force 150MBps data transfer speeds on the eSATA port for misbehaving SATA 1 chipsets. - --invert-lcd
- --no-invert-lcd
-
Invert, or not, the pixels on devices having an LCD display. (
INVLCDbit in the Device Operations mode page) - --lcd-backlight level
-
Set the brightness of the LCD backlight to level. level must have a value between
0and255. (BACKLIGHT BRITEfield in the Device Operations mode page) - --loose-sb2
- --no-loose-sb2
-
Set the
LOOSESB2bit in the Device Operations mode page, or clear it. The meaning of this setting is unknown. Perhaps related to Fibre Channel Single-Byte Command Code (SB-2). - --power-led level
-
Set the brightness of the power LED to level. level must have a value between
0and255. (POWER LED BRITEfield in the Device Operations mode page) - --quiet
-
Be quiet and do not display the table of current configuration parameters.
Handy Store
The proprietary WD Security software stores encryption parameters in special sectors on the drive called the Handy Store. The two known blocks are named the Security Block and the User Block.
Security Block
Stores the password hint, as well as the salt and number of iteration rounds to use to generate the Key Encryption Key (KEK).
User Block
Stores a drive label.
Security Block (backup)
Whenever the Security Block is written, wd-security will also try to write a backup of the Security Block to the last Handy Store block if it is empty, or if it contains a previously written Security Block.
|
Tip
|
Pass /dev/zero as the filename argument of the
handy-store write sub-command to clear a Handy Store block.
|
This can be useful to recover from the primary Security Block being overwritten or otherwise corrupted. For example, if the proprietary WD Security software was used to change the password when the password salt and iterations were other than the defaults. See Broken behavior when changing password for an explanation.
Sub-Commands
- handy-store info [OPTIONS] device
-
Show geometry of Handy Store.
- handy-store set [OPTIONS] device name=value [name=value …]
-
For each name/value pair, set field name to value in Handy Store.
The backup Security Block will only be updated if the salt and iterations values match those in the primary Security Block. If they differ, or if the backup is missing, then it will not be written.
- Configurable Fields
-
- hint hint
-
Set the password hint to hint.
- label label
-
Set the drive label to label.
- OPTIONS
-
- --no-backup
-
Don’t write backup Security Block.
- handy-store show [OPTIONS] device
-
Display Security and User blocks of Handy Store.
- OPTIONS
-
- --backup
-
Display the backup Security Block.
- --no-wdp-utils
-
Don’t try to detect whether wdpassport-utils.py was used to generate the Handy Store Security Block or enable compatibility quirks.
- --wdp-utils
-
Force-enable compatibility quirks for wdpassport-utils.py.
- handy-store read [OPTIONS] device block-addr
-
Read Handy Store block block-addr and display in human-readable form.
block-addr should be in the range 0 to [Last Block], or one of the following named blocks:
"security" or "sec"
Security Block
"user"
User Block
"security-backup" or "sec-backup"
backup Security Block
- OPTIONS
-
- -n num
-
Read num blocks (see [Xfer Max]).
- -o filename
-
Write raw binary output to filename.
- handy-store write [OPTIONS] filename device block-addr
-
Write contents of filename to Handy Store block block_addr.
The file will be read in units of the Handy Store [Block Size].
block-addr should be in the range 0 to [Last Block], or one of the following named blocks:
"security" or "sec"
Security Block
"user"
User Block
"security-backup" or "sec-backup"
backup Security Block
- OPTIONS
-
- --full
-
Read whole file.
- -n num
-
Write num blocks (see [Xfer Max]).
Automatic Unlocking
If the 00-wd-security.rules rules file has been installed, then udev(7) will perform the following operations when a Western Digital external drive is attached:
-
Check for the existence of a corresponding Key File for the device
-
Check whether the device is locked
-
Attempt to use the Key File to unlock the device
-
Notify the kernel to re-read the partition table of the device
Key File Naming
The Key File should be placed in the /etc/keys directory and given a
name containing the model and serial number of the device that it
corresponds to. It should have the following form:
WD_MODEL_SERIAL.key
where MODEL refers to the model of the device as reported by udev, with all spaces and slashes, etc. converted to underscores, and SERIAL refers to the serial number of the device.
The udevadm utility can be used to determine the appropriate values for MODEL and SERIAL as follows:
$ udevadm info --query=property \
--property='ID_USB_MODEL,ID_USB_SERIAL_SHORT' /dev/sdX
ID_USB_MODEL=My_Passport_0820
ID_USB_SERIAL_SHORT=12345678901234567C89012C
where sdX should be replaced by the name of the device file for your device. Using the above values, the Key File should be named:
WD_My_Passport_0820_12345678901234567C89012C.key
The wd-security-devices.sh script will provide this information in an easier to use and more pleasant format.
Key File Contents
Drive WILL be shared with Windows/MacOS
If the proprietary WD Security software will also be used to unlock the device, then the Key File should contain the unlock password encoded in UTF-16LE. The length of the UTF-16LE encoded password should be 25 characters or less, and not more than 50 bytes in total.
The iconv(1) utility can be used to convert a password to UTF-16LE as follows:
$ echo -n 'my-secret-password' >password.utf8 $ iconv -f UTF-8 -t UTF-16LE -o WD_MODEL_SERIAL.key password.utf8 $ rm password.utf8
Drive will NOT be shared with Windows/MacOS
If the proprietary WD Security software will not be used to unlock the device, then it is not necessary to impose any restrictions on the contents of the Key File. For example, it may be populated with 32 bytes of random data:
$ dd if=/dev/urandom of=WD_MODEL_SERIAL.key bs=32 count=1
Test the Key File
Test the Key File by using it to unlock the device:
$ sudo wd-security unlock --key-file WD_MODEL_SERIAL.key /dev/sdX
Install the Key File
Place the Key File, with the appropriate name, into the /etc/keys
directory:
$ sudo mkdir -m 700 /etc/keys $ sudo cp WD_MODEL_SERIAL.key /etc/keys/ $ sudo chmod 400 /etc/keys/WD_MODEL_SERIAL.key
Once the Key File is in place, the corresponding device will be unlocked automatically when it is attached.
Examples
# wd-security status /dev/sdb Status: (0x01) Locked Cipher: (0x30) Full Disk Encryption
# wd-security unlock --rescan /dev/sdb Enter password> _My Secret Password_ Successfully unlocked drive
# wd-security unlock --salt 'abcd' --iterations 123456 \
--write-handy-store /dev/sdb
Enter password> _My Secret Password_
Successfully unlocked drive
# wd-security handy-store set /dev/sdb hint='My password hint' Writing password hint to Handy Store Security Block...done.
# wd-security handy-store set /dev/sdb label="My Book 25EE (6TB)" Writing drive label to Handy Store User Block...done.
# wd-security handy-store show /dev/sdb Password Salt: "钋ꪂ㵏좪" 0x8b 0x94 0x82 0xaa 0x4f 0x3d 0xaa 0xc8 Password Hint: "My password hint" Iteration Rnds: 8635497 Drive Label: "My Book 25EE (6TB)"
# wd-security change-pw --new-key-file mykeyfile.key /dev/sdb Enter current password (hint: My password hint)> _My Secret Password_ Enter new password hint> _My New Hint_
# wd-security change-pw --disable /dev/sdb Enter current password (hint: My New Hint)> _My Secret Password_
# wd-security erase /dev/sdb Erasing device using the following parameters: Cipher: 0x30 (Full Disk Encryption) Key size: 32 Do not Combine key with on-device RNG Continue? [y/N]> _y_ Clearing Handy Store Security Block...
# wd-security config --disable-cdrom /dev/sdb
--- Device Configuration
*Disable SES: no
*Disable CDROM: yes
Disable AP: no
Disable White List: no
2TB Limit: no
--- Device Operations
eSATA15: no
Loose SB2: no
*Enable CD Eject: no
*CD Media Valid: yes
*Power LED: 255
LCD Backlight: 0
Invert LCD: no
# wd-security handy-store write /dev/zero /dev/sdb 15
Exit Status
wd-security exits with a non-zero status on failure and zero for success.
Environment
- WDS_DEBUG
-
May be set to an integer to indicate the desired debug level of the wd-security library (e.g. 1, 2, 3, etc.). Higher numbers will produce more verbose output.
Files
- /etc/keys/WD_MODEL_SERIAL.key
-
Key File used by udev(7) rules to automatically unlock device corresponding to MODEL and SERIAL. See Key File Naming.
- /usr/lib/udev/rules.d/00-wd-security.rules
-
udev(7) rules implementing automatic device unlock.
- /usr/share/doc/wd-security/wd-security-devices.sh
-
Helper script to list attached Western Digital external drives along with the name of the Key File that should be created if automatic unlocking is desired.
Compatibility Notes
Proprietary WD Security software
Poor default salt and iteration settings
The default salt and iteration count are “WDC.” and 1000. The
proprietary WD Security software always uses these values when
creating a password. Not only is 1000 a pathetically low iteration
count for even ancient CPUs, but using fixed values completely negates
the value of having a salt and performing multiple rounds of hashing.
Fixed values means that it is possible to pre-generate a rainbow table
of all possible (or likely) passwords and use it to instantly unlock any
drive that has been configured with the proprietary WD Security software
on Windows or MacOS.
When wd-security enables password protection on a device it will generate a new 8-byte salt randomly and calculate an appropriate iteration count based on timing the hash operation. This significantly increases the difficulty of brute force attempts to derive the unlock password and is completely compatible with the proprietary WD Security software.
Broken behavior when changing password
When the proprietary WD Security software is used to change the encryption password, it will do so using the existing salt and iteration count configured on the drive, which is the correct behavior. After changing the password, it will then overwrite the existing Security Block with the !!DEFAULT!! salt and iteration count, making it impossible to unlock the drive again unless the old salt and iteration count are known and can be restored.
For this reason, it is a good idea to backup the salt and iteration count. If these are known, then access to the drive can be restored by overriding the salt and iteration count on the wd-security command-line when unlocking the drive with the new password, and optionally restoring the Security Block. By default, wd-security will create a backup of the Security Block when enabling password protection, which may then be used to unlock a drive. See Security Block (backup).
|
Tip
|
Never use the proprietary WD Security software to change the password. |
wdpassport-utils.py
Broken password salt mangling
wdpassport-utils.py is a Python utility designed for much the same purpose as this project, but, unfortunately, it does not handle the password salt correctly.
When wdpassport-utils.py sets the password on a device that does not
have an existing Security Block, it will populate a new Security Block
with iterations set to the proprietary WD Security default of 1000,
and with an 8-byte salt randomly generated from ASCII characters. So
far this is less than ideal, but still fine. The problem arises in the
way that wdpassport-utils.py processes the password salt. Instead of
using all 8-bytes as-is from the Security Block, wdpassport-utils.py
will first convert the 8-byte salt into a 4-byte salt by dropping every
other byte. Then it will treat the 4-byte salt as a 4-character ASCII
string and convert it to UTF-16 with platform endianness, resulting in
a new 8-byte salt, which it will then use in the algorithm to produce
the Key Encryption Key (KEK). This procedure is incompatible with the
proprietary WD Security software.
This has 3 consequences:
-
This procedure will happen to work correctly with any salt that is composed entirely of UTF-16LE encoded ASCII characters, e.g. the default salt used by the proprietary WD Security software: “WDC.”, but it will not work correctly with any other salt.
-
The proprietary WD Security software will not be able to unlock any drive that has a Security Block created by wdpassport-utils.py.
-
It will behave differently on big-endian platforms, resulting in a drive that even it cannot unlock when run on a little-endian platform.
Luckily wdpassport-utils.py populates the password hint field with a specific string that can be used to identify a Security Block created by it. By default, wd-security will detect this string and enable compatibility quirks to allow managing a drive that has a Security Block created by wdpassport-utils.py.
Importantly, if wdpassport-utils.py is used to set a password on a device that is not currently protected with a password, but that has an existing Security Block, then it will still perform the salt mangling described above when setting the new password. The proprietary WD Security software will not be able to unlock the device and wd-security will not be able to detect that the password was set using wdpassport-utils.py. In this case it will be necessary to explicitly enable the workaround quirks by passing the --wdp-utils switch.
Bugs
Please report all problems, especially on drives not using the Full Disk Encryption cipher, since I did not have access to such drives during development.
See Also
iconv(1), udevadm(8), udev(7), WD_Encryption_API.txt, got HW crypto?