From 9bad47a2a8383326258d8c808ba5e5684e839c9b Mon Sep 17 00:00:00 2001
From: Szczepan Zalega <szczepan@nitrokey.com>
Date: Fri, 30 Jun 2017 18:47:33 +0200
Subject: Move to Python 3

Tested under Windows 8.1 and MSVC 2017 RC
---
 unittest/constants.py     |  24 ++++----
 unittest/requirements.txt |   1 -
 unittest/test_pro.py      | 149 +++++++++++++++++++++++-----------------------
 unittest/test_storage.py  |  36 +++++------
 4 files changed, 107 insertions(+), 103 deletions(-)

diff --git a/unittest/constants.py b/unittest/constants.py
index 0897b42..f3e876a 100644
--- a/unittest/constants.py
+++ b/unittest/constants.py
@@ -1,22 +1,26 @@
-from enum import Enum
 from misc import to_hex
 
+def bb(x):
+    return bytes(x, encoding='ascii')
+
+
 RFC_SECRET_HR = '12345678901234567890'
 RFC_SECRET = to_hex(RFC_SECRET_HR)  # '31323334353637383930...'
+bbRFC_SECRET = bb(RFC_SECRET)
 
 
 # print( repr((RFC_SECRET, RFC_SECRET_, len(RFC_SECRET))) )
 
-class DefaultPasswords(Enum):
-    ADMIN = '12345678'
-    USER = '123456'
-    ADMIN_TEMP = '123123123'
-    USER_TEMP = '234234234'
-    UPDATE = '12345678'
-    UPDATE_TEMP = '123update123'
+class DefaultPasswords:
+    ADMIN = b'12345678'
+    USER = b'123456'
+    ADMIN_TEMP = b'123123123'
+    USER_TEMP = b'234234234'
+    UPDATE = b'12345678'
+    UPDATE_TEMP = b'123update123'
 
 
-class DeviceErrorCode(Enum):
+class DeviceErrorCode:
     STATUS_OK = 0
     BUSY = 1 # busy or busy progressbar in place of wrong_CRC status
     NOT_PROGRAMMED = 3
@@ -25,7 +29,7 @@ class DeviceErrorCode(Enum):
     STATUS_AES_DEC_FAILED = 0xa
 
 
-class LibraryErrors(Enum):
+class LibraryErrors:
     TOO_LONG_STRING = 200
     INVALID_SLOT = 201
     INVALID_HEX_STRING = 202
diff --git a/unittest/requirements.txt b/unittest/requirements.txt
index 2cb9c05..5c0110b 100644
--- a/unittest/requirements.txt
+++ b/unittest/requirements.txt
@@ -1,5 +1,4 @@
 cffi
 pytest-repeat
 pytest-randomly
-enum
 oath
\ No newline at end of file
diff --git a/unittest/test_pro.py b/unittest/test_pro.py
index 3f1f0a3..e94dc48 100644
--- a/unittest/test_pro.py
+++ b/unittest/test_pro.py
@@ -1,7 +1,7 @@
 import pytest
 
 from conftest import skip_if_device_version_lower_than
-from constants import DefaultPasswords, DeviceErrorCode, RFC_SECRET
+from constants import DefaultPasswords, DeviceErrorCode, RFC_SECRET, bb, bbRFC_SECRET
 from misc import ffi, gs, wait, cast_pointer_to_tuple
 from misc import is_pro_rtm_07, is_pro_rtm_08, is_storage
 
