2022-09-19 02:51:11 -04:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
#=======================================================================
|
|
|
|
#
|
|
|
|
# tpt.py
|
|
|
|
# ------
|
|
|
|
# TillitisKey Provisioning Tool.
|
|
|
|
#
|
|
|
|
# The tool use HKDF (RFC5869) to generate the UDS.
|
|
|
|
#
|
2023-01-05 08:10:49 -05:00
|
|
|
# Copyright (C) 2022, 2023 - Tillitis AB
|
2022-09-19 02:51:11 -04:00
|
|
|
# SPDX-License-Identifier: GPL-2.0-only
|
|
|
|
#
|
|
|
|
#=======================================================================
|
|
|
|
|
2022-11-29 06:46:04 -05:00
|
|
|
import os
|
2022-09-19 02:51:11 -04:00
|
|
|
import sys
|
|
|
|
import argparse
|
|
|
|
from secrets import token_bytes
|
|
|
|
from binascii import unhexlify
|
|
|
|
from hkdf import Hkdf
|
|
|
|
|
2023-01-05 08:10:49 -05:00
|
|
|
VID_MAX = 2**16 - 1
|
|
|
|
PID_MAX = 2**6 - 1
|
|
|
|
REV_MAX = 2**6 - 1
|
|
|
|
SERIAL_MAX_EXPR = "(2**32-1)"
|
|
|
|
SERIAL_MAX = eval(SERIAL_MAX_EXPR)
|
2022-09-19 02:51:11 -04:00
|
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
#-------------------------------------------------------------------
|
2022-09-21 03:38:44 -04:00
|
|
|
def gen_uds(verbose, arg_ent):
|
2022-09-19 02:51:11 -04:00
|
|
|
if verbose:
|
|
|
|
print("\nGenerating UDS")
|
|
|
|
|
2022-09-21 03:38:44 -04:00
|
|
|
if arg_ent == None:
|
|
|
|
ent = str.encode(input("Enter additional entropy: "))
|
2022-09-19 02:51:11 -04:00
|
|
|
else:
|
2022-09-21 03:38:44 -04:00
|
|
|
ent = str.encode(arg_ent)
|
2022-09-19 02:51:11 -04:00
|
|
|
|
|
|
|
ikm = token_bytes(256)
|
2022-09-21 03:38:44 -04:00
|
|
|
my_hkdf = Hkdf(ent, ikm)
|
2022-09-19 02:51:11 -04:00
|
|
|
uds = my_hkdf.expand(b"TillitisKey UDS", 32)
|
|
|
|
uds_hex = uds.hex()
|
|
|
|
|
|
|
|
if verbose:
|
|
|
|
print("\nGenerated UDS:")
|
|
|
|
print(uds_hex, "\n")
|
|
|
|
|
|
|
|
return uds_hex
|
|
|
|
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
def save_uds(verbose, uds):
|
2022-11-29 06:46:04 -05:00
|
|
|
outpath = os.path.abspath("uds.hex")
|
2022-09-19 02:51:11 -04:00
|
|
|
if verbose:
|
2022-11-29 06:46:04 -05:00
|
|
|
print("Writing %s" % (outpath))
|
2022-09-19 02:51:11 -04:00
|
|
|
|
2022-11-29 06:46:04 -05:00
|
|
|
with open (outpath, 'w', encoding = 'utf-8') as uds_file:
|
2022-09-19 02:51:11 -04:00
|
|
|
for i in range(8):
|
|
|
|
uds_file.write(uds[(i*8) : (i*8 + 8)]+"\n")
|
|
|
|
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
def gen_udi(verbose, pid, vid, rev, serial):
|
|
|
|
if verbose:
|
|
|
|
print("Generating UDI")
|
|
|
|
|
|
|
|
if vid == None:
|
2023-01-05 08:10:49 -05:00
|
|
|
vid = int(input("Enter Vendor ID (0 -- %d): " % VID_MAX))
|
2022-09-19 02:51:11 -04:00
|
|
|
|
|
|
|
if pid == None:
|
2023-01-05 08:10:49 -05:00
|
|
|
pid = int(input("Enter Product ID (0 -- %d): " % PID_MAX))
|
2022-09-19 02:51:11 -04:00
|
|
|
|
|
|
|
if rev == None:
|
2023-01-05 08:10:49 -05:00
|
|
|
rev = int(input("Enter Product Revision (0 -- %d): " % REV_MAX))
|
2022-09-19 02:51:11 -04:00
|
|
|
|
|
|
|
if serial == None:
|
2023-01-05 08:10:49 -05:00
|
|
|
serial = int(input("Enter serial number (0 -- %d %s): " % (SERIAL_MAX, SERIAL_MAX_EXPR)))
|
2022-09-19 02:51:11 -04:00
|
|
|
|
2023-01-05 08:10:49 -05:00
|
|
|
assert vid <= VID_MAX
|
|
|
|
assert pid <= PID_MAX
|
|
|
|
assert rev <= REV_MAX
|
|
|
|
assert serial <= SERIAL_MAX
|
2022-09-19 02:51:11 -04:00
|
|
|
|
2023-01-05 08:10:49 -05:00
|
|
|
udi_hex = "0%04x%03x%08x" % (vid, pid << 6 | rev, serial)
|
2022-09-19 02:51:11 -04:00
|
|
|
|
|
|
|
if verbose:
|
|
|
|
print("\nGenerated UDI:")
|
|
|
|
print(udi_hex, "\n")
|
|
|
|
|
|
|
|
return udi_hex
|
|
|
|
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
def save_udi(verbose, udi):
|
2022-11-29 06:46:04 -05:00
|
|
|
outpath = os.path.abspath("udi.hex")
|
2022-09-19 02:51:11 -04:00
|
|
|
if verbose:
|
2022-11-29 06:46:04 -05:00
|
|
|
print("Writing %s" % (outpath))
|
2022-09-19 02:51:11 -04:00
|
|
|
|
2022-11-29 06:46:04 -05:00
|
|
|
with open (outpath, 'w', encoding = 'utf-8') as udi_file:
|
2022-09-19 02:51:11 -04:00
|
|
|
udi_file.write(udi[0 : 8] + "\n")
|
|
|
|
udi_file.write(udi[8 : 16] + "\n")
|
|
|
|
|
|
|
|
def enc_str(b):
|
|
|
|
return bytestring.decode(sys.getfilesystemencoding())
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
def main():
|
|
|
|
parser = argparse.ArgumentParser()
|
|
|
|
parser.add_argument("-v", "--verbose", help="Verbose operation", action="store_true")
|
2022-09-21 03:38:44 -04:00
|
|
|
parser.add_argument("--ent", help="User supplied entropy", type=str)
|
2023-01-05 08:10:49 -05:00
|
|
|
parser.add_argument("--vid", help="Vendor ID (0 -- %d)" % VID_MAX, type=int)
|
|
|
|
parser.add_argument("--pid", help="Product ID (0 -- %d" % PID_MAX, type=int)
|
|
|
|
parser.add_argument("--rev", help="Product Revision (0 -- %d)" % REV_MAX, type=int)
|
|
|
|
parser.add_argument("--serial", help="Serial number (0 -- %d %s)" % (SERIAL_MAX, SERIAL_MAX_EXPR), type=int)
|
2022-09-19 02:51:11 -04:00
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
|
|
if args.verbose:
|
|
|
|
print("TillitisKey Provisining Tool (TPT)")
|
|
|
|
|
2022-09-21 03:38:44 -04:00
|
|
|
uds = gen_uds(args.verbose, args.ent)
|
2022-09-19 02:51:11 -04:00
|
|
|
save_uds(args.verbose, uds)
|
|
|
|
|
|
|
|
udi = gen_udi(args.verbose, args.pid, args.vid, args.rev, args.serial)
|
|
|
|
save_udi(args.verbose, udi)
|
|
|
|
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
if __name__=="__main__":
|
|
|
|
sys.exit(main())
|