diff options
-rw-r--r-- | Makefile | 10 | ||||
-rwxr-xr-x | cryptech_muxd | 12 | ||||
-rw-r--r-- | ecdsa.c | 6 | ||||
-rw-r--r-- | libhal.py | 5 | ||||
-rw-r--r-- | rpc_pkey.c | 20 | ||||
-rw-r--r-- | unit-tests.py | 11 |
6 files changed, 41 insertions, 23 deletions
@@ -27,13 +27,13 @@ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# Number of static hash and HMAC state blocks to allocate. -# Numbers pulled out of a hat, just testing. +# Number of various kinds of static state blocks to allocate. +# Numbers pulled out of a hat, tune as we go. STATIC_CORE_STATE_BLOCKS = 32 -STATIC_HASH_STATE_BLOCKS = 10 -STATIC_HMAC_STATE_BLOCKS = 4 -STATIC_PKEY_STATE_BLOCKS = 32 +STATIC_HASH_STATE_BLOCKS = 32 +STATIC_HMAC_STATE_BLOCKS = 16 +STATIC_PKEY_STATE_BLOCKS = 256 STATIC_KS_VOLATILE_SLOTS = 128 INC = hal.h hal_internal.h diff --git a/cryptech_muxd b/cryptech_muxd index d51e38b..269ac15 100755 --- a/cryptech_muxd +++ b/cryptech_muxd @@ -149,12 +149,14 @@ class RPCIOStream(SerialIOStream): self.queues[handle] = queue with (yield self.rpc_input_lock.acquire()): yield self.write(query) + logger.debug("RPC sent") @tornado.gen.coroutine def rpc_output_loop(self): "Handle reply stream HSM -> network." while True: try: + logger.debug("RPC UART read") reply = yield self.read_until(SLIP_END) except tornado.iostream.StreamClosedError: logger.info("RPC UART closed") @@ -166,6 +168,8 @@ class RPCIOStream(SerialIOStream): handle = client_handle_get(slip_decode(reply)) except: continue + logger.debug("RPC queue put: handle 0x%x, qsize %s, maxsize %s", + handle, self.queues[handle].qsize(), self.queues[handle].maxsize) self.queues[handle].put_nowait(reply) @@ -181,25 +185,29 @@ class RPCServer(PFUnixServer): @tornado.gen.coroutine def handle_stream(self, stream, address): "Handle one network connection." - logger.info("RPC connected %r", stream) handle = stream.socket.fileno() queue = tornado.queues.Queue() + logger.info("RPC connected %r, handle 0x%x", stream, handle) while True: try: + logger.debug("RPC socket read, handle 0x%x", handle) query = yield stream.read_until(SLIP_END) if len(query) < 9: continue query = slip_encode(client_handle_set(slip_decode(query), handle)) yield self.serial.rpc_input(query, handle, queue) + logger.debug("RPC queue wait, handle 0x%x", handle) reply = yield queue.get() if reply is None: raise QueuedStreamClosedError() + logger.debug("RPC socket write, handle 0x%x", handle) yield stream.write(SLIP_END + reply) except tornado.iostream.StreamClosedError: - logger.info("RPC closing %r", stream) + logger.info("RPC closing %r, handle 0x%x", stream, handle) stream.close() return + class CTYIOStream(SerialIOStream): """ Tornado IOStream for a serial console channel. @@ -1010,7 +1010,8 @@ hal_error_t hal_ecdsa_key_gen(const hal_core_t *core, if ((err = point_pick_random(curve, key->d, key->Q)) != HAL_OK) return err; - assert(point_is_on_curve(key->Q, curve)); + if (!point_is_on_curve(key->Q, curve)) + return HAL_ERROR_KEY_NOT_ON_CURVE; *key_ = key; return HAL_OK; @@ -1668,7 +1669,8 @@ hal_error_t hal_ecdsa_sign(const hal_core_t *core, if ((err = point_pick_random(curve, k, R)) != HAL_OK) goto fail; - assert(point_is_on_curve(R, curve)); + if (!point_is_on_curve(R, curve)) + lose(HAL_ERROR_IMPOSSIBLE); if (fp_mod(R->x, n, r) != FP_OKAY) lose(HAL_ERROR_IMPOSSIBLE); @@ -391,8 +391,9 @@ class PKey(Handle): def verify(self, hash = 0, data = "", signature = None): self.hsm.pkey_verify(self, hash = hash, data = data, signature = signature) - def set_attributes(self, attributes): - self.hsm.pkey_set_attributes(self, attributes) + def set_attributes(self, attributes = None, **kwargs): + assert if attributes is None or not kwargs + self.hsm.pkey_set_attributes(self, attributes or kwargs) def get_attributes(self, attributes): attrs = self.hsm.pkey_get_attributes(self, attributes, 0) @@ -44,11 +44,11 @@ #endif #if HAL_STATIC_PKEY_STATE_BLOCKS > 0 -static hal_pkey_slot_t pkey_handle[HAL_STATIC_PKEY_STATE_BLOCKS]; +static hal_pkey_slot_t pkey_slot[HAL_STATIC_PKEY_STATE_BLOCKS]; #endif /* - * Handle allocation is simple: look for an unused (HAL_KEY_TYPE_NONE) + * Handle allocation is simple: look for an unused (HAL_HANDLE_NONE) * slot in the table, and, assuming we find one, construct a composite * handle consisting of the index into the table and a counter whose * sole purpose is to keep the same handle from reoccurring anytime @@ -74,13 +74,13 @@ static inline hal_pkey_slot_t *alloc_slot(const hal_key_flags_t flags) if ((flags & HAL_KEY_FLAG_TOKEN) != 0) glop |= HAL_PKEY_HANDLE_TOKEN_FLAG; - for (int i = 0; slot == NULL && i < sizeof(pkey_handle)/sizeof(*pkey_handle); i++) { - if (pkey_handle[i].type != HAL_KEY_TYPE_NONE) + for (int i = 0; slot == NULL && i < sizeof(pkey_slot)/sizeof(*pkey_slot); i++) { + if (pkey_slot[i].pkey_handle.handle != HAL_HANDLE_NONE) continue; - memset(&pkey_handle[i], 0, sizeof(pkey_handle[i])); - pkey_handle[i].pkey_handle.handle = i | glop; - pkey_handle[i].hint = -1; - slot = &pkey_handle[i]; + memset(&pkey_slot[i], 0, sizeof(pkey_slot[i])); + pkey_slot[i].pkey_handle.handle = i | glop; + pkey_slot[i].hint = -1; + slot = &pkey_slot[i]; } #endif @@ -101,8 +101,8 @@ static inline hal_pkey_slot_t *find_handle(const hal_pkey_handle_t handle) #if HAL_STATIC_PKEY_STATE_BLOCKS > 0 const int i = (int) (handle.handle & 0xFFFF); - if (i < sizeof(pkey_handle)/sizeof(*pkey_handle) && pkey_handle[i].pkey_handle.handle == handle.handle) - slot = &pkey_handle[i]; + if (i < sizeof(pkey_slot)/sizeof(*pkey_slot) && pkey_slot[i].pkey_handle.handle == handle.handle) + slot = &pkey_slot[i]; #endif hal_critical_section_end(); diff --git a/unit-tests.py b/unit-tests.py index c1d0d44..bc7edf7 100644 --- a/unit-tests.py +++ b/unit-tests.py @@ -75,14 +75,20 @@ def main(): global args args = parse_arguments(argv[1:]) argv = argv[:1] + args.only_test - logging.basicConfig(level = logging.DEBUG if args.debug else logging.INFO) - unittest.main(verbosity = 1 if args.quiet else 2, argv = argv, catchbreak = True, testRunner = TextTestRunner) + logging.basicConfig(level = logging.DEBUG if args.debug else logging.INFO, + datefmt = "%Y-%m-%d %H:%M:%S", + format = "%(asctime)-15s %(name)s[%(process)d]:%(levelname)s: %(message)s",) + unittest.main(verbosity = 1 if args.quiet else 2, + argv = argv, + catchbreak = True, + testRunner = TextTestRunner) def parse_arguments(argv = ()): from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter parser = ArgumentParser(description = __doc__, formatter_class = ArgumentDefaultsHelpFormatter) parser.add_argument("--quiet", action = "store_true", help = "suppress chatter") parser.add_argument("--debug", action = "store_true", help = "debug-level logging") + parser.add_argument("--io-log", action = "store_true", help = "log HSM I/O stream") parser.add_argument("--wheel-pin", default = "fnord", help = "PIN for wheel user") parser.add_argument("--so-pin", default = "fnord", help = "PIN for security officer") parser.add_argument("--user-pin", default = "fnord", help = "PIN for normal user") @@ -99,6 +105,7 @@ pin_map = { HAL_USER_NORMAL : "user_pin", HAL_USER_SO : "so_pin", HAL_USER_WHEEL def setUpModule(): global hsm hsm = HSM() + hsm.debug_io = args.io_log def tearDownModule(): hsm.logout() |