@@ -11,15 +11,15 @@ def test_enable_password_safe(C):
     All Password Safe tests depend on AES keys being initialized. They will fail otherwise.
     """
     assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK
-    assert C.NK_enable_password_safe('wrong_password') == DeviceErrorCode.WRONG_PASSWORD
+    assert C.NK_enable_password_safe(b'wrong_password') == DeviceErrorCode.WRONG_PASSWORD
     assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
 
 
 def test_write_password_safe_slot(C):
     assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK
-    assert C.NK_write_password_safe_slot(0, 'slotname1', 'login1', 'pass1') == DeviceErrorCode.STATUS_NOT_AUTHORIZED
+    assert C.NK_write_password_safe_slot(0, b'slotname1', b'login1', b'pass1') == DeviceErrorCode.STATUS_NOT_AUTHORIZED
     assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
-    assert C.NK_write_password_safe_slot(0, 'slotname1', 'login1', 'pass1') == DeviceErrorCode.STATUS_OK
+    assert C.NK_write_password_safe_slot(0, b'slotname1', b'login1', b'pass1') == DeviceErrorCode.STATUS_OK
 
 
 @pytest.mark.slowtest
@@ -29,7 +29,7 @@ def test_write_all_password_safe_slots_and_read_10_times(C):
         numbers = '1234567890'*4
         s += numbers[:wid-len(s)]
         assert len(s) == wid
-        return s
+        return bb(s)
 
     def get_pass(suffix):
         return fill('pass' + suffix, 20)
@@ -65,7 +65,7 @@ def test_read_all_password_safe_slots_10_times(C):
         numbers = '1234567890'*4
         s += numbers[:wid-len(s)]
         assert len(s) == wid
-        return s
+        return bb(s)
 
     def get_pass(suffix):
         return fill('pass' + suffix, 20)
@@ -90,31 +90,31 @@ def test_read_all_password_safe_slots_10_times(C):
 
 def test_get_password_safe_slot_name(C):
     assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
-    assert C.NK_write_password_safe_slot(0, 'slotname1', 'login1', 'pass1') == DeviceErrorCode.STATUS_OK
+    assert C.NK_write_password_safe_slot(0, b'slotname1', b'login1', b'pass1') == DeviceErrorCode.STATUS_OK
     assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK
-    assert gs(C.NK_get_password_safe_slot_name(0)) == ''
+    assert gs(C.NK_get_password_safe_slot_name(0)) == b''
     assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_NOT_AUTHORIZED
 
     assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
-    assert gs(C.NK_get_password_safe_slot_name(0)) == 'slotname1'
+    assert gs(C.NK_get_password_safe_slot_name(0)) == b'slotname1'
     assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK
 
 
 def test_get_password_safe_slot_login_password(C):
     assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
-    assert C.NK_write_password_safe_slot(0, 'slotname1', 'login1', 'pass1') == DeviceErrorCode.STATUS_OK
+    assert C.NK_write_password_safe_slot(0, b'slotname1', b'login1', b'pass1') == DeviceErrorCode.STATUS_OK
     slot_login = C.NK_get_password_safe_slot_login(0)
     assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK
-    assert gs(slot_login) == 'login1'
+    assert gs(slot_login) == b'login1'
     slot_password = gs(C.NK_get_password_safe_slot_password(0))
     assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK
-    assert slot_password == 'pass1'
+    assert slot_password == b'pass1'
 
 
 def test_erase_password_safe_slot(C):
     assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
     assert C.NK_erase_password_safe_slot(0) == DeviceErrorCode.STATUS_OK
-    assert gs(C.NK_get_password_safe_slot_name(0)) == ''
+    assert gs(C.NK_get_password_safe_slot_name(0)) == b''
     assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK  # TODO CHECK shouldn't this be DeviceErrorCode.NOT_PROGRAMMED ?
 
 
@@ -122,7 +122,7 @@ def test_password_safe_slot_status(C):
     C.NK_set_debug(True)
     assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
     assert C.NK_erase_password_safe_slot(0) == DeviceErrorCode.STATUS_OK
-    assert C.NK_write_password_safe_slot(1, 'slotname2', 'login2', 'pass2') == DeviceErrorCode.STATUS_OK
+    assert C.NK_write_password_safe_slot(1, b'slotname2', b'login2', b'pass2') == DeviceErrorCode.STATUS_OK
     safe_slot_status = C.NK_get_password_safe_slot_status()
     assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK
     is_slot_programmed = list(ffi.cast("uint8_t [16]", safe_slot_status)[0:16])
@@ -131,6 +131,7 @@ def test_password_safe_slot_status(C):
     assert is_slot_programmed[1] == 1
 
 
+# TODO TOREGISTER
 def test_issue_device_locks_on_second_key_generation_in_sequence(C):
     if is_pro_rtm_07(C) or is_pro_rtm_08(C):
         pytest.skip("issue to register: device locks up "
@@ -171,13 +172,13 @@ def test_destroy_password_safe(C):
     C.NK_set_debug(True)
     assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
     # write password safe slot
-    assert C.NK_write_password_safe_slot(0, 'slotname1', 'login1', 'pass1') == DeviceErrorCode.STATUS_OK
+    assert C.NK_write_password_safe_slot(0, b'slotname1', b'login1', b'pass1') == DeviceErrorCode.STATUS_OK
     # read slot
-    assert gs(C.NK_get_password_safe_slot_name(0)) == 'slotname1'
+    assert gs(C.NK_get_password_safe_slot_name(0)) == b'slotname1'
     assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK
     slot_login = C.NK_get_password_safe_slot_login(0)
     assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK
-    assert gs(slot_login) == 'login1'
+    assert gs(slot_login) == b'login1'
     # destroy password safe by regenerating aes key
     assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK
 
@@ -186,7 +187,7 @@ def test_destroy_password_safe(C):
     assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK
     assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
 
-    assert gs(C.NK_get_password_safe_slot_name(0)) != 'slotname1'
+    assert gs(C.NK_get_password_safe_slot_name(0)) != b'slotname1'
     assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK
 
     # check was slot status cleared
@@ -199,22 +200,22 @@ def test_destroy_password_safe(C):
 def test_is_AES_supported(C):
     if is_storage(C):
         pytest.skip("Storage does not implement this command")
-    assert C.NK_is_AES_supported('wrong password') != 1
+    assert C.NK_is_AES_supported(b'wrong password') != 1
     assert C.NK_get_last_command_status() == DeviceErrorCode.WRONG_PASSWORD
     assert C.NK_is_AES_supported(DefaultPasswords.USER) == 1
     assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK
 
 
 def test_admin_PIN_change(C):
-    new_password = '123123123'
-    assert C.NK_change_admin_PIN('wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD
+    new_password = b'123123123'
+    assert C.NK_change_admin_PIN(b'wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD
     assert C.NK_change_admin_PIN(DefaultPasswords.ADMIN, new_password) == DeviceErrorCode.STATUS_OK
     assert C.NK_change_admin_PIN(new_password, DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK
 
 
 def test_user_PIN_change(C):
-    new_password = '123123123'
-    assert C.NK_change_user_PIN('wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD
+    new_password = b'123123123'
+    assert C.NK_change_user_PIN(b'wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD
     assert C.NK_change_user_PIN(DefaultPasswords.USER, new_password) == DeviceErrorCode.STATUS_OK
     assert C.NK_change_user_PIN(new_password, DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
 
@@ -223,7 +224,7 @@ def test_admin_retry_counts(C):
     default_admin_retry_count = 3
     assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK
     assert C.NK_get_admin_retry_count() == default_admin_retry_count
-    assert C.NK_change_admin_PIN('wrong_password', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.WRONG_PASSWORD
+    assert C.NK_change_admin_PIN(b'wrong_password', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.WRONG_PASSWORD
     assert C.NK_get_admin_retry_count() == default_admin_retry_count - 1
     assert C.NK_change_admin_PIN(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK
     assert C.NK_get_admin_retry_count() == default_admin_retry_count
@@ -231,7 +232,7 @@ def test_admin_retry_counts(C):
 
 def test_user_retry_counts_change_PIN(C):
     assert C.NK_change_user_PIN(DefaultPasswords.USER, DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
-    wrong_password = 'wrong_password'
+    wrong_password = b'wrong_password'
     default_user_retry_count = 3
     assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK
     assert C.NK_get_user_retry_count() == default_user_retry_count
@@ -244,7 +245,7 @@ def test_user_retry_counts_PWSafe(C):
     default_user_retry_count = 3
     assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK
     assert C.NK_get_user_retry_count() == default_user_retry_count
-    assert C.NK_enable_password_safe('wrong_password') == DeviceErrorCode.WRONG_PASSWORD
+    assert C.NK_enable_password_safe(b'wrong_password') == DeviceErrorCode.WRONG_PASSWORD
     assert C.NK_get_user_retry_count() == default_user_retry_count - 1
     assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
     assert C.NK_get_user_retry_count() == default_user_retry_count
@@ -254,15 +255,15 @@ def test_unlock_user_password(C):
     C.NK_set_debug(True)
     default_user_retry_count = 3
     default_admin_retry_count = 3
-    new_password = '123123123'
+    new_password = b'123123123'
     assert C.NK_get_user_retry_count() == default_user_retry_count
-    assert C.NK_change_user_PIN('wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD
-    assert C.NK_change_user_PIN('wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD
-    assert C.NK_change_user_PIN('wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD
+    assert C.NK_change_user_PIN(b'wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD
+    assert C.NK_change_user_PIN(b'wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD
+    assert C.NK_change_user_PIN(b'wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD
     assert C.NK_get_user_retry_count() == default_user_retry_count - 3
     assert C.NK_get_admin_retry_count() == default_admin_retry_count
 
-    assert C.NK_unlock_user_password('wrong password', DefaultPasswords.USER) == DeviceErrorCode.WRONG_PASSWORD
+    assert C.NK_unlock_user_password(b'wrong password', DefaultPasswords.USER) == DeviceErrorCode.WRONG_PASSWORD
     assert C.NK_get_admin_retry_count() == default_admin_retry_count - 1
     assert C.NK_unlock_user_password(DefaultPasswords.ADMIN, DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
     assert C.NK_get_user_retry_count() == default_user_retry_count
@@ -270,12 +271,12 @@ def test_unlock_user_password(C):
 
 
 def test_admin_auth(C):
-    assert C.NK_first_authenticate('wrong_password', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.WRONG_PASSWORD
+    assert C.NK_first_authenticate(b'wrong_password', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.WRONG_PASSWORD
     assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
 
 
 def test_user_auth(C):
-    assert C.NK_user_authenticate('wrong_password', DefaultPasswords.USER_TEMP) == DeviceErrorCode.WRONG_PASSWORD
+    assert C.NK_user_authenticate(b'wrong_password', DefaultPasswords.USER_TEMP) == DeviceErrorCode.WRONG_PASSWORD
     assert C.NK_user_authenticate(DefaultPasswords.USER, DefaultPasswords.USER_TEMP) == DeviceErrorCode.STATUS_OK
 
 
@@ -284,7 +285,7 @@ def check_HOTP_RFC_codes(C, func, prep=None, use_8_digits=False):
     # https://tools.ietf.org/html/rfc4226#page-32
     """
     assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
