def write_handy_store(page, data):
    cdb = [0xDA, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00]
    i = 2
    for c in htonl(page):
        cdb[i] = c
        i += 1
    py_sg.write(dev, _scsi_pack_cdb(cdb), data)
示例#2
0
def unlock(save_passwd, unlock_with_saved_passwd):
    cdb = [0xC1, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00]
    sec_status, cipher_id, key_reset = get_encryption_status()
    ## Device should be in the correct state
    if (sec_status == 0x00 or sec_status == 0x02):
        print(fail("Your device is already unlocked!"))
        return
    elif (sec_status != 0x01):
        print(fail("Wrong device status!"))
        sys.exit(1)
    if cipher_id == 0x10 or cipher_id == 0x12 or cipher_id == 0x18:
        pwblen = 16
    elif cipher_id == 0x20 or cipher_id == 0x22 or cipher_id == 0x28:
        pwblen = 32
    elif cipher_id == 0x30:
        pwblen = 32
    else:
        print(fail("Unsupported cipher %s" % cipher_id))
        sys.exit(1)

    ## Get password from user

    if not unlock_with_saved_passwd:
        print(question("Insert password to Unlock the device"))
        passwd = getpass.getpass()

        iteration, salt, hint = read_handy_store_block1()

        pwd_hashed = mk_password_block(passwd, iteration, salt)
    else:
        print(success("Unlock use saved password"))
        passwd_bin = open("passwd.bin", "r")
        pwd_hashed = pickle.load(passwd_bin)

    if save_passwd:
        passwd_bin = open("passwd.bin", "w")
        pickle.dump(pwd_hashed, passwd_bin)

    pw_block = [0x45, 0x00, 0x00, 0x00, 0x00, 0x00]
    for c in htons(pwblen):
        pw_block.append(ord(c))

    pwblen = pwblen + 8
    cdb[8] = pwblen

    try:
        ## If there aren't exceptions the unlock operation is OK.
        py_sg.write(dev, _scsi_pack_cdb(cdb),
                    _scsi_pack_cdb(pw_block) + pwd_hashed)
        print(success("Device unlocked."))
    except:
        ## Wrong password or something bad is happened.
        print(fail("Wrong password."))
        pass
示例#3
0
def secure_erase(cipher_id=0):
    cdb = [0xC1, 0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00]
    status, current_cipher_id, key_reset = get_encryption_status()

    if cipher_id == 0:
        cipher_id = current_cipher_id

    pw_block = [0x45, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00]

    if cipher_id == 0x10 or cipher_id == 0x12 or cipher_id == 0x18:
        pwblen = 16
        pw_block[3] = 0x01
    elif cipher_id == 0x20 or cipher_id == 0x22 or cipher_id == 0x28:
        pwblen = 32
        pw_block[3] = 0x01
    elif cipher_id == 0x30:
        pwblen = 32
    #	pw_block[3] = 0x00
    else:
        print(fail("Unsupported cipher %s" % cipher_id))
        sys.exit(1)

    ## Set the actual lenght 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(ord(rand_byte))

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

    try:
        py_sg.write(dev, _scsi_pack_cdb(cdb), _scsi_pack_cdb(pw_block))
        print(
            success(
                "Device erased. You need to create a new partition on the device (Hint: fdisk and mkfs)"
            ))
    except:
        ## Something bad is happened.
        print(fail("Something wrong."))
        pass
def secure_erase(cipher_id = 0):
	cdb = [0xC1, 0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00]
	status, current_cipher_id, key_reset = get_encryption_status()

	if cipher_id == 0:
		cipher_id = current_cipher_id

	pw_block = [0x45,0x00,0x00,0x00,0x30,0x00,0x00,0x00]

	if cipher_id == 0x10 or cipher_id == 0x12 or cipher_id == 0x18:
		pwblen = 16;
		pw_block[3] = 0x01
	elif cipher_id == 0x20 or cipher_id == 0x22 or cipher_id == 0x28:
		pwblen = 32;
		pw_block[3] = 0x01
	elif cipher_id == 0x30:
		pwblen = 32;
	#	pw_block[3] = 0x00
	else:
		print fail("Unsupported cipher %s" % cipher_id)
		sys.exit(1)

	## Set the actual lenght 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(ord(rand_byte))

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

	try:
		py_sg.write(dev, _scsi_pack_cdb(cdb), _scsi_pack_cdb(pw_block))
		print success("Device erased. You need to create a new partition on the device (Hint: fdisk and mkfs)")
	except:
		## Something bad is happened.
		print fail("Something wrong.")
		pass
