From 99c8452187b2f99a92fbbea50ea1968d209b7c44 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Thu, 27 Apr 2017 12:45:52 -0400 Subject: Refactor cryptech_upload to work either directly or via cryptech_muxd. --- projects/hsm/cryptech_upload | 190 +++++++++++++++++++++++++++++-------------- 1 file changed, 131 insertions(+), 59 deletions(-) diff --git a/projects/hsm/cryptech_upload b/projects/hsm/cryptech_upload index 559195d..b6e02bd 100755 --- a/projects/hsm/cryptech_upload +++ b/projects/hsm/cryptech_upload @@ -37,6 +37,7 @@ import sys import time import struct import serial +import socket import getpass import os.path import tarfile @@ -46,7 +47,7 @@ import platform from binascii import crc32 FIRMWARE_CHUNK_SIZE = 4096 -FPGA_CHUNK_SIZE = 4096 +FPGA_CHUNK_SIZE = 4096 def parse_args(): @@ -70,6 +71,12 @@ def parse_args(): help = "Name of management port USB serial device", ) + parser.add_argument("--socket", + default = os.getenv("CRYPTECH_CTY_CLIENT_SOCKET_NAME", + "/tmp/.cryptech_muxd.cty"), + help = "Name of cryptech_muxd management port socket", + ) + parser.add_argument("--firmware-tarball", type = argparse.FileType("rb"), default = default_tarball, @@ -126,63 +133,126 @@ def parse_args(): return parser.parse_args() -def _write(dst, data): - numeric = isinstance(data, (int, long)) - if numeric: - data = struct.pack(" ", "# ")): - print("Device does not seem to be ready for a file transfer (got {!r})".format(prompt)) - return prompt - _write(dst, cmd + "\r") - response = _read(dst) - return response + data = struct.pack(" ", "# ")): + print("Device does not seem to be ready for a file transfer (got {!r})".format(prompt)) + return prompt + self.write(cmd + "\r") + response = self.read() + return response + + +class ManagementPortSerial(ManagementPortAbstract): + """ + Implmentation of HSM management port abstraction over a direct + serial connection. + """ + + def __init__(self, args, timeout = 1): + super(ManagementPortSerial, self).__init__(args) + self.serial = serial.Serial(args.device, 921600, timeout = timeout) + + def send(self, data): + self.serial.write(data) + self.serial.flush() + + def recv(self): + return self.serial.read(1) + + def set_timeout(self, timeout): + self.serial.timeout = timeout + + def close(self): + self.serial.close() + +class ManagementPortSocket(ManagementPortAbstract): + """ + Implmentation of HSM management port abstraction over a PF_UNIX + socket connection to the cryptech_muxd management socket. + """ + + def __init__(self, args, timeout = 1): + super(ManagementPortSocket, self).__init__(args) + self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + self.socket.connect(args.socket) + self.socket.settimeout(timeout) + + def send(self, data): + self.socket.sendall(data) + + def recv(self): + try: + return self.socket.recv(1) + except socket.timeout: + return "" + + def set_timeout(self, timeout): + self.socket.settimeout(timeout) + + def close(self): + self.socket.close() + def send_file(src, size, args, dst): + """ + Upload an image from some file-like source to the management port. + Details depend on what kind of image it is. + """ + if args.fpga: chunk_size = FPGA_CHUNK_SIZE - response = _execute(dst, "fpga bitstream upload") + response = dst.execute("fpga bitstream upload") elif args.firmware: chunk_size = FIRMWARE_CHUNK_SIZE - response = _execute(dst, "firmware upload") + response = dst.execute("firmware upload") if "Rebooting" in response: - response = _execute(dst, "firmware upload") + response = dst.execute("firmware upload") elif args.bootloader: chunk_size = FIRMWARE_CHUNK_SIZE - response = _execute(dst, "bootloader upload") + response = dst.execute("bootloader upload") if "Access denied" in response: print "Access denied" return False @@ -190,12 +260,12 @@ def send_file(src, size, args, dst): print("Device did not accept the upload command (got {!r})".format(response)) return False - dst.timeout = 0.001 + dst.set_timeout(0.001) crc = 0 counter = 0 # 1. Write size of file (4 bytes) - _write(dst, struct.pack("