-    assert C.NK_write_hotp_slot(1, 'python_test', RFC_SECRET, 0, use_8_digits, False, False, "",
+    assert C.NK_write_hotp_slot(1, b'python_test', bbRFC_SECRET, 0, use_8_digits, False, False, b'',
                                 DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
     test_data = [
         1284755224, 1094287082, 137359152, 1726969429, 1640338314, 868254676, 1918287922, 82162583, 673399871,
@@ -295,7 +296,7 @@ def check_HOTP_RFC_codes(C, func, prep=None, use_8_digits=False):
             prep()
         r = func(1)
         code = str(code)[-8:] if use_8_digits else str(code)[-6:]
-        assert code == r
+        assert bb(code) == r
 
 
 @pytest.mark.parametrize("use_8_digits", [False, True, ])
@@ -322,12 +323,12 @@ def test_HOTP_token(C):
     assert C.NK_write_config(255, 255, 255, use_pin_protection, not use_pin_protection,
                              DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
     assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
-    token_ID = "AAV100000022"
-    assert C.NK_write_hotp_slot(1, 'python_test', RFC_SECRET, 0, False, False, True, token_ID,
+    token_ID = b"AAV100000022"
+    assert C.NK_write_hotp_slot(1, b'python_test', bbRFC_SECRET, 0, False, False, True, token_ID,
                                 DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
     for i in range(5):
         hotp_code = gs(C.NK_get_hotp_code(1))
-        assert hotp_code != ""
+        assert hotp_code != b''
         assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK
 
 
@@ -347,11 +348,11 @@ def test_HOTP_counters(C):
     slot_number = 1
     for counter, code in enumerate(HOTP_test_data):
         assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
-        assert C.NK_write_hotp_slot(slot_number, 'python_test', RFC_SECRET, counter, use_8_digits, False, False, "",
+        assert C.NK_write_hotp_slot(slot_number, b'python_test', bbRFC_SECRET, counter, use_8_digits, False, False, b'',
                                     DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
         r = gs(C.NK_get_hotp_code(slot_number))
         code = str(code)[-8:] if use_8_digits else str(code)[-6:]
-        assert code == r
+        assert bb(code) == r
 
 
 INT32_MAX = 2 ** 31 - 1
@@ -360,7 +361,7 @@ def test_HOTP_64bit_counter(C):
         pytest.xfail('bug in NK Storage HOTP firmware - counter is set with a 8 digits string, '
                      'however int32max takes 10 digits to be written')
     oath = pytest.importorskip("oath")
-    lib_at = lambda t: oath.hotp(RFC_SECRET, t, format='dec6')
+    lib_at = lambda t: bb(oath.hotp(RFC_SECRET, t, format='dec6'))
     PIN_protection = False
     use_8_digits = False
     slot_number = 1
@@ -371,7 +372,7 @@ def test_HOTP_64bit_counter(C):
     lib_res = []
     for t in range(INT32_MAX - 5, INT32_MAX + 5, 1):
         assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
-        assert C.NK_write_hotp_slot(slot_number, 'python_test', RFC_SECRET, t, use_8_digits, False, False, "",
+        assert C.NK_write_hotp_slot(slot_number, b'python_test', bbRFC_SECRET, t, use_8_digits, False, False, b'',
                                     DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
         code_device = gs(C.NK_get_hotp_code(slot_number))
         dev_res += (t, code_device)
@@ -384,14 +385,14 @@ def test_TOTP_64bit_time(C):
         pytest.xfail('bug in NK Storage TOTP firmware')
     oath = pytest.importorskip("oath")
     T = 1
-    lib_at = lambda t: oath.totp(RFC_SECRET, t=t)
+    lib_at = lambda t: bb(oath.totp(RFC_SECRET, t=t))
     PIN_protection = False
     slot_number = 1
     assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
     assert C.NK_write_config(255, 255, 255, PIN_protection, not PIN_protection,
                              DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
     assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
-    assert C.NK_write_totp_slot(slot_number, 'python_test', RFC_SECRET, 30, False, False, False, "",
+    assert C.NK_write_totp_slot(slot_number, b'python_test', bbRFC_SECRET, 30, False, False, False, b'',
                                 DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
     dev_res = []
     lib_res = []
@@ -418,14 +419,14 @@ def test_TOTP_RFC_usepin(C, PIN_protection):
                              DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
     # test according to https://tools.ietf.org/html/rfc6238#appendix-B
     assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
-    assert C.NK_write_totp_slot(slot_number, 'python_test', RFC_SECRET, 30, True, False, False, "",
+    assert C.NK_write_totp_slot(slot_number, b'python_test', bbRFC_SECRET, 30, True, False, False, b'',
                                 DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
 
     get_func = None
     if PIN_protection:
         get_func = lambda x, y, z, r: gs(C.NK_get_totp_code_PIN(x, y, z, r, DefaultPasswords.USER_TEMP))
     else:
-        get_func = lambda x: gs(C.NK_get_totp_code)
+        get_func = lambda x, y, z, r: gs(C.NK_get_totp_code(x, y, z, r))
 
     # Mode: Sha1, time step X=30
     test_data = [
@@ -446,7 +447,7 @@ def test_TOTP_RFC_usepin(C, PIN_protection):
         assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
         assert C.NK_totp_set_time(t) == DeviceErrorCode.STATUS_OK
         code_from_device = get_func(slot_number, T, 0, 30)  # FIXME T is not changing the outcome
-        data += [ (t, expected_code) ]
+        data += [ (t, bb(str(expected_code).zfill(8))) ]
         responses += [ (t, code_from_device) ]
         correct += expected_code == code_from_device
     assert data == responses or correct == len(test_data)
@@ -475,12 +476,12 @@ def test_get_OTP_codes(C):
     assert C.NK_write_config(255, 255, 255, False, True, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
     for i in range(15):
         code = gs(C.NK_get_totp_code(i, 0, 0, 0))
-        if code == "":
+        if code == b'':
             assert C.NK_get_last_command_status() == DeviceErrorCode.NOT_PROGRAMMED
 
     for i in range(3):
         code = gs(C.NK_get_hotp_code(i))
-        if code == "":
+        if code == b'':
             assert C.NK_get_last_command_status() == DeviceErrorCode.NOT_PROGRAMMED
 
 
@@ -493,31 +494,31 @@ def test_get_OTP_code_from_not_programmed_slot(C):
     assert C.NK_erase_totp_slot(0, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
 
     code = gs(C.NK_get_hotp_code(0))
-    assert code == ""
+    assert code == b''
     assert C.NK_get_last_command_status() == DeviceErrorCode.NOT_PROGRAMMED
 
     code = gs(C.NK_get_totp_code(0, 0, 0, 0))
-    assert code == ""
+    assert code == b''
     assert C.NK_get_last_command_status() == DeviceErrorCode.NOT_PROGRAMMED
 
 
 def test_get_code_user_authorize(C):
     C.NK_set_debug(True)
     assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
-    assert C.NK_write_totp_slot(0, 'python_otp_auth', RFC_SECRET, 30, True, False, False, "",
+    assert C.NK_write_totp_slot(0, b'python_otp_auth', bbRFC_SECRET, 30, True, False, False, b'',
                                 DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
     # enable PIN protection of OTP codes with write_config
     # TODO create convinience function on C API side to enable/disable OTP USER_PIN protection
     assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
     assert C.NK_write_config(255, 255, 255, True, False, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
     code = gs(C.NK_get_totp_code(0, 0, 0, 0))
-    assert code == ""
+    assert code == b''
     assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_NOT_AUTHORIZED
     # disable PIN protection with write_config
     assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
     assert C.NK_write_config(255, 255, 255, False, True, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
     code = gs(C.NK_get_totp_code(0, 0, 0, 0))
-    assert code != ""
+    assert code != b''
     assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK
 
 
@@ -552,12 +553,12 @@ def test_factory_reset(C):
     assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
     assert C.NK_write_config(255, 255, 255, False, True, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
     assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
-    assert C.NK_write_hotp_slot(1, 'python_test', RFC_SECRET, 0, False, False, False, "",
+    assert C.NK_write_hotp_slot(1, b'python_test', bbRFC_SECRET, 0, False, False, False, b"",
                                 DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
-    assert gs(C.NK_get_hotp_code(1)) == "755224"
+    assert gs(C.NK_get_hotp_code(1)) == b"755224"
     assert C.NK_factory_reset(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK
     wait(10)
-    assert gs(C.NK_get_hotp_code(1)) != "287082"
+    assert gs(C.NK_get_hotp_code(1)) != b"287082"
     assert C.NK_get_last_command_status() == DeviceErrorCode.NOT_PROGRAMMED
     # restore AES key
     assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
@@ -593,7 +594,7 @@ def test_OTP_secret_started_from_null(C, secret):
         skip_if_device_version_lower_than({'P': 8})
 
     oath = pytest.importorskip("oath")
-    lib_at = lambda t: oath.hotp(secret, t, format='dec6')
+    lib_at = lambda t: bb(oath.hotp(secret, t, format='dec6'))
     PIN_protection = False
     use_8_digits = False
     slot_number = 1
@@ -604,7 +605,7 @@ def test_OTP_secret_started_from_null(C, secret):
     lib_res = []
     for t in range(1,5):
         assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
-        assert C.NK_write_hotp_slot(slot_number, 'null_secret', secret, t, use_8_digits, False, False, "",
+        assert C.NK_write_hotp_slot(slot_number, b'null_secret', bb(secret), t, use_8_digits, False, False, b'',
                                     DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
         code_device = gs(C.NK_get_hotp_code(slot_number))
         dev_res += (t, code_device)
@@ -626,7 +627,7 @@ def test_HOTP_slots_read_write_counter(C, counter):
 
     secret = RFC_SECRET
     oath = pytest.importorskip("oath")
-    lib_at = lambda t: oath.hotp(secret, t, format='dec6')
+    lib_at = lambda t: bb(oath.hotp(secret, t, format='dec6'))
     PIN_protection = False
     use_8_digits = False
     assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
@@ -636,7 +637,7 @@ def test_HOTP_slots_read_write_counter(C, counter):
     lib_res = []
     for slot_number in range(3):
         assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
-        assert C.NK_write_hotp_slot(slot_number, 'HOTP rw' + str(slot_number), secret, counter, use_8_digits, False, False, "",
+        assert C.NK_write_hotp_slot(slot_number, b'HOTP rw' + bytes(slot_number), bb(secret), counter, use_8_digits, False, False, b"",
                                     DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
         code_device = gs(C.NK_get_hotp_code(slot_number))
         dev_res += (counter, code_device)
@@ -653,7 +654,7 @@ def test_TOTP_slots_read_write_at_time_period(C, time, period):
     """
     secret = RFC_SECRET
     oath = pytest.importorskip("oath")
-    lib_at = lambda t: oath.totp(RFC_SECRET, t=t, period=period)
+    lib_at = lambda t: bb(oath.totp(RFC_SECRET, t=t, period=period))
     PIN_protection = False
     use_8_digits = False
     T = 0
@@ -664,7 +665,7 @@ def test_TOTP_slots_read_write_at_time_period(C, time, period):
     lib_res = []
     for slot_number in range(15):
         assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
-        assert C.NK_write_totp_slot(slot_number, 'TOTP rw' + str(slot_number), secret, period, use_8_digits, False, False, "",
+        assert C.NK_write_totp_slot(slot_number, b'TOTP rw' + bytes(slot_number), bb(secret), period, use_8_digits, False, False, b"",
                                     DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
         assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
         assert C.NK_totp_set_time(time) == DeviceErrorCode.STATUS_OK
@@ -688,7 +689,7 @@ def test_TOTP_secrets(C, secret):
     time = 0
     period = 30
     oath = pytest.importorskip("oath")
-    lib_at = lambda t: oath.totp(secret, t=t, period=period)
+    lib_at = lambda t: bb(oath.totp(secret, t=t, period=period))
     PIN_protection = False
     use_8_digits = False
     T = 0
@@ -697,7 +698,7 @@ def test_TOTP_secrets(C, secret):
                              DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
     dev_res = []
     lib_res = []
-    assert C.NK_write_totp_slot(slot_number, 'secret' + str(len(secret)), secret, period, use_8_digits, False, False, "",
+    assert C.NK_write_totp_slot(slot_number, b'secret' + bytes(len(secret)), bb(secret), period, use_8_digits, False, False, b"",
                                 DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
     assert C.NK_totp_set_time(time) == DeviceErrorCode.STATUS_OK
     code_device = gs(C.NK_get_totp_code(slot_number, T, 0, period))
@@ -718,7 +719,7 @@ def test_HOTP_secrets(C, secret):
     slot_number = 0
     counter = 0
     oath = pytest.importorskip("oath")
-    lib_at = lambda t: oath.hotp(secret, counter=t)
+    lib_at = lambda t: bb(oath.hotp(secret, counter=t))
     PIN_protection = False
     use_8_digits = False
     T = 0
@@ -727,7 +728,7 @@ def test_HOTP_secrets(C, secret):
                              DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
     dev_res = []
     lib_res = []
-    assert C.NK_write_hotp_slot(slot_number, 'secret' + str(len(secret)), secret, counter, use_8_digits, False, False, "",
+    assert C.NK_write_hotp_slot(slot_number, b'secret' + bytes(len(secret)), bb(secret), counter, use_8_digits, False, False, b"",
                                 DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
     code_device = gs(C.NK_get_hotp_code(slot_number))
     dev_res += (counter, code_device)
@@ -750,7 +751,7 @@ def test_special_double_press(C):
                              DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
     for slot_number in range(3):
         assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
-        assert C.NK_write_hotp_slot(slot_number, 'double' + str(slot_number), secret, counter, use_8_digits, False, False, "",
+        assert C.NK_write_hotp_slot(slot_number, b'double' + bytes(slot_number), bb(secret), counter, use_8_digits, False, False, b"",
                                 DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
     # requires manual check
 
@@ -771,17 +772,17 @@ def test_edit_OTP_slot(C):
                              DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
     slot_number = 0
     assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
-    first_name = 'edit slot'
-    assert C.NK_write_hotp_slot(slot_number, first_name, secret, counter, use_8_digits, False, False, "",
+    first_name = b'edit slot'
+    assert C.NK_write_hotp_slot(slot_number, first_name, bb(secret), counter, use_8_digits, False, False, b"",
                                 DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
     assert gs(C.NK_get_hotp_slot_name(slot_number)) == first_name
 
 
     first_code = gs(C.NK_get_hotp_code(slot_number))
-    changed_name = 'changedname'
-    empty_secret = ''
+    changed_name = b'changedname'
+    empty_secret = b''
     assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
-    assert C.NK_write_hotp_slot(slot_number, changed_name, empty_secret, counter, use_8_digits, False, False, "",
+    assert C.NK_write_hotp_slot(slot_number, changed_name, empty_secret, counter, use_8_digits, False, False, b"",
                                 DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
     second_code = gs(C.NK_get_hotp_code(slot_number))
     assert first_code == second_code
@@ -804,6 +805,6 @@ def test_TOTP_codes_from_nitrokeyapp(secret, C):
     code_device = gs(C.NK_get_totp_code(slot_number, 0, 0, period))
 
     oath = pytest.importorskip("oath")
-    lib_at = lambda : oath.totp(secret, period=period)
+    lib_at = lambda : bb(oath.totp(secret, period=period))
     print (lib_at())
     assert lib_at() == code_device
diff --git a/unittest/test_storage.py b/unittest/test_storage.py
index da7c9a3..6671f5b 100644
--- a/unittest/test_storage.py
+++ b/unittest/test_storage.py
@@ -3,7 +3,7 @@ import pprint
 import pytest
 
 from conftest import skip_if_device_version_lower_than
-from constants import DefaultPasswords, DeviceErrorCode
+from constants import DefaultPasswords, DeviceErrorCode, bb
 from misc import gs, wait
 pprint = pprint.PrettyPrinter(indent=4).pprint
 
@@ -28,7 +28,7 @@ def test_get_status_storage(C):
     assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK
     status_string = gs(status_pointer)
     assert len(status_string) > 0
-    status_dict = get_dict_from_dissect(status_string)
+    status_dict = get_dict_from_dissect(status_string.decode('ascii'))
     default_admin_password_retry_count = 3
     assert int(status_dict['AdminPwRetryCount']) == default_admin_password_retry_count
 
@@ -39,7 +39,7 @@ def test_sd_card_usage(C):
     assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK
     data_string = gs(data_pointer)
     assert len(data_string) > 0
-    data_dict = get_dict_from_dissect(data_string)
+    data_dict = get_dict_from_dissect(data_string.decode("ascii"))
     assert int(data_dict['WriteLevelMax']) <= 100
 
 
@@ -51,7 +51,7 @@ def test_encrypted_volume_unlock(C):
 
 def test_encrypted_volume_unlock_hidden(C):
     skip_if_device_version_lower_than({'S': 43})
-    hidden_volume_password = 'hiddenpassword'
+    hidden_volume_password = b'hiddenpassword'
     assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK
     assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
     assert C.NK_create_hidden_volume(0, 20, 21, hidden_volume_password) == DeviceErrorCode.STATUS_OK
@@ -61,8 +61,8 @@ def test_encrypted_volume_unlock_hidden(C):
 def test_encrypted_volume_setup_multiple_hidden_lock(C):
     import random
     skip_if_device_version_lower_than({'S': 45}) #hangs device on lower version
-    hidden_volume_password = 'hiddenpassword' + str(random.randint(0,100))
-    p = lambda i: hidden_volume_password + str(i)
+    hidden_volume_password = b'hiddenpassword' + bb(str(random.randint(0,100)))
+    p = lambda i: hidden_volume_password + bb(str(i))
     assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK
     assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
     for i in range(4):
@@ -76,8 +76,8 @@ def test_encrypted_volume_setup_multiple_hidden_lock(C):
 @pytest.mark.parametrize("volumes_to_setup", range(1, 5))
 def test_encrypted_volume_setup_multiple_hidden_no_lock_device_volumes(C, volumes_to_setup):
     skip_if_device_version_lower_than({'S': 43})
-    hidden_volume_password = 'hiddenpassword'
-    p = lambda i: hidden_volume_password + str(i)
+    hidden_volume_password = b'hiddenpassword'
+    p = lambda i: hidden_volume_password + bb(str(i))
     assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK
     assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
     for i in range(volumes_to_setup):
@@ -95,8 +95,8 @@ def test_encrypted_volume_setup_multiple_hidden_no_lock_device_volumes(C, volume
 @pytest.mark.parametrize("volumes_to_setup", range(1, 5))
 def test_encrypted_volume_setup_multiple_hidden_no_lock_device_volumes_unlock_at_once(C, volumes_to_setup):
     skip_if_device_version_lower_than({'S': 43})
-    hidden_volume_password = 'hiddenpassword'
-    p = lambda i: hidden_volume_password + str(i)
+    hidden_volume_password = b'hiddenpassword'
+    p = lambda i: hidden_volume_password + bb(str(i))
     assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK
     assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
     for i in range(volumes_to_setup):
@@ -116,8 +116,8 @@ def test_encrypted_volume_setup_multiple_hidden_no_lock_device_volumes_unlock_at
 @pytest.mark.parametrize("use_slot", range(4))
 def test_encrypted_volume_setup_one_hidden_no_lock_device_slot(C, use_slot):
     skip_if_device_version_lower_than({'S': 43})
-    hidden_volume_password = 'hiddenpassword'
-    p = lambda i: hidden_volume_password + str(i)
+    hidden_volume_password = b'hiddenpassword'
+    p = lambda i: hidden_volume_password + bb(str(i))
     assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK
     assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
     i = use_slot
@@ -143,7 +143,7 @@ def test_password_safe_slot_name_corruption(C):
         numbers = '1234567890' * 4
         s += numbers[:wid - len(s)]
         assert len(s) == wid
-        return s
+        return bb(s)
 
     def get_pass(suffix):
         return fill('pass' + suffix, 20)
@@ -170,8 +170,8 @@ def test_password_safe_slot_name_corruption(C):
             assert gs(C.NK_get_password_safe_slot_login(i)) == get_loginname(iss)
             assert gs(C.NK_get_password_safe_slot_password(i)) == get_pass(iss)
 
-    hidden_volume_password = 'hiddenpassword'
-    p = lambda i: hidden_volume_password + str(i)
+    hidden_volume_password = b'hiddenpassword'
+    p = lambda i: hidden_volume_password + bb(str(i))
     def check_volumes_correctness(C):
         for i in range(volumes_to_setup):
             assert C.NK_unlock_hidden_volume(p(i)) == DeviceErrorCode.STATUS_OK
@@ -208,8 +208,8 @@ def test_hidden_volume_corruption(C):
     # bug: this should return error without unlocking encrypted volume each hidden volume lock, but it does not
     assert C.NK_lock_encrypted_volume() == DeviceErrorCode.STATUS_OK
     assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
-    hidden_volume_password = 'hiddenpassword'
-    p = lambda i: hidden_volume_password + str(i)
+    hidden_volume_password = b'hiddenpassword'
+    p = lambda i: hidden_volume_password + bb(str(i))
     for i in range(4):
         assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
         assert C.NK_unlock_hidden_volume(p(i)) == DeviceErrorCode.STATUS_OK
@@ -261,7 +261,7 @@ def test_get_busy_progress_on_idle(C):
 
 def test_change_update_password(C):
     skip_if_device_version_lower_than({'S': 43})
-    wrong_password = 'aaaaaaaaaaa'
+    wrong_password = b'aaaaaaaaaaa'
     assert C.NK_change_update_password(wrong_password, DefaultPasswords.UPDATE_TEMP) == DeviceErrorCode.WRONG_PASSWORD
     assert C.NK_change_update_password(DefaultPasswords.UPDATE, DefaultPasswords.UPDATE_TEMP) == DeviceErrorCode.STATUS_OK
     assert C.NK_change_update_password(DefaultPasswords.UPDATE_TEMP, DefaultPasswords.UPDATE) == DeviceErrorCode.STATUS_OK
-- 
cgit v1.2.3