def unlock():
	cdb = [0xC1,0xE1,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x00]
	sec_status, cipher_id, key_reset = get_encryption_status()
	## Device should be in the correct state 
	if (sec_status == 0x00 or sec_status == 0x02):
		print fail("Your device is already unlocked!")
		return
	elif (sec_status != 0x01):
		print fail("Wrong device status!")
		sys.exit(1)
	if cipher_id == 0x10 or cipher_id == 0x12 or cipher_id == 0x18:
		pwblen = 16;
	elif cipher_id == 0x20 or cipher_id == 0x22 or cipher_id == 0x28:
		pwblen = 32;
	elif cipher_id == 0x30:
		pwblen = 32;
	else:
		print fail("Unsupported cipher %s" % cipher_id)
		sys.exit(1)
	
	## Get password from user
	print question("Insert password to Unlock the device")
	passwd = getpass.getpass()
	
	iteration,salt,hint = read_handy_store_block1()
	
	pwd_hashed = mk_password_block(passwd, iteration, salt)
	pw_block = [0x45,0x00,0x00,0x00,0x00,0x00]
	for c in htons(pwblen):
		pw_block.append(ord(c))

	pwblen = pwblen + 8
	cdb[8] = pwblen

	try:
		## If there aren't exceptions the unlock operation is OK.
		py_sg.write(dev, _scsi_pack_cdb(cdb), _scsi_pack_cdb(pw_block) + pwd_hashed)
		print success("Device unlocked.")
	except:
		## Wrong password or something bad is happened.
		print fail("Wrong password.")
		pass
def unlock():
    global device_name

    ## Device should be in the correct state
    status = get_encryption_status()
    if (status["Locked"] in (0x00, 0x02)):
        print(fail("Your device is already unlocked!"))
        return
    elif (status["Locked"] != 0x01):
        print(fail("Wrong device status!"))
        sys.exit(1)

    ## Get password from user
    passwd = getpass.getpass(
        "[wdpassport] password for {}: ".format(device_name))

    hash_parameters = read_handy_store_block1()
    if not hash_parameters:
        print(fail("Key hash parameters are not valid."))
        sys.exit(1)
    iteration, salt, hint = hash_parameters

    pwd_hashed = mk_password_block(passwd, iteration, salt)
    pw_block = [0x45, 0x00, 0x00, 0x00, 0x00, 0x00]
    pwblen = status["PasswordLength"]
    for c in htons(pwblen):
        pw_block.append(c)

    pwblen = pwblen + 8
    cdb = [0xC1, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00]
    cdb[8] = pwblen

    try:
        ## If there aren't exceptions the unlock operation is OK.
        py_sg.write(dev, _scsi_pack_cdb(cdb),
                    _scsi_pack_cdb(pw_block) + pwd_hashed)
        print(success("Device unlocked."))
    except:
        ## Wrong password or something bad is happened.
        print(fail("Wrong password."))
        pass
def secure_erase():
    cdb = [0xC1, 0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00]
    status = get_encryption_status()

    cipher_id = status["Cipher"]

    pw_block = [0x45, 0x00, 0x00, 0x00, cipher_id, 0x00, 0x00, 0x00]

    # For old ciphers, this code used to set the "combine" flag.
    # pw_block[3] = 0x01

    ## Set the actual lenght of pw_block (8 bytes + pwblen pseudorandom data)
    pwblen = status["PasswordLength"]
    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
    #status, current_cipher_id, key_reset = get_encryption_status()
    key_reset = status["KeyResetEnabler"]
    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))
        print(
            success(
                "Device erased. You need to create a new partition on the device (Hint: fdisk and mkfs)"
            ))
    except:
        ## Something bad is happened.
        print(fail("Something went wrong."))
        pass
