Skip to content

Commit

Permalink
change py_sg requirements (7aman#4)
Browse files Browse the repository at this point in the history
* py_sg renamed to py3_sg

* update readme

---------

Co-authored-by: Kunhee Ha <[email protected]>
  • Loading branch information
7aman and kunheeha authored Jun 2, 2023
1 parent 89871d3 commit f9f55d6
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 44 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2022 Zaman
Copyright (c) 2023 Zaman

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
66 changes: 40 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,95 +1,109 @@
# wdpass

WD Passport Ultra Complete Utilities for Linux.

Thanks to:

- [Dan Lenski](https://github.com/dlenski) for [py_sg](https://pypi.org/project/py_sg/) (Python2)
- [0-duke](https://github.com/0-duke) and [derekhe](https://github.com/derekhe) for [wdpassport-utils](https://github.com/derekhe/wdpassport-utils) (Python2)
- [crypto-universe](https://github.com/crypto-universe/) for Python3 migration of [py_sg](https://github.com/crypto-universe/py3_sg) and [wdpassport-utils](https://github.com/crypto-universe/wdpassport-utils)
- [tvladyslav](https://github.com/tvladyslav/) for Python3 migration of [py_sg](https://github.com/tvladyslav/py3_sg) and [wdpassport-utils](https://github.com/tvladyslav/wdpassport-utils)

## Intro

This script let you unlock, change password and erase Western Digital Passport devices on Linux platform.
This script let you unlock, change password and erase Western Digital Passport devices on Linux platform.

## Requirements

- Install `lsscsi` package or any package that provides `lsscsi` command in your linux distro.

## Install

### Install the latest version from PyPi

```shell
sudo python3 -m pip install wdpass
```

### Install the latest version manually

- Install `lsscsi` package or any package that provides `lsscsi` command.
- Provide `<Python.h>` header file by installing Python Developer Package. (usually `python3-dev` or `python3-devel`)
- Install the latest py3_sg from [py3_sg](https://github.com/crypto-universe/py3_sg)
- Install the latest py3_sg from [py3_sg](https://github.com/tvladyslav/py3_sg)
- And finally install `wdpass` from this repository.

For example on Ubuntu:

```shell
sudo apt install lsscsi python3-dev
sudo python3 -m pip install https://github.com/crypto-universe/py3_sg/archive/master.zip
sudo python3 -m pip install https://github.com/tvladyslav/py3_sg/archive/master.zip
sudo python3 -m pip install https://github.com/7aman/wdpass/archive/master.zip
```

### Install an old version from PyPi

PyPi package is not based on the latest version but it works for most cases.

```shell
# install v0.0.3
sudo python3 -m pip install wdpass
```

## Usage

Run script as root.
Run `wdpass` as root.

There are few options:
```

```shell
-h, --help show this help message and exit
```

Lists all possible arguments.

```
```shell
-s, --status Check device status and encryption type
```

Get device encryption status and cipher suites used.
```

```shell
-u, --unlock Unlock
```

You will be asked to enter the unlock password. If everything is fine device will be unlocked.

```
```shell
-us, --unlock_with_saved_passwd Unlock with the password saved
```

Unlock using the saved password. If everything is fine device will be unlocked.

```
```shell
-sp, --save_passwd Save password
```

When unlock password, it will save user password to passwd.bin, so you can use "-us" for next time to auto unlock.

```
```shell
-m, --mount Enable mount point for an unlocked device
```
After unlock, your operating system still thinks that your device is a strange thing attached to his usb port and he don't know how to manage. You need this option to force the O.S. to rescan the device and handle it as a normal external usb harddrive.

```
After unlock, your operating system still thinks that your device is a strange thing attached to his usb port and he don't know how to manage. You need this option to force the O.S. to re-scan the device and handle it as a normal external usb hard drive.

```shell
-c, --change_passwd Change (or disable) password
```

This option let you to encrypt your device, remove password protection and change your current password.
If device is "without lock" and you want it to be password protect leave the "OLD password" field empty and choose insert the new password.
If the device is password protected and you want to be as a normal unencrypted device, inser the old password and leave the "NEW password" field empty.
If the device is password protected and you want to be as a normal unencrypted device, insert the old password and leave the "NEW password" field empty.
If you only want to change password do it as usual.

```
```shell
-e, --erase Secure erase device
```

"Erase" the device. This will remove the internal key associated to you password and all your data will be unaccessible. You will also lose your partition table and you will need to create a new one (you can use fdisk and mkfs).

```
```shell
-d DEVICE, --device DEVICE Force device path (ex. /dev/sdb). Usually you don't need this option.
```
The script will try to auto detect the current device path of your WD Passport device.
If something is wrong or you want to manually specify the device path yourself you can use this option.
## Disclaimer
I'm in no way sponsored by or connected with Western Digital.
Use any of the information contained in this repository at your own risk. I accept no
responsibility.
26 changes: 26 additions & 0 deletions cspell.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"version": "0.2",
"ignorePaths": [],
"dictionaryDefinitions": [],
"dictionaries": [],
"words": [
"derekhe",
"devel",
"distro",
"fdisk",
"geteuid",
"htonl",
"htons",
"pwblen",
"tvladyslav",
"Unlocker",
"urandom",
"wdpass",
"wdpassport",
"Zaman"
],
"ignoreWords": [
"Lenski"
],
"import": []
}
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
entry_points={
'console_scripts': ['wdpass=wdpass:main'],
},
install_requires=["py_sg >= 0.14"],
install_requires=["py3_sg >= 0.16"],
python_requires='>=3.6',
zip_safe=False,
keywords='HDD WD MyPassport Unlocker WesternDigital',
Expand Down
29 changes: 14 additions & 15 deletions wdpass/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,14 @@
import subprocess

try:
import py_sg
import py3_sg
except ImportError as e:
print(e)
print("You need to install the 'py_sg' module.")
print("More info: https://github.com/crypto-universe/py3_sg")
print("You need to install the 'py3_sg' module.")
print("More info: https://github.com/tvladyslav/py3_sg")
sys.exit(1)

BLOCK_SIZE = 512
HANDSTORESECURITYBLOCK = 1
dev = None


Expand Down Expand Up @@ -163,7 +162,7 @@ def read_handy_store(page):
for c in htonl(page):
cdb[i] = c
i += 1
return py_sg.read_as_bin_str(dev, _scsi_pack_cdb(cdb), BLOCK_SIZE)
return py3_sg.read_as_bin_str(dev, _scsi_pack_cdb(cdb), BLOCK_SIZE)


def hsb_checksum(data):
Expand All @@ -186,7 +185,7 @@ def get_encryption_status():
0x02 => Unlocked
0x06 => Locked, unlock blocked
0x07 => No keys
CurrentChiperID
CurrentCipherID
0x10 => AES_128_ECB
0x12 => AES_128_CBC
0x18 => AES_128_XTS
Expand All @@ -197,11 +196,11 @@ def get_encryption_status():
KeyResetEnabler (4 bytes that change every time)
'''
cdb = [0xC0, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00]
data = py_sg.read_as_bin_str(dev, _scsi_pack_cdb(cdb), BLOCK_SIZE)
data = py3_sg.read_as_bin_str(dev, _scsi_pack_cdb(cdb), BLOCK_SIZE)
if data[0] != 0x45:
fail(f"Wrong encryption status signature {data[0]:#x}")
sys.exit(1)
# (SecurityStatus, CurrentChiperID, KeyResetEnabler)
# (SecurityStatus, CurrentCipherID, KeyResetEnabler)
return (data[3], data[4], data[8:12])


Expand Down Expand Up @@ -293,7 +292,7 @@ def unlock(save_passwd, unlock_with_saved_passwd):
cdb[8] = pwblen + 8

try:
py_sg.write(dev, _scsi_pack_cdb(cdb),
py3_sg.write(dev, _scsi_pack_cdb(cdb),
_scsi_pack_cdb(pw_block) + pwd_hashed)
success("Device unlocked.")
except:
Expand Down Expand Up @@ -364,7 +363,7 @@ def change_password():

cdb[8] = 8 + 2 * pwblen
try:
py_sg.write(dev, _scsi_pack_cdb(cdb), _scsi_pack_cdb(
py3_sg.write(dev, _scsi_pack_cdb(cdb), _scsi_pack_cdb(
pw_block) + old_passwd_hashed + new_passwd_hashed)
success("Password changed.")
except:
Expand Down Expand Up @@ -398,21 +397,21 @@ def secure_erase(cipher_id=0):
fail(f"Unsupported cipher {cipher_id:#x}")
sys.exit(1)

# Set the actual lenght of pw_block (8 bytes + pwblen pseudorandom data)
# Set the actual length of pw_block (8 bytes + pwblen pseudorandom data)
cdb[8] = pwblen + 8
# Fill pw_block with random data
for rand_byte in os.urandom(pwblen):
pw_block.append(rand_byte)

# key_reset needs to be retrieved immidiatly before the reset request
# key_reset needs to be retrieved immediately before the reset request
key_reset = get_encryption_status()[2]
i = 2
for c in key_reset:
cdb[i] = c
i += 1

try:
py_sg.write(dev, _scsi_pack_cdb(cdb), _scsi_pack_cdb(pw_block))
py3_sg.write(dev, _scsi_pack_cdb(cdb), _scsi_pack_cdb(pw_block))
success(
"Device erased. You need to create a new partition on the device (Hint: fdisk and mkfs)")
except:
Expand Down Expand Up @@ -479,7 +478,7 @@ def enable_mount(device):
)

success(
"Now depending on your system you can mount your device or it will be automagically mounted.")
"Now depending on your system you can mount your device or it will be automatically mounted.")
else:
fail("Device needs to be unlocked in order to mount it.")

Expand All @@ -495,7 +494,7 @@ def get_device(device):
stdout=subprocess.PIPE)

if int(p.stdout.read().rstrip()) > 1:
fail("Multiple occurences of 'My Passport' detected.")
fail("Multiple occurrences of 'My Passport' detected.")
fail("You should specify a device manually (with -d option).")
sys.exit(1)

Expand Down
2 changes: 1 addition & 1 deletion wdpass/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.0.5'
__version__ = '0.1.0'

0 comments on commit f9f55d6

Please sign in to comment.