main.py 1.83 KB
Newer Older
1
#!/usr/bin/env python3
Marek Behun's avatar
Marek Behun committed
2

3
import sys
Vojtech Myslivec's avatar
Vojtech Myslivec committed
4
import os
Marek Behun's avatar
Marek Behun committed
5 6 7
from hashlib import sha512
from struct import pack, unpack

8 9 10 11 12

SYSFS_ROOT = "/sys/devices/platform/soc/soc:internal-regs@d0000000/soc:internal-regs@d0000000:crypto@0/"
PUBKEY_PATH = SYSFS_ROOT + "mox_pubkey"
SIGN_PATH = SYSFS_ROOT + "mox_do_sign"

13 14 15 16 17 18 19
# max number of bytes to read from sysfs sig file
MAX_SIGNATURE_LENGTH = 512


def errprint(*args, **kwargs):
    print(*args, **kwargs, file=sys.stderr)

20

Marek Behun's avatar
Marek Behun committed
21
def change_endian(s):
22 23 24 25 26 27
    res = b''
    for i in range(0, len(s), 4):
        res += pack(">I", unpack("<I", s[i:i+4])[0])
    return res


Vojtech Myslivec's avatar
Vojtech Myslivec committed
28 29 30 31 32 33
def check_sysfs():
    if not os.path.isdir(SYSFS_ROOT):
        errprint("sysfs root directory does not exists (probably not running on MOX device)")
        exit(2)


34 35 36 37 38
def check_pubkey():
    try:
        with open(PUBKEY_PATH, "r") as f:
            pubkey = f.readline()
    except (FileNotFoundError, PermissionError):
Vojtech Myslivec's avatar
Vojtech Myslivec committed
39 40
        errprint("The sysfs API is probably broken – could not find MOX pubkey file")
        exit(3)
Marek Behun's avatar
Marek Behun committed
41

42 43 44
    if pubkey in ["", "\n", "none\n"]:
        errprint("This device does not have its OTP key generated or accessible")
        exit(2)
Marek Behun's avatar
Marek Behun committed
45 46


47
def sign_message(message):
Vojtech Myslivec's avatar
Vojtech Myslivec committed
48 49
    check_pubkey()

50
    h = sha512()
51
    h.update(bytes(message, encoding="utf-8"))
52
    dig = h.digest()
Marek Behun's avatar
Marek Behun committed
53

54 55 56 57 58 59
    try:
        with open(SIGN_PATH, "wb") as s:
            s.write(change_endian(dig))
        with open(SIGN_PATH, "rb") as s:
            sig = change_endian(s.read(MAX_SIGNATURE_LENGTH))
    except (FileNotFoundError, PermissionError):
Vojtech Myslivec's avatar
Vojtech Myslivec committed
60
        errprint("The sysfs API is probably broken – could not find MOX sign file")
61
        exit(3)
Marek Behun's avatar
Marek Behun committed
62

63
    print((sig[2:68] + sig[70:]).hex())
Marek Behun's avatar
Marek Behun committed
64 65


66
def main():
Vojtech Myslivec's avatar
Vojtech Myslivec committed
67
    check_sysfs()
68 69 70 71

    if len(sys.argv) < 2:
        print("message not given")
        exit(1)
Marek Behun's avatar
Marek Behun committed
72

73 74
    message = sys.argv[1]
    sign_message(message)
Marek Behun's avatar
Marek Behun committed
75 76


77 78
if __name__ == "__main__":
    main()