def change_password():
	cdb = [0xC1, 0xE2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00]
	sec_status, cipher_id, key_reset = get_encryption_status()
	if (sec_status != 0x02 and sec_status != 0x00):
		print fail("Device has to be unlocked or without encryption to perform this operation")
		sys.exit(1)
	if cipher_id == 0x10 or cipher_id == 0x12 or cipher_id == 0x18:
		pwblen = 16;
	elif cipher_id == 0x20 or cipher_id == 0x22 or cipher_id == 0x28:
		pwblen = 32;
	elif cipher_id == 0x30:
		pwblen = 32;
	else:
		print fail("Unsupported cipher %s" % cipher_id)
		sys.exit(1)

	print question("Insert the OLD password")
	old_passwd = getpass.getpass()
	print question("Insert the NEW password")
	new_passwd = getpass.getpass()
	print question("Confirm the NEW password")
	new_passwd2 = getpass.getpass()
	if new_passwd != new_passwd2:
		print fail("Password confirmation doesn't match the given password")
		sys.exit(1)

	## Both passwords shouldn't be empty
	if (len(old_passwd) <= 0 and len(new_passwd) <= 0):
		print fail("Both passwords shouldn't be empty")
		sys.exit(1)

	iteration,salt,hint = read_handy_store_block1()
	pw_block = [0x45,0x00,0x00,0x00,0x00,0x00]
	for c in htons(pwblen):
		pw_block.append(ord(c))

	if (len(old_passwd) > 0):
		old_passwd_hashed = mk_password_block(old_passwd, iteration, salt)
		pw_block[3] = pw_block[3] | 0x10
	else:
		old_passwd_hashed = ""
		for i in range(32):
			old_passwd_hashed = old_passwd_hashed + chr(0x00)

	if (len(new_passwd) > 0):
		new_passwd_hashed = mk_password_block(new_passwd, iteration, salt)
		pw_block[3] = pw_block[3] | 0x01
	else:
		new_passwd_hashed = ""
		for i in range(32):
			new_passwd_hashed = new_passwd_hashed + chr(0x00)

	if pw_block[3] & 0x11 == 0x11:
		pw_block[3] = pw_block[3] & 0xEE

	pwblen = 8 + 2 * pwblen
	cdb[8] = pwblen
	try:
		## If exception isn't raised the unlock operation gone ok.
		py_sg.write(dev, _scsi_pack_cdb(cdb), _scsi_pack_cdb(pw_block) + old_passwd_hashed + new_passwd_hashed)
		print success("Password changed.")
	except:
		## Wrong password or something bad is happened.
		print fail("Error changing password")
		pass
