diff --git a/tools/pico-hsm-tool.py b/tools/pico-hsm-tool.py index 76993c7..51fa099 100644 --- a/tools/pico-hsm-tool.py +++ b/tools/pico-hsm-tool.py @@ -101,7 +101,6 @@ def parse_args(): subparser_cipher = parser_cipher.add_subparsers(title='commands', dest='subcommand') parser_cipher_encrypt = subparser_cipher.add_parser('encrypt', help='Performs encryption.') parser_cipher_decrypt = subparser_cipher.add_parser('decrypt', help='Performs decryption.') - parser_cipher_keygen = subparser_cipher.add_parser('keygen', help='Generates new AES key.') parser_cipher_hmac = subparser_cipher.add_parser('mac', help='Computes MAC (HMAC or CMAC).') parser_cipher_kdf = subparser_cipher.add_parser('kdf', help='Performs key derivation function on a secret key.') parser_cipher_encrypt.add_argument('--alg', choices=['CHACHAPOLY','AES-ECB','AES-CBC','AES-OFB','AES-CFB','AES-GCM','AES-CCM','AES-CTR','AES-XTS'], required=True) @@ -120,20 +119,12 @@ def parse_args(): parser_cipher.add_argument('-k', '--key', help='The private key index', metavar='KEY_ID', required=all(['keygen' not in s for s in sys.argv])) parser_cipher.add_argument('-s', '--key-size', default=32, help='Size of the key in bytes.') - parser_x25519 = argparse.ArgumentParser(add_help=False) - subparser_x25519 = parser_x25519.add_subparsers(title='commands', dest='subcommand') - parser_x25519_keygen = subparser_x25519.add_parser('keygen', help='Generates a keypair for X25519 or X448.') - parser_x25519.add_argument('-k', '--key', help='The private key index', metavar='KEY_ID', required=True) - - # Subparsers based on parent - - parser_create = subparser.add_parser("x25519", parents=[parser_x25519], - help='X25519 key management.') - # Add some arguments exclusively for parser_create - - parser_update = subparser.add_parser("x448", parents=[parser_x25519], - help='X448 key management.') - # Add some arguments exclusively for parser_update + parser_keygen = subparser.add_parser('keygen', help='Generates private keypair or secret key.') + subparser_keygen = parser_keygen.add_subparsers(title='commands', dest='subcommand', required=True) + parser_keygen_aes = subparser_keygen.add_parser('aes', help='Generates an AES key.') + parser_keygen_aes.add_argument('--size', help='Specifies the size of AES key [128, 192 or 256]',choices=[128, 192, 256], default=128) + parser_keygen_x25519 = subparser_keygen.add_parser('x25519', help='Generates a private X25519 keypair.') + parser_keygen_x448 = subparser_keygen.add_parser('x448', help='Generates a private X448 keypair.') args = parser.parse_args() return args @@ -361,119 +352,97 @@ def secure(picohsm, args): slck.disable_device_aut() def cipher(picohsm, args): - if (args.subcommand == 'keygen'): - ret = picohsm.key_generation(KeyType.AES, param=args.key_size * 8) - print('Key generated successfully.') - print(f'Key ID: {ret}') + if (args.file_in): + fin = open(args.file_in, 'rb') else: - if (args.file_in): - fin = open(args.file_in, 'rb') - else: - fin = sys.stdin.buffer - enc = fin.read() - fin.close() - iv = args.iv - if (args.iv and args.hex): - iv = unhexlify(iv) - aad = args.aad - if (args.aad and args.hex): - aad = unhexlify(aad) - kid = int(args.key) + fin = sys.stdin.buffer + enc = fin.read() + fin.close() + iv = args.iv + if (args.iv and args.hex): + iv = unhexlify(iv) + aad = args.aad + if (args.aad and args.hex): + aad = unhexlify(aad) + kid = int(args.key) - mode = EncryptionMode.ENCRYPT if args.subcommand[0] == 'e' else EncryptionMode.DECRYPT - if (args.alg == 'CHACHAPOLY'): - ret = picohsm.chachapoly(kid, mode, data=enc, iv=iv, aad=aad) - elif (args.alg == 'AES-ECB'): - ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.ECB, data=enc, iv=iv, aad=aad) - elif (args.alg == 'AES-CBC'): - ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.CBC, data=enc, iv=iv, aad=aad) - elif (args.alg == 'AES-OFB'): - ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.OFB, data=enc, iv=iv, aad=aad) - elif (args.alg == 'AES-CFB'): - ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.CFB, data=enc, iv=iv, aad=aad) - elif (args.alg == 'AES-GCM'): - ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.GCM, data=enc, iv=iv, aad=aad) - elif (args.alg == 'AES-CCM'): - ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.CCM, data=enc, iv=iv, aad=aad) - elif (args.alg == 'AES-CTR'): - ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.CTR, data=enc, iv=iv, aad=aad) - elif (args.alg == 'AES-XTS'): - ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.XTS, data=enc, iv=iv, aad=aad) - elif (args.alg == 'CMAC'): - ret = picohsm.cmac(keyid=kid, data=enc) - elif (args.alg == 'HMAC-SHA1'): - ret = picohsm.hmac(hashes.SHA1, kid, data=enc) - elif (args.alg == 'HMAC-SHA224'): - ret = picohsm.hmac(hashes.SHA224, kid, data=enc) - elif (args.alg == 'HMAC-SHA256'): - ret = picohsm.hmac(hashes.SHA256, kid, data=enc) - elif (args.alg == 'HMAC-SHA384'): - ret = picohsm.hmac(hashes.SHA384, kid, data=enc) - elif (args.alg == 'HMAC-SHA512'): - ret = picohsm.hmac(hashes.SHA512, kid, data=enc) - elif (args.alg == 'HKDF-SHA256'): - ret = picohsm.hkdf(hashes.SHA256, kid, data=enc, salt=iv, out_len=args.output_len) - elif (args.alg == 'HKDF-SHA384'): - ret = picohsm.hkdf(hashes.SHA384, kid, data=enc, salt=iv, out_len=args.output_len) - elif (args.alg == 'HKDF-SHA512'): - ret = picohsm.hkdf(hashes.SHA512, kid, data=enc, salt=iv, out_len=args.output_len) - elif (args.alg == 'PBKDF2-SHA1'): - ret = picohsm.pbkdf2(hashes.SHA1, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) - elif (args.alg == 'PBKDF2-SHA224'): - ret = picohsm.pbkdf2(hashes.SHA224, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) - elif (args.alg == 'PBKDF2-SHA256'): - ret = picohsm.pbkdf2(hashes.SHA256, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) - elif (args.alg == 'PBKDF2-SHA384'): - ret = picohsm.pbkdf2(hashes.SHA384, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) - elif (args.alg == 'PBKDF2-SHA512'): - ret = picohsm.pbkdf2(hashes.SHA512, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) - elif (args.alg == 'X963-SHA1'): - ret = picohsm.x963(hashes.SHA1, kid, data=enc, out_len=args.output_len) - elif (args.alg == 'X963-SHA224'): - ret = picohsm.x963(hashes.SHA224, kid, data=enc, out_len=args.output_len) - elif (args.alg == 'X963-SHA256'): - ret = picohsm.x963(hashes.SHA256, kid, data=enc, out_len=args.output_len) - elif (args.alg == 'X963-SHA384'): - ret = picohsm.x963(hashes.SHA384, kid, data=enc, out_len=args.output_len) - elif (args.alg == 'X963-SHA512'): - ret = picohsm.x963(hashes.SHA512, kid, data=enc, out_len=args.output_len) + mode = EncryptionMode.ENCRYPT if args.subcommand[0] == 'e' else EncryptionMode.DECRYPT + if (args.alg == 'CHACHAPOLY'): + ret = picohsm.chachapoly(kid, mode, data=enc, iv=iv, aad=aad) + elif (args.alg == 'AES-ECB'): + ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.ECB, data=enc, iv=iv, aad=aad) + elif (args.alg == 'AES-CBC'): + ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.CBC, data=enc, iv=iv, aad=aad) + elif (args.alg == 'AES-OFB'): + ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.OFB, data=enc, iv=iv, aad=aad) + elif (args.alg == 'AES-CFB'): + ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.CFB, data=enc, iv=iv, aad=aad) + elif (args.alg == 'AES-GCM'): + ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.GCM, data=enc, iv=iv, aad=aad) + elif (args.alg == 'AES-CCM'): + ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.CCM, data=enc, iv=iv, aad=aad) + elif (args.alg == 'AES-CTR'): + ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.CTR, data=enc, iv=iv, aad=aad) + elif (args.alg == 'AES-XTS'): + ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.XTS, data=enc, iv=iv, aad=aad) + elif (args.alg == 'CMAC'): + ret = picohsm.cmac(keyid=kid, data=enc) + elif (args.alg == 'HMAC-SHA1'): + ret = picohsm.hmac(hashes.SHA1, kid, data=enc) + elif (args.alg == 'HMAC-SHA224'): + ret = picohsm.hmac(hashes.SHA224, kid, data=enc) + elif (args.alg == 'HMAC-SHA256'): + ret = picohsm.hmac(hashes.SHA256, kid, data=enc) + elif (args.alg == 'HMAC-SHA384'): + ret = picohsm.hmac(hashes.SHA384, kid, data=enc) + elif (args.alg == 'HMAC-SHA512'): + ret = picohsm.hmac(hashes.SHA512, kid, data=enc) + elif (args.alg == 'HKDF-SHA256'): + ret = picohsm.hkdf(hashes.SHA256, kid, data=enc, salt=iv, out_len=args.output_len) + elif (args.alg == 'HKDF-SHA384'): + ret = picohsm.hkdf(hashes.SHA384, kid, data=enc, salt=iv, out_len=args.output_len) + elif (args.alg == 'HKDF-SHA512'): + ret = picohsm.hkdf(hashes.SHA512, kid, data=enc, salt=iv, out_len=args.output_len) + elif (args.alg == 'PBKDF2-SHA1'): + ret = picohsm.pbkdf2(hashes.SHA1, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) + elif (args.alg == 'PBKDF2-SHA224'): + ret = picohsm.pbkdf2(hashes.SHA224, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) + elif (args.alg == 'PBKDF2-SHA256'): + ret = picohsm.pbkdf2(hashes.SHA256, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) + elif (args.alg == 'PBKDF2-SHA384'): + ret = picohsm.pbkdf2(hashes.SHA384, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) + elif (args.alg == 'PBKDF2-SHA512'): + ret = picohsm.pbkdf2(hashes.SHA512, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) + elif (args.alg == 'X963-SHA1'): + ret = picohsm.x963(hashes.SHA1, kid, data=enc, out_len=args.output_len) + elif (args.alg == 'X963-SHA224'): + ret = picohsm.x963(hashes.SHA224, kid, data=enc, out_len=args.output_len) + elif (args.alg == 'X963-SHA256'): + ret = picohsm.x963(hashes.SHA256, kid, data=enc, out_len=args.output_len) + elif (args.alg == 'X963-SHA384'): + ret = picohsm.x963(hashes.SHA384, kid, data=enc, out_len=args.output_len) + elif (args.alg == 'X963-SHA512'): + ret = picohsm.x963(hashes.SHA512, kid, data=enc, out_len=args.output_len) - if (args.file_out): - fout = open(args.file_out, 'wb') - else: - fout = sys.stdout.buffer - if (args.hex): - fout.write(hexlify(bytes(ret))) - else: - fout.write(bytes(ret)) - if (args.file_out): - fout.close() + if (args.file_out): + fout = open(args.file_out, 'wb') + else: + fout = sys.stdout.buffer + if (args.hex): + fout.write(hexlify(bytes(ret))) + else: + fout.write(bytes(ret)) + if (args.file_out): + fout.close() -def x25519(picohsm, args): - if (args.command == 'x25519'): - P = b'\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xed' - A = utils.int_to_bytes(0x01DB42) - N = b'\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\xDE\xF9\xDE\xA2\xF7\x9C\xD6\x58\x12\x63\x1A\x5C\xF5\xD3\xED' - G = b'\x04\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd9\xd3\xce\x7e\xa2\xc5\xe9\x29\xb2\x61\x7c\x6d\x7e\x4d\x3d\x92\x4c\xd1\x48\x77\x2c\xdd\x1e\xe0\xb4\x86\xa0\xb8\xa1\x19\xae\x20' - h = b'\x08' - elif (args.command == 'x448'): - P = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' - A = utils.int_to_bytes(0x98AA) - N = b'\x3f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\xca\x23\xe9\xc4\x4e\xdb\x49\xae\xd6\x36\x90\x21\x6c\xc2\x72\x8d\xc5\x8f\x55\x23\x78\xc2\x92\xab\x58\x44\xf3' - G = b'\x04\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\x5b\x7b\x45\x3d\x22\xd7\x6f\xf7\x7a\x67\x50\xb1\xc4\x12\x13\x21\x0d\x43\x46\x23\x7e\x02\xb8\xed\xf6\xf3\x8d\xc2\x5d\xf7\x60\xd0\x45\x55\xf5\x34\x5d\xae\xcb\xce\x6f\x32\x58\x6e\xab\x98\x6c\xf6\xb1\xf5\x95\x12\x5d\x23\x7d' - h = b'\x04' - oid = b'\x06\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x02\x03' - p_data = b'\x81' + bytes([len(P)]) + P - a_data = b'\x82' + bytes([len(A)]) + A - g_data = b'\x84' + bytes([len(G)]) + G - n_data = b'\x85' + bytes([len(N)]) + N - h_data = b'\x87' + bytes([len(h)]) + h - - cdata = b'\x5F\x29\x01\x00' - cdata += b'\x42\x0C\x55\x54\x44\x55\x4D\x4D\x59\x30\x30\x30\x30\x31' - cdata += b'\x7f\x49\x81' + bytes([len(oid)+len(p_data)+len(a_data)+len(g_data)+len(n_data)+len(h_data)]) + oid + p_data + a_data + g_data + n_data + h_data - cdata += b'\x5F\x20\x0C\x55\x54\x44\x55\x4D\x4D\x59\x30\x30\x30\x30\x31' - ret = picohsm.send(command=0x46, p1=int(args.key), data=list(cdata)) +def keygen(picohsm, args): + if (args.subcommand == 'aes'): + ret = picohsm.key_generation(KeyType.AES, param=args.size) + elif (args.subcommand in ['x25519', 'x448']): + curve = 'curve' + args.subcommand[1:] + ret = picohsm.key_generation(KeyType.ECC, curve) + print('Key generated successfully.') + print(f'Key ID: {ret}') def main(args): sys.stderr.buffer.write(b'Pico HSM Tool v1.10\n') @@ -499,8 +468,8 @@ def main(args): secure(picohsm, args) elif (args.command == 'cipher'): cipher(picohsm, args) - elif (args.command == 'x25519' or args.command == 'x448'): - x25519(picohsm, args) + elif (args.command == 'keygen'): + keygen(picohsm, args) def run():