def change_password():
    # Check drive's current status.
    status = get_encryption_status()
    if (status["Locked"] not in (0x00, 0x02)):
        print(
            fail(
                "Device has to be unlocked or without encryption to perform this operation."
            ))
        sys.exit(1)

    # Get and confirm the current and new password.
    if status["Locked"] == 0x00:
        # The device doesn't have a password.
        old_passwd = ""
    else:
        old_passwd = getpass.getpass("Current password: "******"New password: "******"New password (again): ")
    if new_passwd != new_passwd2:
        print(fail("Password didn't match."))
        sys.exit(1)

    ## Both passwords shouldn't be empty
    if (len(old_passwd) <= 0 and len(new_passwd) <= 0):
        print(
            fail(
                "Password can't be empty. The device doesn't yet have a password."
            ))
        sys.exit(1)

    # Construct the command.
    pw_block = [0x45, 0x00, 0x00, 0x00, 0x00, 0x00]

    # Get the length in bytes of the key for the drive's current cipher
    # and put that length into the command.
    pwblen = status["PasswordLength"]
    pw_block += list(htons(pwblen))

    # For compatibility with the WD encryption tool, use the same
    # hashing mechanism and parameters to turn the user's password
    # input into a key. The parameters are stored in unencrypted data.
    hash_parameters = read_handy_store_block1()
    if hash_parameters is None:
        # No password hashing parameters are stored on the device.
        # Make some up and write them to the device.
        hash_parameters = (
            1000,
            ''.join(random.SystemRandom().choice(string.ascii_uppercase +
                                                 string.digits)
                    for _ in range(8)).encode("ascii"),  # eight-byte salt
            b'wdpassport-utils'.ljust(202))
        write_handy_store_block1(*hash_parameters)
        assert read_handy_store_block1() == hash_parameters
    iteration, salt, hint = hash_parameters

    if (len(old_passwd) > 0):
        old_passwd_hashed = mk_password_block(old_passwd, iteration, salt)
        pw_block[3] = pw_block[3] | 0x10
    else:
        old_passwd_hashed = bytes([0x00] * 32)

    if (len(new_passwd) > 0):
        new_passwd_hashed = mk_password_block(new_passwd, iteration, salt)
        pw_block[3] = pw_block[3] | 0x01
    else:
        new_passwd_hashed = bytes([0x00] * 32)

    if pw_block[3] & 0x11 == 0x11:
        pw_block[3] = pw_block[3] & 0xEE

    cdb = [0xC1, 0xE2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00]
    pwblen = 8 + 2 * pwblen
    cdb[8] = pwblen
    try:
        ## If exception isn't raised the unlock operation gone ok.
        py_sg.write(
            dev, _scsi_pack_cdb(cdb),
            _scsi_pack_cdb(pw_block) + old_passwd_hashed + new_passwd_hashed)
        print(success("Password changed."))
    except:
        ## Wrong password or something bad is happened.
        print(fail("Error changing password."))
        pass
def change_password():
    cdb = [0xC1, 0xE2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00]
    sec_status, cipher_id, key_reset = get_encryption_status()
    if (sec_status != 0x02 and sec_status != 0x00):
        print fail(
            "Device has to be unlocked or without encryption to perform this operation"
        )
        sys.exit(1)
    if cipher_id == 0x10 or cipher_id == 0x12 or cipher_id == 0x18:
        pwblen = 16
    elif cipher_id == 0x20 or cipher_id == 0x22 or cipher_id == 0x28:
        pwblen = 32
    elif cipher_id == 0x30:
        pwblen = 32
    else:
        print fail("Unsupported cipher %s" % cipher_id)
        sys.exit(1)

    print question("Insert the OLD password")
    old_passwd = getpass.getpass()
    print question("Insert the NEW password")
    new_passwd = getpass.getpass()
    print question("Confirm the NEW password")
    new_passwd2 = getpass.getpass()
    if new_passwd != new_passwd2:
        print fail("Password confirmation doesn't match the given password")
        sys.exit(1)

    ## Both passwords shouldn't be empty
    if (len(old_passwd) <= 0 and len(new_passwd) <= 0):
        print fail("Both passwords shouldn't be empty")
        sys.exit(1)

    iteration, salt, hint = read_handy_store_block1()
    pw_block = [0x45, 0x00, 0x00, 0x00, 0x00, 0x00]
    for c in htons(pwblen):
        pw_block.append(ord(c))

    if (len(old_passwd) > 0):
        old_passwd_hashed = mk_password_block(old_passwd, iteration, salt)
        pw_block[3] = pw_block[3] | 0x10
    else:
        old_passwd_hashed = ""
        for i in range(32):
            old_passwd_hashed = old_passwd_hashed + chr(0x00)

    if (len(new_passwd) > 0):
        new_passwd_hashed = mk_password_block(new_passwd, iteration, salt)
        pw_block[3] = pw_block[3] | 0x01
    else:
        new_passwd_hashed = ""
        for i in range(32):
            new_passwd_hashed = new_passwd_hashed + chr(0x00)

    if pw_block[3] & 0x11 == 0x11:
        pw_block[3] = pw_block[3] & 0xEE

    pwblen = 8 + 2 * pwblen
    cdb[8] = pwblen
    try:
        ## If exception isn't raised the unlock operation gone ok.
        py_sg.write(
            dev, _scsi_pack_cdb(cdb),
            _scsi_pack_cdb(pw_block) + old_passwd_hashed + new_passwd_hashed)
        print success("Password changed.")
    except:
        ## Wrong password or something bad is happened.
        print fail("Error changing password")
        pass